blob: 013ae30a3641d03218ea234678d53f30694062a9 [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 Rossumfd71b9e2000-06-30 23:50:40 +00008Copyright (c) 2000, BeOpen.com.
9Copyright (c) 1995-2000, Corporation for National Research Initiatives.
10Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
11All rights reserved.
Guido van Rossum845547d1996-06-26 18:26:04 +000012
Guido van Rossumfd71b9e2000-06-30 23:50:40 +000013See the file "Misc/COPYRIGHT" for information on usage and
14redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum845547d1996-06-26 18:26:04 +000015
16******************************************************************/
17
18/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +000019
Guido van Rossum7ffa7611996-08-13 21:10:16 +000020/* TCL/TK VERSION INFO:
21
Guido van Rossuma80649b2000-03-28 20:07:05 +000022 Only Tcl/Tk 8.0 and later are supported. Older versions are not
23 supported. (Use Python 1.5.2 if you cannot upgrade your Tcl/Tk
24 libraries.)
25*/
Guido van Rossum7ffa7611996-08-13 21:10:16 +000026
Guido van Rossuma80649b2000-03-28 20:07:05 +000027/* XXX Further speed-up ideas, involving Tcl 8.0 features:
Guido van Rossum212643f1998-04-29 16:22:14 +000028
29 - In Tcl_Call(), create Tcl objects from the arguments, possibly using
30 intelligent mappings between Python objects and Tcl objects (e.g. ints,
31 floats and Tcl window pointers could be handled specially).
32
33 - Register a new Tcl type, "Python callable", which can be called more
34 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
35
Guido van Rossum7ffa7611996-08-13 21:10:16 +000036*/
37
Guido van Rossum35d43371997-08-02 00:09:09 +000038
Guido van Rossum9722ad81995-09-22 23:49:28 +000039#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000040#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000041
Guido van Rossum00d93061998-05-28 23:06:38 +000042#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000043#include "pythread.h"
Guido van Rossum00d93061998-05-28 23:06:38 +000044#endif
45
Guido van Rossum2a5119b1998-05-29 01:28:40 +000046#ifdef MS_WINDOWS
47#include <windows.h>
48#endif
49
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000050#ifdef macintosh
51#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000052#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000053#endif
54
Guido van Rossum49b56061998-10-01 20:42:43 +000055#ifdef PYOS_OS2
56#include "myselect.h"
57#endif
58
Guido van Rossum18468821994-06-20 07:49:28 +000059#include <tcl.h>
60#include <tk.h>
61
Guido van Rossum3e819a71997-08-01 19:29:02 +000062#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
63
Guido van Rossuma80649b2000-03-28 20:07:05 +000064#if TKMAJORMINOR < 8000
65#error "Tk older than 8.0 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000066#endif
67
Guido van Rossuma80649b2000-03-28 20:07:05 +000068#if defined(macintosh)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000069/* Sigh, we have to include this to get at the tcl qd pointer */
70#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000071/* And this one we need to clear the menu bar */
72#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000073#endif
74
Guido van Rossuma80649b2000-03-28 20:07:05 +000075#if !defined(MS_WINDOWS)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000076#define HAVE_CREATEFILEHANDLER
77#endif
78
Guido van Rossum00d93061998-05-28 23:06:38 +000079#ifdef HAVE_CREATEFILEHANDLER
80
81/* Tcl_CreateFileHandler() changed several times; these macros deal with the
82 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
83 Unix, only because Jack added it back); when available on Windows, it only
84 applies to sockets. */
85
Guido van Rossum7bf15641998-05-22 18:28:17 +000086#ifdef MS_WINDOWS
87#define FHANDLETYPE TCL_WIN_SOCKET
88#else
89#define FHANDLETYPE TCL_UNIX_FD
90#endif
91
Guido van Rossum00d93061998-05-28 23:06:38 +000092/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
93 which uses this to handle Tcl events while the user is typing commands. */
94
95#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +000096#define WAIT_FOR_STDIN
97#endif
98
Guido van Rossum00d93061998-05-28 23:06:38 +000099#endif /* HAVE_CREATEFILEHANDLER */
100
Guido van Rossumad4db171998-06-13 13:56:28 +0000101#ifdef MS_WINDOWS
102#include <conio.h>
103#define WAIT_FOR_STDIN
104#endif
105
Guido van Rossum00d93061998-05-28 23:06:38 +0000106#ifdef WITH_THREAD
107
108/* The threading situation is complicated. Tcl is not thread-safe, except for
109 Tcl 8.1, which will probably remain in alpha status for another 6 months
110 (and the README says that Tk will probably remain thread-unsafe forever).
111 So we need to use a lock around all uses of Tcl. Previously, the Python
112 interpreter lock was used for this. However, this causes problems when
113 other Python threads need to run while Tcl is blocked waiting for events.
114
115 To solve this problem, a separate lock for Tcl is introduced. Holding it
116 is incompatible with holding Python's interpreter lock. The following four
117 macros manipulate both locks together.
118
119 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
120 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
121 that could call an event handler, or otherwise affect the state of a Tcl
122 interpreter. These assume that the surrounding code has the Python
123 interpreter lock; inside the brackets, the Python interpreter lock has been
124 released and the lock for Tcl has been acquired.
125
Guido van Rossum5e977831998-06-15 14:03:52 +0000126 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
127 (For example, when transferring data from the Tcl interpreter result to a
128 Python string object.) This can be done by using different macros to close
129 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
130 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
131 releases the Tcl lock.
132
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000133 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000134 handlers when the handler needs to use Python. Such event handlers are
135 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000136 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000137 the Python interpreter lock, restoring the appropriate thread state, and
138 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
139 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000140 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000141
142 These locks expand to several statements and brackets; they should not be
143 used in branches of if statements and the like.
144
145*/
146
Guido van Rossum65d5b571998-12-21 19:32:43 +0000147static PyThread_type_lock tcl_lock = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000148static PyThreadState *tcl_tstate = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000149
150#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000151 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000152 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000153
154#define LEAVE_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000155 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000156
Guido van Rossum62320c91998-06-15 04:36:09 +0000157#define ENTER_OVERLAP \
158 Py_END_ALLOW_THREADS
159
160#define LEAVE_OVERLAP_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000161 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000162
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000163#define ENTER_PYTHON \
164 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000165 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000166
167#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000168 { PyThreadState *tstate = PyEval_SaveThread(); \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000169 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Guido van Rossum00d93061998-05-28 23:06:38 +0000170
171#else
172
173#define ENTER_TCL
174#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000175#define ENTER_OVERLAP
176#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000177#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000178#define LEAVE_PYTHON
179
180#endif
181
Guido van Rossumec22c921996-02-25 04:50:29 +0000182#ifdef macintosh
183
184/*
185** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000186** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000187*/
188
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000189/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000190#define FREECAST (char *)
191
Guido van Rossumec22c921996-02-25 04:50:29 +0000192#include <Events.h> /* For EventRecord */
193
194typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
Guido van Rossum0d2390c1997-08-14 19:57:07 +0000195void Tcl_MacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
Guido van Rossumec22c921996-02-25 04:50:29 +0000196int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
197
198staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
199
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000200#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
201 #pragma import on
202#endif
203
204#include <SIOUX.h>
205extern int SIOUXIsAppWindow(WindowPtr);
206
207#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
208 #pragma import reset
209#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000210#endif /* macintosh */
211
Guido van Rossum97867b21996-08-08 19:09:53 +0000212#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000213#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000214#endif
215
Guido van Rossum18468821994-06-20 07:49:28 +0000216/**** Tkapp Object Declaration ****/
217
218staticforward PyTypeObject Tkapp_Type;
219
Guido van Rossum00d93061998-05-28 23:06:38 +0000220typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000221 PyObject_HEAD
222 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000223} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000224
225#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000226#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
227#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
228
Guido van Rossum35d43371997-08-02 00:09:09 +0000229#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000230(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000231
Barry Warsawfa701a81997-01-16 00:15:11 +0000232
233
Guido van Rossum18468821994-06-20 07:49:28 +0000234/**** Error Handling ****/
235
236static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000237static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000238static int errorInCmd = 0;
239static PyObject *excInCmd;
240static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000241static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000242
Barry Warsawfa701a81997-01-16 00:15:11 +0000243
244
Guido van Rossum18468821994-06-20 07:49:28 +0000245static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000246Tkinter_Error(v)
247 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000248{
Barry Warsawfa701a81997-01-16 00:15:11 +0000249 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
250 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000251}
252
Barry Warsawfa701a81997-01-16 00:15:11 +0000253
Barry Warsawfa701a81997-01-16 00:15:11 +0000254
Guido van Rossum18468821994-06-20 07:49:28 +0000255/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000256
257#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000258#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000259#include "mytime.h"
Guido van Rossum11801851999-01-25 21:39:03 +0000260#include "myselect.h"
Guido van Rossum541f2411998-08-13 13:29:22 +0000261
Guido van Rossum00d93061998-05-28 23:06:38 +0000262/* Millisecond sleep() for Unix platforms. */
263
264static void
265Sleep(milli)
266 int milli;
267{
268 /* XXX Too bad if you don't have select(). */
269 struct timeval t;
270 double frac;
271 t.tv_sec = milli/1000;
272 t.tv_usec = (milli%1000) * 1000;
273 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
274}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000275#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000276#endif /* WITH_THREAD */
277
278
Guido van Rossum18468821994-06-20 07:49:28 +0000279static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000280AsString(value, tmp)
281 PyObject *value;
282 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000283{
Guido van Rossum35d43371997-08-02 00:09:09 +0000284 if (PyString_Check(value))
285 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000286 else {
287 PyObject *v = PyObject_Str(value);
288 PyList_Append(tmp, v);
289 Py_DECREF(v);
290 return PyString_AsString(v);
291 }
Guido van Rossum18468821994-06-20 07:49:28 +0000292}
293
Barry Warsawfa701a81997-01-16 00:15:11 +0000294
295
Guido van Rossum18468821994-06-20 07:49:28 +0000296#define ARGSZ 64
297
298static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000299Merge(args)
300 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000301{
Barry Warsawfa701a81997-01-16 00:15:11 +0000302 PyObject *tmp = NULL;
303 char *argvStore[ARGSZ];
304 char **argv = NULL;
305 int fvStore[ARGSZ];
306 int *fv = NULL;
307 int argc = 0, i;
308 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000309
Barry Warsawfa701a81997-01-16 00:15:11 +0000310 if (!(tmp = PyList_New(0)))
311 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000312
Barry Warsawfa701a81997-01-16 00:15:11 +0000313 argv = argvStore;
314 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000315
Barry Warsawfa701a81997-01-16 00:15:11 +0000316 if (args == NULL)
317 argc = 0;
318
319 else if (!PyTuple_Check(args)) {
320 argc = 1;
321 fv[0] = 0;
322 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000323 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000324 else {
325 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000326
Barry Warsawfa701a81997-01-16 00:15:11 +0000327 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000328 argv = (char **)ckalloc(argc * sizeof(char *));
329 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000330 if (argv == NULL || fv == NULL) {
331 PyErr_NoMemory();
332 goto finally;
333 }
334 }
335
336 for (i = 0; i < argc; i++) {
337 PyObject *v = PyTuple_GetItem(args, i);
338 if (PyTuple_Check(v)) {
339 fv[i] = 1;
340 if (!(argv[i] = Merge(v)))
341 goto finally;
342 }
343 else if (v == Py_None) {
344 argc = i;
345 break;
346 }
347 else {
348 fv[i] = 0;
349 argv[i] = AsString(v, tmp);
350 }
351 }
Guido van Rossum18468821994-06-20 07:49:28 +0000352 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000353 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000354
Barry Warsawfa701a81997-01-16 00:15:11 +0000355 finally:
356 for (i = 0; i < argc; i++)
357 if (fv[i]) {
358 ckfree(argv[i]);
359 }
360 if (argv != argvStore)
361 ckfree(FREECAST argv);
362 if (fv != fvStore)
363 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000364
Barry Warsawfa701a81997-01-16 00:15:11 +0000365 Py_DECREF(tmp);
366 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000367}
368
Barry Warsawfa701a81997-01-16 00:15:11 +0000369
370
Guido van Rossum18468821994-06-20 07:49:28 +0000371static PyObject *
Guido van Rossum00d93061998-05-28 23:06:38 +0000372Split(list)
Barry Warsawfa701a81997-01-16 00:15:11 +0000373 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000374{
Barry Warsawfa701a81997-01-16 00:15:11 +0000375 int argc;
376 char **argv;
377 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000378
Barry Warsawfa701a81997-01-16 00:15:11 +0000379 if (list == NULL) {
380 Py_INCREF(Py_None);
381 return Py_None;
382 }
Guido van Rossum18468821994-06-20 07:49:28 +0000383
Guido van Rossum00d93061998-05-28 23:06:38 +0000384 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000385 /* Not a list.
386 * Could be a quoted string containing funnies, e.g. {"}.
387 * Return the string itself.
388 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000389 return PyString_FromString(list);
390 }
Guido van Rossum18468821994-06-20 07:49:28 +0000391
Barry Warsawfa701a81997-01-16 00:15:11 +0000392 if (argc == 0)
393 v = PyString_FromString("");
394 else if (argc == 1)
395 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000396 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000397 int i;
398 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000399
Barry Warsawfa701a81997-01-16 00:15:11 +0000400 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000401 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000402 Py_DECREF(v);
403 v = NULL;
404 break;
405 }
406 PyTuple_SetItem(v, i, w);
407 }
408 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000409 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000410 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000411}
412
Barry Warsawfa701a81997-01-16 00:15:11 +0000413
414
Guido van Rossum18468821994-06-20 07:49:28 +0000415/**** Tkapp Object ****/
416
417#ifndef WITH_APPINIT
418int
Guido van Rossum35d43371997-08-02 00:09:09 +0000419Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000420 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000421{
Barry Warsawfa701a81997-01-16 00:15:11 +0000422 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000423
Barry Warsawfa701a81997-01-16 00:15:11 +0000424 main = Tk_MainWindow(interp);
425 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000426 PySys_WriteStderr("Tcl_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000427 return TCL_ERROR;
428 }
429 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000430 PySys_WriteStderr("Tk_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000431 return TCL_ERROR;
432 }
433 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000434}
435#endif /* !WITH_APPINIT */
436
Guido van Rossum18468821994-06-20 07:49:28 +0000437
Barry Warsawfa701a81997-01-16 00:15:11 +0000438
439
440/* Initialize the Tk application; see the `main' function in
441 * `tkMain.c'.
442 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000443
444static void EnableEventHook(); /* Forward */
445static void DisableEventHook(); /* Forward */
446
Barry Warsawfa701a81997-01-16 00:15:11 +0000447static TkappObject *
448Tkapp_New(screenName, baseName, className, interactive)
449 char *screenName;
450 char *baseName;
451 char *className;
452 int interactive;
453{
454 TkappObject *v;
455 char *argv0;
456
Guido van Rossumb18618d2000-05-03 23:44:39 +0000457 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000458 if (v == NULL)
459 return NULL;
460
461 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000462
Guido van Rossuma80649b2000-03-28 20:07:05 +0000463#if defined(macintosh)
464 /* This seems to be needed */
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000465 ClearMenuBar();
466 TkMacInitMenus(v->interp);
467#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000468 /* Delete the 'exit' command, which can screw things up */
469 Tcl_DeleteCommand(v->interp, "exit");
470
Barry Warsawfa701a81997-01-16 00:15:11 +0000471 if (screenName != NULL)
472 Tcl_SetVar2(v->interp, "env", "DISPLAY",
473 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000474
Barry Warsawfa701a81997-01-16 00:15:11 +0000475 if (interactive)
476 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
477 else
478 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000479
Barry Warsawfa701a81997-01-16 00:15:11 +0000480 /* This is used to get the application class for Tk 4.1 and up */
481 argv0 = (char*)ckalloc(strlen(className) + 1);
482 if (!argv0) {
483 PyErr_NoMemory();
484 Py_DECREF(v);
485 return NULL;
486 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000487
Barry Warsawfa701a81997-01-16 00:15:11 +0000488 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000489 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000490 argv0[0] = tolower(argv0[0]);
491 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
492 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000493
Barry Warsawfa701a81997-01-16 00:15:11 +0000494 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000495 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000496
Guido van Rossum7bf15641998-05-22 18:28:17 +0000497 EnableEventHook();
498
Barry Warsawfa701a81997-01-16 00:15:11 +0000499 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000500}
501
Barry Warsawfa701a81997-01-16 00:15:11 +0000502
503
Guido van Rossum18468821994-06-20 07:49:28 +0000504/** Tcl Eval **/
505
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000506#if TKMAJORMINOR >= 8001
507#define USING_OBJECTS
508#endif
509
510#ifdef USING_OBJECTS
511
512static Tcl_Obj*
513AsObj(value)
514 PyObject *value;
515{
516 Tcl_Obj *result;
517
518 if (PyString_Check(value))
519 return Tcl_NewStringObj(PyString_AS_STRING(value),
520 PyString_GET_SIZE(value));
521 else if (PyInt_Check(value))
522 return Tcl_NewLongObj(PyInt_AS_LONG(value));
523 else if (PyFloat_Check(value))
524 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
525 else if (PyTuple_Check(value)) {
526 Tcl_Obj **argv = (Tcl_Obj**)
527 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
528 int i;
529 if(!argv)
530 return 0;
531 for(i=0;i<PyTuple_Size(value);i++)
532 argv[i] = AsObj(PyTuple_GetItem(value,i));
533 result = Tcl_NewListObj(PyTuple_Size(value), argv);
534 ckfree(FREECAST argv);
535 return result;
536 }
537 else if (PyUnicode_Check(value)) {
Guido van Rossum990f5c62000-05-04 15:07:16 +0000538#if TKMAJORMINOR <= 8001
539 /* In Tcl 8.1 we must use UTF-8 */
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000540 PyObject* utf8 = PyUnicode_AsUTF8String (value);
541 if (!utf8)
542 return 0;
Guido van Rossum8823acc2000-04-27 20:14:31 +0000543 result = Tcl_NewStringObj (PyString_AS_STRING (utf8),
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000544 PyString_GET_SIZE (utf8));
Guido van Rossum8823acc2000-04-27 20:14:31 +0000545 Py_DECREF(utf8);
546 return result;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000547#else /* TKMAJORMINOR > 8001 */
548 /* In Tcl 8.2 and later, use Tcl_NewUnicodeObj() */
549 if (sizeof(Py_UNICODE) != sizeof(Tcl_UniChar)) {
550 /* XXX Should really test this at compile time */
551 PyErr_SetString(PyExc_SystemError,
552 "Py_UNICODE and Tcl_UniChar differ in size");
553 return 0;
554 }
555 return Tcl_NewUnicodeObj(PyUnicode_AS_UNICODE(value),
556 PyUnicode_GET_SIZE(value));
557#endif /* TKMAJORMINOR > 8001 */
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000558 }
559 else {
560 PyObject *v = PyObject_Str(value);
561 if (!v)
562 return 0;
563 result = AsObj(v);
564 Py_DECREF(v);
565 return result;
566 }
567}
568
Guido van Rossum18468821994-06-20 07:49:28 +0000569static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000570Tkapp_Call(self, args)
571 PyObject *self;
572 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000573{
Guido van Rossum632de272000-03-29 00:19:50 +0000574 Tcl_Obj *objStore[ARGSZ];
575 Tcl_Obj **objv = NULL;
576 int objc = 0, i;
577 PyObject *res = NULL;
578 Tcl_Interp *interp = Tkapp_Interp(self);
579 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
580 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000581
Guido van Rossum632de272000-03-29 00:19:50 +0000582 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000583
Guido van Rossum212643f1998-04-29 16:22:14 +0000584 if (args == NULL)
Guido van Rossum632de272000-03-29 00:19:50 +0000585 objc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000586
Guido van Rossum212643f1998-04-29 16:22:14 +0000587 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000588 objc = 1;
589 objv[0] = AsObj(args);
590 if (objv[0] == 0)
591 goto finally;
592 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000593 }
594 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000595 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000596
Guido van Rossum632de272000-03-29 00:19:50 +0000597 if (objc > ARGSZ) {
598 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
599 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000600 PyErr_NoMemory();
601 goto finally;
602 }
603 }
604
Guido van Rossum632de272000-03-29 00:19:50 +0000605 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000606 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +0000607 if (v == Py_None) {
608 objc = i;
609 break;
610 }
Guido van Rossum632de272000-03-29 00:19:50 +0000611 objv[i] = AsObj(v);
612 if (!objv[i])
613 goto finally;
614 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000615 }
616 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000617
Guido van Rossum62320c91998-06-15 04:36:09 +0000618 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000619
620 i = Tcl_EvalObjv(interp, objc, objv, flags);
621
Guido van Rossum62320c91998-06-15 04:36:09 +0000622 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000623 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000624 Tkinter_Error(self);
Guido van Rossum990f5c62000-05-04 15:07:16 +0000625 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000626 /* We could request the object result here, but doing
627 so would confuse applications that expect a string. */
Guido van Rossum990f5c62000-05-04 15:07:16 +0000628 char *s = Tcl_GetStringResult(interp);
629 char *p = s;
630 /* If the result contains any bytes with the top bit set,
631 it's UTF-8 and we should decode it to Unicode */
632 while (*p != '\0') {
633 if (*p & 0x80)
634 break;
635 p++;
636 }
637 if (*p == '\0')
638 res = PyString_FromStringAndSize(s, (int)(p-s));
639 else {
640 /* Convert UTF-8 to Unicode string */
641 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +0000642 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
643 if (res == NULL) {
644 PyErr_Clear();
645 res = PyString_FromStringAndSize(s, (int)(p-s));
646 }
Guido van Rossum990f5c62000-05-04 15:07:16 +0000647 }
648 }
Guido van Rossum632de272000-03-29 00:19:50 +0000649
Guido van Rossum62320c91998-06-15 04:36:09 +0000650 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000651
Guido van Rossum212643f1998-04-29 16:22:14 +0000652 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000653 for (i = 0; i < objc; i++)
654 Tcl_DecrRefCount(objv[i]);
655 if (objv != objStore)
656 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000657 return res;
658}
659
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000660#else /* !USING_OBJECTS */
661
662static PyObject *
663Tkapp_Call(self, args)
664 PyObject *self;
665 PyObject *args;
666{
667 /* This is copied from Merge() */
668 PyObject *tmp = NULL;
669 char *argvStore[ARGSZ];
670 char **argv = NULL;
671 int fvStore[ARGSZ];
672 int *fv = NULL;
673 int argc = 0, i;
674 PyObject *res = NULL; /* except this has a different type */
675 Tcl_CmdInfo info; /* and this is added */
676 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
677
678 if (!(tmp = PyList_New(0)))
679 return NULL;
680
681 argv = argvStore;
682 fv = fvStore;
683
684 if (args == NULL)
685 argc = 0;
686
687 else if (!PyTuple_Check(args)) {
688 argc = 1;
689 fv[0] = 0;
690 argv[0] = AsString(args, tmp);
691 }
692 else {
693 argc = PyTuple_Size(args);
694
695 if (argc > ARGSZ) {
696 argv = (char **)ckalloc(argc * sizeof(char *));
697 fv = (int *)ckalloc(argc * sizeof(int));
698 if (argv == NULL || fv == NULL) {
699 PyErr_NoMemory();
700 goto finally;
701 }
702 }
703
704 for (i = 0; i < argc; i++) {
705 PyObject *v = PyTuple_GetItem(args, i);
706 if (PyTuple_Check(v)) {
707 fv[i] = 1;
708 if (!(argv[i] = Merge(v)))
709 goto finally;
710 }
711 else if (v == Py_None) {
712 argc = i;
713 break;
714 }
715 else {
716 fv[i] = 0;
717 argv[i] = AsString(v, tmp);
718 }
719 }
720 }
721 /* End code copied from Merge() */
722
723 /* All this to avoid a call to Tcl_Merge() and the corresponding call
724 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
725 if (Py_VerboseFlag >= 2) {
726 for (i = 0; i < argc; i++)
727 PySys_WriteStderr("%s ", argv[i]);
728 }
729 ENTER_TCL
730 info.proc = NULL;
731 if (argc < 1 ||
732 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
733 info.proc == NULL)
734 {
735 char *cmd;
736 cmd = Tcl_Merge(argc, argv);
737 i = Tcl_Eval(interp, cmd);
738 ckfree(cmd);
739 }
740 else {
741 Tcl_ResetResult(interp);
742 i = (*info.proc)(info.clientData, interp, argc, argv);
743 }
744 ENTER_OVERLAP
745 if (info.proc == NULL && Py_VerboseFlag >= 2)
746 PySys_WriteStderr("... use TclEval ");
747 if (i == TCL_ERROR) {
748 if (Py_VerboseFlag >= 2)
749 PySys_WriteStderr("... error: '%s'\n",
750 interp->result);
751 Tkinter_Error(self);
752 }
753 else {
754 if (Py_VerboseFlag >= 2)
755 PySys_WriteStderr("-> '%s'\n", interp->result);
756 res = PyString_FromString(interp->result);
757 }
758 LEAVE_OVERLAP_TCL
759
760 /* Copied from Merge() again */
761 finally:
762 for (i = 0; i < argc; i++)
763 if (fv[i]) {
764 ckfree(argv[i]);
765 }
766 if (argv != argvStore)
767 ckfree(FREECAST argv);
768 if (fv != fvStore)
769 ckfree(FREECAST fv);
770
771 Py_DECREF(tmp);
772 return res;
773}
774
775#endif /* !USING_OBJECTS */
Barry Warsawfa701a81997-01-16 00:15:11 +0000776
777static PyObject *
778Tkapp_GlobalCall(self, args)
779 PyObject *self;
780 PyObject *args;
781{
Guido van Rossum212643f1998-04-29 16:22:14 +0000782 /* Could do the same here as for Tkapp_Call(), but this is not used
783 much, so I can't be bothered. Unfortunately Tcl doesn't export a
784 way for the user to do what all its Global* variants do (save and
785 reset the scope pointer, call the local version, restore the saved
786 scope pointer). */
787
Guido van Rossum62320c91998-06-15 04:36:09 +0000788 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000789 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000790
Guido van Rossum62320c91998-06-15 04:36:09 +0000791 cmd = Merge(args);
Barry Warsawfa701a81997-01-16 00:15:11 +0000792 if (!cmd)
793 PyErr_SetString(Tkinter_TclError, "merge failed");
794
Guido van Rossum00d93061998-05-28 23:06:38 +0000795 else {
796 int err;
797 ENTER_TCL
798 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000799 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000800 if (err == TCL_ERROR)
801 res = Tkinter_Error(self);
802 else
803 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000804 LEAVE_OVERLAP_TCL
Guido van Rossum00d93061998-05-28 23:06:38 +0000805 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000806
807 if (cmd)
808 ckfree(cmd);
809
810 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000811}
812
813static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000814Tkapp_Eval(self, args)
815 PyObject *self;
816 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000817{
Barry Warsawfa701a81997-01-16 00:15:11 +0000818 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000819 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000820 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000821
Guido van Rossum43713e52000-02-29 13:59:29 +0000822 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000823 return NULL;
824
Guido van Rossum00d93061998-05-28 23:06:38 +0000825 ENTER_TCL
826 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000827 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000828 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000829 res = Tkinter_Error(self);
830 else
831 res = PyString_FromString(Tkapp_Result(self));
832 LEAVE_OVERLAP_TCL
833 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000834}
835
836static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000837Tkapp_GlobalEval(self, args)
838 PyObject *self;
839 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000840{
Barry Warsawfa701a81997-01-16 00:15:11 +0000841 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000842 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000843 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000844
Guido van Rossum43713e52000-02-29 13:59:29 +0000845 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000846 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000847
Guido van Rossum00d93061998-05-28 23:06:38 +0000848 ENTER_TCL
849 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000850 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000851 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000852 res = Tkinter_Error(self);
853 else
854 res = PyString_FromString(Tkapp_Result(self));
855 LEAVE_OVERLAP_TCL
856 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000857}
858
859static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000860Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000861 PyObject *self;
862 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000863{
Barry Warsawfa701a81997-01-16 00:15:11 +0000864 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000865 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000866 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000867
Guido van Rossum43713e52000-02-29 13:59:29 +0000868 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000869 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000870
Guido van Rossum00d93061998-05-28 23:06:38 +0000871 ENTER_TCL
872 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000873 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000874 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000875 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000876
Guido van Rossum62320c91998-06-15 04:36:09 +0000877 else
878 res = PyString_FromString(Tkapp_Result(self));
879 LEAVE_OVERLAP_TCL
880 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000881}
882
883static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000884Tkapp_Record(self, args)
885 PyObject *self;
886 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000887{
Barry Warsawfa701a81997-01-16 00:15:11 +0000888 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000889 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000890 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000891
Guido van Rossum35d43371997-08-02 00:09:09 +0000892 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000893 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000894
Guido van Rossum00d93061998-05-28 23:06:38 +0000895 ENTER_TCL
896 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000897 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000898 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000899 res = Tkinter_Error(self);
900 else
901 res = PyString_FromString(Tkapp_Result(self));
902 LEAVE_OVERLAP_TCL
903 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000904}
905
906static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000907Tkapp_AddErrorInfo(self, args)
908 PyObject *self;
909 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000910{
Barry Warsawfa701a81997-01-16 00:15:11 +0000911 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000912
Guido van Rossum43713e52000-02-29 13:59:29 +0000913 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000914 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000915 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000916 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000917 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000918
Barry Warsawfa701a81997-01-16 00:15:11 +0000919 Py_INCREF(Py_None);
920 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000921}
922
Barry Warsawfa701a81997-01-16 00:15:11 +0000923
924
Guido van Rossum18468821994-06-20 07:49:28 +0000925/** Tcl Variable **/
926
927static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000928SetVar(self, args, flags)
929 PyObject *self;
930 PyObject *args;
931 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000932{
Guido van Rossum00d93061998-05-28 23:06:38 +0000933 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000934 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000935 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000936
Guido van Rossum62320c91998-06-15 04:36:09 +0000937 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000938 if (!tmp)
939 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000940
Guido van Rossum43713e52000-02-29 13:59:29 +0000941 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000942 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000943 s = AsString(newValue, tmp);
944 ENTER_TCL
945 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
946 LEAVE_TCL
947 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000948 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000949 PyErr_Clear();
Guido van Rossum43713e52000-02-29 13:59:29 +0000950 if (PyArg_ParseTuple(args, "ssO:setvar", &name1, &name2, &newValue)) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000951 s = AsString (newValue, tmp);
952 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000953 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000954 s, flags);
955 LEAVE_TCL
956 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000957 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000958 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000959 return NULL;
960 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000961 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000962 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000963
Barry Warsawfa701a81997-01-16 00:15:11 +0000964 if (!ok)
965 return Tkinter_Error(self);
966
967 Py_INCREF(Py_None);
968 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000969}
970
971static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000972Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000973 PyObject *self;
974 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000975{
Barry Warsawfa701a81997-01-16 00:15:11 +0000976 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000977}
978
979static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000980Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000981 PyObject *self;
982 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000983{
Barry Warsawfa701a81997-01-16 00:15:11 +0000984 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000985}
986
Barry Warsawfa701a81997-01-16 00:15:11 +0000987
988
Guido van Rossum18468821994-06-20 07:49:28 +0000989static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000990GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000991 PyObject *self;
992 PyObject *args;
993 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000994{
Guido van Rossum35d43371997-08-02 00:09:09 +0000995 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000996 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000997
Guido van Rossum43713e52000-02-29 13:59:29 +0000998 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +0000999 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001000 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001001 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +00001002 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +00001003
Barry Warsawfa701a81997-01-16 00:15:11 +00001004 else
Guido van Rossum35d43371997-08-02 00:09:09 +00001005 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001006 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001007
Barry Warsawfa701a81997-01-16 00:15:11 +00001008 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +00001009 res = Tkinter_Error(self);
1010 else
1011 res = PyString_FromString(s);
1012 LEAVE_OVERLAP_TCL
1013 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001014}
1015
1016static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001017Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001018 PyObject *self;
1019 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001020{
Barry Warsawfa701a81997-01-16 00:15:11 +00001021 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001022}
1023
1024static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001025Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001026 PyObject *self;
1027 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001028{
Barry Warsawfa701a81997-01-16 00:15:11 +00001029 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001030}
1031
Barry Warsawfa701a81997-01-16 00:15:11 +00001032
1033
Guido van Rossum18468821994-06-20 07:49:28 +00001034static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001035UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +00001036 PyObject *self;
1037 PyObject *args;
1038 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +00001039{
Guido van Rossum35d43371997-08-02 00:09:09 +00001040 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001041 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001042 int code;
Guido van Rossum18468821994-06-20 07:49:28 +00001043
Guido van Rossum43713e52000-02-29 13:59:29 +00001044 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001045 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001046 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001047 if (name2 == NULL)
1048 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
1049
1050 else
1051 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001052 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001053
Barry Warsawfa701a81997-01-16 00:15:11 +00001054 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001055 res = Tkinter_Error(self);
1056 else {
1057 Py_INCREF(Py_None);
1058 res = Py_None;
1059 }
1060 LEAVE_OVERLAP_TCL
1061 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001062}
1063
1064static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001065Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001066 PyObject *self;
1067 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001068{
Barry Warsawfa701a81997-01-16 00:15:11 +00001069 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001070}
1071
1072static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001073Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001074 PyObject *self;
1075 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001076{
Barry Warsawfa701a81997-01-16 00:15:11 +00001077 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001078}
1079
Barry Warsawfa701a81997-01-16 00:15:11 +00001080
1081
Guido van Rossum18468821994-06-20 07:49:28 +00001082/** Tcl to Python **/
1083
1084static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001085Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001086 PyObject *self;
1087 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001088{
Barry Warsawfa701a81997-01-16 00:15:11 +00001089 char *s;
1090 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001091
Guido van Rossum43713e52000-02-29 13:59:29 +00001092 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001093 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001094 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001095 return Tkinter_Error(self);
1096 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001097}
1098
1099static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001100Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001101 PyObject *self;
1102 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001103{
Barry Warsawfa701a81997-01-16 00:15:11 +00001104 char *s;
1105 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001106
Guido van Rossum43713e52000-02-29 13:59:29 +00001107 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001108 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001109 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001110 return Tkinter_Error(self);
1111 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001112}
1113
1114static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001115Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001116 PyObject *self;
1117 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001118{
Barry Warsawfa701a81997-01-16 00:15:11 +00001119 char *s;
1120 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001121
Guido van Rossum43713e52000-02-29 13:59:29 +00001122 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001123 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001124 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1125 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001126 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001127}
1128
1129static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001130Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001131 PyObject *self;
1132 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001133{
Barry Warsawfa701a81997-01-16 00:15:11 +00001134 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001135 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001136 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001137
Guido van Rossum43713e52000-02-29 13:59:29 +00001138 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001139 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001140 ENTER_TCL
1141 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001142 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001143 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001144 res = Tkinter_Error(self);
1145 else
1146 res = Py_BuildValue("s", Tkapp_Result(self));
1147 LEAVE_OVERLAP_TCL
1148 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001149}
1150
1151static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001152Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001153 PyObject *self;
1154 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001155{
Barry Warsawfa701a81997-01-16 00:15:11 +00001156 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001157 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001158 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001159 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001160
Guido van Rossum43713e52000-02-29 13:59:29 +00001161 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001162 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001163 ENTER_TCL
1164 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001165 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001166 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001167 res = Tkinter_Error(self);
1168 else
1169 res = Py_BuildValue("l", v);
1170 LEAVE_OVERLAP_TCL
1171 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001172}
1173
1174static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001175Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001176 PyObject *self;
1177 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001178{
Barry Warsawfa701a81997-01-16 00:15:11 +00001179 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001180 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001181 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001182 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001183
Guido van Rossum43713e52000-02-29 13:59:29 +00001184 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001185 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001186 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001187 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001188 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001189 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001190 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001191 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001192 res = Tkinter_Error(self);
1193 else
1194 res = Py_BuildValue("d", v);
1195 LEAVE_OVERLAP_TCL
1196 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001197}
1198
1199static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001200Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001201 PyObject *self;
1202 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001203{
Barry Warsawfa701a81997-01-16 00:15:11 +00001204 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001205 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001206 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001207 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001208
Guido van Rossum43713e52000-02-29 13:59:29 +00001209 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001210 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001211 ENTER_TCL
1212 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001213 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001214 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001215 res = Tkinter_Error(self);
1216 else
1217 res = Py_BuildValue("i", v);
1218 LEAVE_OVERLAP_TCL
1219 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001220}
1221
Barry Warsawfa701a81997-01-16 00:15:11 +00001222
1223
Guido van Rossum18468821994-06-20 07:49:28 +00001224static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001225Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001226 PyObject *self;
1227 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001228{
Barry Warsawfa701a81997-01-16 00:15:11 +00001229 char *list;
1230 int argc;
1231 char **argv;
1232 PyObject *v;
1233 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001234
Guido van Rossum43713e52000-02-29 13:59:29 +00001235 if (!PyArg_ParseTuple(args, "s:splitlist", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001236 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001237
Barry Warsawfa701a81997-01-16 00:15:11 +00001238 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1239 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001240
Barry Warsawfa701a81997-01-16 00:15:11 +00001241 if (!(v = PyTuple_New(argc)))
1242 return NULL;
1243
1244 for (i = 0; i < argc; i++) {
1245 PyObject *s = PyString_FromString(argv[i]);
1246 if (!s || PyTuple_SetItem(v, i, s)) {
1247 Py_DECREF(v);
1248 v = NULL;
1249 goto finally;
1250 }
1251 }
Guido van Rossum18468821994-06-20 07:49:28 +00001252
Barry Warsawfa701a81997-01-16 00:15:11 +00001253 finally:
1254 ckfree(FREECAST argv);
1255 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001256}
1257
1258static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001259Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001260 PyObject *self;
1261 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001262{
Barry Warsawfa701a81997-01-16 00:15:11 +00001263 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001264
Guido van Rossum43713e52000-02-29 13:59:29 +00001265 if (!PyArg_ParseTuple(args, "s:split", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001266 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001267 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001268}
1269
1270static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001271Tkapp_Merge(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 *s = Merge(args);
1276 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001277
Barry Warsawfa701a81997-01-16 00:15:11 +00001278 if (s) {
1279 res = PyString_FromString(s);
1280 ckfree(s);
1281 }
1282 else
1283 PyErr_SetString(Tkinter_TclError, "merge failed");
1284
1285 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001286}
1287
Barry Warsawfa701a81997-01-16 00:15:11 +00001288
1289
Guido van Rossum18468821994-06-20 07:49:28 +00001290/** Tcl Command **/
1291
Guido van Rossum00d93061998-05-28 23:06:38 +00001292/* Client data struct */
1293typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001294 PyObject *self;
1295 PyObject *func;
1296} PythonCmd_ClientData;
1297
1298static int
1299PythonCmd_Error(interp)
1300 Tcl_Interp *interp;
1301{
1302 errorInCmd = 1;
1303 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1304 LEAVE_PYTHON
1305 return TCL_ERROR;
1306}
1307
Guido van Rossum18468821994-06-20 07:49:28 +00001308/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001309 * function or method.
1310 */
Guido van Rossum18468821994-06-20 07:49:28 +00001311static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001312PythonCmd(clientData, interp, argc, argv)
Guido van Rossum00d93061998-05-28 23:06:38 +00001313 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001314 Tcl_Interp *interp;
1315 int argc;
1316 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +00001317{
Guido van Rossum00d93061998-05-28 23:06:38 +00001318 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001319 PyObject *self, *func, *arg, *res, *tmp;
1320 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001321
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001322 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001323
Barry Warsawfa701a81997-01-16 00:15:11 +00001324 /* TBD: no error checking here since we know, via the
1325 * Tkapp_CreateCommand() that the client data is a two-tuple
1326 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001327 self = data->self;
1328 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001329
Barry Warsawfa701a81997-01-16 00:15:11 +00001330 /* Create argument list (argv1, ..., argvN) */
1331 if (!(arg = PyTuple_New(argc - 1)))
1332 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001333
Barry Warsawfa701a81997-01-16 00:15:11 +00001334 for (i = 0; i < (argc - 1); i++) {
1335 PyObject *s = PyString_FromString(argv[i + 1]);
1336 if (!s || PyTuple_SetItem(arg, i, s)) {
1337 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001338 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001339 }
1340 }
1341 res = PyEval_CallObject(func, arg);
1342 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001343
Barry Warsawfa701a81997-01-16 00:15:11 +00001344 if (res == NULL)
1345 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001346
Barry Warsawfa701a81997-01-16 00:15:11 +00001347 if (!(tmp = PyList_New(0))) {
1348 Py_DECREF(res);
1349 return PythonCmd_Error(interp);
1350 }
1351
1352 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
1353 Py_DECREF(res);
1354 Py_DECREF(tmp);
1355
Guido van Rossum00d93061998-05-28 23:06:38 +00001356 LEAVE_PYTHON
1357
Barry Warsawfa701a81997-01-16 00:15:11 +00001358 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +00001359}
1360
1361static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001362PythonCmdDelete(clientData)
Guido van Rossum00d93061998-05-28 23:06:38 +00001363 ClientData clientData;
Guido van Rossum18468821994-06-20 07:49:28 +00001364{
Guido van Rossum00d93061998-05-28 23:06:38 +00001365 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1366
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001367 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001368 Py_XDECREF(data->self);
1369 Py_XDECREF(data->func);
1370 PyMem_DEL(data);
1371 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001372}
1373
Barry Warsawfa701a81997-01-16 00:15:11 +00001374
1375
Guido van Rossum18468821994-06-20 07:49:28 +00001376static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001377Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001378 PyObject *self;
1379 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001380{
Guido van Rossum00d93061998-05-28 23:06:38 +00001381 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001382 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001383 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001384 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001385
Guido van Rossum43713e52000-02-29 13:59:29 +00001386 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001387 return NULL;
1388 if (!PyCallable_Check(func)) {
1389 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001390 return NULL;
1391 }
Guido van Rossum18468821994-06-20 07:49:28 +00001392
Guido van Rossum00d93061998-05-28 23:06:38 +00001393 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001394 if (!data)
1395 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001396 Py_XINCREF(self);
1397 Py_XINCREF(func);
1398 data->self = self;
1399 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001400
Guido van Rossum00d93061998-05-28 23:06:38 +00001401 ENTER_TCL
1402 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1403 (ClientData)data, PythonCmdDelete);
1404 LEAVE_TCL
1405 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001406 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001407 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001408 return NULL;
1409 }
Guido van Rossum18468821994-06-20 07:49:28 +00001410
Barry Warsawfa701a81997-01-16 00:15:11 +00001411 Py_INCREF(Py_None);
1412 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001413}
1414
Barry Warsawfa701a81997-01-16 00:15:11 +00001415
1416
Guido van Rossum18468821994-06-20 07:49:28 +00001417static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001418Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001419 PyObject *self;
1420 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001421{
Barry Warsawfa701a81997-01-16 00:15:11 +00001422 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001423 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001424
Guido van Rossum43713e52000-02-29 13:59:29 +00001425 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001426 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001427 ENTER_TCL
1428 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1429 LEAVE_TCL
1430 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001431 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1432 return NULL;
1433 }
1434 Py_INCREF(Py_None);
1435 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001436}
1437
Barry Warsawfa701a81997-01-16 00:15:11 +00001438
1439
Guido van Rossum00d93061998-05-28 23:06:38 +00001440#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001441/** File Handler **/
1442
Guido van Rossum00d93061998-05-28 23:06:38 +00001443typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001444 PyObject *func;
1445 PyObject *file;
1446 int id;
1447 struct _fhcdata *next;
1448} FileHandler_ClientData;
1449
1450static FileHandler_ClientData *HeadFHCD;
1451
1452static FileHandler_ClientData *
1453NewFHCD(func, file, id)
1454 PyObject *func;
1455 PyObject *file;
1456 int id;
1457{
1458 FileHandler_ClientData *p;
1459 p = PyMem_NEW(FileHandler_ClientData, 1);
1460 if (p != NULL) {
1461 Py_XINCREF(func);
1462 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001463 p->func = func;
1464 p->file = file;
1465 p->id = id;
1466 p->next = HeadFHCD;
1467 HeadFHCD = p;
1468 }
1469 return p;
1470}
1471
1472static void
1473DeleteFHCD(id)
1474 int id;
1475{
1476 FileHandler_ClientData *p, **pp;
1477
1478 pp = &HeadFHCD;
1479 while ((p = *pp) != NULL) {
1480 if (p->id == id) {
1481 *pp = p->next;
1482 Py_XDECREF(p->func);
1483 Py_XDECREF(p->file);
1484 PyMem_DEL(p);
1485 }
1486 else
1487 pp = &p->next;
1488 }
1489}
1490
Guido van Rossuma597dde1995-01-10 20:56:29 +00001491static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001492FileHandler(clientData, mask)
Guido van Rossum00d93061998-05-28 23:06:38 +00001493 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001494 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +00001495{
Guido van Rossum00d93061998-05-28 23:06:38 +00001496 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001497 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001498
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001499 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001500 func = data->func;
1501 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001502
Barry Warsawfa701a81997-01-16 00:15:11 +00001503 arg = Py_BuildValue("(Oi)", file, (long) mask);
1504 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001505 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001506
1507 if (res == NULL) {
1508 errorInCmd = 1;
1509 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1510 }
1511 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001512 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001513}
1514
1515static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001516GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +00001517 /* Either an int >= 0 or an object with a
1518 *.fileno() method that returns an int >= 0
1519 */
1520 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001521{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001522 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001523 int id;
1524 if (PyInt_Check(file)) {
1525 id = PyInt_AsLong(file);
1526 if (id < 0)
1527 PyErr_SetString(PyExc_ValueError, "invalid file id");
1528 return id;
1529 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001530 args = PyTuple_New(0);
1531 if (args == NULL)
1532 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001533
1534 meth = PyObject_GetAttrString(file, "fileno");
1535 if (meth == NULL) {
1536 Py_DECREF(args);
1537 return -1;
1538 }
1539
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001540 res = PyEval_CallObject(meth, args);
1541 Py_DECREF(args);
1542 Py_DECREF(meth);
1543 if (res == NULL)
1544 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001545
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001546 if (PyInt_Check(res))
1547 id = PyInt_AsLong(res);
1548 else
1549 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001550
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001551 if (id < 0)
1552 PyErr_SetString(PyExc_ValueError,
1553 "invalid fileno() return value");
1554 Py_DECREF(res);
1555 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001556}
1557
1558static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001559Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001560 PyObject *self;
1561 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001562{
Guido van Rossum00d93061998-05-28 23:06:38 +00001563 FileHandler_ClientData *data;
1564 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001565 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001566
Guido van Rossum43713e52000-02-29 13:59:29 +00001567 if (!PyArg_ParseTuple(args, "OiO:createfilehandler", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001568 return NULL;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001569 tfile = GetFileNo(file);
1570 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001571 return NULL;
1572 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001573 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001574 return NULL;
1575 }
1576
Guido van Rossuma80649b2000-03-28 20:07:05 +00001577 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001578 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001579 return NULL;
1580
Barry Warsawfa701a81997-01-16 00:15:11 +00001581 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001582 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001583 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001584 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001585 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001586 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001587}
1588
1589static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001590Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001591 PyObject *self;
1592 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001593{
Barry Warsawfa701a81997-01-16 00:15:11 +00001594 PyObject *file;
Guido van Rossum00d93061998-05-28 23:06:38 +00001595 FileHandler_ClientData *data;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001596 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001597
Guido van Rossum43713e52000-02-29 13:59:29 +00001598 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001599 return NULL;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001600 tfile = GetFileNo(file);
1601 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001602 return NULL;
1603
Guido van Rossuma80649b2000-03-28 20:07:05 +00001604 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001605
Barry Warsawfa701a81997-01-16 00:15:11 +00001606 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001607 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001608 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001609 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001610 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001611 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001612}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001613#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001614
Barry Warsawfa701a81997-01-16 00:15:11 +00001615
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001616/**** Tktt Object (timer token) ****/
1617
1618staticforward PyTypeObject Tktt_Type;
1619
Guido van Rossum00d93061998-05-28 23:06:38 +00001620typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001621 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001622 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001623 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001624} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001625
1626static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001627Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001628 PyObject *self;
1629 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001630{
Barry Warsawfa701a81997-01-16 00:15:11 +00001631 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001632 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001633
Guido van Rossum43713e52000-02-29 13:59:29 +00001634 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001635 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001636 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001637 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001638 v->token = NULL;
1639 }
1640 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001641 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001642 Py_DECREF(func);
1643 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001644 }
1645 Py_INCREF(Py_None);
1646 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001647}
1648
1649static PyMethodDef Tktt_methods[] =
1650{
Guido van Rossum35d43371997-08-02 00:09:09 +00001651 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001652 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001653};
1654
1655static TkttObject *
Guido van Rossum00d93061998-05-28 23:06:38 +00001656Tktt_New(func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001657 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001658{
Barry Warsawfa701a81997-01-16 00:15:11 +00001659 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001660
Guido van Rossumb18618d2000-05-03 23:44:39 +00001661 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00001662 if (v == NULL)
1663 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001664
Guido van Rossum00d93061998-05-28 23:06:38 +00001665 Py_INCREF(func);
1666 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001667 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001668
1669 /* Extra reference, deleted when called or when handler is deleted */
1670 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001671 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001672}
1673
1674static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001675Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001676 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001677{
Guido van Rossum00d93061998-05-28 23:06:38 +00001678 TkttObject *v = (TkttObject *)self;
1679 PyObject *func = v->func;
1680
1681 Py_XDECREF(func);
1682
Guido van Rossumb18618d2000-05-03 23:44:39 +00001683 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001684}
1685
Guido van Rossum597ac201998-05-12 14:36:19 +00001686static PyObject *
1687Tktt_Repr(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001688 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001689{
Barry Warsawfa701a81997-01-16 00:15:11 +00001690 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001691 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001692
Fred Drakea44d3532000-06-30 15:01:00 +00001693 sprintf(buf, "<tktimertoken at %p%s>", v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001694 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001695 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001696}
1697
1698static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001699Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001700 PyObject *self;
1701 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001702{
Barry Warsawfa701a81997-01-16 00:15:11 +00001703 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001704}
1705
1706static PyTypeObject Tktt_Type =
1707{
Guido van Rossum35d43371997-08-02 00:09:09 +00001708 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001709 0, /*ob_size */
1710 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001711 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001712 0, /*tp_itemsize */
1713 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001714 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001715 Tktt_GetAttr, /*tp_getattr */
1716 0, /*tp_setattr */
1717 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001718 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001719 0, /*tp_as_number */
1720 0, /*tp_as_sequence */
1721 0, /*tp_as_mapping */
1722 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001723};
1724
Barry Warsawfa701a81997-01-16 00:15:11 +00001725
1726
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001727/** Timer Handler **/
1728
1729static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001730TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001731 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001732{
Guido van Rossum00d93061998-05-28 23:06:38 +00001733 TkttObject *v = (TkttObject *)clientData;
1734 PyObject *func = v->func;
1735 PyObject *res;
1736
1737 if (func == NULL)
1738 return;
1739
1740 v->func = NULL;
1741
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001742 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001743
1744 res = PyEval_CallObject(func, NULL);
1745 Py_DECREF(func);
1746 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001747
Barry Warsawfa701a81997-01-16 00:15:11 +00001748 if (res == NULL) {
1749 errorInCmd = 1;
1750 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1751 }
1752 else
1753 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001754
1755 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001756}
1757
1758static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001759Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001760 PyObject *self;
1761 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001762{
Barry Warsawfa701a81997-01-16 00:15:11 +00001763 int milliseconds;
1764 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001765 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001766
Guido van Rossum43713e52000-02-29 13:59:29 +00001767 if (!PyArg_ParseTuple(args, "iO:createtimerhandler", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001768 return NULL;
1769 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001770 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001771 return NULL;
1772 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001773 v = Tktt_New(func);
1774 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1775 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001776
Guido van Rossum00d93061998-05-28 23:06:38 +00001777 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001778}
1779
Barry Warsawfa701a81997-01-16 00:15:11 +00001780
Guido van Rossum18468821994-06-20 07:49:28 +00001781/** Event Loop **/
1782
Guido van Rossum18468821994-06-20 07:49:28 +00001783static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001784Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001785 PyObject *self;
1786 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001787{
Barry Warsawfa701a81997-01-16 00:15:11 +00001788 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001789#ifdef WITH_THREAD
1790 PyThreadState *tstate = PyThreadState_Get();
1791#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001792
Guido van Rossum43713e52000-02-29 13:59:29 +00001793 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001794 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001795
Barry Warsawfa701a81997-01-16 00:15:11 +00001796 quitMainLoop = 0;
1797 while (Tk_GetNumMainWindows() > threshold &&
1798 !quitMainLoop &&
1799 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001800 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001801 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001802
1803#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001804 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001805 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001806 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001807 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001808 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001809 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001810 if (result == 0)
1811 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001812 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001813#else
1814 result = Tcl_DoOneEvent(0);
1815#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001816
Guido van Rossum35d43371997-08-02 00:09:09 +00001817 if (PyErr_CheckSignals() != 0)
1818 return NULL;
1819 if (result < 0)
1820 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001821 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001822 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001823
Barry Warsawfa701a81997-01-16 00:15:11 +00001824 if (errorInCmd) {
1825 errorInCmd = 0;
1826 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1827 excInCmd = valInCmd = trbInCmd = NULL;
1828 return NULL;
1829 }
1830 Py_INCREF(Py_None);
1831 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001832}
1833
1834static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001835Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001836 PyObject *self;
1837 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001838{
Guido van Rossum35d43371997-08-02 00:09:09 +00001839 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001840 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001841
Guido van Rossum43713e52000-02-29 13:59:29 +00001842 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001843 return NULL;
1844
Guido van Rossum00d93061998-05-28 23:06:38 +00001845 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001846 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001847 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001848 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001849}
1850
1851static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001852Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001853 PyObject *self;
1854 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001855{
1856
Guido van Rossum43713e52000-02-29 13:59:29 +00001857 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001858 return NULL;
1859
1860 quitMainLoop = 1;
1861 Py_INCREF(Py_None);
1862 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001863}
1864
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001865static PyObject *
1866Tkapp_InterpAddr(self, args)
1867 PyObject *self;
1868 PyObject *args;
1869{
1870
Guido van Rossum43713e52000-02-29 13:59:29 +00001871 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001872 return NULL;
1873
1874 return PyInt_FromLong((long)Tkapp_Interp(self));
1875}
1876
Barry Warsawfa701a81997-01-16 00:15:11 +00001877
1878
Guido van Rossum18468821994-06-20 07:49:28 +00001879/**** Tkapp Method List ****/
1880
1881static PyMethodDef Tkapp_methods[] =
1882{
Guido van Rossum35d43371997-08-02 00:09:09 +00001883 {"call", Tkapp_Call, 0},
1884 {"globalcall", Tkapp_GlobalCall, 0},
1885 {"eval", Tkapp_Eval, 1},
1886 {"globaleval", Tkapp_GlobalEval, 1},
1887 {"evalfile", Tkapp_EvalFile, 1},
1888 {"record", Tkapp_Record, 1},
1889 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1890 {"setvar", Tkapp_SetVar, 1},
1891 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1892 {"getvar", Tkapp_GetVar, 1},
1893 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1894 {"unsetvar", Tkapp_UnsetVar, 1},
1895 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1896 {"getint", Tkapp_GetInt, 1},
1897 {"getdouble", Tkapp_GetDouble, 1},
1898 {"getboolean", Tkapp_GetBoolean, 1},
1899 {"exprstring", Tkapp_ExprString, 1},
1900 {"exprlong", Tkapp_ExprLong, 1},
1901 {"exprdouble", Tkapp_ExprDouble, 1},
1902 {"exprboolean", Tkapp_ExprBoolean, 1},
1903 {"splitlist", Tkapp_SplitList, 1},
1904 {"split", Tkapp_Split, 1},
1905 {"merge", Tkapp_Merge, 0},
1906 {"createcommand", Tkapp_CreateCommand, 1},
1907 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001908#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001909 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1910 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001911#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001912 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001913 {"mainloop", Tkapp_MainLoop, 1},
1914 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001915 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001916 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001917 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001918};
1919
Barry Warsawfa701a81997-01-16 00:15:11 +00001920
1921
Guido van Rossum18468821994-06-20 07:49:28 +00001922/**** Tkapp Type Methods ****/
1923
1924static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001925Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001926 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001927{
Guido van Rossum00d93061998-05-28 23:06:38 +00001928 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001929 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001930 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00001931 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001932 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001933}
1934
1935static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001936Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001937 PyObject *self;
1938 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001939{
Guido van Rossum35d43371997-08-02 00:09:09 +00001940 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001941}
1942
1943static PyTypeObject Tkapp_Type =
1944{
Guido van Rossum35d43371997-08-02 00:09:09 +00001945 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001946 0, /*ob_size */
1947 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001948 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001949 0, /*tp_itemsize */
1950 Tkapp_Dealloc, /*tp_dealloc */
1951 0, /*tp_print */
1952 Tkapp_GetAttr, /*tp_getattr */
1953 0, /*tp_setattr */
1954 0, /*tp_compare */
1955 0, /*tp_repr */
1956 0, /*tp_as_number */
1957 0, /*tp_as_sequence */
1958 0, /*tp_as_mapping */
1959 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001960};
1961
Barry Warsawfa701a81997-01-16 00:15:11 +00001962
1963
Guido van Rossum18468821994-06-20 07:49:28 +00001964/**** Tkinter Module ****/
1965
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001966typedef struct {
1967 PyObject* tuple;
1968 int size; /* current size */
1969 int maxsize; /* allocated size */
1970} FlattenContext;
1971
1972static int
1973_bump(FlattenContext* context, int size)
1974{
1975 /* expand tuple to hold (at least) size new items. return true if
1976 successful, false if an exception was raised*/
1977
1978 int maxsize = context->maxsize * 2;
1979
1980 if (maxsize < context->size + size)
1981 maxsize = context->size + size;
1982
1983 context->maxsize = maxsize;
1984
1985 return _PyTuple_Resize(&context->tuple, maxsize, 0) >= 0;
1986}
1987
1988static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001989_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001990{
1991 /* add tuple or list to argument tuple (recursively) */
1992
1993 int i, size;
1994
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001995 if (depth > 1000) {
1996 PyErr_SetString(PyExc_ValueError,"nesting too deep in _flatten");
1997 return 0;
1998 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001999 size = PyList_GET_SIZE(item);
2000 /* preallocate (assume no nesting) */
2001 if (context->size + size > context->maxsize && !_bump(context, size))
2002 return 0;
2003 /* copy items to output tuple */
2004 for (i = 0; i < size; i++) {
2005 PyObject *o = PyList_GET_ITEM(item, i);
2006 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002007 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002008 return 0;
2009 } else if (o != Py_None) {
2010 if (context->size + 1 > context->maxsize && !_bump(context, 1))
2011 return 0;
2012 Py_INCREF(o);
2013 PyTuple_SET_ITEM(context->tuple, context->size++, o);
2014 }
2015 }
2016 } else if (PyTuple_Check(item)) {
2017 /* same, for tuples */
2018 size = PyTuple_GET_SIZE(item);
2019 if (context->size + size > context->maxsize && !_bump(context, size))
2020 return 0;
2021 for (i = 0; i < size; i++) {
2022 PyObject *o = PyTuple_GET_ITEM(item, i);
2023 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002024 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002025 return 0;
2026 } else if (o != Py_None) {
2027 if (context->size + 1 > context->maxsize && !_bump(context, 1))
2028 return 0;
2029 Py_INCREF(o);
2030 PyTuple_SET_ITEM(context->tuple, context->size++, o);
2031 }
2032 }
2033 } else {
2034 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2035 return 0;
2036 }
2037 return 1;
2038}
2039
2040static PyObject *
2041Tkinter_Flatten(PyObject* self, PyObject* args)
2042{
2043 FlattenContext context;
2044 PyObject* item;
2045
2046 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2047 return NULL;
2048
2049 context.maxsize = PySequence_Length(item);
2050 if (context.maxsize <= 0)
2051 return PyTuple_New(0);
2052
2053 context.tuple = PyTuple_New(context.maxsize);
2054 if (!context.tuple)
2055 return NULL;
2056
2057 context.size = 0;
2058
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002059 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002060 return NULL;
2061
2062 if (_PyTuple_Resize(&context.tuple, context.size, 0))
2063 return NULL;
2064
2065 return context.tuple;
2066}
2067
Guido van Rossum18468821994-06-20 07:49:28 +00002068static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00002069Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00002070 PyObject *self;
2071 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00002072{
Barry Warsawfa701a81997-01-16 00:15:11 +00002073 char *screenName = NULL;
2074 char *baseName = NULL;
2075 char *className = NULL;
2076 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002077
Guido van Rossum35d43371997-08-02 00:09:09 +00002078 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00002079 if (baseName != NULL)
2080 baseName++;
2081 else
2082 baseName = Py_GetProgramName();
2083 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00002084
Guido van Rossum43713e52000-02-29 13:59:29 +00002085 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002086 &screenName, &baseName, &className,
2087 &interactive))
2088 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002089
Barry Warsawfa701a81997-01-16 00:15:11 +00002090 return (PyObject *) Tkapp_New(screenName, baseName, className,
2091 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00002092}
2093
2094static PyMethodDef moduleMethods[] =
2095{
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002096 {"_flatten", Tkinter_Flatten, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00002097 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002098#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00002099 {"createfilehandler", Tkapp_CreateFileHandler, 1},
2100 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00002101#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00002102 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00002103 {"mainloop", Tkapp_MainLoop, 1},
2104 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00002105 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00002106 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002107};
2108
Guido van Rossum7bf15641998-05-22 18:28:17 +00002109#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002110
2111static int stdin_ready = 0;
2112
Guido van Rossumad4db171998-06-13 13:56:28 +00002113#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00002114static void
2115MyFileProc(clientData, mask)
2116 void *clientData;
2117 int mask;
2118{
2119 stdin_ready = 1;
2120}
Guido van Rossumad4db171998-06-13 13:56:28 +00002121#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002122
Guido van Rossum00d93061998-05-28 23:06:38 +00002123static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002124
Guido van Rossum18468821994-06-20 07:49:28 +00002125static int
Guido van Rossum35d43371997-08-02 00:09:09 +00002126EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00002127{
Guido van Rossumad4db171998-06-13 13:56:28 +00002128#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002129 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002130#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002131#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002132 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002133#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002134 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002135 errorInCmd = 0;
2136#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002137 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002138 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002139#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002140 while (!errorInCmd && !stdin_ready) {
2141 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002142#ifdef MS_WINDOWS
2143 if (_kbhit()) {
2144 stdin_ready = 1;
2145 break;
2146 }
2147#endif
2148#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002149 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00002150 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002151 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002152
Guido van Rossum00d93061998-05-28 23:06:38 +00002153 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002154
2155 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00002156 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002157 if (result == 0)
2158 Sleep(20);
2159 Py_END_ALLOW_THREADS
2160#else
2161 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002162#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002163
2164 if (result < 0)
2165 break;
2166 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002167#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002168 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002169#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002170 if (errorInCmd) {
2171 errorInCmd = 0;
2172 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2173 excInCmd = valInCmd = trbInCmd = NULL;
2174 PyErr_Print();
2175 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002176#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002177 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002178#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002179 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002180}
Guido van Rossum18468821994-06-20 07:49:28 +00002181
Guido van Rossum00d93061998-05-28 23:06:38 +00002182#endif
2183
Guido van Rossum7bf15641998-05-22 18:28:17 +00002184static void
2185EnableEventHook()
2186{
Guido van Rossum00d93061998-05-28 23:06:38 +00002187#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002188 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002189#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002190 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002191#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002192 PyOS_InputHook = EventHook;
2193 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002194#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002195}
2196
2197static void
2198DisableEventHook()
2199{
Guido van Rossum00d93061998-05-28 23:06:38 +00002200#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002201 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2202 PyOS_InputHook = NULL;
2203 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002204#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002205}
2206
Barry Warsawfa701a81997-01-16 00:15:11 +00002207
2208/* all errors will be checked in one fell swoop in init_tkinter() */
2209static void
2210ins_long(d, name, val)
2211 PyObject *d;
2212 char *name;
2213 long val;
2214{
2215 PyObject *v = PyInt_FromLong(val);
2216 if (v) {
2217 PyDict_SetItemString(d, name, v);
2218 Py_DECREF(v);
2219 }
2220}
2221static void
2222ins_string(d, name, val)
2223 PyObject *d;
2224 char *name;
2225 char *val;
2226{
2227 PyObject *v = PyString_FromString(val);
2228 if (v) {
2229 PyDict_SetItemString(d, name, v);
2230 Py_DECREF(v);
2231 }
2232}
2233
2234
Guido van Rossum3886bb61998-12-04 18:50:17 +00002235DL_EXPORT(void)
Guido van Rossum35d43371997-08-02 00:09:09 +00002236init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00002237{
Barry Warsawfa701a81997-01-16 00:15:11 +00002238 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002239
Barry Warsawfa701a81997-01-16 00:15:11 +00002240 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002241
2242#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002243 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002244#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002245
Barry Warsawfa701a81997-01-16 00:15:11 +00002246 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002247
Barry Warsawfa701a81997-01-16 00:15:11 +00002248 d = PyModule_GetDict(m);
2249 Tkinter_TclError = Py_BuildValue("s", "TclError");
2250 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002251
Guido van Rossum35d43371997-08-02 00:09:09 +00002252 ins_long(d, "READABLE", TCL_READABLE);
2253 ins_long(d, "WRITABLE", TCL_WRITABLE);
2254 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2255 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2256 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2257 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2258 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2259 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2260 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002261 ins_string(d, "TK_VERSION", TK_VERSION);
2262 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002263
Guido van Rossum83551bf1997-09-13 00:44:23 +00002264 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002265
2266 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002267 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2268
Guido van Rossume187b0e2000-03-27 21:46:29 +00002269 /* This helps the dynamic loader; in Unicode aware Tcl versions
2270 it also helps Tcl find its encodings. */
2271 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002272
Barry Warsawfa701a81997-01-16 00:15:11 +00002273 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002274 return;
2275
Guido van Rossum43ff8681998-07-14 18:02:13 +00002276#if 0
2277 /* This was not a good idea; through <Destroy> bindings,
2278 Tcl_Finalize() may invoke Python code but at that point the
2279 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002280 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002281#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002282
Jack Jansen34cc5c31995-10-31 16:15:12 +00002283#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002284 /*
2285 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2286 ** Most of the initializations in that routine (toolbox init calls and
2287 ** such) have already been done for us, so we only need these.
2288 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002289 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002290
2291 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002292#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002293 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002294#endif /* GENERATINGCFM */
2295#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002296}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002297
Guido van Rossumec22c921996-02-25 04:50:29 +00002298
Barry Warsawfa701a81997-01-16 00:15:11 +00002299
Guido van Rossum9722ad81995-09-22 23:49:28 +00002300#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002301
2302/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002303** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002304*/
2305
Guido van Rossum9722ad81995-09-22 23:49:28 +00002306void
2307panic(char * format, ...)
2308{
Barry Warsawfa701a81997-01-16 00:15:11 +00002309 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002310
Barry Warsawfa701a81997-01-16 00:15:11 +00002311 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002312
Guido van Rossum227cf761998-08-05 13:53:32 +00002313 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002314 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002315
Barry Warsawfa701a81997-01-16 00:15:11 +00002316 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002317
Barry Warsawfa701a81997-01-16 00:15:11 +00002318 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002319}
Jack Jansen40b546d1995-11-14 10:34:45 +00002320
Guido van Rossumec22c921996-02-25 04:50:29 +00002321/*
2322** Pass events to SIOUX before passing them to Tk.
2323*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002324
Guido van Rossumec22c921996-02-25 04:50:29 +00002325static int
2326PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00002327 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002328{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002329 WindowPtr frontwin;
2330 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002331 ** Sioux eats too many events, so we don't pass it everything. We
2332 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002333 ** the Sioux window is frontmost. This means that Tk menus don't work
2334 ** in that case, but at least we can scroll the sioux window.
2335 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2336 ** part of the external interface of Sioux...
2337 */
2338 frontwin = FrontWindow();
2339 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2340 if (SIOUXHandleOneEvent(eventPtr))
2341 return 0; /* Nothing happened to the Tcl event queue */
2342 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002343 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002344}
2345
Guido van Rossumec22c921996-02-25 04:50:29 +00002346#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002347
2348/*
2349** Additional Mac specific code for dealing with shared libraries.
2350*/
2351
2352#include <Resources.h>
2353#include <CodeFragments.h>
2354
2355static int loaded_from_shlib = 0;
2356static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002357
Jack Jansen34cc5c31995-10-31 16:15:12 +00002358/*
2359** If this module is dynamically loaded the following routine should
2360** be the init routine. It takes care of adding the shared library to
2361** the resource-file chain, so that the tk routines can find their
2362** resources.
2363*/
2364OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002365init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002366{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002367 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002368 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002369 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002370 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2371 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002372 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002373 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2374 loaded_from_shlib = 1;
2375 }
2376 return noErr;
2377}
2378
2379/*
2380** Insert the library resources into the search path. Put them after
2381** the resources from the application. Again, we ignore errors.
2382*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002383static
Jack Jansen34cc5c31995-10-31 16:15:12 +00002384mac_addlibresources()
2385{
2386 if ( !loaded_from_shlib )
2387 return;
2388 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2389}
2390
Guido van Rossumec22c921996-02-25 04:50:29 +00002391#endif /* GENERATINGCFM */
2392#endif /* macintosh */