blob: d94ae36e1f1211380cf57c58bfdfd16096ec9ed2 [file] [log] [blame]
Guido van Rossum845547d1996-06-26 18:26:04 +00001/***********************************************************
2Copyright (C) 1994 Steen Lumholt.
3Copyright 1994-1995 by Stichting Mathematisch Centrum, Amsterdam,
4The Netherlands.
5
6 All Rights Reserved
7
Guido van Rossumd266eb41996-10-25 14:44:06 +00008Permission to use, copy, modify, and distribute this software and its
9documentation for any purpose and without fee is hereby granted,
Guido van Rossum845547d1996-06-26 18:26:04 +000010provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000011both that copyright notice and this permission notice appear in
Guido van Rossum845547d1996-06-26 18:26:04 +000012supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000013Centrum or CWI or Corporation for National Research Initiatives or
14CNRI not be used in advertising or publicity pertaining to
15distribution of the software without specific, written prior
16permission.
Guido van Rossum845547d1996-06-26 18:26:04 +000017
Guido van Rossumd266eb41996-10-25 14:44:06 +000018While CWI is the initial source for this software, a modified version
19is made available by the Corporation for National Research Initiatives
20(CNRI) at the Internet address ftp://ftp.python.org.
21
22STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
23REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
24MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
25CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
26DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
27PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
28TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum845547d1996-06-26 18:26:04 +000030
31******************************************************************/
32
33/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +000034
Guido van Rossum7ffa7611996-08-13 21:10:16 +000035/* TCL/TK VERSION INFO:
36
37 Unix:
Guido van Rossum496f8f61997-07-19 19:57:42 +000038 Tcl/Tk 8.0 (even alpha or beta) or 7.6/4.2 are recommended.
Guido van Rossum35d43371997-08-02 00:09:09 +000039 Versions 7.5/4.1 are the earliest versions still supported.
40 Versions 7.4/4.0 or Tk 3.x are no longer supported.
Guido van Rossum7ffa7611996-08-13 21:10:16 +000041
42 Mac and Windows:
Guido van Rossum496f8f61997-07-19 19:57:42 +000043 Use Tcl 8.0 if available (even alpha or beta).
44 The oldest usable version is 4.1p1/7.5p1.
45
Guido van Rossum212643f1998-04-29 16:22:14 +000046 XXX Further speed-up ideas, involving Tcl 8.0 features:
47
48 - In Tcl_Call(), create Tcl objects from the arguments, possibly using
49 intelligent mappings between Python objects and Tcl objects (e.g. ints,
50 floats and Tcl window pointers could be handled specially).
51
52 - Register a new Tcl type, "Python callable", which can be called more
53 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
54
Guido van Rossum7ffa7611996-08-13 21:10:16 +000055*/
56
Guido van Rossum35d43371997-08-02 00:09:09 +000057
Guido van Rossum9722ad81995-09-22 23:49:28 +000058#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000059#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000060
Guido van Rossum00d93061998-05-28 23:06:38 +000061#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000062#include "pythread.h"
Guido van Rossum00d93061998-05-28 23:06:38 +000063#endif
64
Guido van Rossum2a5119b1998-05-29 01:28:40 +000065#ifdef MS_WINDOWS
66#include <windows.h>
67#endif
68
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000069#ifdef macintosh
70#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000071#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000072#endif
73
Guido van Rossum49b56061998-10-01 20:42:43 +000074#ifdef PYOS_OS2
75#include "myselect.h"
76#endif
77
Guido van Rossum18468821994-06-20 07:49:28 +000078#include <tcl.h>
79#include <tk.h>
80
Guido van Rossum3e819a71997-08-01 19:29:02 +000081#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
82
Guido van Rossum00d93061998-05-28 23:06:38 +000083#if TKMAJORMINOR < 4001
84 #error "Tk 4.0 or 3.x are not supported -- use 4.1 or higher"
85#endif
86
Guido van Rossum0d2390c1997-08-14 19:57:07 +000087#if TKMAJORMINOR >= 8000 && defined(macintosh)
88/* Sigh, we have to include this to get at the tcl qd pointer */
89#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000090/* And this one we need to clear the menu bar */
91#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000092#endif
93
Guido van Rossumb0105441997-10-08 15:25:37 +000094#if TKMAJORMINOR < 8000 || !defined(MS_WINDOWS)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000095#define HAVE_CREATEFILEHANDLER
96#endif
97
Guido van Rossum00d93061998-05-28 23:06:38 +000098#ifdef HAVE_CREATEFILEHANDLER
99
100/* Tcl_CreateFileHandler() changed several times; these macros deal with the
101 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
102 Unix, only because Jack added it back); when available on Windows, it only
103 applies to sockets. */
104
Guido van Rossum7bf15641998-05-22 18:28:17 +0000105#ifdef MS_WINDOWS
106#define FHANDLETYPE TCL_WIN_SOCKET
107#else
108#define FHANDLETYPE TCL_UNIX_FD
109#endif
110
111#if TKMAJORMINOR < 8000
112#define FHANDLE Tcl_File
113#define MAKEFHANDLE(fd) Tcl_GetFile((ClientData)(fd), FHANDLETYPE)
114#else
115#define FHANDLE int
116#define MAKEFHANDLE(fd) (fd)
117#endif
118
Guido van Rossum00d93061998-05-28 23:06:38 +0000119/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
120 which uses this to handle Tcl events while the user is typing commands. */
121
122#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000123#define WAIT_FOR_STDIN
124#endif
125
Guido van Rossum00d93061998-05-28 23:06:38 +0000126#endif /* HAVE_CREATEFILEHANDLER */
127
Guido van Rossumad4db171998-06-13 13:56:28 +0000128#ifdef MS_WINDOWS
129#include <conio.h>
130#define WAIT_FOR_STDIN
131#endif
132
Guido van Rossum00d93061998-05-28 23:06:38 +0000133#ifdef WITH_THREAD
134
135/* The threading situation is complicated. Tcl is not thread-safe, except for
136 Tcl 8.1, which will probably remain in alpha status for another 6 months
137 (and the README says that Tk will probably remain thread-unsafe forever).
138 So we need to use a lock around all uses of Tcl. Previously, the Python
139 interpreter lock was used for this. However, this causes problems when
140 other Python threads need to run while Tcl is blocked waiting for events.
141
142 To solve this problem, a separate lock for Tcl is introduced. Holding it
143 is incompatible with holding Python's interpreter lock. The following four
144 macros manipulate both locks together.
145
146 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
147 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
148 that could call an event handler, or otherwise affect the state of a Tcl
149 interpreter. These assume that the surrounding code has the Python
150 interpreter lock; inside the brackets, the Python interpreter lock has been
151 released and the lock for Tcl has been acquired.
152
Guido van Rossum5e977831998-06-15 14:03:52 +0000153 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
154 (For example, when transferring data from the Tcl interpreter result to a
155 Python string object.) This can be done by using different macros to close
156 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
157 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
158 releases the Tcl lock.
159
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000160 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000161 handlers when the handler needs to use Python. Such event handlers are
162 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000163 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000164 the Python interpreter lock, restoring the appropriate thread state, and
165 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
166 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000167 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000168
169 These locks expand to several statements and brackets; they should not be
170 used in branches of if statements and the like.
171
172*/
173
Guido van Rossum65d5b571998-12-21 19:32:43 +0000174static PyThread_type_lock tcl_lock = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000175static PyThreadState *tcl_tstate = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000176
177#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000178 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000179 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000180
181#define LEAVE_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000182 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000183
Guido van Rossum62320c91998-06-15 04:36:09 +0000184#define ENTER_OVERLAP \
185 Py_END_ALLOW_THREADS
186
187#define LEAVE_OVERLAP_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000188 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000189
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000190#define ENTER_PYTHON \
191 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000192 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000193
194#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000195 { PyThreadState *tstate = PyEval_SaveThread(); \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000196 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Guido van Rossum00d93061998-05-28 23:06:38 +0000197
198#else
199
200#define ENTER_TCL
201#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000202#define ENTER_OVERLAP
203#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000204#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000205#define LEAVE_PYTHON
206
207#endif
208
Guido van Rossumec22c921996-02-25 04:50:29 +0000209#ifdef macintosh
210
211/*
212** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000213** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000214*/
215
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000216/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000217#define FREECAST (char *)
218
Guido van Rossumec22c921996-02-25 04:50:29 +0000219#include <Events.h> /* For EventRecord */
220
221typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
Guido van Rossum0d2390c1997-08-14 19:57:07 +0000222/* They changed the name... */
223#if TKMAJORMINOR < 8000
224#define Tcl_MacSetEventProc TclMacSetEventProc
225#endif
226void Tcl_MacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
Guido van Rossumec22c921996-02-25 04:50:29 +0000227int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
228
229staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
230
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000231#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
232 #pragma import on
233#endif
234
235#include <SIOUX.h>
236extern int SIOUXIsAppWindow(WindowPtr);
237
238#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
239 #pragma import reset
240#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000241#endif /* macintosh */
242
Guido van Rossum97867b21996-08-08 19:09:53 +0000243#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000244#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000245#endif
246
Guido van Rossum18468821994-06-20 07:49:28 +0000247/**** Tkapp Object Declaration ****/
248
249staticforward PyTypeObject Tkapp_Type;
250
Guido van Rossum00d93061998-05-28 23:06:38 +0000251typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000252 PyObject_HEAD
253 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000254} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000255
256#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000257#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
258#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
259
Guido van Rossum35d43371997-08-02 00:09:09 +0000260#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000261(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000262
Barry Warsawfa701a81997-01-16 00:15:11 +0000263
264
Guido van Rossum18468821994-06-20 07:49:28 +0000265/**** Error Handling ****/
266
267static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000268static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000269static int errorInCmd = 0;
270static PyObject *excInCmd;
271static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000273
Barry Warsawfa701a81997-01-16 00:15:11 +0000274
275
Guido van Rossum18468821994-06-20 07:49:28 +0000276static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000277Tkinter_Error(v)
278 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000279{
Barry Warsawfa701a81997-01-16 00:15:11 +0000280 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
281 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000282}
283
Barry Warsawfa701a81997-01-16 00:15:11 +0000284
Barry Warsawfa701a81997-01-16 00:15:11 +0000285
Guido van Rossum18468821994-06-20 07:49:28 +0000286/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000287
288#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000289#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000290#include "mytime.h"
Guido van Rossum11801851999-01-25 21:39:03 +0000291#include "myselect.h"
Guido van Rossum541f2411998-08-13 13:29:22 +0000292
Guido van Rossum00d93061998-05-28 23:06:38 +0000293/* Millisecond sleep() for Unix platforms. */
294
295static void
296Sleep(milli)
297 int milli;
298{
299 /* XXX Too bad if you don't have select(). */
300 struct timeval t;
301 double frac;
302 t.tv_sec = milli/1000;
303 t.tv_usec = (milli%1000) * 1000;
304 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
305}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000306#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000307#endif /* WITH_THREAD */
308
309
Guido van Rossum18468821994-06-20 07:49:28 +0000310static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000311AsString(value, tmp)
312 PyObject *value;
313 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000314{
Guido van Rossum35d43371997-08-02 00:09:09 +0000315 if (PyString_Check(value))
316 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000317 else {
318 PyObject *v = PyObject_Str(value);
319 PyList_Append(tmp, v);
320 Py_DECREF(v);
321 return PyString_AsString(v);
322 }
Guido van Rossum18468821994-06-20 07:49:28 +0000323}
324
Barry Warsawfa701a81997-01-16 00:15:11 +0000325
326
Guido van Rossum18468821994-06-20 07:49:28 +0000327#define ARGSZ 64
328
329static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000330Merge(args)
331 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000332{
Barry Warsawfa701a81997-01-16 00:15:11 +0000333 PyObject *tmp = NULL;
334 char *argvStore[ARGSZ];
335 char **argv = NULL;
336 int fvStore[ARGSZ];
337 int *fv = NULL;
338 int argc = 0, i;
339 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000340
Barry Warsawfa701a81997-01-16 00:15:11 +0000341 if (!(tmp = PyList_New(0)))
342 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000343
Barry Warsawfa701a81997-01-16 00:15:11 +0000344 argv = argvStore;
345 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000346
Barry Warsawfa701a81997-01-16 00:15:11 +0000347 if (args == NULL)
348 argc = 0;
349
350 else if (!PyTuple_Check(args)) {
351 argc = 1;
352 fv[0] = 0;
353 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000354 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000355 else {
356 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000357
Barry Warsawfa701a81997-01-16 00:15:11 +0000358 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000359 argv = (char **)ckalloc(argc * sizeof(char *));
360 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000361 if (argv == NULL || fv == NULL) {
362 PyErr_NoMemory();
363 goto finally;
364 }
365 }
366
367 for (i = 0; i < argc; i++) {
368 PyObject *v = PyTuple_GetItem(args, i);
369 if (PyTuple_Check(v)) {
370 fv[i] = 1;
371 if (!(argv[i] = Merge(v)))
372 goto finally;
373 }
374 else if (v == Py_None) {
375 argc = i;
376 break;
377 }
378 else {
379 fv[i] = 0;
380 argv[i] = AsString(v, tmp);
381 }
382 }
Guido van Rossum18468821994-06-20 07:49:28 +0000383 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000384 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000385
Barry Warsawfa701a81997-01-16 00:15:11 +0000386 finally:
387 for (i = 0; i < argc; i++)
388 if (fv[i]) {
389 ckfree(argv[i]);
390 }
391 if (argv != argvStore)
392 ckfree(FREECAST argv);
393 if (fv != fvStore)
394 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000395
Barry Warsawfa701a81997-01-16 00:15:11 +0000396 Py_DECREF(tmp);
397 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000398}
399
Barry Warsawfa701a81997-01-16 00:15:11 +0000400
401
Guido van Rossum18468821994-06-20 07:49:28 +0000402static PyObject *
Guido van Rossum00d93061998-05-28 23:06:38 +0000403Split(list)
Barry Warsawfa701a81997-01-16 00:15:11 +0000404 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000405{
Barry Warsawfa701a81997-01-16 00:15:11 +0000406 int argc;
407 char **argv;
408 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000409
Barry Warsawfa701a81997-01-16 00:15:11 +0000410 if (list == NULL) {
411 Py_INCREF(Py_None);
412 return Py_None;
413 }
Guido van Rossum18468821994-06-20 07:49:28 +0000414
Guido van Rossum00d93061998-05-28 23:06:38 +0000415 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000416 /* Not a list.
417 * Could be a quoted string containing funnies, e.g. {"}.
418 * Return the string itself.
419 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000420 return PyString_FromString(list);
421 }
Guido van Rossum18468821994-06-20 07:49:28 +0000422
Barry Warsawfa701a81997-01-16 00:15:11 +0000423 if (argc == 0)
424 v = PyString_FromString("");
425 else if (argc == 1)
426 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000427 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000428 int i;
429 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000430
Barry Warsawfa701a81997-01-16 00:15:11 +0000431 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000432 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000433 Py_DECREF(v);
434 v = NULL;
435 break;
436 }
437 PyTuple_SetItem(v, i, w);
438 }
439 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000440 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000441 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000442}
443
Barry Warsawfa701a81997-01-16 00:15:11 +0000444
445
Guido van Rossum18468821994-06-20 07:49:28 +0000446/**** Tkapp Object ****/
447
448#ifndef WITH_APPINIT
449int
Guido van Rossum35d43371997-08-02 00:09:09 +0000450Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000451 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000452{
Barry Warsawfa701a81997-01-16 00:15:11 +0000453 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000454
Barry Warsawfa701a81997-01-16 00:15:11 +0000455 main = Tk_MainWindow(interp);
456 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000457 PySys_WriteStderr("Tcl_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000458 return TCL_ERROR;
459 }
460 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000461 PySys_WriteStderr("Tk_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000462 return TCL_ERROR;
463 }
464 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000465}
466#endif /* !WITH_APPINIT */
467
Guido van Rossum18468821994-06-20 07:49:28 +0000468
Barry Warsawfa701a81997-01-16 00:15:11 +0000469
470
471/* Initialize the Tk application; see the `main' function in
472 * `tkMain.c'.
473 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000474
475static void EnableEventHook(); /* Forward */
476static void DisableEventHook(); /* Forward */
477
Barry Warsawfa701a81997-01-16 00:15:11 +0000478static TkappObject *
479Tkapp_New(screenName, baseName, className, interactive)
480 char *screenName;
481 char *baseName;
482 char *className;
483 int interactive;
484{
485 TkappObject *v;
486 char *argv0;
487
488 v = PyObject_NEW(TkappObject, &Tkapp_Type);
489 if (v == NULL)
490 return NULL;
491
492 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000493
Guido van Rossum6b26a061999-11-05 18:09:56 +0000494#if TKMAJORMINOR == 8001
495 TclpInitLibraryPath(baseName);
496#endif /* TKMAJORMINOR */
497
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000498#if defined(macintosh) && TKMAJORMINOR >= 8000
499 /* This seems to be needed since Tk 8.0 */
500 ClearMenuBar();
501 TkMacInitMenus(v->interp);
502#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000503 /* Delete the 'exit' command, which can screw things up */
504 Tcl_DeleteCommand(v->interp, "exit");
505
Barry Warsawfa701a81997-01-16 00:15:11 +0000506 if (screenName != NULL)
507 Tcl_SetVar2(v->interp, "env", "DISPLAY",
508 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000509
Barry Warsawfa701a81997-01-16 00:15:11 +0000510 if (interactive)
511 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
512 else
513 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000514
Barry Warsawfa701a81997-01-16 00:15:11 +0000515 /* This is used to get the application class for Tk 4.1 and up */
516 argv0 = (char*)ckalloc(strlen(className) + 1);
517 if (!argv0) {
518 PyErr_NoMemory();
519 Py_DECREF(v);
520 return NULL;
521 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000522
Barry Warsawfa701a81997-01-16 00:15:11 +0000523 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000524 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000525 argv0[0] = tolower(argv0[0]);
526 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
527 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000528
Barry Warsawfa701a81997-01-16 00:15:11 +0000529 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000530 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000531
Guido van Rossum7bf15641998-05-22 18:28:17 +0000532 EnableEventHook();
533
Barry Warsawfa701a81997-01-16 00:15:11 +0000534 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000535}
536
Barry Warsawfa701a81997-01-16 00:15:11 +0000537
538
Guido van Rossum18468821994-06-20 07:49:28 +0000539/** Tcl Eval **/
540
541static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000542Tkapp_Call(self, args)
543 PyObject *self;
544 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000545{
Guido van Rossum212643f1998-04-29 16:22:14 +0000546 /* This is copied from Merge() */
547 PyObject *tmp = NULL;
548 char *argvStore[ARGSZ];
549 char **argv = NULL;
550 int fvStore[ARGSZ];
551 int *fv = NULL;
552 int argc = 0, i;
553 PyObject *res = NULL; /* except this has a different type */
554 Tcl_CmdInfo info; /* and this is added */
555 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
Guido van Rossum18468821994-06-20 07:49:28 +0000556
Guido van Rossum212643f1998-04-29 16:22:14 +0000557 if (!(tmp = PyList_New(0)))
558 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000559
Guido van Rossum212643f1998-04-29 16:22:14 +0000560 argv = argvStore;
561 fv = fvStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000562
Guido van Rossum212643f1998-04-29 16:22:14 +0000563 if (args == NULL)
564 argc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000565
Guido van Rossum212643f1998-04-29 16:22:14 +0000566 else if (!PyTuple_Check(args)) {
567 argc = 1;
568 fv[0] = 0;
569 argv[0] = AsString(args, tmp);
570 }
571 else {
572 argc = PyTuple_Size(args);
573
574 if (argc > ARGSZ) {
575 argv = (char **)ckalloc(argc * sizeof(char *));
576 fv = (int *)ckalloc(argc * sizeof(int));
577 if (argv == NULL || fv == NULL) {
578 PyErr_NoMemory();
579 goto finally;
580 }
581 }
582
583 for (i = 0; i < argc; i++) {
584 PyObject *v = PyTuple_GetItem(args, i);
585 if (PyTuple_Check(v)) {
586 fv[i] = 1;
587 if (!(argv[i] = Merge(v)))
588 goto finally;
589 }
590 else if (v == Py_None) {
591 argc = i;
592 break;
593 }
594 else {
595 fv[i] = 0;
596 argv[i] = AsString(v, tmp);
597 }
598 }
599 }
600 /* End code copied from Merge() */
601
602 /* All this to avoid a call to Tcl_Merge() and the corresponding call
603 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
604 if (Py_VerboseFlag >= 2) {
605 for (i = 0; i < argc; i++)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000606 PySys_WriteStderr("%s ", argv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000607 }
Guido van Rossum62320c91998-06-15 04:36:09 +0000608 ENTER_TCL
609 info.proc = NULL;
Guido van Rossum212643f1998-04-29 16:22:14 +0000610 if (argc < 1 ||
611 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
612 info.proc == NULL)
613 {
614 char *cmd;
Guido van Rossum212643f1998-04-29 16:22:14 +0000615 cmd = Tcl_Merge(argc, argv);
616 i = Tcl_Eval(interp, cmd);
Barry Warsawfa701a81997-01-16 00:15:11 +0000617 ckfree(cmd);
Guido van Rossum212643f1998-04-29 16:22:14 +0000618 }
619 else {
620 Tcl_ResetResult(interp);
621 i = (*info.proc)(info.clientData, interp, argc, argv);
622 }
Guido van Rossum62320c91998-06-15 04:36:09 +0000623 ENTER_OVERLAP
624 if (info.proc == NULL && Py_VerboseFlag >= 2)
625 PySys_WriteStderr("... use TclEval ");
Guido van Rossum212643f1998-04-29 16:22:14 +0000626 if (i == TCL_ERROR) {
627 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000628 PySys_WriteStderr("... error: '%s'\n",
Guido van Rossum212643f1998-04-29 16:22:14 +0000629 interp->result);
630 Tkinter_Error(self);
631 }
632 else {
633 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000634 PySys_WriteStderr("-> '%s'\n", interp->result);
Guido van Rossum212643f1998-04-29 16:22:14 +0000635 res = PyString_FromString(interp->result);
636 }
Guido van Rossum62320c91998-06-15 04:36:09 +0000637 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000638
Guido van Rossum212643f1998-04-29 16:22:14 +0000639 /* Copied from Merge() again */
640 finally:
641 for (i = 0; i < argc; i++)
642 if (fv[i]) {
643 ckfree(argv[i]);
644 }
645 if (argv != argvStore)
646 ckfree(FREECAST argv);
647 if (fv != fvStore)
648 ckfree(FREECAST fv);
649
650 Py_DECREF(tmp);
Barry Warsawfa701a81997-01-16 00:15:11 +0000651 return res;
652}
653
654
655static PyObject *
656Tkapp_GlobalCall(self, args)
657 PyObject *self;
658 PyObject *args;
659{
Guido van Rossum212643f1998-04-29 16:22:14 +0000660 /* Could do the same here as for Tkapp_Call(), but this is not used
661 much, so I can't be bothered. Unfortunately Tcl doesn't export a
662 way for the user to do what all its Global* variants do (save and
663 reset the scope pointer, call the local version, restore the saved
664 scope pointer). */
665
Guido van Rossum62320c91998-06-15 04:36:09 +0000666 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000667 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000668
Guido van Rossum62320c91998-06-15 04:36:09 +0000669 cmd = Merge(args);
Barry Warsawfa701a81997-01-16 00:15:11 +0000670 if (!cmd)
671 PyErr_SetString(Tkinter_TclError, "merge failed");
672
Guido van Rossum00d93061998-05-28 23:06:38 +0000673 else {
674 int err;
675 ENTER_TCL
676 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000677 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000678 if (err == TCL_ERROR)
679 res = Tkinter_Error(self);
680 else
681 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000682 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +0000683 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000684
685 if (cmd)
686 ckfree(cmd);
687
688 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000689}
690
691static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000692Tkapp_Eval(self, args)
693 PyObject *self;
694 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000695{
Barry Warsawfa701a81997-01-16 00:15:11 +0000696 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000697 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000698 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000699
Guido van Rossum43713e52000-02-29 13:59:29 +0000700 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000701 return NULL;
702
Guido van Rossum00d93061998-05-28 23:06:38 +0000703 ENTER_TCL
704 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000705 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000706 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000707 res = Tkinter_Error(self);
708 else
709 res = PyString_FromString(Tkapp_Result(self));
710 LEAVE_OVERLAP_TCL
711 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000712}
713
714static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000715Tkapp_GlobalEval(self, args)
716 PyObject *self;
717 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000718{
Barry Warsawfa701a81997-01-16 00:15:11 +0000719 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000720 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000721 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000722
Guido van Rossum43713e52000-02-29 13:59:29 +0000723 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000724 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000725
Guido van Rossum00d93061998-05-28 23:06:38 +0000726 ENTER_TCL
727 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000728 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000729 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000730 res = Tkinter_Error(self);
731 else
732 res = PyString_FromString(Tkapp_Result(self));
733 LEAVE_OVERLAP_TCL
734 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000735}
736
737static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000738Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000739 PyObject *self;
740 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000741{
Barry Warsawfa701a81997-01-16 00:15:11 +0000742 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000743 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000744 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000745
Guido van Rossum43713e52000-02-29 13:59:29 +0000746 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000747 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000748
Guido van Rossum00d93061998-05-28 23:06:38 +0000749 ENTER_TCL
750 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000751 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000752 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000753 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000754
Guido van Rossum62320c91998-06-15 04:36:09 +0000755 else
756 res = PyString_FromString(Tkapp_Result(self));
757 LEAVE_OVERLAP_TCL
758 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000759}
760
761static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000762Tkapp_Record(self, args)
763 PyObject *self;
764 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000765{
Barry Warsawfa701a81997-01-16 00:15:11 +0000766 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000767 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000768 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000769
Guido van Rossum35d43371997-08-02 00:09:09 +0000770 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000771 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000772
Guido van Rossum00d93061998-05-28 23:06:38 +0000773 ENTER_TCL
774 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000775 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000776 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000777 res = Tkinter_Error(self);
778 else
779 res = PyString_FromString(Tkapp_Result(self));
780 LEAVE_OVERLAP_TCL
781 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000782}
783
784static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000785Tkapp_AddErrorInfo(self, args)
786 PyObject *self;
787 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000788{
Barry Warsawfa701a81997-01-16 00:15:11 +0000789 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000790
Guido van Rossum43713e52000-02-29 13:59:29 +0000791 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000792 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000793 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000794 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000795 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000796
Barry Warsawfa701a81997-01-16 00:15:11 +0000797 Py_INCREF(Py_None);
798 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000799}
800
Barry Warsawfa701a81997-01-16 00:15:11 +0000801
802
Guido van Rossum18468821994-06-20 07:49:28 +0000803/** Tcl Variable **/
804
805static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000806SetVar(self, args, flags)
807 PyObject *self;
808 PyObject *args;
809 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000810{
Guido van Rossum00d93061998-05-28 23:06:38 +0000811 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000812 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000813 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000814
Guido van Rossum62320c91998-06-15 04:36:09 +0000815 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000816 if (!tmp)
817 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000818
Guido van Rossum43713e52000-02-29 13:59:29 +0000819 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000820 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000821 s = AsString(newValue, tmp);
822 ENTER_TCL
823 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
824 LEAVE_TCL
825 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000826 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000827 PyErr_Clear();
Guido van Rossum43713e52000-02-29 13:59:29 +0000828 if (PyArg_ParseTuple(args, "ssO:setvar", &name1, &name2, &newValue)) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000829 s = AsString (newValue, tmp);
830 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000831 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000832 s, flags);
833 LEAVE_TCL
834 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000835 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000836 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000837 return NULL;
838 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000839 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000840 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000841
Barry Warsawfa701a81997-01-16 00:15:11 +0000842 if (!ok)
843 return Tkinter_Error(self);
844
845 Py_INCREF(Py_None);
846 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000847}
848
849static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000850Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000851 PyObject *self;
852 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000853{
Barry Warsawfa701a81997-01-16 00:15:11 +0000854 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000855}
856
857static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000858Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000859 PyObject *self;
860 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000861{
Barry Warsawfa701a81997-01-16 00:15:11 +0000862 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000863}
864
Barry Warsawfa701a81997-01-16 00:15:11 +0000865
866
Guido van Rossum18468821994-06-20 07:49:28 +0000867static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000868GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000869 PyObject *self;
870 PyObject *args;
871 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000872{
Guido van Rossum35d43371997-08-02 00:09:09 +0000873 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000874 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000875
Guido van Rossum43713e52000-02-29 13:59:29 +0000876 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +0000877 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000878 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000879 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000880 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000881
Barry Warsawfa701a81997-01-16 00:15:11 +0000882 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000883 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000884 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000885
Barry Warsawfa701a81997-01-16 00:15:11 +0000886 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000887 res = Tkinter_Error(self);
888 else
889 res = PyString_FromString(s);
890 LEAVE_OVERLAP_TCL
891 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000892}
893
894static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000895Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000896 PyObject *self;
897 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000898{
Barry Warsawfa701a81997-01-16 00:15:11 +0000899 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000900}
901
902static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000903Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000904 PyObject *self;
905 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000906{
Barry Warsawfa701a81997-01-16 00:15:11 +0000907 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000908}
909
Barry Warsawfa701a81997-01-16 00:15:11 +0000910
911
Guido van Rossum18468821994-06-20 07:49:28 +0000912static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000913UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000914 PyObject *self;
915 PyObject *args;
916 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000917{
Guido van Rossum35d43371997-08-02 00:09:09 +0000918 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +0000919 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000920 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000921
Guido van Rossum43713e52000-02-29 13:59:29 +0000922 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000923 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000924 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000925 if (name2 == NULL)
926 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
927
928 else
929 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000930 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000931
Barry Warsawfa701a81997-01-16 00:15:11 +0000932 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000933 res = Tkinter_Error(self);
934 else {
935 Py_INCREF(Py_None);
936 res = Py_None;
937 }
938 LEAVE_OVERLAP_TCL
939 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000940}
941
942static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000943Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000944 PyObject *self;
945 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000946{
Barry Warsawfa701a81997-01-16 00:15:11 +0000947 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000948}
949
950static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000951Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000952 PyObject *self;
953 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000954{
Barry Warsawfa701a81997-01-16 00:15:11 +0000955 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000956}
957
Barry Warsawfa701a81997-01-16 00:15:11 +0000958
959
Guido van Rossum18468821994-06-20 07:49:28 +0000960/** Tcl to Python **/
961
962static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000963Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000964 PyObject *self;
965 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000966{
Barry Warsawfa701a81997-01-16 00:15:11 +0000967 char *s;
968 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000969
Guido van Rossum43713e52000-02-29 13:59:29 +0000970 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000971 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000972 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000973 return Tkinter_Error(self);
974 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000975}
976
977static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000978Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000979 PyObject *self;
980 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000981{
Barry Warsawfa701a81997-01-16 00:15:11 +0000982 char *s;
983 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000984
Guido van Rossum43713e52000-02-29 13:59:29 +0000985 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000986 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000987 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000988 return Tkinter_Error(self);
989 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000990}
991
992static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000993Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000994 PyObject *self;
995 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000996{
Barry Warsawfa701a81997-01-16 00:15:11 +0000997 char *s;
998 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000999
Guido van Rossum43713e52000-02-29 13:59:29 +00001000 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001001 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001002 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1003 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001004 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001005}
1006
1007static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001008Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001009 PyObject *self;
1010 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001011{
Barry Warsawfa701a81997-01-16 00:15:11 +00001012 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001013 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001014 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001015
Guido van Rossum43713e52000-02-29 13:59:29 +00001016 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001017 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001018 ENTER_TCL
1019 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001020 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001021 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001022 res = Tkinter_Error(self);
1023 else
1024 res = Py_BuildValue("s", Tkapp_Result(self));
1025 LEAVE_OVERLAP_TCL
1026 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001027}
1028
1029static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001030Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001031 PyObject *self;
1032 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001033{
Barry Warsawfa701a81997-01-16 00:15:11 +00001034 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001035 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001036 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001037 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001038
Guido van Rossum43713e52000-02-29 13:59:29 +00001039 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001040 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001041 ENTER_TCL
1042 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001043 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001044 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001045 res = Tkinter_Error(self);
1046 else
1047 res = Py_BuildValue("l", v);
1048 LEAVE_OVERLAP_TCL
1049 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001050}
1051
1052static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001053Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001054 PyObject *self;
1055 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001056{
Barry Warsawfa701a81997-01-16 00:15:11 +00001057 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001058 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001059 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001060 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001061
Guido van Rossum43713e52000-02-29 13:59:29 +00001062 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001063 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001064 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001065 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001066 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001067 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001068 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001069 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001070 res = Tkinter_Error(self);
1071 else
1072 res = Py_BuildValue("d", v);
1073 LEAVE_OVERLAP_TCL
1074 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001075}
1076
1077static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001078Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001079 PyObject *self;
1080 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001081{
Barry Warsawfa701a81997-01-16 00:15:11 +00001082 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001083 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001084 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001085 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001086
Guido van Rossum43713e52000-02-29 13:59:29 +00001087 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001088 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001089 ENTER_TCL
1090 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001091 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001092 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001093 res = Tkinter_Error(self);
1094 else
1095 res = Py_BuildValue("i", v);
1096 LEAVE_OVERLAP_TCL
1097 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001098}
1099
Barry Warsawfa701a81997-01-16 00:15:11 +00001100
1101
Guido van Rossum18468821994-06-20 07:49:28 +00001102static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001103Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001104 PyObject *self;
1105 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001106{
Barry Warsawfa701a81997-01-16 00:15:11 +00001107 char *list;
1108 int argc;
1109 char **argv;
1110 PyObject *v;
1111 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001112
Guido van Rossum43713e52000-02-29 13:59:29 +00001113 if (!PyArg_ParseTuple(args, "s:splitlist", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001114 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001115
Barry Warsawfa701a81997-01-16 00:15:11 +00001116 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1117 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001118
Barry Warsawfa701a81997-01-16 00:15:11 +00001119 if (!(v = PyTuple_New(argc)))
1120 return NULL;
1121
1122 for (i = 0; i < argc; i++) {
1123 PyObject *s = PyString_FromString(argv[i]);
1124 if (!s || PyTuple_SetItem(v, i, s)) {
1125 Py_DECREF(v);
1126 v = NULL;
1127 goto finally;
1128 }
1129 }
Guido van Rossum18468821994-06-20 07:49:28 +00001130
Barry Warsawfa701a81997-01-16 00:15:11 +00001131 finally:
1132 ckfree(FREECAST argv);
1133 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001134}
1135
1136static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001137Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001138 PyObject *self;
1139 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001140{
Barry Warsawfa701a81997-01-16 00:15:11 +00001141 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001142
Guido van Rossum43713e52000-02-29 13:59:29 +00001143 if (!PyArg_ParseTuple(args, "s:split", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001144 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001145 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001146}
1147
1148static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001149Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001150 PyObject *self;
1151 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001152{
Barry Warsawfa701a81997-01-16 00:15:11 +00001153 char *s = Merge(args);
1154 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001155
Barry Warsawfa701a81997-01-16 00:15:11 +00001156 if (s) {
1157 res = PyString_FromString(s);
1158 ckfree(s);
1159 }
1160 else
1161 PyErr_SetString(Tkinter_TclError, "merge failed");
1162
1163 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001164}
1165
Barry Warsawfa701a81997-01-16 00:15:11 +00001166
1167
Guido van Rossum18468821994-06-20 07:49:28 +00001168/** Tcl Command **/
1169
Guido van Rossum00d93061998-05-28 23:06:38 +00001170/* Client data struct */
1171typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001172 PyObject *self;
1173 PyObject *func;
1174} PythonCmd_ClientData;
1175
1176static int
1177PythonCmd_Error(interp)
1178 Tcl_Interp *interp;
1179{
1180 errorInCmd = 1;
1181 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1182 LEAVE_PYTHON
1183 return TCL_ERROR;
1184}
1185
Guido van Rossum18468821994-06-20 07:49:28 +00001186/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001187 * function or method.
1188 */
Guido van Rossum18468821994-06-20 07:49:28 +00001189static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001190PythonCmd(clientData, interp, argc, argv)
Guido van Rossum00d93061998-05-28 23:06:38 +00001191 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001192 Tcl_Interp *interp;
1193 int argc;
1194 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +00001195{
Guido van Rossum00d93061998-05-28 23:06:38 +00001196 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001197 PyObject *self, *func, *arg, *res, *tmp;
1198 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001199
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001200 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001201
Barry Warsawfa701a81997-01-16 00:15:11 +00001202 /* TBD: no error checking here since we know, via the
1203 * Tkapp_CreateCommand() that the client data is a two-tuple
1204 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001205 self = data->self;
1206 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001207
Barry Warsawfa701a81997-01-16 00:15:11 +00001208 /* Create argument list (argv1, ..., argvN) */
1209 if (!(arg = PyTuple_New(argc - 1)))
1210 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001211
Barry Warsawfa701a81997-01-16 00:15:11 +00001212 for (i = 0; i < (argc - 1); i++) {
1213 PyObject *s = PyString_FromString(argv[i + 1]);
1214 if (!s || PyTuple_SetItem(arg, i, s)) {
1215 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001216 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001217 }
1218 }
1219 res = PyEval_CallObject(func, arg);
1220 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001221
Barry Warsawfa701a81997-01-16 00:15:11 +00001222 if (res == NULL)
1223 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001224
Barry Warsawfa701a81997-01-16 00:15:11 +00001225 if (!(tmp = PyList_New(0))) {
1226 Py_DECREF(res);
1227 return PythonCmd_Error(interp);
1228 }
1229
1230 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
1231 Py_DECREF(res);
1232 Py_DECREF(tmp);
1233
Guido van Rossum00d93061998-05-28 23:06:38 +00001234 LEAVE_PYTHON
1235
Barry Warsawfa701a81997-01-16 00:15:11 +00001236 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +00001237}
1238
1239static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001240PythonCmdDelete(clientData)
Guido van Rossum00d93061998-05-28 23:06:38 +00001241 ClientData clientData;
Guido van Rossum18468821994-06-20 07:49:28 +00001242{
Guido van Rossum00d93061998-05-28 23:06:38 +00001243 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1244
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001245 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001246 Py_XDECREF(data->self);
1247 Py_XDECREF(data->func);
1248 PyMem_DEL(data);
1249 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001250}
1251
Barry Warsawfa701a81997-01-16 00:15:11 +00001252
1253
Guido van Rossum18468821994-06-20 07:49:28 +00001254static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001255Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001256 PyObject *self;
1257 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001258{
Guido van Rossum00d93061998-05-28 23:06:38 +00001259 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001260 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001261 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001262 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001263
Guido van Rossum43713e52000-02-29 13:59:29 +00001264 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001265 return NULL;
1266 if (!PyCallable_Check(func)) {
1267 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001268 return NULL;
1269 }
Guido van Rossum18468821994-06-20 07:49:28 +00001270
Guido van Rossum00d93061998-05-28 23:06:38 +00001271 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001272 if (!data)
1273 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001274 Py_XINCREF(self);
1275 Py_XINCREF(func);
1276 data->self = self;
1277 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001278
Guido van Rossum00d93061998-05-28 23:06:38 +00001279 ENTER_TCL
1280 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1281 (ClientData)data, PythonCmdDelete);
1282 LEAVE_TCL
1283 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001284 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001285 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001286 return NULL;
1287 }
Guido van Rossum18468821994-06-20 07:49:28 +00001288
Barry Warsawfa701a81997-01-16 00:15:11 +00001289 Py_INCREF(Py_None);
1290 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001291}
1292
Barry Warsawfa701a81997-01-16 00:15:11 +00001293
1294
Guido van Rossum18468821994-06-20 07:49:28 +00001295static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001296Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001297 PyObject *self;
1298 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001299{
Barry Warsawfa701a81997-01-16 00:15:11 +00001300 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001301 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001302
Guido van Rossum43713e52000-02-29 13:59:29 +00001303 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001304 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001305 ENTER_TCL
1306 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1307 LEAVE_TCL
1308 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001309 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1310 return NULL;
1311 }
1312 Py_INCREF(Py_None);
1313 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001314}
1315
Barry Warsawfa701a81997-01-16 00:15:11 +00001316
1317
Guido van Rossum00d93061998-05-28 23:06:38 +00001318#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001319/** File Handler **/
1320
Guido van Rossum00d93061998-05-28 23:06:38 +00001321typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001322 PyObject *func;
1323 PyObject *file;
1324 int id;
1325 struct _fhcdata *next;
1326} FileHandler_ClientData;
1327
1328static FileHandler_ClientData *HeadFHCD;
1329
1330static FileHandler_ClientData *
1331NewFHCD(func, file, id)
1332 PyObject *func;
1333 PyObject *file;
1334 int id;
1335{
1336 FileHandler_ClientData *p;
1337 p = PyMem_NEW(FileHandler_ClientData, 1);
1338 if (p != NULL) {
1339 Py_XINCREF(func);
1340 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001341 p->func = func;
1342 p->file = file;
1343 p->id = id;
1344 p->next = HeadFHCD;
1345 HeadFHCD = p;
1346 }
1347 return p;
1348}
1349
1350static void
1351DeleteFHCD(id)
1352 int id;
1353{
1354 FileHandler_ClientData *p, **pp;
1355
1356 pp = &HeadFHCD;
1357 while ((p = *pp) != NULL) {
1358 if (p->id == id) {
1359 *pp = p->next;
1360 Py_XDECREF(p->func);
1361 Py_XDECREF(p->file);
1362 PyMem_DEL(p);
1363 }
1364 else
1365 pp = &p->next;
1366 }
1367}
1368
Guido van Rossuma597dde1995-01-10 20:56:29 +00001369static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001370FileHandler(clientData, mask)
Guido van Rossum00d93061998-05-28 23:06:38 +00001371 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001372 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +00001373{
Guido van Rossum00d93061998-05-28 23:06:38 +00001374 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001375 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001376
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001377 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001378 func = data->func;
1379 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001380
Barry Warsawfa701a81997-01-16 00:15:11 +00001381 arg = Py_BuildValue("(Oi)", file, (long) mask);
1382 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001383 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001384
1385 if (res == NULL) {
1386 errorInCmd = 1;
1387 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1388 }
1389 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001390 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001391}
1392
1393static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001394GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +00001395 /* Either an int >= 0 or an object with a
1396 *.fileno() method that returns an int >= 0
1397 */
1398 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001399{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001400 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001401 int id;
1402 if (PyInt_Check(file)) {
1403 id = PyInt_AsLong(file);
1404 if (id < 0)
1405 PyErr_SetString(PyExc_ValueError, "invalid file id");
1406 return id;
1407 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001408 args = PyTuple_New(0);
1409 if (args == NULL)
1410 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001411
1412 meth = PyObject_GetAttrString(file, "fileno");
1413 if (meth == NULL) {
1414 Py_DECREF(args);
1415 return -1;
1416 }
1417
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001418 res = PyEval_CallObject(meth, args);
1419 Py_DECREF(args);
1420 Py_DECREF(meth);
1421 if (res == NULL)
1422 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001423
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001424 if (PyInt_Check(res))
1425 id = PyInt_AsLong(res);
1426 else
1427 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001428
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001429 if (id < 0)
1430 PyErr_SetString(PyExc_ValueError,
1431 "invalid fileno() return value");
1432 Py_DECREF(res);
1433 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001434}
1435
1436static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001437Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001438 PyObject *self;
1439 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001440{
Guido van Rossum00d93061998-05-28 23:06:38 +00001441 FileHandler_ClientData *data;
1442 PyObject *file, *func;
Barry Warsawfa701a81997-01-16 00:15:11 +00001443 int mask, id;
Guido van Rossum7bf15641998-05-22 18:28:17 +00001444 FHANDLE tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001445
Guido van Rossum43713e52000-02-29 13:59:29 +00001446 if (!PyArg_ParseTuple(args, "OiO:createfilehandler", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001447 return NULL;
1448 id = GetFileNo(file);
1449 if (id < 0)
1450 return NULL;
1451 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001452 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001453 return NULL;
1454 }
1455
Guido van Rossum00d93061998-05-28 23:06:38 +00001456 data = NewFHCD(func, file, id);
1457 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001458 return NULL;
1459
Guido van Rossum7bf15641998-05-22 18:28:17 +00001460 tfile = MAKEFHANDLE(id);
Barry Warsawfa701a81997-01-16 00:15:11 +00001461 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001462 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001463 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001464 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001465 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001466 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001467}
1468
1469static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001470Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001471 PyObject *self;
1472 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001473{
Barry Warsawfa701a81997-01-16 00:15:11 +00001474 PyObject *file;
Guido van Rossum00d93061998-05-28 23:06:38 +00001475 FileHandler_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001476 int id;
Guido van Rossum7bf15641998-05-22 18:28:17 +00001477 FHANDLE tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001478
Guido van Rossum43713e52000-02-29 13:59:29 +00001479 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001480 return NULL;
1481 id = GetFileNo(file);
1482 if (id < 0)
1483 return NULL;
1484
Guido van Rossum00d93061998-05-28 23:06:38 +00001485 DeleteFHCD(id);
Guido van Rossum18468821994-06-20 07:49:28 +00001486
Guido van Rossum7bf15641998-05-22 18:28:17 +00001487 tfile = MAKEFHANDLE(id);
Barry Warsawfa701a81997-01-16 00:15:11 +00001488 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001489 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001490 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001491 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001492 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001493 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001494}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001495#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001496
Barry Warsawfa701a81997-01-16 00:15:11 +00001497
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001498/**** Tktt Object (timer token) ****/
1499
1500staticforward PyTypeObject Tktt_Type;
1501
Guido van Rossum00d93061998-05-28 23:06:38 +00001502typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001503 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001504 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001505 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001506} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001507
1508static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001509Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001510 PyObject *self;
1511 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001512{
Barry Warsawfa701a81997-01-16 00:15:11 +00001513 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001514 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001515
Guido van Rossum43713e52000-02-29 13:59:29 +00001516 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001517 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001518 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001519 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001520 v->token = NULL;
1521 }
1522 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001523 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001524 Py_DECREF(func);
1525 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001526 }
1527 Py_INCREF(Py_None);
1528 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001529}
1530
1531static PyMethodDef Tktt_methods[] =
1532{
Guido van Rossum35d43371997-08-02 00:09:09 +00001533 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001534 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001535};
1536
1537static TkttObject *
Guido van Rossum00d93061998-05-28 23:06:38 +00001538Tktt_New(func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001539 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001540{
Barry Warsawfa701a81997-01-16 00:15:11 +00001541 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001542
Barry Warsawfa701a81997-01-16 00:15:11 +00001543 v = PyObject_NEW(TkttObject, &Tktt_Type);
1544 if (v == NULL)
1545 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001546
Guido van Rossum00d93061998-05-28 23:06:38 +00001547 Py_INCREF(func);
1548 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001549 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001550
1551 /* Extra reference, deleted when called or when handler is deleted */
1552 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001553 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001554}
1555
1556static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001557Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001558 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001559{
Guido van Rossum00d93061998-05-28 23:06:38 +00001560 TkttObject *v = (TkttObject *)self;
1561 PyObject *func = v->func;
1562
1563 Py_XDECREF(func);
1564
Guido van Rossum35d43371997-08-02 00:09:09 +00001565 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001566}
1567
Guido van Rossum597ac201998-05-12 14:36:19 +00001568static PyObject *
1569Tktt_Repr(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001570 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001571{
Barry Warsawfa701a81997-01-16 00:15:11 +00001572 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001573 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001574
Guido van Rossum597ac201998-05-12 14:36:19 +00001575 sprintf(buf, "<tktimertoken at 0x%lx%s>", (long)v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001576 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001577 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001578}
1579
1580static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001581Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001582 PyObject *self;
1583 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001584{
Barry Warsawfa701a81997-01-16 00:15:11 +00001585 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001586}
1587
1588static PyTypeObject Tktt_Type =
1589{
Guido van Rossum35d43371997-08-02 00:09:09 +00001590 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001591 0, /*ob_size */
1592 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001593 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001594 0, /*tp_itemsize */
1595 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001596 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001597 Tktt_GetAttr, /*tp_getattr */
1598 0, /*tp_setattr */
1599 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001600 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001601 0, /*tp_as_number */
1602 0, /*tp_as_sequence */
1603 0, /*tp_as_mapping */
1604 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001605};
1606
Barry Warsawfa701a81997-01-16 00:15:11 +00001607
1608
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001609/** Timer Handler **/
1610
1611static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001612TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001613 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001614{
Guido van Rossum00d93061998-05-28 23:06:38 +00001615 TkttObject *v = (TkttObject *)clientData;
1616 PyObject *func = v->func;
1617 PyObject *res;
1618
1619 if (func == NULL)
1620 return;
1621
1622 v->func = NULL;
1623
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001624 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001625
1626 res = PyEval_CallObject(func, NULL);
1627 Py_DECREF(func);
1628 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001629
Barry Warsawfa701a81997-01-16 00:15:11 +00001630 if (res == NULL) {
1631 errorInCmd = 1;
1632 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1633 }
1634 else
1635 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001636
1637 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001638}
1639
1640static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001641Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001642 PyObject *self;
1643 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001644{
Barry Warsawfa701a81997-01-16 00:15:11 +00001645 int milliseconds;
1646 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001647 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001648
Guido van Rossum43713e52000-02-29 13:59:29 +00001649 if (!PyArg_ParseTuple(args, "iO:createtimerhandler", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001650 return NULL;
1651 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001652 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001653 return NULL;
1654 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001655 v = Tktt_New(func);
1656 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1657 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001658
Guido van Rossum00d93061998-05-28 23:06:38 +00001659 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001660}
1661
Barry Warsawfa701a81997-01-16 00:15:11 +00001662
Guido van Rossum18468821994-06-20 07:49:28 +00001663/** Event Loop **/
1664
Guido van Rossum18468821994-06-20 07:49:28 +00001665static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001666Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001667 PyObject *self;
1668 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001669{
Barry Warsawfa701a81997-01-16 00:15:11 +00001670 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001671#ifdef WITH_THREAD
1672 PyThreadState *tstate = PyThreadState_Get();
1673#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001674
Guido van Rossum43713e52000-02-29 13:59:29 +00001675 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001676 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001677
Barry Warsawfa701a81997-01-16 00:15:11 +00001678 quitMainLoop = 0;
1679 while (Tk_GetNumMainWindows() > threshold &&
1680 !quitMainLoop &&
1681 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001682 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001683 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001684
1685#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001686 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001687 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001688 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001689 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001690 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001691 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001692 if (result == 0)
1693 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001694 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001695#else
1696 result = Tcl_DoOneEvent(0);
1697#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001698
Guido van Rossum35d43371997-08-02 00:09:09 +00001699 if (PyErr_CheckSignals() != 0)
1700 return NULL;
1701 if (result < 0)
1702 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001703 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001704 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001705
Barry Warsawfa701a81997-01-16 00:15:11 +00001706 if (errorInCmd) {
1707 errorInCmd = 0;
1708 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1709 excInCmd = valInCmd = trbInCmd = NULL;
1710 return NULL;
1711 }
1712 Py_INCREF(Py_None);
1713 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001714}
1715
1716static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001717Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001718 PyObject *self;
1719 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001720{
Guido van Rossum35d43371997-08-02 00:09:09 +00001721 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001722 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001723
Guido van Rossum43713e52000-02-29 13:59:29 +00001724 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001725 return NULL;
1726
Guido van Rossum00d93061998-05-28 23:06:38 +00001727 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001728 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001729 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001730 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001731}
1732
1733static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001734Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001735 PyObject *self;
1736 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001737{
1738
Guido van Rossum43713e52000-02-29 13:59:29 +00001739 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001740 return NULL;
1741
1742 quitMainLoop = 1;
1743 Py_INCREF(Py_None);
1744 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001745}
1746
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001747static PyObject *
1748Tkapp_InterpAddr(self, args)
1749 PyObject *self;
1750 PyObject *args;
1751{
1752
Guido van Rossum43713e52000-02-29 13:59:29 +00001753 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001754 return NULL;
1755
1756 return PyInt_FromLong((long)Tkapp_Interp(self));
1757}
1758
Barry Warsawfa701a81997-01-16 00:15:11 +00001759
1760
Guido van Rossum18468821994-06-20 07:49:28 +00001761/**** Tkapp Method List ****/
1762
1763static PyMethodDef Tkapp_methods[] =
1764{
Guido van Rossum35d43371997-08-02 00:09:09 +00001765 {"call", Tkapp_Call, 0},
1766 {"globalcall", Tkapp_GlobalCall, 0},
1767 {"eval", Tkapp_Eval, 1},
1768 {"globaleval", Tkapp_GlobalEval, 1},
1769 {"evalfile", Tkapp_EvalFile, 1},
1770 {"record", Tkapp_Record, 1},
1771 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1772 {"setvar", Tkapp_SetVar, 1},
1773 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1774 {"getvar", Tkapp_GetVar, 1},
1775 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1776 {"unsetvar", Tkapp_UnsetVar, 1},
1777 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1778 {"getint", Tkapp_GetInt, 1},
1779 {"getdouble", Tkapp_GetDouble, 1},
1780 {"getboolean", Tkapp_GetBoolean, 1},
1781 {"exprstring", Tkapp_ExprString, 1},
1782 {"exprlong", Tkapp_ExprLong, 1},
1783 {"exprdouble", Tkapp_ExprDouble, 1},
1784 {"exprboolean", Tkapp_ExprBoolean, 1},
1785 {"splitlist", Tkapp_SplitList, 1},
1786 {"split", Tkapp_Split, 1},
1787 {"merge", Tkapp_Merge, 0},
1788 {"createcommand", Tkapp_CreateCommand, 1},
1789 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001790#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001791 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1792 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001793#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001794 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001795 {"mainloop", Tkapp_MainLoop, 1},
1796 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001797 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001798 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001799 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001800};
1801
Barry Warsawfa701a81997-01-16 00:15:11 +00001802
1803
Guido van Rossum18468821994-06-20 07:49:28 +00001804/**** Tkapp Type Methods ****/
1805
1806static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001807Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001808 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001809{
Guido van Rossum00d93061998-05-28 23:06:38 +00001810 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001811 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001812 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001813 PyMem_DEL(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001814 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001815}
1816
1817static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001818Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001819 PyObject *self;
1820 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001821{
Guido van Rossum35d43371997-08-02 00:09:09 +00001822 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001823}
1824
1825static PyTypeObject Tkapp_Type =
1826{
Guido van Rossum35d43371997-08-02 00:09:09 +00001827 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001828 0, /*ob_size */
1829 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001830 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001831 0, /*tp_itemsize */
1832 Tkapp_Dealloc, /*tp_dealloc */
1833 0, /*tp_print */
1834 Tkapp_GetAttr, /*tp_getattr */
1835 0, /*tp_setattr */
1836 0, /*tp_compare */
1837 0, /*tp_repr */
1838 0, /*tp_as_number */
1839 0, /*tp_as_sequence */
1840 0, /*tp_as_mapping */
1841 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001842};
1843
Barry Warsawfa701a81997-01-16 00:15:11 +00001844
1845
Guido van Rossum18468821994-06-20 07:49:28 +00001846/**** Tkinter Module ****/
1847
1848static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001849Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001850 PyObject *self;
1851 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001852{
Barry Warsawfa701a81997-01-16 00:15:11 +00001853 char *screenName = NULL;
1854 char *baseName = NULL;
1855 char *className = NULL;
1856 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001857
Guido van Rossum35d43371997-08-02 00:09:09 +00001858 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001859 if (baseName != NULL)
1860 baseName++;
1861 else
1862 baseName = Py_GetProgramName();
1863 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001864
Guido van Rossum43713e52000-02-29 13:59:29 +00001865 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00001866 &screenName, &baseName, &className,
1867 &interactive))
1868 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001869
Barry Warsawfa701a81997-01-16 00:15:11 +00001870 return (PyObject *) Tkapp_New(screenName, baseName, className,
1871 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001872}
1873
1874static PyMethodDef moduleMethods[] =
1875{
Barry Warsawfa701a81997-01-16 00:15:11 +00001876 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001877#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001878 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1879 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001880#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001881 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001882 {"mainloop", Tkapp_MainLoop, 1},
1883 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001884 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001885 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001886};
1887
Guido van Rossum7bf15641998-05-22 18:28:17 +00001888#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001889
1890static int stdin_ready = 0;
1891
Guido van Rossumad4db171998-06-13 13:56:28 +00001892#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001893static void
1894MyFileProc(clientData, mask)
1895 void *clientData;
1896 int mask;
1897{
1898 stdin_ready = 1;
1899}
Guido van Rossumad4db171998-06-13 13:56:28 +00001900#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001901
Guido van Rossum00d93061998-05-28 23:06:38 +00001902static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001903
Guido van Rossum18468821994-06-20 07:49:28 +00001904static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001905EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00001906{
Guido van Rossumad4db171998-06-13 13:56:28 +00001907#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00001908 FHANDLE tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00001909#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001910#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00001911 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001912#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001913 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00001914 errorInCmd = 0;
1915#ifndef MS_WINDOWS
1916 tfile = MAKEFHANDLE(fileno(stdin));
Guido van Rossum7bf15641998-05-22 18:28:17 +00001917 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00001918#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001919 while (!errorInCmd && !stdin_ready) {
1920 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00001921#ifdef MS_WINDOWS
1922 if (_kbhit()) {
1923 stdin_ready = 1;
1924 break;
1925 }
1926#endif
1927#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00001928 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001929 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00001930 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001931
Guido van Rossum00d93061998-05-28 23:06:38 +00001932 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001933
1934 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001935 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001936 if (result == 0)
1937 Sleep(20);
1938 Py_END_ALLOW_THREADS
1939#else
1940 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001941#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001942
1943 if (result < 0)
1944 break;
1945 }
Guido van Rossumad4db171998-06-13 13:56:28 +00001946#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00001947 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00001948#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001949 if (errorInCmd) {
1950 errorInCmd = 0;
1951 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1952 excInCmd = valInCmd = trbInCmd = NULL;
1953 PyErr_Print();
1954 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001955#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00001956 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001957#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001958 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001959}
Guido van Rossum18468821994-06-20 07:49:28 +00001960
Guido van Rossum00d93061998-05-28 23:06:38 +00001961#endif
1962
Guido van Rossum7bf15641998-05-22 18:28:17 +00001963static void
1964EnableEventHook()
1965{
Guido van Rossum00d93061998-05-28 23:06:38 +00001966#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001967 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001968#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00001969 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001970#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001971 PyOS_InputHook = EventHook;
1972 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001973#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001974}
1975
1976static void
1977DisableEventHook()
1978{
Guido van Rossum00d93061998-05-28 23:06:38 +00001979#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001980 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
1981 PyOS_InputHook = NULL;
1982 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001983#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001984}
1985
Barry Warsawfa701a81997-01-16 00:15:11 +00001986
1987/* all errors will be checked in one fell swoop in init_tkinter() */
1988static void
1989ins_long(d, name, val)
1990 PyObject *d;
1991 char *name;
1992 long val;
1993{
1994 PyObject *v = PyInt_FromLong(val);
1995 if (v) {
1996 PyDict_SetItemString(d, name, v);
1997 Py_DECREF(v);
1998 }
1999}
2000static void
2001ins_string(d, name, val)
2002 PyObject *d;
2003 char *name;
2004 char *val;
2005{
2006 PyObject *v = PyString_FromString(val);
2007 if (v) {
2008 PyDict_SetItemString(d, name, v);
2009 Py_DECREF(v);
2010 }
2011}
2012
2013
Guido van Rossum3886bb61998-12-04 18:50:17 +00002014DL_EXPORT(void)
Guido van Rossum35d43371997-08-02 00:09:09 +00002015init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00002016{
Barry Warsawfa701a81997-01-16 00:15:11 +00002017 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002018
Barry Warsawfa701a81997-01-16 00:15:11 +00002019 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002020
2021#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002022 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002023#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002024
Barry Warsawfa701a81997-01-16 00:15:11 +00002025 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002026
Barry Warsawfa701a81997-01-16 00:15:11 +00002027 d = PyModule_GetDict(m);
2028 Tkinter_TclError = Py_BuildValue("s", "TclError");
2029 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002030
Guido van Rossum35d43371997-08-02 00:09:09 +00002031 ins_long(d, "READABLE", TCL_READABLE);
2032 ins_long(d, "WRITABLE", TCL_WRITABLE);
2033 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2034 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2035 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2036 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2037 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2038 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2039 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002040 ins_string(d, "TK_VERSION", TK_VERSION);
2041 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002042
Guido van Rossum83551bf1997-09-13 00:44:23 +00002043 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002044
2045 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002046 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2047
Barry Warsawfa701a81997-01-16 00:15:11 +00002048 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002049 return;
2050
Guido van Rossum43ff8681998-07-14 18:02:13 +00002051#if 0
2052 /* This was not a good idea; through <Destroy> bindings,
2053 Tcl_Finalize() may invoke Python code but at that point the
2054 interpreter and thread state have already been destroyed! */
Guido van Rossum26216371998-04-20 18:47:52 +00002055#if TKMAJORMINOR >= 8000
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002056 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002057#endif
Guido van Rossum43ff8681998-07-14 18:02:13 +00002058#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002059
Jack Jansen34cc5c31995-10-31 16:15:12 +00002060#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002061 /*
2062 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2063 ** Most of the initializations in that routine (toolbox init calls and
2064 ** such) have already been done for us, so we only need these.
2065 */
2066#if TKMAJORMINOR >= 8000
2067 tcl_macQdPtr = &qd;
2068#endif
2069
2070 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002071#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002072 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002073#endif /* GENERATINGCFM */
2074#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002075}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002076
Guido van Rossumec22c921996-02-25 04:50:29 +00002077
Barry Warsawfa701a81997-01-16 00:15:11 +00002078
Guido van Rossum9722ad81995-09-22 23:49:28 +00002079#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002080
2081/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002082** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002083*/
2084
Guido van Rossum9722ad81995-09-22 23:49:28 +00002085void
2086panic(char * format, ...)
2087{
Barry Warsawfa701a81997-01-16 00:15:11 +00002088 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002089
Barry Warsawfa701a81997-01-16 00:15:11 +00002090 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002091
Guido van Rossum227cf761998-08-05 13:53:32 +00002092 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002093 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002094
Barry Warsawfa701a81997-01-16 00:15:11 +00002095 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002096
Barry Warsawfa701a81997-01-16 00:15:11 +00002097 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002098}
Jack Jansen40b546d1995-11-14 10:34:45 +00002099
Guido van Rossumec22c921996-02-25 04:50:29 +00002100/*
2101** Pass events to SIOUX before passing them to Tk.
2102*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002103
Guido van Rossumec22c921996-02-25 04:50:29 +00002104static int
2105PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00002106 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002107{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002108 WindowPtr frontwin;
2109 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002110 ** Sioux eats too many events, so we don't pass it everything. We
2111 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002112 ** the Sioux window is frontmost. This means that Tk menus don't work
2113 ** in that case, but at least we can scroll the sioux window.
2114 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2115 ** part of the external interface of Sioux...
2116 */
2117 frontwin = FrontWindow();
2118 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2119 if (SIOUXHandleOneEvent(eventPtr))
2120 return 0; /* Nothing happened to the Tcl event queue */
2121 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002122 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002123}
2124
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002125#if defined(USE_GUSI) && TKMAJORMINOR < 8000
Guido van Rossum290283b1997-06-02 22:16:43 +00002126/*
2127 * For Python we have to override this routine (from TclMacNotify),
2128 * since we use GUSI for our sockets, not Tcl streams. Hence, we have
2129 * to use GUSI select to see whether our socket is ready. Note that
2130 * createfilehandler (above) sets the type to TCL_UNIX_FD for our
2131 * files and sockets.
2132 *
2133 * NOTE: this code was lifted from Tcl 7.6, it may need to be modified
2134 * for other versions. */
2135
2136int
2137Tcl_FileReady(file, mask)
2138 Tcl_File file; /* File handle for a stream. */
2139 int mask; /* OR'ed combination of TCL_READABLE,
2140 * TCL_WRITABLE, and TCL_EXCEPTION:
2141 * indicates conditions caller cares about. */
2142{
2143 int type;
2144 int fd;
2145
2146 fd = (int) Tcl_GetFileInfo(file, &type);
2147
2148 if (type == TCL_MAC_SOCKET) {
2149 return TclMacSocketReady(file, mask);
2150 } else if (type == TCL_MAC_FILE) {
2151 /*
2152 * Under the Macintosh, files are always ready, so we just
2153 * return the mask that was passed in.
2154 */
2155
2156 return mask;
2157 } else if (type == TCL_UNIX_FD) {
2158 fd_set readset, writeset, excset;
2159 struct timeval tv;
2160
2161 FD_ZERO(&readset);
2162 FD_ZERO(&writeset);
2163 FD_ZERO(&excset);
2164
2165 if ( mask & TCL_READABLE ) FD_SET(fd, &readset);
2166 if ( mask & TCL_WRITABLE ) FD_SET(fd, &writeset);
2167 if ( mask & TCL_EXCEPTION ) FD_SET(fd, &excset);
2168
2169 tv.tv_sec = tv.tv_usec = 0;
2170 if ( select(fd+1, &readset, &writeset, &excset, &tv) <= 0 )
2171 return 0;
2172
2173 mask = 0;
2174 if ( FD_ISSET(fd, &readset) ) mask |= TCL_READABLE;
2175 if ( FD_ISSET(fd, &writeset) ) mask |= TCL_WRITABLE;
2176 if ( FD_ISSET(fd, &excset) ) mask |= TCL_EXCEPTION;
2177
2178 return mask;
2179 }
2180
2181 return 0;
2182}
2183#endif /* USE_GUSI */
2184
Guido van Rossumec22c921996-02-25 04:50:29 +00002185#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002186
2187/*
2188** Additional Mac specific code for dealing with shared libraries.
2189*/
2190
2191#include <Resources.h>
2192#include <CodeFragments.h>
2193
2194static int loaded_from_shlib = 0;
2195static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002196
Jack Jansen34cc5c31995-10-31 16:15:12 +00002197/*
2198** If this module is dynamically loaded the following routine should
2199** be the init routine. It takes care of adding the shared library to
2200** the resource-file chain, so that the tk routines can find their
2201** resources.
2202*/
2203OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002204init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002205{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002206 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002207 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002208 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002209 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2210 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002211 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002212 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2213 loaded_from_shlib = 1;
2214 }
2215 return noErr;
2216}
2217
2218/*
2219** Insert the library resources into the search path. Put them after
2220** the resources from the application. Again, we ignore errors.
2221*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002222static
Jack Jansen34cc5c31995-10-31 16:15:12 +00002223mac_addlibresources()
2224{
2225 if ( !loaded_from_shlib )
2226 return;
2227 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2228}
2229
Guido van Rossumec22c921996-02-25 04:50:29 +00002230#endif /* GENERATINGCFM */
2231#endif /* macintosh */