blob: fa8d589663be0d8604faac37561f44f378a59cbc [file] [log] [blame]
Guido van Rossum845547d1996-06-26 18:26:04 +00001/***********************************************************
2Copyright (C) 1994 Steen Lumholt.
3Copyright 1994-1995 by Stichting Mathematisch Centrum, Amsterdam,
4The Netherlands.
5
6 All Rights Reserved
7
Guido van Rossumd266eb41996-10-25 14:44:06 +00008Permission to use, copy, modify, and distribute this software and its
9documentation for any purpose and without fee is hereby granted,
Guido van Rossum845547d1996-06-26 18:26:04 +000010provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000011both that copyright notice and this permission notice appear in
Guido van Rossum845547d1996-06-26 18:26:04 +000012supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000013Centrum or CWI or Corporation for National Research Initiatives or
14CNRI not be used in advertising or publicity pertaining to
15distribution of the software without specific, written prior
16permission.
Guido van Rossum845547d1996-06-26 18:26:04 +000017
Guido van Rossumd266eb41996-10-25 14:44:06 +000018While CWI is the initial source for this software, a modified version
19is made available by the Corporation for National Research Initiatives
20(CNRI) at the Internet address ftp://ftp.python.org.
21
22STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
23REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
24MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
25CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
26DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
27PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
28TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum845547d1996-06-26 18:26:04 +000030
31******************************************************************/
32
33/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +000034
Guido van Rossum7ffa7611996-08-13 21:10:16 +000035/* TCL/TK VERSION INFO:
36
Guido van Rossuma80649b2000-03-28 20:07:05 +000037 Only Tcl/Tk 8.0 and later are supported. Older versions are not
38 supported. (Use Python 1.5.2 if you cannot upgrade your Tcl/Tk
39 libraries.)
40*/
Guido van Rossum7ffa7611996-08-13 21:10:16 +000041
Guido van Rossuma80649b2000-03-28 20:07:05 +000042/* XXX Further speed-up ideas, involving Tcl 8.0 features:
Guido van Rossum212643f1998-04-29 16:22:14 +000043
44 - In Tcl_Call(), create Tcl objects from the arguments, possibly using
45 intelligent mappings between Python objects and Tcl objects (e.g. ints,
46 floats and Tcl window pointers could be handled specially).
47
48 - Register a new Tcl type, "Python callable", which can be called more
49 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
50
Guido van Rossum7ffa7611996-08-13 21:10:16 +000051*/
52
Guido van Rossum35d43371997-08-02 00:09:09 +000053
Guido van Rossum9722ad81995-09-22 23:49:28 +000054#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000055#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000056
Guido van Rossum00d93061998-05-28 23:06:38 +000057#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000058#include "pythread.h"
Guido van Rossum00d93061998-05-28 23:06:38 +000059#endif
60
Guido van Rossum2a5119b1998-05-29 01:28:40 +000061#ifdef MS_WINDOWS
62#include <windows.h>
63#endif
64
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000065#ifdef macintosh
66#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000067#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000068#endif
69
Guido van Rossum49b56061998-10-01 20:42:43 +000070#ifdef PYOS_OS2
71#include "myselect.h"
72#endif
73
Guido van Rossum18468821994-06-20 07:49:28 +000074#include <tcl.h>
75#include <tk.h>
76
Guido van Rossum3e819a71997-08-01 19:29:02 +000077#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
78
Guido van Rossuma80649b2000-03-28 20:07:05 +000079#if TKMAJORMINOR < 8000
80#error "Tk older than 8.0 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000081#endif
82
Guido van Rossuma80649b2000-03-28 20:07:05 +000083#if defined(macintosh)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000084/* Sigh, we have to include this to get at the tcl qd pointer */
85#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000086/* And this one we need to clear the menu bar */
87#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000088#endif
89
Guido van Rossuma80649b2000-03-28 20:07:05 +000090#if !defined(MS_WINDOWS)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000091#define HAVE_CREATEFILEHANDLER
92#endif
93
Guido van Rossum00d93061998-05-28 23:06:38 +000094#ifdef HAVE_CREATEFILEHANDLER
95
96/* Tcl_CreateFileHandler() changed several times; these macros deal with the
97 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
98 Unix, only because Jack added it back); when available on Windows, it only
99 applies to sockets. */
100
Guido van Rossum7bf15641998-05-22 18:28:17 +0000101#ifdef MS_WINDOWS
102#define FHANDLETYPE TCL_WIN_SOCKET
103#else
104#define FHANDLETYPE TCL_UNIX_FD
105#endif
106
Guido van Rossum00d93061998-05-28 23:06:38 +0000107/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
108 which uses this to handle Tcl events while the user is typing commands. */
109
110#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000111#define WAIT_FOR_STDIN
112#endif
113
Guido van Rossum00d93061998-05-28 23:06:38 +0000114#endif /* HAVE_CREATEFILEHANDLER */
115
Guido van Rossumad4db171998-06-13 13:56:28 +0000116#ifdef MS_WINDOWS
117#include <conio.h>
118#define WAIT_FOR_STDIN
119#endif
120
Guido van Rossum00d93061998-05-28 23:06:38 +0000121#ifdef WITH_THREAD
122
123/* The threading situation is complicated. Tcl is not thread-safe, except for
124 Tcl 8.1, which will probably remain in alpha status for another 6 months
125 (and the README says that Tk will probably remain thread-unsafe forever).
126 So we need to use a lock around all uses of Tcl. Previously, the Python
127 interpreter lock was used for this. However, this causes problems when
128 other Python threads need to run while Tcl is blocked waiting for events.
129
130 To solve this problem, a separate lock for Tcl is introduced. Holding it
131 is incompatible with holding Python's interpreter lock. The following four
132 macros manipulate both locks together.
133
134 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
135 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
136 that could call an event handler, or otherwise affect the state of a Tcl
137 interpreter. These assume that the surrounding code has the Python
138 interpreter lock; inside the brackets, the Python interpreter lock has been
139 released and the lock for Tcl has been acquired.
140
Guido van Rossum5e977831998-06-15 14:03:52 +0000141 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
142 (For example, when transferring data from the Tcl interpreter result to a
143 Python string object.) This can be done by using different macros to close
144 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
145 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
146 releases the Tcl lock.
147
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000148 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000149 handlers when the handler needs to use Python. Such event handlers are
150 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000151 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000152 the Python interpreter lock, restoring the appropriate thread state, and
153 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
154 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000155 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000156
157 These locks expand to several statements and brackets; they should not be
158 used in branches of if statements and the like.
159
160*/
161
Guido van Rossum65d5b571998-12-21 19:32:43 +0000162static PyThread_type_lock tcl_lock = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000163static PyThreadState *tcl_tstate = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000164
165#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000166 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000167 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000168
169#define LEAVE_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000170 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000171
Guido van Rossum62320c91998-06-15 04:36:09 +0000172#define ENTER_OVERLAP \
173 Py_END_ALLOW_THREADS
174
175#define LEAVE_OVERLAP_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000176 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000177
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000178#define ENTER_PYTHON \
179 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000180 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000181
182#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000183 { PyThreadState *tstate = PyEval_SaveThread(); \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000184 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Guido van Rossum00d93061998-05-28 23:06:38 +0000185
186#else
187
188#define ENTER_TCL
189#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000190#define ENTER_OVERLAP
191#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000192#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000193#define LEAVE_PYTHON
194
195#endif
196
Guido van Rossumec22c921996-02-25 04:50:29 +0000197#ifdef macintosh
198
199/*
200** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000201** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000202*/
203
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000204/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000205#define FREECAST (char *)
206
Guido van Rossumec22c921996-02-25 04:50:29 +0000207#include <Events.h> /* For EventRecord */
208
209typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
Guido van Rossum0d2390c1997-08-14 19:57:07 +0000210void Tcl_MacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
Guido van Rossumec22c921996-02-25 04:50:29 +0000211int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
212
213staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
214
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000215#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
216 #pragma import on
217#endif
218
219#include <SIOUX.h>
220extern int SIOUXIsAppWindow(WindowPtr);
221
222#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
223 #pragma import reset
224#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000225#endif /* macintosh */
226
Guido van Rossum97867b21996-08-08 19:09:53 +0000227#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000228#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000229#endif
230
Guido van Rossum18468821994-06-20 07:49:28 +0000231/**** Tkapp Object Declaration ****/
232
233staticforward PyTypeObject Tkapp_Type;
234
Guido van Rossum00d93061998-05-28 23:06:38 +0000235typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000236 PyObject_HEAD
237 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000238} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000239
240#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000241#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
242#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
243
Guido van Rossum35d43371997-08-02 00:09:09 +0000244#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000245(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000246
Barry Warsawfa701a81997-01-16 00:15:11 +0000247
248
Guido van Rossum18468821994-06-20 07:49:28 +0000249/**** Error Handling ****/
250
251static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000252static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000253static int errorInCmd = 0;
254static PyObject *excInCmd;
255static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000256static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000257
Barry Warsawfa701a81997-01-16 00:15:11 +0000258
259
Guido van Rossum18468821994-06-20 07:49:28 +0000260static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000261Tkinter_Error(v)
262 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000263{
Barry Warsawfa701a81997-01-16 00:15:11 +0000264 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
265 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000266}
267
Barry Warsawfa701a81997-01-16 00:15:11 +0000268
Barry Warsawfa701a81997-01-16 00:15:11 +0000269
Guido van Rossum18468821994-06-20 07:49:28 +0000270/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000271
272#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000273#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000274#include "mytime.h"
Guido van Rossum11801851999-01-25 21:39:03 +0000275#include "myselect.h"
Guido van Rossum541f2411998-08-13 13:29:22 +0000276
Guido van Rossum00d93061998-05-28 23:06:38 +0000277/* Millisecond sleep() for Unix platforms. */
278
279static void
280Sleep(milli)
281 int milli;
282{
283 /* XXX Too bad if you don't have select(). */
284 struct timeval t;
285 double frac;
286 t.tv_sec = milli/1000;
287 t.tv_usec = (milli%1000) * 1000;
288 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
289}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000290#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000291#endif /* WITH_THREAD */
292
293
Guido van Rossum18468821994-06-20 07:49:28 +0000294static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000295AsString(value, tmp)
296 PyObject *value;
297 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000298{
Guido van Rossum35d43371997-08-02 00:09:09 +0000299 if (PyString_Check(value))
300 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000301 else {
302 PyObject *v = PyObject_Str(value);
303 PyList_Append(tmp, v);
304 Py_DECREF(v);
305 return PyString_AsString(v);
306 }
Guido van Rossum18468821994-06-20 07:49:28 +0000307}
308
Barry Warsawfa701a81997-01-16 00:15:11 +0000309
310
Guido van Rossum18468821994-06-20 07:49:28 +0000311#define ARGSZ 64
312
313static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000314Merge(args)
315 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000316{
Barry Warsawfa701a81997-01-16 00:15:11 +0000317 PyObject *tmp = NULL;
318 char *argvStore[ARGSZ];
319 char **argv = NULL;
320 int fvStore[ARGSZ];
321 int *fv = NULL;
322 int argc = 0, i;
323 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000324
Barry Warsawfa701a81997-01-16 00:15:11 +0000325 if (!(tmp = PyList_New(0)))
326 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000327
Barry Warsawfa701a81997-01-16 00:15:11 +0000328 argv = argvStore;
329 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000330
Barry Warsawfa701a81997-01-16 00:15:11 +0000331 if (args == NULL)
332 argc = 0;
333
334 else if (!PyTuple_Check(args)) {
335 argc = 1;
336 fv[0] = 0;
337 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000338 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000339 else {
340 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000341
Barry Warsawfa701a81997-01-16 00:15:11 +0000342 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000343 argv = (char **)ckalloc(argc * sizeof(char *));
344 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000345 if (argv == NULL || fv == NULL) {
346 PyErr_NoMemory();
347 goto finally;
348 }
349 }
350
351 for (i = 0; i < argc; i++) {
352 PyObject *v = PyTuple_GetItem(args, i);
353 if (PyTuple_Check(v)) {
354 fv[i] = 1;
355 if (!(argv[i] = Merge(v)))
356 goto finally;
357 }
358 else if (v == Py_None) {
359 argc = i;
360 break;
361 }
362 else {
363 fv[i] = 0;
364 argv[i] = AsString(v, tmp);
365 }
366 }
Guido van Rossum18468821994-06-20 07:49:28 +0000367 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000368 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000369
Barry Warsawfa701a81997-01-16 00:15:11 +0000370 finally:
371 for (i = 0; i < argc; i++)
372 if (fv[i]) {
373 ckfree(argv[i]);
374 }
375 if (argv != argvStore)
376 ckfree(FREECAST argv);
377 if (fv != fvStore)
378 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000379
Barry Warsawfa701a81997-01-16 00:15:11 +0000380 Py_DECREF(tmp);
381 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000382}
383
Barry Warsawfa701a81997-01-16 00:15:11 +0000384
385
Guido van Rossum18468821994-06-20 07:49:28 +0000386static PyObject *
Guido van Rossum00d93061998-05-28 23:06:38 +0000387Split(list)
Barry Warsawfa701a81997-01-16 00:15:11 +0000388 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000389{
Barry Warsawfa701a81997-01-16 00:15:11 +0000390 int argc;
391 char **argv;
392 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000393
Barry Warsawfa701a81997-01-16 00:15:11 +0000394 if (list == NULL) {
395 Py_INCREF(Py_None);
396 return Py_None;
397 }
Guido van Rossum18468821994-06-20 07:49:28 +0000398
Guido van Rossum00d93061998-05-28 23:06:38 +0000399 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000400 /* Not a list.
401 * Could be a quoted string containing funnies, e.g. {"}.
402 * Return the string itself.
403 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000404 return PyString_FromString(list);
405 }
Guido van Rossum18468821994-06-20 07:49:28 +0000406
Barry Warsawfa701a81997-01-16 00:15:11 +0000407 if (argc == 0)
408 v = PyString_FromString("");
409 else if (argc == 1)
410 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000411 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000412 int i;
413 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000414
Barry Warsawfa701a81997-01-16 00:15:11 +0000415 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000416 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000417 Py_DECREF(v);
418 v = NULL;
419 break;
420 }
421 PyTuple_SetItem(v, i, w);
422 }
423 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000424 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000425 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000426}
427
Guido van Rossum632de272000-03-29 00:19:50 +0000428static Tcl_Obj*
429AsObj(value)
430 PyObject *value;
431{
432 Tcl_Obj *result;
433
434 if (PyString_Check(value))
435 return Tcl_NewStringObj(PyString_AS_STRING(value),
436 PyString_GET_SIZE(value));
437 else if (PyInt_Check(value))
438 return Tcl_NewLongObj(PyInt_AS_LONG(value));
439 else if (PyFloat_Check(value))
440 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
441 else if (PyTuple_Check(value)) {
442 Tcl_Obj **argv = (Tcl_Obj**)
443 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
444 int i;
445 if(!argv)
446 return 0;
447 for(i=0;i<PyTuple_Size(value);i++)
448 argv[i] = AsObj(PyTuple_GetItem(value,i));
449 result = Tcl_NewListObj(PyTuple_Size(value), argv);
450 ckfree(FREECAST argv);
451 return result;
452 }
453 else if (PyUnicode_Check(value)) {
454 PyObject* utf8 = PyUnicode_AsUTF8String (value);
455 if (!utf8)
456 return 0;
457 return Tcl_NewStringObj (PyString_AS_STRING (utf8),
458 PyString_GET_SIZE (utf8));
459 }
460 else {
461 PyObject *v = PyObject_Str(value);
462 if (!v)
463 return 0;
464 result = AsObj(v);
465 Py_DECREF(v);
466 return result;
467 }
468}
Barry Warsawfa701a81997-01-16 00:15:11 +0000469
470
Guido van Rossum18468821994-06-20 07:49:28 +0000471/**** Tkapp Object ****/
472
473#ifndef WITH_APPINIT
474int
Guido van Rossum35d43371997-08-02 00:09:09 +0000475Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000476 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000477{
Barry Warsawfa701a81997-01-16 00:15:11 +0000478 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000479
Barry Warsawfa701a81997-01-16 00:15:11 +0000480 main = Tk_MainWindow(interp);
481 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000482 PySys_WriteStderr("Tcl_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000483 return TCL_ERROR;
484 }
485 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000486 PySys_WriteStderr("Tk_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000487 return TCL_ERROR;
488 }
489 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000490}
491#endif /* !WITH_APPINIT */
492
Guido van Rossum18468821994-06-20 07:49:28 +0000493
Barry Warsawfa701a81997-01-16 00:15:11 +0000494
495
496/* Initialize the Tk application; see the `main' function in
497 * `tkMain.c'.
498 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000499
500static void EnableEventHook(); /* Forward */
501static void DisableEventHook(); /* Forward */
502
Barry Warsawfa701a81997-01-16 00:15:11 +0000503static TkappObject *
504Tkapp_New(screenName, baseName, className, interactive)
505 char *screenName;
506 char *baseName;
507 char *className;
508 int interactive;
509{
510 TkappObject *v;
511 char *argv0;
512
513 v = PyObject_NEW(TkappObject, &Tkapp_Type);
514 if (v == NULL)
515 return NULL;
516
517 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000518
Guido van Rossuma80649b2000-03-28 20:07:05 +0000519#if defined(macintosh)
520 /* This seems to be needed */
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000521 ClearMenuBar();
522 TkMacInitMenus(v->interp);
523#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000524 /* Delete the 'exit' command, which can screw things up */
525 Tcl_DeleteCommand(v->interp, "exit");
526
Barry Warsawfa701a81997-01-16 00:15:11 +0000527 if (screenName != NULL)
528 Tcl_SetVar2(v->interp, "env", "DISPLAY",
529 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000530
Barry Warsawfa701a81997-01-16 00:15:11 +0000531 if (interactive)
532 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
533 else
534 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000535
Barry Warsawfa701a81997-01-16 00:15:11 +0000536 /* This is used to get the application class for Tk 4.1 and up */
537 argv0 = (char*)ckalloc(strlen(className) + 1);
538 if (!argv0) {
539 PyErr_NoMemory();
540 Py_DECREF(v);
541 return NULL;
542 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000543
Barry Warsawfa701a81997-01-16 00:15:11 +0000544 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000545 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000546 argv0[0] = tolower(argv0[0]);
547 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
548 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000549
Barry Warsawfa701a81997-01-16 00:15:11 +0000550 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000551 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000552
Guido van Rossum7bf15641998-05-22 18:28:17 +0000553 EnableEventHook();
554
Barry Warsawfa701a81997-01-16 00:15:11 +0000555 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000556}
557
Barry Warsawfa701a81997-01-16 00:15:11 +0000558
559
Guido van Rossum18468821994-06-20 07:49:28 +0000560/** Tcl Eval **/
561
562static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000563Tkapp_Call(self, args)
564 PyObject *self;
565 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000566{
Guido van Rossum632de272000-03-29 00:19:50 +0000567 Tcl_Obj *objStore[ARGSZ];
568 Tcl_Obj **objv = NULL;
569 int objc = 0, i;
570 PyObject *res = NULL;
571 Tcl_Interp *interp = Tkapp_Interp(self);
572 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
573 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000574
Guido van Rossum632de272000-03-29 00:19:50 +0000575 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000576
Guido van Rossum212643f1998-04-29 16:22:14 +0000577 if (args == NULL)
Guido van Rossum632de272000-03-29 00:19:50 +0000578 objc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000579
Guido van Rossum212643f1998-04-29 16:22:14 +0000580 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000581 objc = 1;
582 objv[0] = AsObj(args);
583 if (objv[0] == 0)
584 goto finally;
585 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000586 }
587 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000588 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000589
Guido van Rossum632de272000-03-29 00:19:50 +0000590 if (objc > ARGSZ) {
591 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
592 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000593 PyErr_NoMemory();
594 goto finally;
595 }
596 }
597
Guido van Rossum632de272000-03-29 00:19:50 +0000598 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000599 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum632de272000-03-29 00:19:50 +0000600 objv[i] = AsObj(v);
601 if (!objv[i])
602 goto finally;
603 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000604 }
605 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000606
Guido van Rossum62320c91998-06-15 04:36:09 +0000607 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000608
609 i = Tcl_EvalObjv(interp, objc, objv, flags);
610
Guido van Rossum62320c91998-06-15 04:36:09 +0000611 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000612 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000613 Tkinter_Error(self);
Guido van Rossum632de272000-03-29 00:19:50 +0000614 else
615 /* We could request the object result here, but doing
616 so would confuse applications that expect a string. */
617 res = PyString_FromString(Tcl_GetStringResult(interp));
618
Guido van Rossum62320c91998-06-15 04:36:09 +0000619 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000620
Guido van Rossum212643f1998-04-29 16:22:14 +0000621 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000622 for (i = 0; i < objc; i++)
623 Tcl_DecrRefCount(objv[i]);
624 if (objv != objStore)
625 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000626 return res;
627}
628
629
630static PyObject *
631Tkapp_GlobalCall(self, args)
632 PyObject *self;
633 PyObject *args;
634{
Guido van Rossum212643f1998-04-29 16:22:14 +0000635 /* Could do the same here as for Tkapp_Call(), but this is not used
636 much, so I can't be bothered. Unfortunately Tcl doesn't export a
637 way for the user to do what all its Global* variants do (save and
638 reset the scope pointer, call the local version, restore the saved
639 scope pointer). */
640
Guido van Rossum62320c91998-06-15 04:36:09 +0000641 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000642 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000643
Guido van Rossum62320c91998-06-15 04:36:09 +0000644 cmd = Merge(args);
Barry Warsawfa701a81997-01-16 00:15:11 +0000645 if (!cmd)
646 PyErr_SetString(Tkinter_TclError, "merge failed");
647
Guido van Rossum00d93061998-05-28 23:06:38 +0000648 else {
649 int err;
650 ENTER_TCL
651 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000652 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000653 if (err == TCL_ERROR)
654 res = Tkinter_Error(self);
655 else
656 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000657 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +0000658 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000659
660 if (cmd)
661 ckfree(cmd);
662
663 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000664}
665
666static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000667Tkapp_Eval(self, args)
668 PyObject *self;
669 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000670{
Barry Warsawfa701a81997-01-16 00:15:11 +0000671 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000672 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000673 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000674
Guido van Rossum43713e52000-02-29 13:59:29 +0000675 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000676 return NULL;
677
Guido van Rossum00d93061998-05-28 23:06:38 +0000678 ENTER_TCL
679 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000680 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000681 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000682 res = Tkinter_Error(self);
683 else
684 res = PyString_FromString(Tkapp_Result(self));
685 LEAVE_OVERLAP_TCL
686 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000687}
688
689static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000690Tkapp_GlobalEval(self, args)
691 PyObject *self;
692 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000693{
Barry Warsawfa701a81997-01-16 00:15:11 +0000694 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000695 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000696 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000697
Guido van Rossum43713e52000-02-29 13:59:29 +0000698 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000699 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000700
Guido van Rossum00d93061998-05-28 23:06:38 +0000701 ENTER_TCL
702 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000703 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000704 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000705 res = Tkinter_Error(self);
706 else
707 res = PyString_FromString(Tkapp_Result(self));
708 LEAVE_OVERLAP_TCL
709 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000710}
711
712static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000713Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000714 PyObject *self;
715 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000716{
Barry Warsawfa701a81997-01-16 00:15:11 +0000717 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000718 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000719 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000720
Guido van Rossum43713e52000-02-29 13:59:29 +0000721 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000722 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000723
Guido van Rossum00d93061998-05-28 23:06:38 +0000724 ENTER_TCL
725 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000726 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000727 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000728 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000729
Guido van Rossum62320c91998-06-15 04:36:09 +0000730 else
731 res = PyString_FromString(Tkapp_Result(self));
732 LEAVE_OVERLAP_TCL
733 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000734}
735
736static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000737Tkapp_Record(self, args)
738 PyObject *self;
739 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000740{
Barry Warsawfa701a81997-01-16 00:15:11 +0000741 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000742 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000743 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000744
Guido van Rossum35d43371997-08-02 00:09:09 +0000745 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000746 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000747
Guido van Rossum00d93061998-05-28 23:06:38 +0000748 ENTER_TCL
749 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000750 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000751 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000752 res = Tkinter_Error(self);
753 else
754 res = PyString_FromString(Tkapp_Result(self));
755 LEAVE_OVERLAP_TCL
756 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000757}
758
759static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000760Tkapp_AddErrorInfo(self, args)
761 PyObject *self;
762 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000763{
Barry Warsawfa701a81997-01-16 00:15:11 +0000764 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000765
Guido van Rossum43713e52000-02-29 13:59:29 +0000766 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000767 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000768 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000769 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000770 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000771
Barry Warsawfa701a81997-01-16 00:15:11 +0000772 Py_INCREF(Py_None);
773 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000774}
775
Barry Warsawfa701a81997-01-16 00:15:11 +0000776
777
Guido van Rossum18468821994-06-20 07:49:28 +0000778/** Tcl Variable **/
779
780static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000781SetVar(self, args, flags)
782 PyObject *self;
783 PyObject *args;
784 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000785{
Guido van Rossum00d93061998-05-28 23:06:38 +0000786 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000787 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000788 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000789
Guido van Rossum62320c91998-06-15 04:36:09 +0000790 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000791 if (!tmp)
792 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000793
Guido van Rossum43713e52000-02-29 13:59:29 +0000794 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000795 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000796 s = AsString(newValue, tmp);
797 ENTER_TCL
798 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
799 LEAVE_TCL
800 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000801 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000802 PyErr_Clear();
Guido van Rossum43713e52000-02-29 13:59:29 +0000803 if (PyArg_ParseTuple(args, "ssO:setvar", &name1, &name2, &newValue)) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000804 s = AsString (newValue, tmp);
805 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000806 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000807 s, flags);
808 LEAVE_TCL
809 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000810 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000811 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000812 return NULL;
813 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000814 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000815 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000816
Barry Warsawfa701a81997-01-16 00:15:11 +0000817 if (!ok)
818 return Tkinter_Error(self);
819
820 Py_INCREF(Py_None);
821 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000822}
823
824static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000825Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000826 PyObject *self;
827 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000828{
Barry Warsawfa701a81997-01-16 00:15:11 +0000829 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000830}
831
832static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000833Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000834 PyObject *self;
835 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000836{
Barry Warsawfa701a81997-01-16 00:15:11 +0000837 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000838}
839
Barry Warsawfa701a81997-01-16 00:15:11 +0000840
841
Guido van Rossum18468821994-06-20 07:49:28 +0000842static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000843GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000844 PyObject *self;
845 PyObject *args;
846 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000847{
Guido van Rossum35d43371997-08-02 00:09:09 +0000848 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000849 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000850
Guido van Rossum43713e52000-02-29 13:59:29 +0000851 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +0000852 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000853 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000854 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000855 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000856
Barry Warsawfa701a81997-01-16 00:15:11 +0000857 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000858 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000859 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000860
Barry Warsawfa701a81997-01-16 00:15:11 +0000861 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000862 res = Tkinter_Error(self);
863 else
864 res = PyString_FromString(s);
865 LEAVE_OVERLAP_TCL
866 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000867}
868
869static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000870Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000871 PyObject *self;
872 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000873{
Barry Warsawfa701a81997-01-16 00:15:11 +0000874 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000875}
876
877static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000878Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000879 PyObject *self;
880 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000881{
Barry Warsawfa701a81997-01-16 00:15:11 +0000882 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000883}
884
Barry Warsawfa701a81997-01-16 00:15:11 +0000885
886
Guido van Rossum18468821994-06-20 07:49:28 +0000887static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000888UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000889 PyObject *self;
890 PyObject *args;
891 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000892{
Guido van Rossum35d43371997-08-02 00:09:09 +0000893 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +0000894 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000895 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000896
Guido van Rossum43713e52000-02-29 13:59:29 +0000897 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000898 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000899 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000900 if (name2 == NULL)
901 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
902
903 else
904 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000905 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000906
Barry Warsawfa701a81997-01-16 00:15:11 +0000907 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000908 res = Tkinter_Error(self);
909 else {
910 Py_INCREF(Py_None);
911 res = Py_None;
912 }
913 LEAVE_OVERLAP_TCL
914 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000915}
916
917static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000918Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000919 PyObject *self;
920 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000921{
Barry Warsawfa701a81997-01-16 00:15:11 +0000922 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000923}
924
925static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000926Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000927 PyObject *self;
928 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000929{
Barry Warsawfa701a81997-01-16 00:15:11 +0000930 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000931}
932
Barry Warsawfa701a81997-01-16 00:15:11 +0000933
934
Guido van Rossum18468821994-06-20 07:49:28 +0000935/** Tcl to Python **/
936
937static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000938Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000939 PyObject *self;
940 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000941{
Barry Warsawfa701a81997-01-16 00:15:11 +0000942 char *s;
943 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000944
Guido van Rossum43713e52000-02-29 13:59:29 +0000945 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000946 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000947 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000948 return Tkinter_Error(self);
949 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000950}
951
952static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000953Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000954 PyObject *self;
955 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000956{
Barry Warsawfa701a81997-01-16 00:15:11 +0000957 char *s;
958 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000959
Guido van Rossum43713e52000-02-29 13:59:29 +0000960 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000961 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000962 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000963 return Tkinter_Error(self);
964 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000965}
966
967static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000968Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000969 PyObject *self;
970 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000971{
Barry Warsawfa701a81997-01-16 00:15:11 +0000972 char *s;
973 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000974
Guido van Rossum43713e52000-02-29 13:59:29 +0000975 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000976 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000977 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
978 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000979 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000980}
981
982static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000983Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000984 PyObject *self;
985 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000986{
Barry Warsawfa701a81997-01-16 00:15:11 +0000987 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000988 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000989 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000990
Guido van Rossum43713e52000-02-29 13:59:29 +0000991 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000992 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000993 ENTER_TCL
994 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +0000995 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000996 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000997 res = Tkinter_Error(self);
998 else
999 res = Py_BuildValue("s", Tkapp_Result(self));
1000 LEAVE_OVERLAP_TCL
1001 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001002}
1003
1004static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001005Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001006 PyObject *self;
1007 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001008{
Barry Warsawfa701a81997-01-16 00:15:11 +00001009 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001010 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001011 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001012 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001013
Guido van Rossum43713e52000-02-29 13:59:29 +00001014 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001015 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001016 ENTER_TCL
1017 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001018 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001019 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001020 res = Tkinter_Error(self);
1021 else
1022 res = Py_BuildValue("l", v);
1023 LEAVE_OVERLAP_TCL
1024 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001025}
1026
1027static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001028Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001029 PyObject *self;
1030 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001031{
Barry Warsawfa701a81997-01-16 00:15:11 +00001032 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001033 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001034 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001035 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001036
Guido van Rossum43713e52000-02-29 13:59:29 +00001037 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001038 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001039 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001040 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001041 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001042 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001043 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001044 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001045 res = Tkinter_Error(self);
1046 else
1047 res = Py_BuildValue("d", 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_ExprBoolean(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;
Guido van Rossum00d93061998-05-28 23:06:38 +00001059 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001060 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001061
Guido van Rossum43713e52000-02-29 13:59:29 +00001062 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001063 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001064 ENTER_TCL
1065 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001066 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001067 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001068 res = Tkinter_Error(self);
1069 else
1070 res = Py_BuildValue("i", v);
1071 LEAVE_OVERLAP_TCL
1072 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001073}
1074
Barry Warsawfa701a81997-01-16 00:15:11 +00001075
1076
Guido van Rossum18468821994-06-20 07:49:28 +00001077static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001078Tkapp_SplitList(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 *list;
1083 int argc;
1084 char **argv;
1085 PyObject *v;
1086 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001087
Guido van Rossum43713e52000-02-29 13:59:29 +00001088 if (!PyArg_ParseTuple(args, "s:splitlist", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001089 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001090
Barry Warsawfa701a81997-01-16 00:15:11 +00001091 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1092 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001093
Barry Warsawfa701a81997-01-16 00:15:11 +00001094 if (!(v = PyTuple_New(argc)))
1095 return NULL;
1096
1097 for (i = 0; i < argc; i++) {
1098 PyObject *s = PyString_FromString(argv[i]);
1099 if (!s || PyTuple_SetItem(v, i, s)) {
1100 Py_DECREF(v);
1101 v = NULL;
1102 goto finally;
1103 }
1104 }
Guido van Rossum18468821994-06-20 07:49:28 +00001105
Barry Warsawfa701a81997-01-16 00:15:11 +00001106 finally:
1107 ckfree(FREECAST argv);
1108 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001109}
1110
1111static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001112Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001113 PyObject *self;
1114 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001115{
Barry Warsawfa701a81997-01-16 00:15:11 +00001116 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001117
Guido van Rossum43713e52000-02-29 13:59:29 +00001118 if (!PyArg_ParseTuple(args, "s:split", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001119 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001120 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001121}
1122
1123static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001124Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001125 PyObject *self;
1126 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001127{
Barry Warsawfa701a81997-01-16 00:15:11 +00001128 char *s = Merge(args);
1129 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001130
Barry Warsawfa701a81997-01-16 00:15:11 +00001131 if (s) {
1132 res = PyString_FromString(s);
1133 ckfree(s);
1134 }
1135 else
1136 PyErr_SetString(Tkinter_TclError, "merge failed");
1137
1138 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001139}
1140
Barry Warsawfa701a81997-01-16 00:15:11 +00001141
1142
Guido van Rossum18468821994-06-20 07:49:28 +00001143/** Tcl Command **/
1144
Guido van Rossum00d93061998-05-28 23:06:38 +00001145/* Client data struct */
1146typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001147 PyObject *self;
1148 PyObject *func;
1149} PythonCmd_ClientData;
1150
1151static int
1152PythonCmd_Error(interp)
1153 Tcl_Interp *interp;
1154{
1155 errorInCmd = 1;
1156 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1157 LEAVE_PYTHON
1158 return TCL_ERROR;
1159}
1160
Guido van Rossum18468821994-06-20 07:49:28 +00001161/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001162 * function or method.
1163 */
Guido van Rossum18468821994-06-20 07:49:28 +00001164static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001165PythonCmd(clientData, interp, argc, argv)
Guido van Rossum00d93061998-05-28 23:06:38 +00001166 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001167 Tcl_Interp *interp;
1168 int argc;
1169 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +00001170{
Guido van Rossum00d93061998-05-28 23:06:38 +00001171 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001172 PyObject *self, *func, *arg, *res, *tmp;
1173 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001174
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001175 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001176
Barry Warsawfa701a81997-01-16 00:15:11 +00001177 /* TBD: no error checking here since we know, via the
1178 * Tkapp_CreateCommand() that the client data is a two-tuple
1179 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001180 self = data->self;
1181 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001182
Barry Warsawfa701a81997-01-16 00:15:11 +00001183 /* Create argument list (argv1, ..., argvN) */
1184 if (!(arg = PyTuple_New(argc - 1)))
1185 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001186
Barry Warsawfa701a81997-01-16 00:15:11 +00001187 for (i = 0; i < (argc - 1); i++) {
1188 PyObject *s = PyString_FromString(argv[i + 1]);
1189 if (!s || PyTuple_SetItem(arg, i, s)) {
1190 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001191 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001192 }
1193 }
1194 res = PyEval_CallObject(func, arg);
1195 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001196
Barry Warsawfa701a81997-01-16 00:15:11 +00001197 if (res == NULL)
1198 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001199
Barry Warsawfa701a81997-01-16 00:15:11 +00001200 if (!(tmp = PyList_New(0))) {
1201 Py_DECREF(res);
1202 return PythonCmd_Error(interp);
1203 }
1204
1205 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
1206 Py_DECREF(res);
1207 Py_DECREF(tmp);
1208
Guido van Rossum00d93061998-05-28 23:06:38 +00001209 LEAVE_PYTHON
1210
Barry Warsawfa701a81997-01-16 00:15:11 +00001211 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +00001212}
1213
1214static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001215PythonCmdDelete(clientData)
Guido van Rossum00d93061998-05-28 23:06:38 +00001216 ClientData clientData;
Guido van Rossum18468821994-06-20 07:49:28 +00001217{
Guido van Rossum00d93061998-05-28 23:06:38 +00001218 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1219
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001220 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001221 Py_XDECREF(data->self);
1222 Py_XDECREF(data->func);
1223 PyMem_DEL(data);
1224 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001225}
1226
Barry Warsawfa701a81997-01-16 00:15:11 +00001227
1228
Guido van Rossum18468821994-06-20 07:49:28 +00001229static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001230Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001231 PyObject *self;
1232 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001233{
Guido van Rossum00d93061998-05-28 23:06:38 +00001234 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001235 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001236 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001237 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001238
Guido van Rossum43713e52000-02-29 13:59:29 +00001239 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001240 return NULL;
1241 if (!PyCallable_Check(func)) {
1242 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001243 return NULL;
1244 }
Guido van Rossum18468821994-06-20 07:49:28 +00001245
Guido van Rossum00d93061998-05-28 23:06:38 +00001246 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001247 if (!data)
1248 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001249 Py_XINCREF(self);
1250 Py_XINCREF(func);
1251 data->self = self;
1252 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001253
Guido van Rossum00d93061998-05-28 23:06:38 +00001254 ENTER_TCL
1255 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1256 (ClientData)data, PythonCmdDelete);
1257 LEAVE_TCL
1258 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001259 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001260 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001261 return NULL;
1262 }
Guido van Rossum18468821994-06-20 07:49:28 +00001263
Barry Warsawfa701a81997-01-16 00:15:11 +00001264 Py_INCREF(Py_None);
1265 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001266}
1267
Barry Warsawfa701a81997-01-16 00:15:11 +00001268
1269
Guido van Rossum18468821994-06-20 07:49:28 +00001270static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001271Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001272 PyObject *self;
1273 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001274{
Barry Warsawfa701a81997-01-16 00:15:11 +00001275 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001276 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001277
Guido van Rossum43713e52000-02-29 13:59:29 +00001278 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001279 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001280 ENTER_TCL
1281 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1282 LEAVE_TCL
1283 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001284 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1285 return NULL;
1286 }
1287 Py_INCREF(Py_None);
1288 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001289}
1290
Barry Warsawfa701a81997-01-16 00:15:11 +00001291
1292
Guido van Rossum00d93061998-05-28 23:06:38 +00001293#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001294/** File Handler **/
1295
Guido van Rossum00d93061998-05-28 23:06:38 +00001296typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001297 PyObject *func;
1298 PyObject *file;
1299 int id;
1300 struct _fhcdata *next;
1301} FileHandler_ClientData;
1302
1303static FileHandler_ClientData *HeadFHCD;
1304
1305static FileHandler_ClientData *
1306NewFHCD(func, file, id)
1307 PyObject *func;
1308 PyObject *file;
1309 int id;
1310{
1311 FileHandler_ClientData *p;
1312 p = PyMem_NEW(FileHandler_ClientData, 1);
1313 if (p != NULL) {
1314 Py_XINCREF(func);
1315 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001316 p->func = func;
1317 p->file = file;
1318 p->id = id;
1319 p->next = HeadFHCD;
1320 HeadFHCD = p;
1321 }
1322 return p;
1323}
1324
1325static void
1326DeleteFHCD(id)
1327 int id;
1328{
1329 FileHandler_ClientData *p, **pp;
1330
1331 pp = &HeadFHCD;
1332 while ((p = *pp) != NULL) {
1333 if (p->id == id) {
1334 *pp = p->next;
1335 Py_XDECREF(p->func);
1336 Py_XDECREF(p->file);
1337 PyMem_DEL(p);
1338 }
1339 else
1340 pp = &p->next;
1341 }
1342}
1343
Guido van Rossuma597dde1995-01-10 20:56:29 +00001344static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001345FileHandler(clientData, mask)
Guido van Rossum00d93061998-05-28 23:06:38 +00001346 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001347 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +00001348{
Guido van Rossum00d93061998-05-28 23:06:38 +00001349 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001350 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001351
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001352 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001353 func = data->func;
1354 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001355
Barry Warsawfa701a81997-01-16 00:15:11 +00001356 arg = Py_BuildValue("(Oi)", file, (long) mask);
1357 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001358 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001359
1360 if (res == NULL) {
1361 errorInCmd = 1;
1362 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1363 }
1364 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001365 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001366}
1367
1368static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001369GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +00001370 /* Either an int >= 0 or an object with a
1371 *.fileno() method that returns an int >= 0
1372 */
1373 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001374{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001375 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001376 int id;
1377 if (PyInt_Check(file)) {
1378 id = PyInt_AsLong(file);
1379 if (id < 0)
1380 PyErr_SetString(PyExc_ValueError, "invalid file id");
1381 return id;
1382 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001383 args = PyTuple_New(0);
1384 if (args == NULL)
1385 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001386
1387 meth = PyObject_GetAttrString(file, "fileno");
1388 if (meth == NULL) {
1389 Py_DECREF(args);
1390 return -1;
1391 }
1392
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001393 res = PyEval_CallObject(meth, args);
1394 Py_DECREF(args);
1395 Py_DECREF(meth);
1396 if (res == NULL)
1397 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001398
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001399 if (PyInt_Check(res))
1400 id = PyInt_AsLong(res);
1401 else
1402 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001403
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001404 if (id < 0)
1405 PyErr_SetString(PyExc_ValueError,
1406 "invalid fileno() return value");
1407 Py_DECREF(res);
1408 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001409}
1410
1411static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001412Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001413 PyObject *self;
1414 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001415{
Guido van Rossum00d93061998-05-28 23:06:38 +00001416 FileHandler_ClientData *data;
1417 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001418 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001419
Guido van Rossum43713e52000-02-29 13:59:29 +00001420 if (!PyArg_ParseTuple(args, "OiO:createfilehandler", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001421 return NULL;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001422 tfile = GetFileNo(file);
1423 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001424 return NULL;
1425 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001426 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001427 return NULL;
1428 }
1429
Guido van Rossuma80649b2000-03-28 20:07:05 +00001430 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001431 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001432 return NULL;
1433
Barry Warsawfa701a81997-01-16 00:15:11 +00001434 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001435 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001436 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001437 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001438 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001439 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001440}
1441
1442static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001443Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001444 PyObject *self;
1445 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001446{
Barry Warsawfa701a81997-01-16 00:15:11 +00001447 PyObject *file;
Guido van Rossum00d93061998-05-28 23:06:38 +00001448 FileHandler_ClientData *data;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001449 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001450
Guido van Rossum43713e52000-02-29 13:59:29 +00001451 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001452 return NULL;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001453 tfile = GetFileNo(file);
1454 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001455 return NULL;
1456
Guido van Rossuma80649b2000-03-28 20:07:05 +00001457 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001458
Barry Warsawfa701a81997-01-16 00:15:11 +00001459 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001460 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001461 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001462 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001463 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001464 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001465}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001466#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001467
Barry Warsawfa701a81997-01-16 00:15:11 +00001468
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001469/**** Tktt Object (timer token) ****/
1470
1471staticforward PyTypeObject Tktt_Type;
1472
Guido van Rossum00d93061998-05-28 23:06:38 +00001473typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001474 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001475 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001476 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001477} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001478
1479static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001480Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001481 PyObject *self;
1482 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001483{
Barry Warsawfa701a81997-01-16 00:15:11 +00001484 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001485 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001486
Guido van Rossum43713e52000-02-29 13:59:29 +00001487 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001488 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001489 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001490 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001491 v->token = NULL;
1492 }
1493 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001494 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001495 Py_DECREF(func);
1496 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001497 }
1498 Py_INCREF(Py_None);
1499 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001500}
1501
1502static PyMethodDef Tktt_methods[] =
1503{
Guido van Rossum35d43371997-08-02 00:09:09 +00001504 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001505 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001506};
1507
1508static TkttObject *
Guido van Rossum00d93061998-05-28 23:06:38 +00001509Tktt_New(func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001510 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001511{
Barry Warsawfa701a81997-01-16 00:15:11 +00001512 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001513
Barry Warsawfa701a81997-01-16 00:15:11 +00001514 v = PyObject_NEW(TkttObject, &Tktt_Type);
1515 if (v == NULL)
1516 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001517
Guido van Rossum00d93061998-05-28 23:06:38 +00001518 Py_INCREF(func);
1519 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001520 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001521
1522 /* Extra reference, deleted when called or when handler is deleted */
1523 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001524 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001525}
1526
1527static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001528Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001529 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001530{
Guido van Rossum00d93061998-05-28 23:06:38 +00001531 TkttObject *v = (TkttObject *)self;
1532 PyObject *func = v->func;
1533
1534 Py_XDECREF(func);
1535
Guido van Rossum35d43371997-08-02 00:09:09 +00001536 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001537}
1538
Guido van Rossum597ac201998-05-12 14:36:19 +00001539static PyObject *
1540Tktt_Repr(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001541 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001542{
Barry Warsawfa701a81997-01-16 00:15:11 +00001543 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001544 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001545
Guido van Rossum597ac201998-05-12 14:36:19 +00001546 sprintf(buf, "<tktimertoken at 0x%lx%s>", (long)v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001547 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001548 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001549}
1550
1551static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001552Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001553 PyObject *self;
1554 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001555{
Barry Warsawfa701a81997-01-16 00:15:11 +00001556 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001557}
1558
1559static PyTypeObject Tktt_Type =
1560{
Guido van Rossum35d43371997-08-02 00:09:09 +00001561 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001562 0, /*ob_size */
1563 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001564 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001565 0, /*tp_itemsize */
1566 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001567 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001568 Tktt_GetAttr, /*tp_getattr */
1569 0, /*tp_setattr */
1570 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001571 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001572 0, /*tp_as_number */
1573 0, /*tp_as_sequence */
1574 0, /*tp_as_mapping */
1575 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001576};
1577
Barry Warsawfa701a81997-01-16 00:15:11 +00001578
1579
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001580/** Timer Handler **/
1581
1582static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001583TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001584 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001585{
Guido van Rossum00d93061998-05-28 23:06:38 +00001586 TkttObject *v = (TkttObject *)clientData;
1587 PyObject *func = v->func;
1588 PyObject *res;
1589
1590 if (func == NULL)
1591 return;
1592
1593 v->func = NULL;
1594
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001595 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001596
1597 res = PyEval_CallObject(func, NULL);
1598 Py_DECREF(func);
1599 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001600
Barry Warsawfa701a81997-01-16 00:15:11 +00001601 if (res == NULL) {
1602 errorInCmd = 1;
1603 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1604 }
1605 else
1606 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001607
1608 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001609}
1610
1611static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001612Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001613 PyObject *self;
1614 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001615{
Barry Warsawfa701a81997-01-16 00:15:11 +00001616 int milliseconds;
1617 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001618 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001619
Guido van Rossum43713e52000-02-29 13:59:29 +00001620 if (!PyArg_ParseTuple(args, "iO:createtimerhandler", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001621 return NULL;
1622 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001623 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001624 return NULL;
1625 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001626 v = Tktt_New(func);
1627 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1628 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001629
Guido van Rossum00d93061998-05-28 23:06:38 +00001630 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001631}
1632
Barry Warsawfa701a81997-01-16 00:15:11 +00001633
Guido van Rossum18468821994-06-20 07:49:28 +00001634/** Event Loop **/
1635
Guido van Rossum18468821994-06-20 07:49:28 +00001636static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001637Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001638 PyObject *self;
1639 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001640{
Barry Warsawfa701a81997-01-16 00:15:11 +00001641 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001642#ifdef WITH_THREAD
1643 PyThreadState *tstate = PyThreadState_Get();
1644#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001645
Guido van Rossum43713e52000-02-29 13:59:29 +00001646 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001647 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001648
Barry Warsawfa701a81997-01-16 00:15:11 +00001649 quitMainLoop = 0;
1650 while (Tk_GetNumMainWindows() > threshold &&
1651 !quitMainLoop &&
1652 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001653 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001654 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001655
1656#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001657 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001658 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001659 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001660 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001661 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001662 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001663 if (result == 0)
1664 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001665 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001666#else
1667 result = Tcl_DoOneEvent(0);
1668#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001669
Guido van Rossum35d43371997-08-02 00:09:09 +00001670 if (PyErr_CheckSignals() != 0)
1671 return NULL;
1672 if (result < 0)
1673 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001674 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001675 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001676
Barry Warsawfa701a81997-01-16 00:15:11 +00001677 if (errorInCmd) {
1678 errorInCmd = 0;
1679 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1680 excInCmd = valInCmd = trbInCmd = NULL;
1681 return NULL;
1682 }
1683 Py_INCREF(Py_None);
1684 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001685}
1686
1687static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001688Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001689 PyObject *self;
1690 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001691{
Guido van Rossum35d43371997-08-02 00:09:09 +00001692 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001693 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001694
Guido van Rossum43713e52000-02-29 13:59:29 +00001695 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001696 return NULL;
1697
Guido van Rossum00d93061998-05-28 23:06:38 +00001698 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001699 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001700 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001701 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001702}
1703
1704static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001705Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001706 PyObject *self;
1707 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001708{
1709
Guido van Rossum43713e52000-02-29 13:59:29 +00001710 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001711 return NULL;
1712
1713 quitMainLoop = 1;
1714 Py_INCREF(Py_None);
1715 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001716}
1717
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001718static PyObject *
1719Tkapp_InterpAddr(self, args)
1720 PyObject *self;
1721 PyObject *args;
1722{
1723
Guido van Rossum43713e52000-02-29 13:59:29 +00001724 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001725 return NULL;
1726
1727 return PyInt_FromLong((long)Tkapp_Interp(self));
1728}
1729
Barry Warsawfa701a81997-01-16 00:15:11 +00001730
1731
Guido van Rossum18468821994-06-20 07:49:28 +00001732/**** Tkapp Method List ****/
1733
1734static PyMethodDef Tkapp_methods[] =
1735{
Guido van Rossum35d43371997-08-02 00:09:09 +00001736 {"call", Tkapp_Call, 0},
1737 {"globalcall", Tkapp_GlobalCall, 0},
1738 {"eval", Tkapp_Eval, 1},
1739 {"globaleval", Tkapp_GlobalEval, 1},
1740 {"evalfile", Tkapp_EvalFile, 1},
1741 {"record", Tkapp_Record, 1},
1742 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1743 {"setvar", Tkapp_SetVar, 1},
1744 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1745 {"getvar", Tkapp_GetVar, 1},
1746 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1747 {"unsetvar", Tkapp_UnsetVar, 1},
1748 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1749 {"getint", Tkapp_GetInt, 1},
1750 {"getdouble", Tkapp_GetDouble, 1},
1751 {"getboolean", Tkapp_GetBoolean, 1},
1752 {"exprstring", Tkapp_ExprString, 1},
1753 {"exprlong", Tkapp_ExprLong, 1},
1754 {"exprdouble", Tkapp_ExprDouble, 1},
1755 {"exprboolean", Tkapp_ExprBoolean, 1},
1756 {"splitlist", Tkapp_SplitList, 1},
1757 {"split", Tkapp_Split, 1},
1758 {"merge", Tkapp_Merge, 0},
1759 {"createcommand", Tkapp_CreateCommand, 1},
1760 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001761#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001762 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1763 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001764#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001765 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001766 {"mainloop", Tkapp_MainLoop, 1},
1767 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001768 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001769 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001770 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001771};
1772
Barry Warsawfa701a81997-01-16 00:15:11 +00001773
1774
Guido van Rossum18468821994-06-20 07:49:28 +00001775/**** Tkapp Type Methods ****/
1776
1777static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001778Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001779 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001780{
Guido van Rossum00d93061998-05-28 23:06:38 +00001781 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001782 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001783 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001784 PyMem_DEL(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001785 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001786}
1787
1788static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001789Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001790 PyObject *self;
1791 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001792{
Guido van Rossum35d43371997-08-02 00:09:09 +00001793 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001794}
1795
1796static PyTypeObject Tkapp_Type =
1797{
Guido van Rossum35d43371997-08-02 00:09:09 +00001798 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001799 0, /*ob_size */
1800 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001801 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001802 0, /*tp_itemsize */
1803 Tkapp_Dealloc, /*tp_dealloc */
1804 0, /*tp_print */
1805 Tkapp_GetAttr, /*tp_getattr */
1806 0, /*tp_setattr */
1807 0, /*tp_compare */
1808 0, /*tp_repr */
1809 0, /*tp_as_number */
1810 0, /*tp_as_sequence */
1811 0, /*tp_as_mapping */
1812 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001813};
1814
Barry Warsawfa701a81997-01-16 00:15:11 +00001815
1816
Guido van Rossum18468821994-06-20 07:49:28 +00001817/**** Tkinter Module ****/
1818
1819static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001820Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001821 PyObject *self;
1822 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001823{
Barry Warsawfa701a81997-01-16 00:15:11 +00001824 char *screenName = NULL;
1825 char *baseName = NULL;
1826 char *className = NULL;
1827 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001828
Guido van Rossum35d43371997-08-02 00:09:09 +00001829 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001830 if (baseName != NULL)
1831 baseName++;
1832 else
1833 baseName = Py_GetProgramName();
1834 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001835
Guido van Rossum43713e52000-02-29 13:59:29 +00001836 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00001837 &screenName, &baseName, &className,
1838 &interactive))
1839 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001840
Barry Warsawfa701a81997-01-16 00:15:11 +00001841 return (PyObject *) Tkapp_New(screenName, baseName, className,
1842 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001843}
1844
1845static PyMethodDef moduleMethods[] =
1846{
Barry Warsawfa701a81997-01-16 00:15:11 +00001847 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001848#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001849 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1850 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001851#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001852 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001853 {"mainloop", Tkapp_MainLoop, 1},
1854 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001855 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001856 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001857};
1858
Guido van Rossum7bf15641998-05-22 18:28:17 +00001859#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001860
1861static int stdin_ready = 0;
1862
Guido van Rossumad4db171998-06-13 13:56:28 +00001863#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001864static void
1865MyFileProc(clientData, mask)
1866 void *clientData;
1867 int mask;
1868{
1869 stdin_ready = 1;
1870}
Guido van Rossumad4db171998-06-13 13:56:28 +00001871#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001872
Guido van Rossum00d93061998-05-28 23:06:38 +00001873static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001874
Guido van Rossum18468821994-06-20 07:49:28 +00001875static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001876EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00001877{
Guido van Rossumad4db171998-06-13 13:56:28 +00001878#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00001879 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00001880#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001881#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00001882 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001883#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001884 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00001885 errorInCmd = 0;
1886#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00001887 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001888 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00001889#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001890 while (!errorInCmd && !stdin_ready) {
1891 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00001892#ifdef MS_WINDOWS
1893 if (_kbhit()) {
1894 stdin_ready = 1;
1895 break;
1896 }
1897#endif
1898#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00001899 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001900 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00001901 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001902
Guido van Rossum00d93061998-05-28 23:06:38 +00001903 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001904
1905 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001906 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001907 if (result == 0)
1908 Sleep(20);
1909 Py_END_ALLOW_THREADS
1910#else
1911 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001912#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001913
1914 if (result < 0)
1915 break;
1916 }
Guido van Rossumad4db171998-06-13 13:56:28 +00001917#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00001918 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00001919#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001920 if (errorInCmd) {
1921 errorInCmd = 0;
1922 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1923 excInCmd = valInCmd = trbInCmd = NULL;
1924 PyErr_Print();
1925 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001926#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00001927 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001928#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001929 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001930}
Guido van Rossum18468821994-06-20 07:49:28 +00001931
Guido van Rossum00d93061998-05-28 23:06:38 +00001932#endif
1933
Guido van Rossum7bf15641998-05-22 18:28:17 +00001934static void
1935EnableEventHook()
1936{
Guido van Rossum00d93061998-05-28 23:06:38 +00001937#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001938 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001939#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00001940 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001941#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001942 PyOS_InputHook = EventHook;
1943 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001944#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001945}
1946
1947static void
1948DisableEventHook()
1949{
Guido van Rossum00d93061998-05-28 23:06:38 +00001950#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001951 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
1952 PyOS_InputHook = NULL;
1953 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001954#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001955}
1956
Barry Warsawfa701a81997-01-16 00:15:11 +00001957
1958/* all errors will be checked in one fell swoop in init_tkinter() */
1959static void
1960ins_long(d, name, val)
1961 PyObject *d;
1962 char *name;
1963 long val;
1964{
1965 PyObject *v = PyInt_FromLong(val);
1966 if (v) {
1967 PyDict_SetItemString(d, name, v);
1968 Py_DECREF(v);
1969 }
1970}
1971static void
1972ins_string(d, name, val)
1973 PyObject *d;
1974 char *name;
1975 char *val;
1976{
1977 PyObject *v = PyString_FromString(val);
1978 if (v) {
1979 PyDict_SetItemString(d, name, v);
1980 Py_DECREF(v);
1981 }
1982}
1983
1984
Guido van Rossum3886bb61998-12-04 18:50:17 +00001985DL_EXPORT(void)
Guido van Rossum35d43371997-08-02 00:09:09 +00001986init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00001987{
Barry Warsawfa701a81997-01-16 00:15:11 +00001988 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001989
Barry Warsawfa701a81997-01-16 00:15:11 +00001990 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00001991
1992#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00001993 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00001994#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00001995
Barry Warsawfa701a81997-01-16 00:15:11 +00001996 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001997
Barry Warsawfa701a81997-01-16 00:15:11 +00001998 d = PyModule_GetDict(m);
1999 Tkinter_TclError = Py_BuildValue("s", "TclError");
2000 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002001
Guido van Rossum35d43371997-08-02 00:09:09 +00002002 ins_long(d, "READABLE", TCL_READABLE);
2003 ins_long(d, "WRITABLE", TCL_WRITABLE);
2004 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2005 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2006 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2007 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2008 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2009 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2010 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002011 ins_string(d, "TK_VERSION", TK_VERSION);
2012 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002013
Guido van Rossum83551bf1997-09-13 00:44:23 +00002014 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002015
2016 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002017 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2018
Guido van Rossume187b0e2000-03-27 21:46:29 +00002019 /* This helps the dynamic loader; in Unicode aware Tcl versions
2020 it also helps Tcl find its encodings. */
2021 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002022
Barry Warsawfa701a81997-01-16 00:15:11 +00002023 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002024 return;
2025
Guido van Rossum43ff8681998-07-14 18:02:13 +00002026#if 0
2027 /* This was not a good idea; through <Destroy> bindings,
2028 Tcl_Finalize() may invoke Python code but at that point the
2029 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002030 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002031#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002032
Jack Jansen34cc5c31995-10-31 16:15:12 +00002033#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002034 /*
2035 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2036 ** Most of the initializations in that routine (toolbox init calls and
2037 ** such) have already been done for us, so we only need these.
2038 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002039 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002040
2041 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002042#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002043 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002044#endif /* GENERATINGCFM */
2045#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002046}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002047
Guido van Rossumec22c921996-02-25 04:50:29 +00002048
Barry Warsawfa701a81997-01-16 00:15:11 +00002049
Guido van Rossum9722ad81995-09-22 23:49:28 +00002050#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002051
2052/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002053** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002054*/
2055
Guido van Rossum9722ad81995-09-22 23:49:28 +00002056void
2057panic(char * format, ...)
2058{
Barry Warsawfa701a81997-01-16 00:15:11 +00002059 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002060
Barry Warsawfa701a81997-01-16 00:15:11 +00002061 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002062
Guido van Rossum227cf761998-08-05 13:53:32 +00002063 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002064 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002065
Barry Warsawfa701a81997-01-16 00:15:11 +00002066 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002067
Barry Warsawfa701a81997-01-16 00:15:11 +00002068 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002069}
Jack Jansen40b546d1995-11-14 10:34:45 +00002070
Guido van Rossumec22c921996-02-25 04:50:29 +00002071/*
2072** Pass events to SIOUX before passing them to Tk.
2073*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002074
Guido van Rossumec22c921996-02-25 04:50:29 +00002075static int
2076PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00002077 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002078{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002079 WindowPtr frontwin;
2080 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002081 ** Sioux eats too many events, so we don't pass it everything. We
2082 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002083 ** the Sioux window is frontmost. This means that Tk menus don't work
2084 ** in that case, but at least we can scroll the sioux window.
2085 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2086 ** part of the external interface of Sioux...
2087 */
2088 frontwin = FrontWindow();
2089 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2090 if (SIOUXHandleOneEvent(eventPtr))
2091 return 0; /* Nothing happened to the Tcl event queue */
2092 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002093 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002094}
2095
Guido van Rossumec22c921996-02-25 04:50:29 +00002096#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002097
2098/*
2099** Additional Mac specific code for dealing with shared libraries.
2100*/
2101
2102#include <Resources.h>
2103#include <CodeFragments.h>
2104
2105static int loaded_from_shlib = 0;
2106static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002107
Jack Jansen34cc5c31995-10-31 16:15:12 +00002108/*
2109** If this module is dynamically loaded the following routine should
2110** be the init routine. It takes care of adding the shared library to
2111** the resource-file chain, so that the tk routines can find their
2112** resources.
2113*/
2114OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002115init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002116{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002117 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002118 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002119 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002120 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2121 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002122 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002123 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2124 loaded_from_shlib = 1;
2125 }
2126 return noErr;
2127}
2128
2129/*
2130** Insert the library resources into the search path. Put them after
2131** the resources from the application. Again, we ignore errors.
2132*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002133static
Jack Jansen34cc5c31995-10-31 16:15:12 +00002134mac_addlibresources()
2135{
2136 if ( !loaded_from_shlib )
2137 return;
2138 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2139}
2140
Guido van Rossumec22c921996-02-25 04:50:29 +00002141#endif /* GENERATINGCFM */
2142#endif /* macintosh */