blob: 46bf8da5648ed2b4408d861d38488021ed1b6c3f [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"
291
Guido van Rossum00d93061998-05-28 23:06:38 +0000292/* Millisecond sleep() for Unix platforms. */
293
294static void
295Sleep(milli)
296 int milli;
297{
298 /* XXX Too bad if you don't have select(). */
299 struct timeval t;
300 double frac;
301 t.tv_sec = milli/1000;
302 t.tv_usec = (milli%1000) * 1000;
303 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
304}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000305#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000306#endif /* WITH_THREAD */
307
308
Guido van Rossum18468821994-06-20 07:49:28 +0000309static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000310AsString(value, tmp)
311 PyObject *value;
312 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000313{
Guido van Rossum35d43371997-08-02 00:09:09 +0000314 if (PyString_Check(value))
315 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000316 else {
317 PyObject *v = PyObject_Str(value);
318 PyList_Append(tmp, v);
319 Py_DECREF(v);
320 return PyString_AsString(v);
321 }
Guido van Rossum18468821994-06-20 07:49:28 +0000322}
323
Barry Warsawfa701a81997-01-16 00:15:11 +0000324
325
Guido van Rossum18468821994-06-20 07:49:28 +0000326#define ARGSZ 64
327
328static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000329Merge(args)
330 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000331{
Barry Warsawfa701a81997-01-16 00:15:11 +0000332 PyObject *tmp = NULL;
333 char *argvStore[ARGSZ];
334 char **argv = NULL;
335 int fvStore[ARGSZ];
336 int *fv = NULL;
337 int argc = 0, i;
338 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000339
Barry Warsawfa701a81997-01-16 00:15:11 +0000340 if (!(tmp = PyList_New(0)))
341 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000342
Barry Warsawfa701a81997-01-16 00:15:11 +0000343 argv = argvStore;
344 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000345
Barry Warsawfa701a81997-01-16 00:15:11 +0000346 if (args == NULL)
347 argc = 0;
348
349 else if (!PyTuple_Check(args)) {
350 argc = 1;
351 fv[0] = 0;
352 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000353 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000354 else {
355 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000356
Barry Warsawfa701a81997-01-16 00:15:11 +0000357 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000358 argv = (char **)ckalloc(argc * sizeof(char *));
359 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000360 if (argv == NULL || fv == NULL) {
361 PyErr_NoMemory();
362 goto finally;
363 }
364 }
365
366 for (i = 0; i < argc; i++) {
367 PyObject *v = PyTuple_GetItem(args, i);
368 if (PyTuple_Check(v)) {
369 fv[i] = 1;
370 if (!(argv[i] = Merge(v)))
371 goto finally;
372 }
373 else if (v == Py_None) {
374 argc = i;
375 break;
376 }
377 else {
378 fv[i] = 0;
379 argv[i] = AsString(v, tmp);
380 }
381 }
Guido van Rossum18468821994-06-20 07:49:28 +0000382 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000383 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000384
Barry Warsawfa701a81997-01-16 00:15:11 +0000385 finally:
386 for (i = 0; i < argc; i++)
387 if (fv[i]) {
388 ckfree(argv[i]);
389 }
390 if (argv != argvStore)
391 ckfree(FREECAST argv);
392 if (fv != fvStore)
393 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000394
Barry Warsawfa701a81997-01-16 00:15:11 +0000395 Py_DECREF(tmp);
396 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000397}
398
Barry Warsawfa701a81997-01-16 00:15:11 +0000399
400
Guido van Rossum18468821994-06-20 07:49:28 +0000401static PyObject *
Guido van Rossum00d93061998-05-28 23:06:38 +0000402Split(list)
Barry Warsawfa701a81997-01-16 00:15:11 +0000403 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000404{
Barry Warsawfa701a81997-01-16 00:15:11 +0000405 int argc;
406 char **argv;
407 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000408
Barry Warsawfa701a81997-01-16 00:15:11 +0000409 if (list == NULL) {
410 Py_INCREF(Py_None);
411 return Py_None;
412 }
Guido van Rossum18468821994-06-20 07:49:28 +0000413
Guido van Rossum00d93061998-05-28 23:06:38 +0000414 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000415 /* Not a list.
416 * Could be a quoted string containing funnies, e.g. {"}.
417 * Return the string itself.
418 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000419 return PyString_FromString(list);
420 }
Guido van Rossum18468821994-06-20 07:49:28 +0000421
Barry Warsawfa701a81997-01-16 00:15:11 +0000422 if (argc == 0)
423 v = PyString_FromString("");
424 else if (argc == 1)
425 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000426 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000427 int i;
428 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000429
Barry Warsawfa701a81997-01-16 00:15:11 +0000430 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000431 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000432 Py_DECREF(v);
433 v = NULL;
434 break;
435 }
436 PyTuple_SetItem(v, i, w);
437 }
438 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000439 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000440 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000441}
442
Barry Warsawfa701a81997-01-16 00:15:11 +0000443
444
Guido van Rossum18468821994-06-20 07:49:28 +0000445/**** Tkapp Object ****/
446
447#ifndef WITH_APPINIT
448int
Guido van Rossum35d43371997-08-02 00:09:09 +0000449Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000450 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000451{
Barry Warsawfa701a81997-01-16 00:15:11 +0000452 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000453
Barry Warsawfa701a81997-01-16 00:15:11 +0000454 main = Tk_MainWindow(interp);
455 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000456 PySys_WriteStderr("Tcl_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000457 return TCL_ERROR;
458 }
459 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000460 PySys_WriteStderr("Tk_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000461 return TCL_ERROR;
462 }
463 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000464}
465#endif /* !WITH_APPINIT */
466
Guido van Rossum18468821994-06-20 07:49:28 +0000467
Barry Warsawfa701a81997-01-16 00:15:11 +0000468
469
470/* Initialize the Tk application; see the `main' function in
471 * `tkMain.c'.
472 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000473
474static void EnableEventHook(); /* Forward */
475static void DisableEventHook(); /* Forward */
476
Barry Warsawfa701a81997-01-16 00:15:11 +0000477static TkappObject *
478Tkapp_New(screenName, baseName, className, interactive)
479 char *screenName;
480 char *baseName;
481 char *className;
482 int interactive;
483{
484 TkappObject *v;
485 char *argv0;
486
487 v = PyObject_NEW(TkappObject, &Tkapp_Type);
488 if (v == NULL)
489 return NULL;
490
491 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000492
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000493#if defined(macintosh) && TKMAJORMINOR >= 8000
494 /* This seems to be needed since Tk 8.0 */
495 ClearMenuBar();
496 TkMacInitMenus(v->interp);
497#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000498 /* Delete the 'exit' command, which can screw things up */
499 Tcl_DeleteCommand(v->interp, "exit");
500
Barry Warsawfa701a81997-01-16 00:15:11 +0000501 if (screenName != NULL)
502 Tcl_SetVar2(v->interp, "env", "DISPLAY",
503 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000504
Barry Warsawfa701a81997-01-16 00:15:11 +0000505 if (interactive)
506 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
507 else
508 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000509
Barry Warsawfa701a81997-01-16 00:15:11 +0000510 /* This is used to get the application class for Tk 4.1 and up */
511 argv0 = (char*)ckalloc(strlen(className) + 1);
512 if (!argv0) {
513 PyErr_NoMemory();
514 Py_DECREF(v);
515 return NULL;
516 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000517
Barry Warsawfa701a81997-01-16 00:15:11 +0000518 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000519 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000520 argv0[0] = tolower(argv0[0]);
521 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
522 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000523
Barry Warsawfa701a81997-01-16 00:15:11 +0000524 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000525 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000526
Guido van Rossum7bf15641998-05-22 18:28:17 +0000527 EnableEventHook();
528
Barry Warsawfa701a81997-01-16 00:15:11 +0000529 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000530}
531
Barry Warsawfa701a81997-01-16 00:15:11 +0000532
533
Guido van Rossum18468821994-06-20 07:49:28 +0000534/** Tcl Eval **/
535
536static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000537Tkapp_Call(self, args)
538 PyObject *self;
539 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000540{
Guido van Rossum212643f1998-04-29 16:22:14 +0000541 /* This is copied from Merge() */
542 PyObject *tmp = NULL;
543 char *argvStore[ARGSZ];
544 char **argv = NULL;
545 int fvStore[ARGSZ];
546 int *fv = NULL;
547 int argc = 0, i;
548 PyObject *res = NULL; /* except this has a different type */
549 Tcl_CmdInfo info; /* and this is added */
550 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
Guido van Rossum18468821994-06-20 07:49:28 +0000551
Guido van Rossum212643f1998-04-29 16:22:14 +0000552 if (!(tmp = PyList_New(0)))
553 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000554
Guido van Rossum212643f1998-04-29 16:22:14 +0000555 argv = argvStore;
556 fv = fvStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000557
Guido van Rossum212643f1998-04-29 16:22:14 +0000558 if (args == NULL)
559 argc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000560
Guido van Rossum212643f1998-04-29 16:22:14 +0000561 else if (!PyTuple_Check(args)) {
562 argc = 1;
563 fv[0] = 0;
564 argv[0] = AsString(args, tmp);
565 }
566 else {
567 argc = PyTuple_Size(args);
568
569 if (argc > ARGSZ) {
570 argv = (char **)ckalloc(argc * sizeof(char *));
571 fv = (int *)ckalloc(argc * sizeof(int));
572 if (argv == NULL || fv == NULL) {
573 PyErr_NoMemory();
574 goto finally;
575 }
576 }
577
578 for (i = 0; i < argc; i++) {
579 PyObject *v = PyTuple_GetItem(args, i);
580 if (PyTuple_Check(v)) {
581 fv[i] = 1;
582 if (!(argv[i] = Merge(v)))
583 goto finally;
584 }
585 else if (v == Py_None) {
586 argc = i;
587 break;
588 }
589 else {
590 fv[i] = 0;
591 argv[i] = AsString(v, tmp);
592 }
593 }
594 }
595 /* End code copied from Merge() */
596
597 /* All this to avoid a call to Tcl_Merge() and the corresponding call
598 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
599 if (Py_VerboseFlag >= 2) {
600 for (i = 0; i < argc; i++)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000601 PySys_WriteStderr("%s ", argv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000602 }
Guido van Rossum62320c91998-06-15 04:36:09 +0000603 ENTER_TCL
604 info.proc = NULL;
Guido van Rossum212643f1998-04-29 16:22:14 +0000605 if (argc < 1 ||
606 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
607 info.proc == NULL)
608 {
609 char *cmd;
Guido van Rossum212643f1998-04-29 16:22:14 +0000610 cmd = Tcl_Merge(argc, argv);
611 i = Tcl_Eval(interp, cmd);
Barry Warsawfa701a81997-01-16 00:15:11 +0000612 ckfree(cmd);
Guido van Rossum212643f1998-04-29 16:22:14 +0000613 }
614 else {
615 Tcl_ResetResult(interp);
616 i = (*info.proc)(info.clientData, interp, argc, argv);
617 }
Guido van Rossum62320c91998-06-15 04:36:09 +0000618 ENTER_OVERLAP
619 if (info.proc == NULL && Py_VerboseFlag >= 2)
620 PySys_WriteStderr("... use TclEval ");
Guido van Rossum212643f1998-04-29 16:22:14 +0000621 if (i == TCL_ERROR) {
622 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000623 PySys_WriteStderr("... error: '%s'\n",
Guido van Rossum212643f1998-04-29 16:22:14 +0000624 interp->result);
625 Tkinter_Error(self);
626 }
627 else {
628 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000629 PySys_WriteStderr("-> '%s'\n", interp->result);
Guido van Rossum212643f1998-04-29 16:22:14 +0000630 res = PyString_FromString(interp->result);
631 }
Guido van Rossum62320c91998-06-15 04:36:09 +0000632 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000633
Guido van Rossum212643f1998-04-29 16:22:14 +0000634 /* Copied from Merge() again */
635 finally:
636 for (i = 0; i < argc; i++)
637 if (fv[i]) {
638 ckfree(argv[i]);
639 }
640 if (argv != argvStore)
641 ckfree(FREECAST argv);
642 if (fv != fvStore)
643 ckfree(FREECAST fv);
644
645 Py_DECREF(tmp);
Barry Warsawfa701a81997-01-16 00:15:11 +0000646 return res;
647}
648
649
650static PyObject *
651Tkapp_GlobalCall(self, args)
652 PyObject *self;
653 PyObject *args;
654{
Guido van Rossum212643f1998-04-29 16:22:14 +0000655 /* Could do the same here as for Tkapp_Call(), but this is not used
656 much, so I can't be bothered. Unfortunately Tcl doesn't export a
657 way for the user to do what all its Global* variants do (save and
658 reset the scope pointer, call the local version, restore the saved
659 scope pointer). */
660
Guido van Rossum62320c91998-06-15 04:36:09 +0000661 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000662 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000663
Guido van Rossum62320c91998-06-15 04:36:09 +0000664 cmd = Merge(args);
Barry Warsawfa701a81997-01-16 00:15:11 +0000665 if (!cmd)
666 PyErr_SetString(Tkinter_TclError, "merge failed");
667
Guido van Rossum00d93061998-05-28 23:06:38 +0000668 else {
669 int err;
670 ENTER_TCL
671 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000672 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000673 if (err == TCL_ERROR)
674 res = Tkinter_Error(self);
675 else
676 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000677 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +0000678 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000679
680 if (cmd)
681 ckfree(cmd);
682
683 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000684}
685
686static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000687Tkapp_Eval(self, args)
688 PyObject *self;
689 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000690{
Barry Warsawfa701a81997-01-16 00:15:11 +0000691 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000692 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000693 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000694
Guido van Rossum35d43371997-08-02 00:09:09 +0000695 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000696 return NULL;
697
Guido van Rossum00d93061998-05-28 23:06:38 +0000698 ENTER_TCL
699 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000700 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000701 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000702 res = Tkinter_Error(self);
703 else
704 res = PyString_FromString(Tkapp_Result(self));
705 LEAVE_OVERLAP_TCL
706 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000707}
708
709static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000710Tkapp_GlobalEval(self, args)
711 PyObject *self;
712 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000713{
Barry Warsawfa701a81997-01-16 00:15:11 +0000714 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000715 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000716 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000717
Guido van Rossum35d43371997-08-02 00:09:09 +0000718 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000719 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000720
Guido van Rossum00d93061998-05-28 23:06:38 +0000721 ENTER_TCL
722 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000723 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000724 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000725 res = Tkinter_Error(self);
726 else
727 res = PyString_FromString(Tkapp_Result(self));
728 LEAVE_OVERLAP_TCL
729 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000730}
731
732static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000733Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000734 PyObject *self;
735 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000736{
Barry Warsawfa701a81997-01-16 00:15:11 +0000737 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000738 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000739 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000740
Guido van Rossum35d43371997-08-02 00:09:09 +0000741 if (!PyArg_ParseTuple(args, "s", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000742 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000743
Guido van Rossum00d93061998-05-28 23:06:38 +0000744 ENTER_TCL
745 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000746 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000747 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000748 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000749
Guido van Rossum62320c91998-06-15 04:36:09 +0000750 else
751 res = PyString_FromString(Tkapp_Result(self));
752 LEAVE_OVERLAP_TCL
753 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000754}
755
756static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000757Tkapp_Record(self, args)
758 PyObject *self;
759 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000760{
Barry Warsawfa701a81997-01-16 00:15:11 +0000761 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000762 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000763 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000764
Guido van Rossum35d43371997-08-02 00:09:09 +0000765 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000766 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000767
Guido van Rossum00d93061998-05-28 23:06:38 +0000768 ENTER_TCL
769 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000770 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000771 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000772 res = Tkinter_Error(self);
773 else
774 res = PyString_FromString(Tkapp_Result(self));
775 LEAVE_OVERLAP_TCL
776 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000777}
778
779static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000780Tkapp_AddErrorInfo(self, args)
781 PyObject *self;
782 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000783{
Barry Warsawfa701a81997-01-16 00:15:11 +0000784 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000785
Guido van Rossum35d43371997-08-02 00:09:09 +0000786 if (!PyArg_ParseTuple(args, "s", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000787 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000788 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000789 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000790 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000791
Barry Warsawfa701a81997-01-16 00:15:11 +0000792 Py_INCREF(Py_None);
793 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000794}
795
Barry Warsawfa701a81997-01-16 00:15:11 +0000796
797
Guido van Rossum18468821994-06-20 07:49:28 +0000798/** Tcl Variable **/
799
800static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000801SetVar(self, args, flags)
802 PyObject *self;
803 PyObject *args;
804 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000805{
Guido van Rossum00d93061998-05-28 23:06:38 +0000806 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000807 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000808 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000809
Guido van Rossum62320c91998-06-15 04:36:09 +0000810 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000811 if (!tmp)
812 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000813
Guido van Rossum00d93061998-05-28 23:06:38 +0000814 if (PyArg_ParseTuple(args, "sO", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000815 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000816 s = AsString(newValue, tmp);
817 ENTER_TCL
818 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
819 LEAVE_TCL
820 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000821 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000822 PyErr_Clear();
Guido van Rossum00d93061998-05-28 23:06:38 +0000823 if (PyArg_ParseTuple(args, "ssO", &name1, &name2, &newValue)) {
824 s = AsString (newValue, tmp);
825 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000826 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000827 s, flags);
828 LEAVE_TCL
829 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000830 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000831 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000832 return NULL;
833 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000834 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000835 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000836
Barry Warsawfa701a81997-01-16 00:15:11 +0000837 if (!ok)
838 return Tkinter_Error(self);
839
840 Py_INCREF(Py_None);
841 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000842}
843
844static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000845Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000846 PyObject *self;
847 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000848{
Barry Warsawfa701a81997-01-16 00:15:11 +0000849 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000850}
851
852static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000853Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000854 PyObject *self;
855 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000856{
Barry Warsawfa701a81997-01-16 00:15:11 +0000857 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000858}
859
Barry Warsawfa701a81997-01-16 00:15:11 +0000860
861
Guido van Rossum18468821994-06-20 07:49:28 +0000862static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000863GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000864 PyObject *self;
865 PyObject *args;
866 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000867{
Guido van Rossum35d43371997-08-02 00:09:09 +0000868 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000869 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000870
Guido van Rossum35d43371997-08-02 00:09:09 +0000871 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
872 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000873 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000874 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000875 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000876
Barry Warsawfa701a81997-01-16 00:15:11 +0000877 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000878 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000879 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000880
Barry Warsawfa701a81997-01-16 00:15:11 +0000881 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000882 res = Tkinter_Error(self);
883 else
884 res = PyString_FromString(s);
885 LEAVE_OVERLAP_TCL
886 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000887}
888
889static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000890Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000891 PyObject *self;
892 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000893{
Barry Warsawfa701a81997-01-16 00:15:11 +0000894 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000895}
896
897static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000898Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000899 PyObject *self;
900 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000901{
Barry Warsawfa701a81997-01-16 00:15:11 +0000902 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000903}
904
Barry Warsawfa701a81997-01-16 00:15:11 +0000905
906
Guido van Rossum18468821994-06-20 07:49:28 +0000907static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000908UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000909 PyObject *self;
910 PyObject *args;
911 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000912{
Guido van Rossum35d43371997-08-02 00:09:09 +0000913 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +0000914 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000915 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000916
Guido van Rossum35d43371997-08-02 00:09:09 +0000917 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000918 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000919 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000920 if (name2 == NULL)
921 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
922
923 else
924 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000925 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000926
Barry Warsawfa701a81997-01-16 00:15:11 +0000927 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000928 res = Tkinter_Error(self);
929 else {
930 Py_INCREF(Py_None);
931 res = Py_None;
932 }
933 LEAVE_OVERLAP_TCL
934 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000935}
936
937static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000938Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000939 PyObject *self;
940 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000941{
Barry Warsawfa701a81997-01-16 00:15:11 +0000942 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000943}
944
945static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000946Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000947 PyObject *self;
948 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000949{
Barry Warsawfa701a81997-01-16 00:15:11 +0000950 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000951}
952
Barry Warsawfa701a81997-01-16 00:15:11 +0000953
954
Guido van Rossum18468821994-06-20 07:49:28 +0000955/** Tcl to Python **/
956
957static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000958Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000959 PyObject *self;
960 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000961{
Barry Warsawfa701a81997-01-16 00:15:11 +0000962 char *s;
963 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000964
Guido van Rossum35d43371997-08-02 00:09:09 +0000965 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000966 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000967 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000968 return Tkinter_Error(self);
969 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000970}
971
972static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000973Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000974 PyObject *self;
975 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000976{
Barry Warsawfa701a81997-01-16 00:15:11 +0000977 char *s;
978 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000979
Guido van Rossum35d43371997-08-02 00:09:09 +0000980 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000981 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000982 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000983 return Tkinter_Error(self);
984 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000985}
986
987static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000988Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000989 PyObject *self;
990 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000991{
Barry Warsawfa701a81997-01-16 00:15:11 +0000992 char *s;
993 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000994
Guido van Rossum35d43371997-08-02 00:09:09 +0000995 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000996 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000997 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
998 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000999 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001000}
1001
1002static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001003Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001004 PyObject *self;
1005 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001006{
Barry Warsawfa701a81997-01-16 00:15:11 +00001007 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001008 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001009 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001010
Guido van Rossum35d43371997-08-02 00:09:09 +00001011 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001012 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001013 ENTER_TCL
1014 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001015 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001016 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001017 res = Tkinter_Error(self);
1018 else
1019 res = Py_BuildValue("s", Tkapp_Result(self));
1020 LEAVE_OVERLAP_TCL
1021 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001022}
1023
1024static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001025Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001026 PyObject *self;
1027 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001028{
Barry Warsawfa701a81997-01-16 00:15:11 +00001029 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001030 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001031 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001032 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001033
Guido van Rossum35d43371997-08-02 00:09:09 +00001034 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001035 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001036 ENTER_TCL
1037 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001038 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001039 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001040 res = Tkinter_Error(self);
1041 else
1042 res = Py_BuildValue("l", v);
1043 LEAVE_OVERLAP_TCL
1044 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001045}
1046
1047static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001048Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001049 PyObject *self;
1050 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001051{
Barry Warsawfa701a81997-01-16 00:15:11 +00001052 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001053 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001054 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001055 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001056
Guido van Rossum35d43371997-08-02 00:09:09 +00001057 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001058 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001059 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001060 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001061 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001062 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001063 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001064 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001065 res = Tkinter_Error(self);
1066 else
1067 res = Py_BuildValue("d", v);
1068 LEAVE_OVERLAP_TCL
1069 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001070}
1071
1072static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001073Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001074 PyObject *self;
1075 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001076{
Barry Warsawfa701a81997-01-16 00:15:11 +00001077 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001078 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001079 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001080 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001081
Guido van Rossum35d43371997-08-02 00:09:09 +00001082 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001083 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001084 ENTER_TCL
1085 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001086 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001087 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001088 res = Tkinter_Error(self);
1089 else
1090 res = Py_BuildValue("i", v);
1091 LEAVE_OVERLAP_TCL
1092 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001093}
1094
Barry Warsawfa701a81997-01-16 00:15:11 +00001095
1096
Guido van Rossum18468821994-06-20 07:49:28 +00001097static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001098Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001099 PyObject *self;
1100 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001101{
Barry Warsawfa701a81997-01-16 00:15:11 +00001102 char *list;
1103 int argc;
1104 char **argv;
1105 PyObject *v;
1106 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001107
Guido van Rossum35d43371997-08-02 00:09:09 +00001108 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001109 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001110
Barry Warsawfa701a81997-01-16 00:15:11 +00001111 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1112 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001113
Barry Warsawfa701a81997-01-16 00:15:11 +00001114 if (!(v = PyTuple_New(argc)))
1115 return NULL;
1116
1117 for (i = 0; i < argc; i++) {
1118 PyObject *s = PyString_FromString(argv[i]);
1119 if (!s || PyTuple_SetItem(v, i, s)) {
1120 Py_DECREF(v);
1121 v = NULL;
1122 goto finally;
1123 }
1124 }
Guido van Rossum18468821994-06-20 07:49:28 +00001125
Barry Warsawfa701a81997-01-16 00:15:11 +00001126 finally:
1127 ckfree(FREECAST argv);
1128 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001129}
1130
1131static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001132Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001133 PyObject *self;
1134 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001135{
Barry Warsawfa701a81997-01-16 00:15:11 +00001136 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001137
Guido van Rossum35d43371997-08-02 00:09:09 +00001138 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001139 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001140 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001141}
1142
1143static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001144Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001145 PyObject *self;
1146 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001147{
Barry Warsawfa701a81997-01-16 00:15:11 +00001148 char *s = Merge(args);
1149 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001150
Barry Warsawfa701a81997-01-16 00:15:11 +00001151 if (s) {
1152 res = PyString_FromString(s);
1153 ckfree(s);
1154 }
1155 else
1156 PyErr_SetString(Tkinter_TclError, "merge failed");
1157
1158 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001159}
1160
Barry Warsawfa701a81997-01-16 00:15:11 +00001161
1162
Guido van Rossum18468821994-06-20 07:49:28 +00001163/** Tcl Command **/
1164
Guido van Rossum00d93061998-05-28 23:06:38 +00001165/* Client data struct */
1166typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001167 PyObject *self;
1168 PyObject *func;
1169} PythonCmd_ClientData;
1170
1171static int
1172PythonCmd_Error(interp)
1173 Tcl_Interp *interp;
1174{
1175 errorInCmd = 1;
1176 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1177 LEAVE_PYTHON
1178 return TCL_ERROR;
1179}
1180
Guido van Rossum18468821994-06-20 07:49:28 +00001181/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001182 * function or method.
1183 */
Guido van Rossum18468821994-06-20 07:49:28 +00001184static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001185PythonCmd(clientData, interp, argc, argv)
Guido van Rossum00d93061998-05-28 23:06:38 +00001186 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001187 Tcl_Interp *interp;
1188 int argc;
1189 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +00001190{
Guido van Rossum00d93061998-05-28 23:06:38 +00001191 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001192 PyObject *self, *func, *arg, *res, *tmp;
1193 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001194
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001195 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001196
Barry Warsawfa701a81997-01-16 00:15:11 +00001197 /* TBD: no error checking here since we know, via the
1198 * Tkapp_CreateCommand() that the client data is a two-tuple
1199 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001200 self = data->self;
1201 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001202
Barry Warsawfa701a81997-01-16 00:15:11 +00001203 /* Create argument list (argv1, ..., argvN) */
1204 if (!(arg = PyTuple_New(argc - 1)))
1205 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001206
Barry Warsawfa701a81997-01-16 00:15:11 +00001207 for (i = 0; i < (argc - 1); i++) {
1208 PyObject *s = PyString_FromString(argv[i + 1]);
1209 if (!s || PyTuple_SetItem(arg, i, s)) {
1210 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001211 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001212 }
1213 }
1214 res = PyEval_CallObject(func, arg);
1215 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001216
Barry Warsawfa701a81997-01-16 00:15:11 +00001217 if (res == NULL)
1218 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001219
Barry Warsawfa701a81997-01-16 00:15:11 +00001220 if (!(tmp = PyList_New(0))) {
1221 Py_DECREF(res);
1222 return PythonCmd_Error(interp);
1223 }
1224
1225 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
1226 Py_DECREF(res);
1227 Py_DECREF(tmp);
1228
Guido van Rossum00d93061998-05-28 23:06:38 +00001229 LEAVE_PYTHON
1230
Barry Warsawfa701a81997-01-16 00:15:11 +00001231 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +00001232}
1233
1234static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001235PythonCmdDelete(clientData)
Guido van Rossum00d93061998-05-28 23:06:38 +00001236 ClientData clientData;
Guido van Rossum18468821994-06-20 07:49:28 +00001237{
Guido van Rossum00d93061998-05-28 23:06:38 +00001238 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1239
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001240 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001241 Py_XDECREF(data->self);
1242 Py_XDECREF(data->func);
1243 PyMem_DEL(data);
1244 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001245}
1246
Barry Warsawfa701a81997-01-16 00:15:11 +00001247
1248
Guido van Rossum18468821994-06-20 07:49:28 +00001249static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001250Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001251 PyObject *self;
1252 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001253{
Guido van Rossum00d93061998-05-28 23:06:38 +00001254 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001255 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001256 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001257 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001258
1259 if (!PyArg_ParseTuple(args, "sO", &cmdName, &func))
1260 return NULL;
1261 if (!PyCallable_Check(func)) {
1262 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001263 return NULL;
1264 }
Guido van Rossum18468821994-06-20 07:49:28 +00001265
Guido van Rossum00d93061998-05-28 23:06:38 +00001266 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001267 if (!data)
1268 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001269 Py_XINCREF(self);
1270 Py_XINCREF(func);
1271 data->self = self;
1272 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001273
Guido van Rossum00d93061998-05-28 23:06:38 +00001274 ENTER_TCL
1275 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1276 (ClientData)data, PythonCmdDelete);
1277 LEAVE_TCL
1278 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001279 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001280 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001281 return NULL;
1282 }
Guido van Rossum18468821994-06-20 07:49:28 +00001283
Barry Warsawfa701a81997-01-16 00:15:11 +00001284 Py_INCREF(Py_None);
1285 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001286}
1287
Barry Warsawfa701a81997-01-16 00:15:11 +00001288
1289
Guido van Rossum18468821994-06-20 07:49:28 +00001290static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001291Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001292 PyObject *self;
1293 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001294{
Barry Warsawfa701a81997-01-16 00:15:11 +00001295 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001296 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001297
Guido van Rossum35d43371997-08-02 00:09:09 +00001298 if (!PyArg_ParseTuple(args, "s", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001299 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001300 ENTER_TCL
1301 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1302 LEAVE_TCL
1303 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001304 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1305 return NULL;
1306 }
1307 Py_INCREF(Py_None);
1308 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001309}
1310
Barry Warsawfa701a81997-01-16 00:15:11 +00001311
1312
Guido van Rossum00d93061998-05-28 23:06:38 +00001313#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001314/** File Handler **/
1315
Guido van Rossum00d93061998-05-28 23:06:38 +00001316typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001317 PyObject *func;
1318 PyObject *file;
1319 int id;
1320 struct _fhcdata *next;
1321} FileHandler_ClientData;
1322
1323static FileHandler_ClientData *HeadFHCD;
1324
1325static FileHandler_ClientData *
1326NewFHCD(func, file, id)
1327 PyObject *func;
1328 PyObject *file;
1329 int id;
1330{
1331 FileHandler_ClientData *p;
1332 p = PyMem_NEW(FileHandler_ClientData, 1);
1333 if (p != NULL) {
1334 Py_XINCREF(func);
1335 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001336 p->func = func;
1337 p->file = file;
1338 p->id = id;
1339 p->next = HeadFHCD;
1340 HeadFHCD = p;
1341 }
1342 return p;
1343}
1344
1345static void
1346DeleteFHCD(id)
1347 int id;
1348{
1349 FileHandler_ClientData *p, **pp;
1350
1351 pp = &HeadFHCD;
1352 while ((p = *pp) != NULL) {
1353 if (p->id == id) {
1354 *pp = p->next;
1355 Py_XDECREF(p->func);
1356 Py_XDECREF(p->file);
1357 PyMem_DEL(p);
1358 }
1359 else
1360 pp = &p->next;
1361 }
1362}
1363
Guido van Rossuma597dde1995-01-10 20:56:29 +00001364static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001365FileHandler(clientData, mask)
Guido van Rossum00d93061998-05-28 23:06:38 +00001366 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001367 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +00001368{
Guido van Rossum00d93061998-05-28 23:06:38 +00001369 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001370 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001371
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001372 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001373 func = data->func;
1374 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001375
Barry Warsawfa701a81997-01-16 00:15:11 +00001376 arg = Py_BuildValue("(Oi)", file, (long) mask);
1377 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001378 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001379
1380 if (res == NULL) {
1381 errorInCmd = 1;
1382 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1383 }
1384 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001385 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001386}
1387
1388static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001389GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +00001390 /* Either an int >= 0 or an object with a
1391 *.fileno() method that returns an int >= 0
1392 */
1393 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001394{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001395 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001396 int id;
1397 if (PyInt_Check(file)) {
1398 id = PyInt_AsLong(file);
1399 if (id < 0)
1400 PyErr_SetString(PyExc_ValueError, "invalid file id");
1401 return id;
1402 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001403 args = PyTuple_New(0);
1404 if (args == NULL)
1405 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001406
1407 meth = PyObject_GetAttrString(file, "fileno");
1408 if (meth == NULL) {
1409 Py_DECREF(args);
1410 return -1;
1411 }
1412
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001413 res = PyEval_CallObject(meth, args);
1414 Py_DECREF(args);
1415 Py_DECREF(meth);
1416 if (res == NULL)
1417 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001418
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001419 if (PyInt_Check(res))
1420 id = PyInt_AsLong(res);
1421 else
1422 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001423
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001424 if (id < 0)
1425 PyErr_SetString(PyExc_ValueError,
1426 "invalid fileno() return value");
1427 Py_DECREF(res);
1428 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001429}
1430
1431static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001432Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001433 PyObject *self;
1434 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001435{
Guido van Rossum00d93061998-05-28 23:06:38 +00001436 FileHandler_ClientData *data;
1437 PyObject *file, *func;
Barry Warsawfa701a81997-01-16 00:15:11 +00001438 int mask, id;
Guido van Rossum7bf15641998-05-22 18:28:17 +00001439 FHANDLE tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001440
Guido van Rossum35d43371997-08-02 00:09:09 +00001441 if (!PyArg_ParseTuple(args, "OiO", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001442 return NULL;
1443 id = GetFileNo(file);
1444 if (id < 0)
1445 return NULL;
1446 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001447 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001448 return NULL;
1449 }
1450
Guido van Rossum00d93061998-05-28 23:06:38 +00001451 data = NewFHCD(func, file, id);
1452 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001453 return NULL;
1454
Guido van Rossum7bf15641998-05-22 18:28:17 +00001455 tfile = MAKEFHANDLE(id);
Barry Warsawfa701a81997-01-16 00:15:11 +00001456 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001457 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001458 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001459 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001460 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001461 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001462}
1463
1464static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001465Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001466 PyObject *self;
1467 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001468{
Barry Warsawfa701a81997-01-16 00:15:11 +00001469 PyObject *file;
Guido van Rossum00d93061998-05-28 23:06:38 +00001470 FileHandler_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001471 int id;
Guido van Rossum7bf15641998-05-22 18:28:17 +00001472 FHANDLE tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001473
Guido van Rossum35d43371997-08-02 00:09:09 +00001474 if (!PyArg_ParseTuple(args, "O", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001475 return NULL;
1476 id = GetFileNo(file);
1477 if (id < 0)
1478 return NULL;
1479
Guido van Rossum00d93061998-05-28 23:06:38 +00001480 DeleteFHCD(id);
Guido van Rossum18468821994-06-20 07:49:28 +00001481
Guido van Rossum7bf15641998-05-22 18:28:17 +00001482 tfile = MAKEFHANDLE(id);
Barry Warsawfa701a81997-01-16 00:15:11 +00001483 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001484 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001485 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001486 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001487 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001488 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001489}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001490#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001491
Barry Warsawfa701a81997-01-16 00:15:11 +00001492
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001493/**** Tktt Object (timer token) ****/
1494
1495staticforward PyTypeObject Tktt_Type;
1496
Guido van Rossum00d93061998-05-28 23:06:38 +00001497typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001498 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001499 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001500 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001501} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001502
1503static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001504Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001505 PyObject *self;
1506 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001507{
Barry Warsawfa701a81997-01-16 00:15:11 +00001508 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001509 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001510
Guido van Rossum35d43371997-08-02 00:09:09 +00001511 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001512 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001513 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001514 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001515 v->token = NULL;
1516 }
1517 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001518 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001519 Py_DECREF(func);
1520 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001521 }
1522 Py_INCREF(Py_None);
1523 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001524}
1525
1526static PyMethodDef Tktt_methods[] =
1527{
Guido van Rossum35d43371997-08-02 00:09:09 +00001528 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001529 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001530};
1531
1532static TkttObject *
Guido van Rossum00d93061998-05-28 23:06:38 +00001533Tktt_New(func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001534 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001535{
Barry Warsawfa701a81997-01-16 00:15:11 +00001536 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001537
Barry Warsawfa701a81997-01-16 00:15:11 +00001538 v = PyObject_NEW(TkttObject, &Tktt_Type);
1539 if (v == NULL)
1540 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001541
Guido van Rossum00d93061998-05-28 23:06:38 +00001542 Py_INCREF(func);
1543 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001544 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001545
1546 /* Extra reference, deleted when called or when handler is deleted */
1547 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001548 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001549}
1550
1551static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001552Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001553 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001554{
Guido van Rossum00d93061998-05-28 23:06:38 +00001555 TkttObject *v = (TkttObject *)self;
1556 PyObject *func = v->func;
1557
1558 Py_XDECREF(func);
1559
Guido van Rossum35d43371997-08-02 00:09:09 +00001560 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001561}
1562
Guido van Rossum597ac201998-05-12 14:36:19 +00001563static PyObject *
1564Tktt_Repr(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001565 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001566{
Barry Warsawfa701a81997-01-16 00:15:11 +00001567 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001568 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001569
Guido van Rossum597ac201998-05-12 14:36:19 +00001570 sprintf(buf, "<tktimertoken at 0x%lx%s>", (long)v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001571 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001572 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001573}
1574
1575static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001576Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001577 PyObject *self;
1578 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001579{
Barry Warsawfa701a81997-01-16 00:15:11 +00001580 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001581}
1582
1583static PyTypeObject Tktt_Type =
1584{
Guido van Rossum35d43371997-08-02 00:09:09 +00001585 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001586 0, /*ob_size */
1587 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001588 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001589 0, /*tp_itemsize */
1590 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001591 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001592 Tktt_GetAttr, /*tp_getattr */
1593 0, /*tp_setattr */
1594 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001595 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001596 0, /*tp_as_number */
1597 0, /*tp_as_sequence */
1598 0, /*tp_as_mapping */
1599 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001600};
1601
Barry Warsawfa701a81997-01-16 00:15:11 +00001602
1603
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001604/** Timer Handler **/
1605
1606static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001607TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001608 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001609{
Guido van Rossum00d93061998-05-28 23:06:38 +00001610 TkttObject *v = (TkttObject *)clientData;
1611 PyObject *func = v->func;
1612 PyObject *res;
1613
1614 if (func == NULL)
1615 return;
1616
1617 v->func = NULL;
1618
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001619 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001620
1621 res = PyEval_CallObject(func, NULL);
1622 Py_DECREF(func);
1623 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001624
Barry Warsawfa701a81997-01-16 00:15:11 +00001625 if (res == NULL) {
1626 errorInCmd = 1;
1627 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1628 }
1629 else
1630 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001631
1632 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001633}
1634
1635static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001636Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001637 PyObject *self;
1638 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001639{
Barry Warsawfa701a81997-01-16 00:15:11 +00001640 int milliseconds;
1641 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001642 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001643
Guido van Rossum35d43371997-08-02 00:09:09 +00001644 if (!PyArg_ParseTuple(args, "iO", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001645 return NULL;
1646 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001647 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001648 return NULL;
1649 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001650 v = Tktt_New(func);
1651 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1652 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001653
Guido van Rossum00d93061998-05-28 23:06:38 +00001654 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001655}
1656
Barry Warsawfa701a81997-01-16 00:15:11 +00001657
Guido van Rossum18468821994-06-20 07:49:28 +00001658/** Event Loop **/
1659
Guido van Rossum18468821994-06-20 07:49:28 +00001660static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001661Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001662 PyObject *self;
1663 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001664{
Barry Warsawfa701a81997-01-16 00:15:11 +00001665 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001666#ifdef WITH_THREAD
1667 PyThreadState *tstate = PyThreadState_Get();
1668#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001669
Barry Warsawfa701a81997-01-16 00:15:11 +00001670 if (!PyArg_ParseTuple(args, "|i", &threshold))
1671 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001672
Barry Warsawfa701a81997-01-16 00:15:11 +00001673 quitMainLoop = 0;
1674 while (Tk_GetNumMainWindows() > threshold &&
1675 !quitMainLoop &&
1676 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001677 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001678 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001679
1680#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001681 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001682 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001683 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001684 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001685 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001686 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001687 if (result == 0)
1688 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001689 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001690#else
1691 result = Tcl_DoOneEvent(0);
1692#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001693
Guido van Rossum35d43371997-08-02 00:09:09 +00001694 if (PyErr_CheckSignals() != 0)
1695 return NULL;
1696 if (result < 0)
1697 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001698 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001699 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001700
Barry Warsawfa701a81997-01-16 00:15:11 +00001701 if (errorInCmd) {
1702 errorInCmd = 0;
1703 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1704 excInCmd = valInCmd = trbInCmd = NULL;
1705 return NULL;
1706 }
1707 Py_INCREF(Py_None);
1708 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001709}
1710
1711static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001712Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001713 PyObject *self;
1714 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001715{
Guido van Rossum35d43371997-08-02 00:09:09 +00001716 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001717 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001718
Barry Warsawfa701a81997-01-16 00:15:11 +00001719 if (!PyArg_ParseTuple(args, "|i", &flags))
1720 return NULL;
1721
Guido van Rossum00d93061998-05-28 23:06:38 +00001722 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001723 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001724 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001725 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001726}
1727
1728static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001729Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001730 PyObject *self;
1731 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001732{
1733
Guido van Rossum35d43371997-08-02 00:09:09 +00001734 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001735 return NULL;
1736
1737 quitMainLoop = 1;
1738 Py_INCREF(Py_None);
1739 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001740}
1741
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001742static PyObject *
1743Tkapp_InterpAddr(self, args)
1744 PyObject *self;
1745 PyObject *args;
1746{
1747
1748 if (!PyArg_ParseTuple(args, ""))
1749 return NULL;
1750
1751 return PyInt_FromLong((long)Tkapp_Interp(self));
1752}
1753
Barry Warsawfa701a81997-01-16 00:15:11 +00001754
1755
Guido van Rossum18468821994-06-20 07:49:28 +00001756/**** Tkapp Method List ****/
1757
1758static PyMethodDef Tkapp_methods[] =
1759{
Guido van Rossum35d43371997-08-02 00:09:09 +00001760 {"call", Tkapp_Call, 0},
1761 {"globalcall", Tkapp_GlobalCall, 0},
1762 {"eval", Tkapp_Eval, 1},
1763 {"globaleval", Tkapp_GlobalEval, 1},
1764 {"evalfile", Tkapp_EvalFile, 1},
1765 {"record", Tkapp_Record, 1},
1766 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1767 {"setvar", Tkapp_SetVar, 1},
1768 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1769 {"getvar", Tkapp_GetVar, 1},
1770 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1771 {"unsetvar", Tkapp_UnsetVar, 1},
1772 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1773 {"getint", Tkapp_GetInt, 1},
1774 {"getdouble", Tkapp_GetDouble, 1},
1775 {"getboolean", Tkapp_GetBoolean, 1},
1776 {"exprstring", Tkapp_ExprString, 1},
1777 {"exprlong", Tkapp_ExprLong, 1},
1778 {"exprdouble", Tkapp_ExprDouble, 1},
1779 {"exprboolean", Tkapp_ExprBoolean, 1},
1780 {"splitlist", Tkapp_SplitList, 1},
1781 {"split", Tkapp_Split, 1},
1782 {"merge", Tkapp_Merge, 0},
1783 {"createcommand", Tkapp_CreateCommand, 1},
1784 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001785#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001786 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1787 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001788#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001789 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001790 {"mainloop", Tkapp_MainLoop, 1},
1791 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001792 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001793 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001794 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001795};
1796
Barry Warsawfa701a81997-01-16 00:15:11 +00001797
1798
Guido van Rossum18468821994-06-20 07:49:28 +00001799/**** Tkapp Type Methods ****/
1800
1801static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001802Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001803 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001804{
Guido van Rossum00d93061998-05-28 23:06:38 +00001805 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001806 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001807 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001808 PyMem_DEL(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001809 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001810}
1811
1812static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001813Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001814 PyObject *self;
1815 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001816{
Guido van Rossum35d43371997-08-02 00:09:09 +00001817 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001818}
1819
1820static PyTypeObject Tkapp_Type =
1821{
Guido van Rossum35d43371997-08-02 00:09:09 +00001822 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001823 0, /*ob_size */
1824 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001825 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001826 0, /*tp_itemsize */
1827 Tkapp_Dealloc, /*tp_dealloc */
1828 0, /*tp_print */
1829 Tkapp_GetAttr, /*tp_getattr */
1830 0, /*tp_setattr */
1831 0, /*tp_compare */
1832 0, /*tp_repr */
1833 0, /*tp_as_number */
1834 0, /*tp_as_sequence */
1835 0, /*tp_as_mapping */
1836 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001837};
1838
Barry Warsawfa701a81997-01-16 00:15:11 +00001839
1840
Guido van Rossum18468821994-06-20 07:49:28 +00001841/**** Tkinter Module ****/
1842
1843static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001844Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001845 PyObject *self;
1846 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001847{
Barry Warsawfa701a81997-01-16 00:15:11 +00001848 char *screenName = NULL;
1849 char *baseName = NULL;
1850 char *className = NULL;
1851 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001852
Guido van Rossum35d43371997-08-02 00:09:09 +00001853 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001854 if (baseName != NULL)
1855 baseName++;
1856 else
1857 baseName = Py_GetProgramName();
1858 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001859
Barry Warsawfa701a81997-01-16 00:15:11 +00001860 if (!PyArg_ParseTuple(args, "|zssi",
1861 &screenName, &baseName, &className,
1862 &interactive))
1863 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001864
Barry Warsawfa701a81997-01-16 00:15:11 +00001865 return (PyObject *) Tkapp_New(screenName, baseName, className,
1866 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001867}
1868
1869static PyMethodDef moduleMethods[] =
1870{
Barry Warsawfa701a81997-01-16 00:15:11 +00001871 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001872#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001873 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1874 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001875#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001876 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001877 {"mainloop", Tkapp_MainLoop, 1},
1878 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001879 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001880 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001881};
1882
Guido van Rossum7bf15641998-05-22 18:28:17 +00001883#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001884
1885static int stdin_ready = 0;
1886
Guido van Rossumad4db171998-06-13 13:56:28 +00001887#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001888static void
1889MyFileProc(clientData, mask)
1890 void *clientData;
1891 int mask;
1892{
1893 stdin_ready = 1;
1894}
Guido van Rossumad4db171998-06-13 13:56:28 +00001895#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001896
Guido van Rossum00d93061998-05-28 23:06:38 +00001897static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001898
Guido van Rossum18468821994-06-20 07:49:28 +00001899static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001900EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00001901{
Guido van Rossumad4db171998-06-13 13:56:28 +00001902#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00001903 FHANDLE tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00001904#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001905#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00001906 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001907#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001908 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00001909 errorInCmd = 0;
1910#ifndef MS_WINDOWS
1911 tfile = MAKEFHANDLE(fileno(stdin));
Guido van Rossum7bf15641998-05-22 18:28:17 +00001912 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00001913#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001914 while (!errorInCmd && !stdin_ready) {
1915 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00001916#ifdef MS_WINDOWS
1917 if (_kbhit()) {
1918 stdin_ready = 1;
1919 break;
1920 }
1921#endif
1922#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00001923 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001924 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00001925 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001926
Guido van Rossum00d93061998-05-28 23:06:38 +00001927 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001928
1929 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001930 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001931 if (result == 0)
1932 Sleep(20);
1933 Py_END_ALLOW_THREADS
1934#else
1935 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001936#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001937
1938 if (result < 0)
1939 break;
1940 }
Guido van Rossumad4db171998-06-13 13:56:28 +00001941#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00001942 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00001943#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001944 if (errorInCmd) {
1945 errorInCmd = 0;
1946 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1947 excInCmd = valInCmd = trbInCmd = NULL;
1948 PyErr_Print();
1949 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001950#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00001951 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001952#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001953 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001954}
Guido van Rossum18468821994-06-20 07:49:28 +00001955
Guido van Rossum00d93061998-05-28 23:06:38 +00001956#endif
1957
Guido van Rossum7bf15641998-05-22 18:28:17 +00001958static void
1959EnableEventHook()
1960{
Guido van Rossum00d93061998-05-28 23:06:38 +00001961#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001962 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001963#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00001964 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001965#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001966 PyOS_InputHook = EventHook;
1967 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001968#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001969}
1970
1971static void
1972DisableEventHook()
1973{
Guido van Rossum00d93061998-05-28 23:06:38 +00001974#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001975 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
1976 PyOS_InputHook = NULL;
1977 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001978#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001979}
1980
Barry Warsawfa701a81997-01-16 00:15:11 +00001981
1982/* all errors will be checked in one fell swoop in init_tkinter() */
1983static void
1984ins_long(d, name, val)
1985 PyObject *d;
1986 char *name;
1987 long val;
1988{
1989 PyObject *v = PyInt_FromLong(val);
1990 if (v) {
1991 PyDict_SetItemString(d, name, v);
1992 Py_DECREF(v);
1993 }
1994}
1995static void
1996ins_string(d, name, val)
1997 PyObject *d;
1998 char *name;
1999 char *val;
2000{
2001 PyObject *v = PyString_FromString(val);
2002 if (v) {
2003 PyDict_SetItemString(d, name, v);
2004 Py_DECREF(v);
2005 }
2006}
2007
2008
Guido van Rossum3886bb61998-12-04 18:50:17 +00002009DL_EXPORT(void)
Guido van Rossum35d43371997-08-02 00:09:09 +00002010init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00002011{
Barry Warsawfa701a81997-01-16 00:15:11 +00002012 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002013
Barry Warsawfa701a81997-01-16 00:15:11 +00002014 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002015
2016#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002017 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002018#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002019
Barry Warsawfa701a81997-01-16 00:15:11 +00002020 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002021
Barry Warsawfa701a81997-01-16 00:15:11 +00002022 d = PyModule_GetDict(m);
2023 Tkinter_TclError = Py_BuildValue("s", "TclError");
2024 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002025
Guido van Rossum35d43371997-08-02 00:09:09 +00002026 ins_long(d, "READABLE", TCL_READABLE);
2027 ins_long(d, "WRITABLE", TCL_WRITABLE);
2028 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2029 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2030 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2031 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2032 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2033 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2034 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002035 ins_string(d, "TK_VERSION", TK_VERSION);
2036 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002037
Guido van Rossum83551bf1997-09-13 00:44:23 +00002038 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002039
2040 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002041 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2042
Barry Warsawfa701a81997-01-16 00:15:11 +00002043 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002044 return;
2045
Guido van Rossum43ff8681998-07-14 18:02:13 +00002046#if 0
2047 /* This was not a good idea; through <Destroy> bindings,
2048 Tcl_Finalize() may invoke Python code but at that point the
2049 interpreter and thread state have already been destroyed! */
Guido van Rossum26216371998-04-20 18:47:52 +00002050#if TKMAJORMINOR >= 8000
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002051 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002052#endif
Guido van Rossum43ff8681998-07-14 18:02:13 +00002053#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002054
Jack Jansen34cc5c31995-10-31 16:15:12 +00002055#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002056 /*
2057 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2058 ** Most of the initializations in that routine (toolbox init calls and
2059 ** such) have already been done for us, so we only need these.
2060 */
2061#if TKMAJORMINOR >= 8000
2062 tcl_macQdPtr = &qd;
2063#endif
2064
2065 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002066#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002067 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002068#endif /* GENERATINGCFM */
2069#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002070}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002071
Guido van Rossumec22c921996-02-25 04:50:29 +00002072
Barry Warsawfa701a81997-01-16 00:15:11 +00002073
Guido van Rossum9722ad81995-09-22 23:49:28 +00002074#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002075
2076/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002077** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002078*/
2079
Guido van Rossum9722ad81995-09-22 23:49:28 +00002080void
2081panic(char * format, ...)
2082{
Barry Warsawfa701a81997-01-16 00:15:11 +00002083 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002084
Barry Warsawfa701a81997-01-16 00:15:11 +00002085 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002086
Guido van Rossum227cf761998-08-05 13:53:32 +00002087 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002088 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002089
Barry Warsawfa701a81997-01-16 00:15:11 +00002090 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002091
Barry Warsawfa701a81997-01-16 00:15:11 +00002092 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002093}
Jack Jansen40b546d1995-11-14 10:34:45 +00002094
Guido van Rossumec22c921996-02-25 04:50:29 +00002095/*
2096** Pass events to SIOUX before passing them to Tk.
2097*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002098
Guido van Rossumec22c921996-02-25 04:50:29 +00002099static int
2100PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00002101 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002102{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002103 WindowPtr frontwin;
2104 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002105 ** Sioux eats too many events, so we don't pass it everything. We
2106 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002107 ** the Sioux window is frontmost. This means that Tk menus don't work
2108 ** in that case, but at least we can scroll the sioux window.
2109 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2110 ** part of the external interface of Sioux...
2111 */
2112 frontwin = FrontWindow();
2113 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2114 if (SIOUXHandleOneEvent(eventPtr))
2115 return 0; /* Nothing happened to the Tcl event queue */
2116 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002117 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002118}
2119
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002120#if defined(USE_GUSI) && TKMAJORMINOR < 8000
Guido van Rossum290283b1997-06-02 22:16:43 +00002121/*
2122 * For Python we have to override this routine (from TclMacNotify),
2123 * since we use GUSI for our sockets, not Tcl streams. Hence, we have
2124 * to use GUSI select to see whether our socket is ready. Note that
2125 * createfilehandler (above) sets the type to TCL_UNIX_FD for our
2126 * files and sockets.
2127 *
2128 * NOTE: this code was lifted from Tcl 7.6, it may need to be modified
2129 * for other versions. */
2130
2131int
2132Tcl_FileReady(file, mask)
2133 Tcl_File file; /* File handle for a stream. */
2134 int mask; /* OR'ed combination of TCL_READABLE,
2135 * TCL_WRITABLE, and TCL_EXCEPTION:
2136 * indicates conditions caller cares about. */
2137{
2138 int type;
2139 int fd;
2140
2141 fd = (int) Tcl_GetFileInfo(file, &type);
2142
2143 if (type == TCL_MAC_SOCKET) {
2144 return TclMacSocketReady(file, mask);
2145 } else if (type == TCL_MAC_FILE) {
2146 /*
2147 * Under the Macintosh, files are always ready, so we just
2148 * return the mask that was passed in.
2149 */
2150
2151 return mask;
2152 } else if (type == TCL_UNIX_FD) {
2153 fd_set readset, writeset, excset;
2154 struct timeval tv;
2155
2156 FD_ZERO(&readset);
2157 FD_ZERO(&writeset);
2158 FD_ZERO(&excset);
2159
2160 if ( mask & TCL_READABLE ) FD_SET(fd, &readset);
2161 if ( mask & TCL_WRITABLE ) FD_SET(fd, &writeset);
2162 if ( mask & TCL_EXCEPTION ) FD_SET(fd, &excset);
2163
2164 tv.tv_sec = tv.tv_usec = 0;
2165 if ( select(fd+1, &readset, &writeset, &excset, &tv) <= 0 )
2166 return 0;
2167
2168 mask = 0;
2169 if ( FD_ISSET(fd, &readset) ) mask |= TCL_READABLE;
2170 if ( FD_ISSET(fd, &writeset) ) mask |= TCL_WRITABLE;
2171 if ( FD_ISSET(fd, &excset) ) mask |= TCL_EXCEPTION;
2172
2173 return mask;
2174 }
2175
2176 return 0;
2177}
2178#endif /* USE_GUSI */
2179
Guido van Rossumec22c921996-02-25 04:50:29 +00002180#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002181
2182/*
2183** Additional Mac specific code for dealing with shared libraries.
2184*/
2185
2186#include <Resources.h>
2187#include <CodeFragments.h>
2188
2189static int loaded_from_shlib = 0;
2190static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002191
Jack Jansen34cc5c31995-10-31 16:15:12 +00002192/*
2193** If this module is dynamically loaded the following routine should
2194** be the init routine. It takes care of adding the shared library to
2195** the resource-file chain, so that the tk routines can find their
2196** resources.
2197*/
2198OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002199init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002200{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002201 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002202 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002203 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002204 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2205 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002206 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002207 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2208 loaded_from_shlib = 1;
2209 }
2210 return noErr;
2211}
2212
2213/*
2214** Insert the library resources into the search path. Put them after
2215** the resources from the application. Again, we ignore errors.
2216*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002217static
Jack Jansen34cc5c31995-10-31 16:15:12 +00002218mac_addlibresources()
2219{
2220 if ( !loaded_from_shlib )
2221 return;
2222 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2223}
2224
Guido van Rossumec22c921996-02-25 04:50:29 +00002225#endif /* GENERATINGCFM */
2226#endif /* macintosh */