blob: c623cbc6715cdfd15ab2fb9e0cab67ca2fea58c9 [file] [log] [blame]
Guido van Rossum845547d1996-06-26 18:26:04 +00001/***********************************************************
2Copyright (C) 1994 Steen Lumholt.
Guido van Rossum845547d1996-06-26 18:26:04 +00003
4 All Rights Reserved
5
Guido van Rossum845547d1996-06-26 18:26:04 +00006******************************************************************/
7
8/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +00009
Guido van Rossum7ffa7611996-08-13 21:10:16 +000010/* TCL/TK VERSION INFO:
11
Guido van Rossuma80649b2000-03-28 20:07:05 +000012 Only Tcl/Tk 8.0 and later are supported. Older versions are not
13 supported. (Use Python 1.5.2 if you cannot upgrade your Tcl/Tk
14 libraries.)
15*/
Guido van Rossum7ffa7611996-08-13 21:10:16 +000016
Guido van Rossuma80649b2000-03-28 20:07:05 +000017/* XXX Further speed-up ideas, involving Tcl 8.0 features:
Guido van Rossum212643f1998-04-29 16:22:14 +000018
19 - In Tcl_Call(), create Tcl objects from the arguments, possibly using
20 intelligent mappings between Python objects and Tcl objects (e.g. ints,
21 floats and Tcl window pointers could be handled specially).
22
23 - Register a new Tcl type, "Python callable", which can be called more
24 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
25
Guido van Rossum7ffa7611996-08-13 21:10:16 +000026*/
27
Guido van Rossum35d43371997-08-02 00:09:09 +000028
Guido van Rossum9722ad81995-09-22 23:49:28 +000029#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000030#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000031
Guido van Rossum00d93061998-05-28 23:06:38 +000032#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000033#include "pythread.h"
Guido van Rossum00d93061998-05-28 23:06:38 +000034#endif
35
Guido van Rossum2a5119b1998-05-29 01:28:40 +000036#ifdef MS_WINDOWS
37#include <windows.h>
38#endif
39
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000040#ifdef macintosh
41#define MAC_TCL
Guido van Rossum49b56061998-10-01 20:42:43 +000042#endif
43
Martin v. Löwis71e25a02002-10-01 18:08:06 +000044/* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately,
45 making _tkinter correct for this API means to break earlier
46 versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
47 earlier versions. Once Tcl releases before 8.4 don't need to be supported
48 anymore, this should go. */
49#define USE_COMPAT_CONST
50
Jack Jansencb852442001-12-09 23:15:56 +000051#ifdef TK_FRAMEWORK
52#include <Tcl/tcl.h>
53#include <Tk/tk.h>
54#else
Guido van Rossum18468821994-06-20 07:49:28 +000055#include <tcl.h>
56#include <tk.h>
Jack Jansencb852442001-12-09 23:15:56 +000057#endif
Guido van Rossum18468821994-06-20 07:49:28 +000058
Guido van Rossum3e819a71997-08-01 19:29:02 +000059#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
60
Martin v. Löwis6bfa2e62002-10-01 17:48:31 +000061#if TKMAJORMINOR < 8002
62#error "Tk older than 8.2 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000063#endif
64
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +000065/* Unicode conversion assumes that Tcl_UniChar is two bytes.
66 We cannot test this directly, so we test UTF-8 size instead,
67 expecting that TCL_UTF_MAX is changed if Tcl ever supports
68 either UTF-16 or UCS-4. */
69#if TCL_UTF_MAX != 3
70#error "unsupported Tcl configuration"
71#endif
72
Guido van Rossuma80649b2000-03-28 20:07:05 +000073#if defined(macintosh)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000074/* Sigh, we have to include this to get at the tcl qd pointer */
75#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000076/* And this one we need to clear the menu bar */
77#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000078#endif
79
Jack Jansen84c10b12001-07-16 19:32:52 +000080#if !(defined(MS_WINDOWS) || defined(__CYGWIN__) || defined(macintosh))
81/* Mac has it, but it doesn't really work:-( */
Guido van Rossum0d2390c1997-08-14 19:57:07 +000082#define HAVE_CREATEFILEHANDLER
83#endif
84
Guido van Rossum00d93061998-05-28 23:06:38 +000085#ifdef HAVE_CREATEFILEHANDLER
86
87/* Tcl_CreateFileHandler() changed several times; these macros deal with the
88 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
89 Unix, only because Jack added it back); when available on Windows, it only
90 applies to sockets. */
91
Guido van Rossum7bf15641998-05-22 18:28:17 +000092#ifdef MS_WINDOWS
93#define FHANDLETYPE TCL_WIN_SOCKET
94#else
95#define FHANDLETYPE TCL_UNIX_FD
96#endif
97
Guido van Rossum00d93061998-05-28 23:06:38 +000098/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
99 which uses this to handle Tcl events while the user is typing commands. */
100
101#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000102#define WAIT_FOR_STDIN
103#endif
104
Guido van Rossum00d93061998-05-28 23:06:38 +0000105#endif /* HAVE_CREATEFILEHANDLER */
106
Guido van Rossumad4db171998-06-13 13:56:28 +0000107#ifdef MS_WINDOWS
108#include <conio.h>
109#define WAIT_FOR_STDIN
110#endif
111
Guido van Rossum00d93061998-05-28 23:06:38 +0000112#ifdef WITH_THREAD
113
114/* The threading situation is complicated. Tcl is not thread-safe, except for
115 Tcl 8.1, which will probably remain in alpha status for another 6 months
116 (and the README says that Tk will probably remain thread-unsafe forever).
117 So we need to use a lock around all uses of Tcl. Previously, the Python
118 interpreter lock was used for this. However, this causes problems when
119 other Python threads need to run while Tcl is blocked waiting for events.
120
121 To solve this problem, a separate lock for Tcl is introduced. Holding it
122 is incompatible with holding Python's interpreter lock. The following four
123 macros manipulate both locks together.
124
125 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
126 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
127 that could call an event handler, or otherwise affect the state of a Tcl
128 interpreter. These assume that the surrounding code has the Python
129 interpreter lock; inside the brackets, the Python interpreter lock has been
130 released and the lock for Tcl has been acquired.
131
Guido van Rossum5e977831998-06-15 14:03:52 +0000132 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
133 (For example, when transferring data from the Tcl interpreter result to a
134 Python string object.) This can be done by using different macros to close
135 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
136 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
137 releases the Tcl lock.
138
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000139 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000140 handlers when the handler needs to use Python. Such event handlers are
141 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000142 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000143 the Python interpreter lock, restoring the appropriate thread state, and
144 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
145 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000146 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000147
148 These locks expand to several statements and brackets; they should not be
149 used in branches of if statements and the like.
150
151*/
152
Guido van Rossum65d5b571998-12-21 19:32:43 +0000153static PyThread_type_lock tcl_lock = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000154static PyThreadState *tcl_tstate = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000155
156#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000157 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000158 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000159
160#define LEAVE_TCL \
Guido van Rossum2834b972000-10-06 16:58:26 +0000161 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000162
Guido van Rossum62320c91998-06-15 04:36:09 +0000163#define ENTER_OVERLAP \
164 Py_END_ALLOW_THREADS
165
166#define LEAVE_OVERLAP_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000167 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000168
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000169#define ENTER_PYTHON \
170 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000171 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000172
173#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000174 { PyThreadState *tstate = PyEval_SaveThread(); \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000175 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Guido van Rossum00d93061998-05-28 23:06:38 +0000176
177#else
178
179#define ENTER_TCL
180#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000181#define ENTER_OVERLAP
182#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000183#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000184#define LEAVE_PYTHON
185
186#endif
187
Guido van Rossumec22c921996-02-25 04:50:29 +0000188#ifdef macintosh
189
190/*
191** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000192** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000193*/
194
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000195/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000196#define FREECAST (char *)
197
Guido van Rossumec22c921996-02-25 04:50:29 +0000198#include <Events.h> /* For EventRecord */
199
Fred Drake509d79a2000-07-08 04:04:38 +0000200typedef int (*TclMacConvertEventPtr) (EventRecord *eventPtr);
Guido van Rossum2834b972000-10-06 16:58:26 +0000201void Tcl_MacSetEventProc(TclMacConvertEventPtr procPtr);
202int TkMacConvertEvent(EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000203
Jeremy Hylton938ace62002-07-17 16:30:39 +0000204static int PyMacConvertEvent(EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000205
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000206#include <SIOUX.h>
207extern int SIOUXIsAppWindow(WindowPtr);
208
Guido van Rossumec22c921996-02-25 04:50:29 +0000209#endif /* macintosh */
210
Guido van Rossum97867b21996-08-08 19:09:53 +0000211#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000212#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000213#endif
214
Guido van Rossum18468821994-06-20 07:49:28 +0000215/**** Tkapp Object Declaration ****/
216
Jeremy Hylton938ace62002-07-17 16:30:39 +0000217static PyTypeObject Tkapp_Type;
Guido van Rossum18468821994-06-20 07:49:28 +0000218
Guido van Rossum00d93061998-05-28 23:06:38 +0000219typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000220 PyObject_HEAD
221 Tcl_Interp *interp;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000222 int wantobjects;
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000223 /* We cannot include tclInt.h, as this is internal.
224 So we cache interesting types here. */
225 Tcl_ObjType *BooleanType;
226 Tcl_ObjType *ByteArrayType;
227 Tcl_ObjType *DoubleType;
228 Tcl_ObjType *IntType;
229 Tcl_ObjType *ListType;
230 Tcl_ObjType *ProcBodyType;
231 Tcl_ObjType *StringType;
Guido van Rossum00d93061998-05-28 23:06:38 +0000232} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000233
234#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000235#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000236#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000237
Guido van Rossum35d43371997-08-02 00:09:09 +0000238#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000239(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000240
Barry Warsawfa701a81997-01-16 00:15:11 +0000241
242
Guido van Rossum18468821994-06-20 07:49:28 +0000243/**** Error Handling ****/
244
245static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000246static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000247static int errorInCmd = 0;
248static PyObject *excInCmd;
249static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000250static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000251
Barry Warsawfa701a81997-01-16 00:15:11 +0000252
253
Guido van Rossum18468821994-06-20 07:49:28 +0000254static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000255Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000256{
Barry Warsawfa701a81997-01-16 00:15:11 +0000257 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
258 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000259}
260
Barry Warsawfa701a81997-01-16 00:15:11 +0000261
Barry Warsawfa701a81997-01-16 00:15:11 +0000262
Guido van Rossum18468821994-06-20 07:49:28 +0000263/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000264
265#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000266#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000267
Guido van Rossum00d93061998-05-28 23:06:38 +0000268/* Millisecond sleep() for Unix platforms. */
269
270static void
Fred Drake509d79a2000-07-08 04:04:38 +0000271Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000272{
273 /* XXX Too bad if you don't have select(). */
274 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000275 t.tv_sec = milli/1000;
276 t.tv_usec = (milli%1000) * 1000;
277 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
278}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000279#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000280#endif /* WITH_THREAD */
281
282
Guido van Rossum18468821994-06-20 07:49:28 +0000283static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000284AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000285{
Guido van Rossum35d43371997-08-02 00:09:09 +0000286 if (PyString_Check(value))
287 return PyString_AsString(value);
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000288#ifdef Py_USING_UNICODE
Guido van Rossum2834b972000-10-06 16:58:26 +0000289 else if (PyUnicode_Check(value)) {
290 PyObject *v = PyUnicode_AsUTF8String(value);
291 if (v == NULL)
292 return NULL;
293 if (PyList_Append(tmp, v) != 0) {
294 Py_DECREF(v);
295 return NULL;
296 }
297 Py_DECREF(v);
298 return PyString_AsString(v);
299 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000300#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000301 else {
302 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000303 if (v == NULL)
304 return NULL;
305 if (PyList_Append(tmp, v) != 0) {
306 Py_DECREF(v);
307 return NULL;
308 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000309 Py_DECREF(v);
310 return PyString_AsString(v);
311 }
Guido van Rossum18468821994-06-20 07:49:28 +0000312}
313
Barry Warsawfa701a81997-01-16 00:15:11 +0000314
315
Guido van Rossum18468821994-06-20 07:49:28 +0000316#define ARGSZ 64
317
318static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000319Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000320{
Barry Warsawfa701a81997-01-16 00:15:11 +0000321 PyObject *tmp = NULL;
322 char *argvStore[ARGSZ];
323 char **argv = NULL;
324 int fvStore[ARGSZ];
325 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000326 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000327 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000328
Barry Warsawfa701a81997-01-16 00:15:11 +0000329 if (!(tmp = PyList_New(0)))
330 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000331
Barry Warsawfa701a81997-01-16 00:15:11 +0000332 argv = argvStore;
333 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000334
Barry Warsawfa701a81997-01-16 00:15:11 +0000335 if (args == NULL)
336 argc = 0;
337
338 else if (!PyTuple_Check(args)) {
339 argc = 1;
340 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000341 if (!(argv[0] = AsString(args, tmp)))
342 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000343 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000344 else {
345 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000346
Barry Warsawfa701a81997-01-16 00:15:11 +0000347 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000348 argv = (char **)ckalloc(argc * sizeof(char *));
349 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000350 if (argv == NULL || fv == NULL) {
351 PyErr_NoMemory();
352 goto finally;
353 }
354 }
355
356 for (i = 0; i < argc; i++) {
357 PyObject *v = PyTuple_GetItem(args, i);
358 if (PyTuple_Check(v)) {
359 fv[i] = 1;
360 if (!(argv[i] = Merge(v)))
361 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000362 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000363 }
364 else if (v == Py_None) {
365 argc = i;
366 break;
367 }
368 else {
369 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000370 if (!(argv[i] = AsString(v, tmp)))
371 goto finally;
372 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000373 }
374 }
Guido van Rossum18468821994-06-20 07:49:28 +0000375 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000376 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000377 if (res == NULL)
378 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000379
Barry Warsawfa701a81997-01-16 00:15:11 +0000380 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000381 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000382 if (fv[i]) {
383 ckfree(argv[i]);
384 }
385 if (argv != argvStore)
386 ckfree(FREECAST argv);
387 if (fv != fvStore)
388 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000389
Barry Warsawfa701a81997-01-16 00:15:11 +0000390 Py_DECREF(tmp);
391 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000392}
393
Barry Warsawfa701a81997-01-16 00:15:11 +0000394
395
Guido van Rossum18468821994-06-20 07:49:28 +0000396static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000397Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000398{
Barry Warsawfa701a81997-01-16 00:15:11 +0000399 int argc;
400 char **argv;
401 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000402
Barry Warsawfa701a81997-01-16 00:15:11 +0000403 if (list == NULL) {
404 Py_INCREF(Py_None);
405 return Py_None;
406 }
Guido van Rossum18468821994-06-20 07:49:28 +0000407
Guido van Rossum00d93061998-05-28 23:06:38 +0000408 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000409 /* Not a list.
410 * Could be a quoted string containing funnies, e.g. {"}.
411 * Return the string itself.
412 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000413 return PyString_FromString(list);
414 }
Guido van Rossum18468821994-06-20 07:49:28 +0000415
Barry Warsawfa701a81997-01-16 00:15:11 +0000416 if (argc == 0)
417 v = PyString_FromString("");
418 else if (argc == 1)
419 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000420 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000421 int i;
422 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000423
Barry Warsawfa701a81997-01-16 00:15:11 +0000424 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000425 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000426 Py_DECREF(v);
427 v = NULL;
428 break;
429 }
430 PyTuple_SetItem(v, i, w);
431 }
432 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000433 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000434 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000435}
436
Martin v. Löwisffad6332002-11-26 09:28:05 +0000437/* In some cases, Tcl will still return strings that are supposed to be
438 lists. SplitObj walks through a nested tuple, finding string objects that
439 need to be split. */
440
441PyObject *
442SplitObj(PyObject *arg)
443{
444 if (PyTuple_Check(arg)) {
445 int i, size;
446 PyObject *elem, *newelem, *result;
447
448 size = PyTuple_Size(arg);
449 result = NULL;
450 /* Recursively invoke SplitObj for all tuple items.
451 If this does not return a new object, no action is
452 needed. */
453 for(i = 0; i < size; i++) {
454 elem = PyTuple_GetItem(arg, i);
455 newelem = SplitObj(elem);
456 if (!newelem) {
457 Py_XDECREF(result);
458 return NULL;
459 }
460 if (!result) {
461 int k;
462 if (newelem == elem) {
463 Py_DECREF(newelem);
464 continue;
465 }
466 result = PyTuple_New(size);
467 if (!result)
468 return NULL;
469 for(k = 0; k < i; k++) {
470 elem = PyTuple_GetItem(arg, k);
471 Py_INCREF(elem);
472 PyTuple_SetItem(result, k, elem);
473 }
474 }
475 PyTuple_SetItem(result, i, newelem);
476 }
477 if (result)
478 return result;
479 /* Fall through, returning arg. */
480 }
481 else if (PyString_Check(arg)) {
482 int argc;
483 char **argv;
484 char *list = PyString_AsString(arg);
485
486 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
487 Py_INCREF(arg);
488 return arg;
489 }
490 Tcl_Free(FREECAST argv);
491 if (argc > 1)
492 return Split(PyString_AsString(arg));
493 /* Fall through, returning arg. */
494 }
495 Py_INCREF(arg);
496 return arg;
497}
Barry Warsawfa701a81997-01-16 00:15:11 +0000498
499
Guido van Rossum18468821994-06-20 07:49:28 +0000500/**** Tkapp Object ****/
501
502#ifndef WITH_APPINIT
503int
Fred Drake509d79a2000-07-08 04:04:38 +0000504Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000505{
Barry Warsawfa701a81997-01-16 00:15:11 +0000506 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000507
Barry Warsawfa701a81997-01-16 00:15:11 +0000508 main = Tk_MainWindow(interp);
509 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000510 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000511 return TCL_ERROR;
512 }
513 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000514 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000515 return TCL_ERROR;
516 }
517 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000518}
519#endif /* !WITH_APPINIT */
520
Guido van Rossum18468821994-06-20 07:49:28 +0000521
Barry Warsawfa701a81997-01-16 00:15:11 +0000522
523
524/* Initialize the Tk application; see the `main' function in
525 * `tkMain.c'.
526 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000527
Thomas Wouters58d05102000-07-24 14:43:35 +0000528static void EnableEventHook(void); /* Forward */
529static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000530
Barry Warsawfa701a81997-01-16 00:15:11 +0000531static TkappObject *
Martin v. Löwisffad6332002-11-26 09:28:05 +0000532Tkapp_New(char *screenName, char *baseName, char *className,
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000533 int interactive, int wantobjects)
Barry Warsawfa701a81997-01-16 00:15:11 +0000534{
535 TkappObject *v;
536 char *argv0;
537
Guido van Rossumb18618d2000-05-03 23:44:39 +0000538 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000539 if (v == NULL)
540 return NULL;
541
542 v->interp = Tcl_CreateInterp();
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000543 v->wantobjects = wantobjects;
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000544
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000545 v->BooleanType = Tcl_GetObjType("boolean");
546 v->ByteArrayType = Tcl_GetObjType("bytearray");
547 v->DoubleType = Tcl_GetObjType("double");
548 v->IntType = Tcl_GetObjType("int");
549 v->ListType = Tcl_GetObjType("list");
550 v->ProcBodyType = Tcl_GetObjType("procbody");
551 v->StringType = Tcl_GetObjType("string");
552
Guido van Rossuma80649b2000-03-28 20:07:05 +0000553#if defined(macintosh)
554 /* This seems to be needed */
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000555 ClearMenuBar();
556 TkMacInitMenus(v->interp);
557#endif
Jack Jansencb852442001-12-09 23:15:56 +0000558
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000559 /* Delete the 'exit' command, which can screw things up */
560 Tcl_DeleteCommand(v->interp, "exit");
561
Barry Warsawfa701a81997-01-16 00:15:11 +0000562 if (screenName != NULL)
563 Tcl_SetVar2(v->interp, "env", "DISPLAY",
564 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000565
Barry Warsawfa701a81997-01-16 00:15:11 +0000566 if (interactive)
567 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
568 else
569 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000570
Barry Warsawfa701a81997-01-16 00:15:11 +0000571 /* This is used to get the application class for Tk 4.1 and up */
572 argv0 = (char*)ckalloc(strlen(className) + 1);
573 if (!argv0) {
574 PyErr_NoMemory();
575 Py_DECREF(v);
576 return NULL;
577 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000578
Barry Warsawfa701a81997-01-16 00:15:11 +0000579 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000580 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000581 argv0[0] = tolower(argv0[0]);
582 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
583 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000584
Barry Warsawfa701a81997-01-16 00:15:11 +0000585 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000586 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000587
Guido van Rossum7bf15641998-05-22 18:28:17 +0000588 EnableEventHook();
589
Barry Warsawfa701a81997-01-16 00:15:11 +0000590 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000591}
592
Barry Warsawfa701a81997-01-16 00:15:11 +0000593
594
Guido van Rossum18468821994-06-20 07:49:28 +0000595/** Tcl Eval **/
596
Martin v. Löwisffad6332002-11-26 09:28:05 +0000597typedef struct {
598 PyObject_HEAD
599 Tcl_Obj *value;
600} PyTclObject;
601
602staticforward PyTypeObject PyTclObject_Type;
603#define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type)
604
605static PyObject *
606newPyTclObject(Tcl_Obj *arg)
607{
608 PyTclObject *self;
609 self = PyObject_New(PyTclObject, &PyTclObject_Type);
610 if (self == NULL)
611 return NULL;
612 Tcl_IncrRefCount(arg);
613 self->value = arg;
614 return (PyObject*)self;
615}
616
617static void
618PyTclObject_dealloc(PyTclObject *self)
619{
620 Tcl_DecrRefCount(self->value);
621 PyObject_Del(self);
622}
623
624static PyObject *
625PyTclObject_str(PyTclObject *self)
626{
627 return PyString_FromString(Tcl_GetString(self->value));
628}
629
630static PyObject *
631PyTclObject_repr(PyTclObject *self)
632{
633 char buf[50];
634 PyOS_snprintf(buf, 50, "<%s object at 0x%.8x>",
635 self->value->typePtr->name, (int)self->value);
636 return PyString_FromString(buf);
637}
638
639static PyObject*
640get_typename(PyTclObject* obj, void* ignored)
641{
642 return PyString_FromString(obj->value->typePtr->name);
643}
644
645static PyGetSetDef PyTclObject_getsetlist[] = {
646 {"typename", (getter)get_typename, NULL, "name of the Tcl type"},
647 {0},
648};
649
650statichere PyTypeObject PyTclObject_Type = {
651 PyObject_HEAD_INIT(NULL)
652 0, /*ob_size*/
653 "_tkinter.Tcl_Obj", /*tp_name*/
654 sizeof(PyTclObject), /*tp_basicsize*/
655 0, /*tp_itemsize*/
656 /* methods */
657 (destructor)PyTclObject_dealloc, /*tp_dealloc*/
658 0, /*tp_print*/
659 0, /*tp_getattr*/
660 0, /*tp_setattr*/
661 0, /*tp_compare*/
662 (reprfunc)PyTclObject_repr, /*tp_repr*/
663 0, /*tp_as_number*/
664 0, /*tp_as_sequence*/
665 0, /*tp_as_mapping*/
666 0, /*tp_hash*/
667 0, /*tp_call*/
668 (reprfunc)PyTclObject_str, /*tp_str*/
669 PyObject_GenericGetAttr,/*tp_getattro*/
670 0, /*tp_setattro*/
671 0, /*tp_as_buffer*/
672 Py_TPFLAGS_DEFAULT, /*tp_flags*/
673 0, /*tp_doc*/
674 0, /*tp_traverse*/
675 0, /*tp_clear*/
676 0, /*tp_richcompare*/
677 0, /*tp_weaklistoffset*/
678 0, /*tp_iter*/
679 0, /*tp_iternext*/
680 0, /*tp_methods*/
681 0, /*tp_members*/
682 PyTclObject_getsetlist, /*tp_getset*/
683 0, /*tp_base*/
684 0, /*tp_dict*/
685 0, /*tp_descr_get*/
686 0, /*tp_descr_set*/
687 0, /*tp_dictoffset*/
688 0, /*tp_init*/
689 0, /*tp_alloc*/
690 0, /*tp_new*/
691 0, /*tp_free*/
692 0, /*tp_is_gc*/
693};
694
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000695static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000696AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000697{
698 Tcl_Obj *result;
699
700 if (PyString_Check(value))
701 return Tcl_NewStringObj(PyString_AS_STRING(value),
702 PyString_GET_SIZE(value));
703 else if (PyInt_Check(value))
704 return Tcl_NewLongObj(PyInt_AS_LONG(value));
705 else if (PyFloat_Check(value))
706 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
707 else if (PyTuple_Check(value)) {
708 Tcl_Obj **argv = (Tcl_Obj**)
709 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
710 int i;
711 if(!argv)
712 return 0;
713 for(i=0;i<PyTuple_Size(value);i++)
714 argv[i] = AsObj(PyTuple_GetItem(value,i));
715 result = Tcl_NewListObj(PyTuple_Size(value), argv);
716 ckfree(FREECAST argv);
717 return result;
718 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000719#ifdef Py_USING_UNICODE
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000720 else if (PyUnicode_Check(value)) {
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000721 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
722 int size = PyUnicode_GET_SIZE(value);
723 /* This #ifdef assumes that Tcl uses UCS-2.
724 See TCL_UTF_MAX test above. */
725#ifdef Py_UNICODE_WIDE
726 Tcl_UniChar *outbuf;
727 int i;
728 outbuf = (Tcl_UniChar*)ckalloc(size * sizeof(Tcl_UniChar));
729 if (!outbuf) {
730 PyErr_NoMemory();
731 return NULL;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000732 }
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000733 for (i = 0; i < size; i++) {
734 if (inbuf[i] >= 0x10000) {
735 /* Tcl doesn't do UTF-16, yet. */
736 PyErr_SetString(PyExc_ValueError,
737 "unsupported character");
738 ckfree(FREECAST outbuf);
739 return NULL;
740 }
741 outbuf[i] = inbuf[i];
742 }
743 result = Tcl_NewUnicodeObj(outbuf, size);
744 ckfree(FREECAST outbuf);
745 return result;
746#else
747 return Tcl_NewUnicodeObj(inbuf, size);
748#endif
749
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000750 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000751#endif
Martin v. Löwisffad6332002-11-26 09:28:05 +0000752 else if(PyTclObject_Check(value)) {
753 Tcl_Obj *v = ((PyTclObject*)value)->value;
754 Tcl_IncrRefCount(v);
755 return v;
756 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000757 else {
758 PyObject *v = PyObject_Str(value);
759 if (!v)
760 return 0;
761 result = AsObj(v);
762 Py_DECREF(v);
763 return result;
764 }
765}
766
Martin v. Löwisffad6332002-11-26 09:28:05 +0000767static PyObject*
768FromObj(PyObject* tkapp, Tcl_Obj *value)
769{
770 PyObject *result = NULL;
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000771 TkappObject *app = (TkappObject*)tkapp;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000772
Martin v. Löwise07e18d2002-12-04 19:54:36 +0000773 if (value->typePtr == NULL) {
774 /* If the result contains any bytes with the top bit set,
775 it's UTF-8 and we should decode it to Unicode */
776#ifdef Py_USING_UNICODE
777 int i;
778 char *s = value->bytes;
779 int len = value->length;
780 for (i = 0; i < len; i++) {
781 if (value->bytes[i] & 0x80)
782 break;
783 }
784
785 if (i == value->length)
786 result = PyString_FromStringAndSize(s, len);
787 else {
788 /* Convert UTF-8 to Unicode string */
789 result = PyUnicode_DecodeUTF8(s, len, "strict");
790 if (result == NULL) {
791 PyErr_Clear();
792 result = PyString_FromStringAndSize(s, len);
793 }
794 }
795#else
796 res = PyString_FromStringAndSize(value->bytes, value->length);
797#endif
798 return result;
799 }
Martin v. Löwisffad6332002-11-26 09:28:05 +0000800
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000801 if (value->typePtr == app->BooleanType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000802 result = value->internalRep.longValue ? Py_True : Py_False;
803 Py_INCREF(result);
804 return result;
805 }
806
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000807 if (value->typePtr == app->ByteArrayType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000808 int size;
Martin v. Löwis33ec3ba2002-12-07 14:57:11 +0000809 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000810 return PyString_FromStringAndSize(data, size);
811 }
812
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000813 if (value->typePtr == app->DoubleType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000814 return PyFloat_FromDouble(value->internalRep.doubleValue);
815 }
816
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000817 if (value->typePtr == app->IntType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000818 return PyInt_FromLong(value->internalRep.longValue);
819 }
820
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000821 if (value->typePtr == app->ListType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000822 int size;
823 int i, status;
824 PyObject *elem;
825 Tcl_Obj *tcl_elem;
826
827 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
828 if (status == TCL_ERROR)
829 return Tkinter_Error(tkapp);
830 result = PyTuple_New(size);
831 if (!result)
832 return NULL;
833 for (i = 0; i < size; i++) {
834 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
835 value, i, &tcl_elem);
836 if (status == TCL_ERROR) {
837 Py_DECREF(result);
838 return Tkinter_Error(tkapp);
839 }
840 elem = FromObj(tkapp, tcl_elem);
841 if (!elem) {
842 Py_DECREF(result);
843 return NULL;
844 }
845 PyTuple_SetItem(result, i, elem);
846 }
847 return result;
848 }
849
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000850 if (value->typePtr == app->ProcBodyType) {
Martin v. Löwis33ec3ba2002-12-07 14:57:11 +0000851 /* fall through: return tcl object. */
Martin v. Löwisffad6332002-11-26 09:28:05 +0000852 }
853
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000854 if (value->typePtr == app->StringType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000855#ifdef Py_USING_UNICODE
856#ifdef Py_UNICODE_WIDE
857 PyObject *result;
858 int size;
859 Tcl_UniChar *input;
860 Py_UNICODE *output;
861
862 size = Tcl_GetCharLength(value);
863 result = PyUnicode_FromUnicode(NULL, size);
864 if (!result)
865 return NULL;
866 input = Tcl_GetUnicode(value);
867 output = PyUnicode_AS_UNICODE(result);
868 while (size--)
869 *output++ = *input++;
870 return result;
871#else
872 return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
873 Tcl_GetCharLength(value));
874#endif
875#else
876 int size;
877 char *c;
878 c = Tcl_GetStringFromObj(value, &size);
879 return PyString_FromStringAndSize(c, size);
880#endif
881 }
882
883 return newPyTclObject(value);
884}
885
Guido van Rossum18468821994-06-20 07:49:28 +0000886static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000887Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000888{
Guido van Rossum632de272000-03-29 00:19:50 +0000889 Tcl_Obj *objStore[ARGSZ];
890 Tcl_Obj **objv = NULL;
891 int objc = 0, i;
892 PyObject *res = NULL;
893 Tcl_Interp *interp = Tkapp_Interp(self);
894 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
895 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000896
Guido van Rossum632de272000-03-29 00:19:50 +0000897 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000898
Guido van Rossum212643f1998-04-29 16:22:14 +0000899 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +0000900 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +0000901
Guido van Rossum212643f1998-04-29 16:22:14 +0000902 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000903 objv[0] = AsObj(args);
904 if (objv[0] == 0)
905 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000906 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +0000907 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000908 }
909 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000910 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000911
Guido van Rossum632de272000-03-29 00:19:50 +0000912 if (objc > ARGSZ) {
913 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
914 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000915 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +0000916 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +0000917 goto finally;
918 }
919 }
920
Guido van Rossum632de272000-03-29 00:19:50 +0000921 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000922 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +0000923 if (v == Py_None) {
924 objc = i;
925 break;
926 }
Guido van Rossum632de272000-03-29 00:19:50 +0000927 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +0000928 if (!objv[i]) {
929 /* Reset objc, so it attempts to clear
930 objects only up to i. */
931 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +0000932 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000933 }
Guido van Rossum632de272000-03-29 00:19:50 +0000934 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000935 }
936 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000937
Guido van Rossum62320c91998-06-15 04:36:09 +0000938 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000939
940 i = Tcl_EvalObjv(interp, objc, objv, flags);
941
Guido van Rossum62320c91998-06-15 04:36:09 +0000942 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000943 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000944 Tkinter_Error(self);
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000945 else if(((TkappObject*)self)->wantobjects) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000946 Tcl_Obj *value = Tcl_GetObjResult(interp);
947 /* Not sure whether the IncrRef is necessary, but something
948 may overwrite the interpreter result while we are
949 converting it. */
950 Tcl_IncrRefCount(value);
951 res = FromObj(self, value);
952 Tcl_DecrRefCount(value);
953 } else {
Martin v. Löwis71e25a02002-10-01 18:08:06 +0000954 const char *s = Tcl_GetStringResult(interp);
955 const char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000956
Guido van Rossum990f5c62000-05-04 15:07:16 +0000957 /* If the result contains any bytes with the top bit set,
958 it's UTF-8 and we should decode it to Unicode */
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000959#ifdef Py_USING_UNICODE
Guido van Rossum990f5c62000-05-04 15:07:16 +0000960 while (*p != '\0') {
961 if (*p & 0x80)
962 break;
963 p++;
964 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000965
Guido van Rossum990f5c62000-05-04 15:07:16 +0000966 if (*p == '\0')
967 res = PyString_FromStringAndSize(s, (int)(p-s));
968 else {
969 /* Convert UTF-8 to Unicode string */
970 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +0000971 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
972 if (res == NULL) {
Guido van Rossum2834b972000-10-06 16:58:26 +0000973 PyErr_Clear();
974 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum69529ad2000-05-04 15:55:17 +0000975 }
Guido van Rossum990f5c62000-05-04 15:07:16 +0000976 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000977#else
978 p = strchr(p, '\0');
979 res = PyString_FromStringAndSize(s, (int)(p-s));
980#endif
Guido van Rossum990f5c62000-05-04 15:07:16 +0000981 }
Guido van Rossum632de272000-03-29 00:19:50 +0000982
Guido van Rossum62320c91998-06-15 04:36:09 +0000983 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000984
Guido van Rossum212643f1998-04-29 16:22:14 +0000985 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000986 for (i = 0; i < objc; i++)
987 Tcl_DecrRefCount(objv[i]);
988 if (objv != objStore)
989 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000990 return res;
991}
992
993
994static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000995Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000996{
Guido van Rossum212643f1998-04-29 16:22:14 +0000997 /* Could do the same here as for Tkapp_Call(), but this is not used
998 much, so I can't be bothered. Unfortunately Tcl doesn't export a
999 way for the user to do what all its Global* variants do (save and
1000 reset the scope pointer, call the local version, restore the saved
1001 scope pointer). */
1002
Guido van Rossum62320c91998-06-15 04:36:09 +00001003 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +00001004 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001005
Guido van Rossum62320c91998-06-15 04:36:09 +00001006 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +00001007 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +00001008 int err;
1009 ENTER_TCL
1010 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +00001011 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001012 if (err == TCL_ERROR)
1013 res = Tkinter_Error(self);
1014 else
1015 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +00001016 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001017 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +00001018 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001019
1020 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001021}
1022
1023static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001024Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001025{
Barry Warsawfa701a81997-01-16 00:15:11 +00001026 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001027 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001028 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001029
Guido van Rossum43713e52000-02-29 13:59:29 +00001030 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001031 return NULL;
1032
Guido van Rossum00d93061998-05-28 23:06:38 +00001033 ENTER_TCL
1034 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001035 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001036 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001037 res = Tkinter_Error(self);
1038 else
1039 res = PyString_FromString(Tkapp_Result(self));
1040 LEAVE_OVERLAP_TCL
1041 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001042}
1043
1044static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001045Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001046{
Barry Warsawfa701a81997-01-16 00:15:11 +00001047 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001048 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001049 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +00001050
Guido van Rossum43713e52000-02-29 13:59:29 +00001051 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001052 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001053
Guido van Rossum00d93061998-05-28 23:06:38 +00001054 ENTER_TCL
1055 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001056 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001057 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001058 res = Tkinter_Error(self);
1059 else
1060 res = PyString_FromString(Tkapp_Result(self));
1061 LEAVE_OVERLAP_TCL
1062 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001063}
1064
1065static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001066Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001067{
Barry Warsawfa701a81997-01-16 00:15:11 +00001068 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +00001069 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001070 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001071
Guido van Rossum43713e52000-02-29 13:59:29 +00001072 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001073 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001074
Guido van Rossum00d93061998-05-28 23:06:38 +00001075 ENTER_TCL
1076 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +00001077 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001078 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001079 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001080
Guido van Rossum62320c91998-06-15 04:36:09 +00001081 else
1082 res = PyString_FromString(Tkapp_Result(self));
1083 LEAVE_OVERLAP_TCL
1084 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001085}
1086
1087static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001088Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001089{
Barry Warsawfa701a81997-01-16 00:15:11 +00001090 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001091 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001092 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001093
Guido van Rossum35d43371997-08-02 00:09:09 +00001094 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001095 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001096
Guido van Rossum00d93061998-05-28 23:06:38 +00001097 ENTER_TCL
1098 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +00001099 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001100 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001101 res = Tkinter_Error(self);
1102 else
1103 res = PyString_FromString(Tkapp_Result(self));
1104 LEAVE_OVERLAP_TCL
1105 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001106}
1107
1108static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001109Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001110{
Barry Warsawfa701a81997-01-16 00:15:11 +00001111 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +00001112
Guido van Rossum43713e52000-02-29 13:59:29 +00001113 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +00001114 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001115 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001116 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +00001117 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001118
Barry Warsawfa701a81997-01-16 00:15:11 +00001119 Py_INCREF(Py_None);
1120 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001121}
1122
Barry Warsawfa701a81997-01-16 00:15:11 +00001123
1124
Guido van Rossum18468821994-06-20 07:49:28 +00001125/** Tcl Variable **/
1126
1127static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001128SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001129{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001130 char *name1, *name2, *s;
1131 const char *ok;
Barry Warsawfa701a81997-01-16 00:15:11 +00001132 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +00001133 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +00001134
Guido van Rossum62320c91998-06-15 04:36:09 +00001135 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +00001136 if (!tmp)
1137 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001138
Guido van Rossum43713e52000-02-29 13:59:29 +00001139 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001140 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +00001141 s = AsString(newValue, tmp);
Guido van Rossum2834b972000-10-06 16:58:26 +00001142 if (s == NULL)
1143 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001144 ENTER_TCL
1145 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
1146 LEAVE_TCL
1147 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001148 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001149 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +00001150 if (PyArg_ParseTuple(args, "ssO:setvar",
1151 &name1, &name2, &newValue)) {
1152 s = AsString(newValue, tmp);
1153 if (s == NULL)
1154 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001155 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001156 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +00001157 s, flags);
1158 LEAVE_TCL
1159 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001160 else {
Guido van Rossum00d93061998-05-28 23:06:38 +00001161 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +00001162 return NULL;
1163 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001164 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001165 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +00001166
Barry Warsawfa701a81997-01-16 00:15:11 +00001167 if (!ok)
1168 return Tkinter_Error(self);
1169
1170 Py_INCREF(Py_None);
1171 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001172}
1173
1174static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001175Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001176{
Barry Warsawfa701a81997-01-16 00:15:11 +00001177 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001178}
1179
1180static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001181Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001182{
Barry Warsawfa701a81997-01-16 00:15:11 +00001183 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001184}
1185
Barry Warsawfa701a81997-01-16 00:15:11 +00001186
1187
Guido van Rossum18468821994-06-20 07:49:28 +00001188static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001189GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001190{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001191 char *name1, *name2=NULL;
1192 const char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001193 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001194
Guido van Rossum43713e52000-02-29 13:59:29 +00001195 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +00001196 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001197 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001198 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +00001199 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +00001200
Barry Warsawfa701a81997-01-16 00:15:11 +00001201 else
Guido van Rossum35d43371997-08-02 00:09:09 +00001202 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001203 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001204
Barry Warsawfa701a81997-01-16 00:15:11 +00001205 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +00001206 res = Tkinter_Error(self);
1207 else
1208 res = PyString_FromString(s);
1209 LEAVE_OVERLAP_TCL
1210 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001211}
1212
1213static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001214Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001215{
Barry Warsawfa701a81997-01-16 00:15:11 +00001216 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001217}
1218
1219static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001220Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001221{
Barry Warsawfa701a81997-01-16 00:15:11 +00001222 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001223}
1224
Barry Warsawfa701a81997-01-16 00:15:11 +00001225
1226
Guido van Rossum18468821994-06-20 07:49:28 +00001227static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001228UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001229{
Guido van Rossum35d43371997-08-02 00:09:09 +00001230 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001231 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001232 int code;
Guido van Rossum18468821994-06-20 07:49:28 +00001233
Guido van Rossum43713e52000-02-29 13:59:29 +00001234 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001235 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001236 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001237 if (name2 == NULL)
1238 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
1239
1240 else
1241 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001242 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001243
Barry Warsawfa701a81997-01-16 00:15:11 +00001244 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001245 res = Tkinter_Error(self);
1246 else {
1247 Py_INCREF(Py_None);
1248 res = Py_None;
1249 }
1250 LEAVE_OVERLAP_TCL
1251 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001252}
1253
1254static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001255Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001256{
Barry Warsawfa701a81997-01-16 00:15:11 +00001257 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001258}
1259
1260static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001261Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001262{
Barry Warsawfa701a81997-01-16 00:15:11 +00001263 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001264}
1265
Barry Warsawfa701a81997-01-16 00:15:11 +00001266
1267
Guido van Rossum18468821994-06-20 07:49:28 +00001268/** Tcl to Python **/
1269
1270static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001271Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001272{
Barry Warsawfa701a81997-01-16 00:15:11 +00001273 char *s;
1274 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001275
Martin v. Löwisffad6332002-11-26 09:28:05 +00001276 if (PyTuple_Size(args) == 1) {
1277 PyObject* o = PyTuple_GetItem(args, 0);
1278 if (PyInt_Check(o)) {
1279 Py_INCREF(o);
1280 return o;
1281 }
1282 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001283 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001284 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001285 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001286 return Tkinter_Error(self);
1287 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001288}
1289
1290static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001291Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001292{
Barry Warsawfa701a81997-01-16 00:15:11 +00001293 char *s;
1294 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001295
Martin v. Löwisffad6332002-11-26 09:28:05 +00001296 if (PyTuple_Size(args) == 1) {
1297 PyObject *o = PyTuple_GetItem(args, 0);
1298 if (PyFloat_Check(o)) {
1299 Py_INCREF(o);
1300 return o;
1301 }
1302 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001303 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001304 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001305 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001306 return Tkinter_Error(self);
1307 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001308}
1309
1310static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001311Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001312{
Barry Warsawfa701a81997-01-16 00:15:11 +00001313 char *s;
1314 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001315
Martin v. Löwisffad6332002-11-26 09:28:05 +00001316 if (PyTuple_Size(args) == 1) {
1317 PyObject *o = PyTuple_GetItem(args, 0);
1318 if (PyInt_Check(o)) {
1319 Py_INCREF(o);
1320 return o;
1321 }
1322 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001323 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001324 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001325 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1326 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001327 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001328}
1329
1330static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001331Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001332{
Barry Warsawfa701a81997-01-16 00:15:11 +00001333 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001334 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001335 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001336
Guido van Rossum43713e52000-02-29 13:59:29 +00001337 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001338 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001339 ENTER_TCL
1340 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001341 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001342 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001343 res = Tkinter_Error(self);
1344 else
1345 res = Py_BuildValue("s", Tkapp_Result(self));
1346 LEAVE_OVERLAP_TCL
1347 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001348}
1349
1350static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001351Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001352{
Barry Warsawfa701a81997-01-16 00:15:11 +00001353 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001354 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001355 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001356 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001357
Guido van Rossum43713e52000-02-29 13:59:29 +00001358 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001359 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001360 ENTER_TCL
1361 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001362 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001363 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001364 res = Tkinter_Error(self);
1365 else
1366 res = Py_BuildValue("l", v);
1367 LEAVE_OVERLAP_TCL
1368 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001369}
1370
1371static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001372Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001373{
Barry Warsawfa701a81997-01-16 00:15:11 +00001374 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001375 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001376 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001377 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001378
Guido van Rossum43713e52000-02-29 13:59:29 +00001379 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001380 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001381 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001382 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001383 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001384 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001385 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001386 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001387 res = Tkinter_Error(self);
1388 else
1389 res = Py_BuildValue("d", v);
1390 LEAVE_OVERLAP_TCL
1391 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001392}
1393
1394static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001395Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001396{
Barry Warsawfa701a81997-01-16 00:15:11 +00001397 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001398 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001399 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001400 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001401
Guido van Rossum43713e52000-02-29 13:59:29 +00001402 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001403 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001404 ENTER_TCL
1405 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001406 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001407 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001408 res = Tkinter_Error(self);
1409 else
1410 res = Py_BuildValue("i", v);
1411 LEAVE_OVERLAP_TCL
1412 return res;
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 *
Fred Drake509d79a2000-07-08 04:04:38 +00001418Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001419{
Barry Warsawfa701a81997-01-16 00:15:11 +00001420 char *list;
1421 int argc;
1422 char **argv;
1423 PyObject *v;
1424 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001425
Martin v. Löwisffad6332002-11-26 09:28:05 +00001426 if (PyTuple_Size(args) == 1) {
1427 v = PyTuple_GetItem(args, 0);
1428 if (PyTuple_Check(v)) {
1429 Py_INCREF(v);
1430 return v;
1431 }
1432 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001433 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001434 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001435
Barry Warsawfa701a81997-01-16 00:15:11 +00001436 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1437 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001438
Barry Warsawfa701a81997-01-16 00:15:11 +00001439 if (!(v = PyTuple_New(argc)))
1440 return NULL;
1441
1442 for (i = 0; i < argc; i++) {
1443 PyObject *s = PyString_FromString(argv[i]);
1444 if (!s || PyTuple_SetItem(v, i, s)) {
1445 Py_DECREF(v);
1446 v = NULL;
1447 goto finally;
1448 }
1449 }
Guido van Rossum18468821994-06-20 07:49:28 +00001450
Barry Warsawfa701a81997-01-16 00:15:11 +00001451 finally:
1452 ckfree(FREECAST argv);
1453 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001454}
1455
1456static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001457Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001458{
Barry Warsawfa701a81997-01-16 00:15:11 +00001459 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001460
Martin v. Löwisffad6332002-11-26 09:28:05 +00001461 if (PyTuple_Size(args) == 1) {
1462 PyObject* o = PyTuple_GetItem(args, 0);
1463 if (PyTuple_Check(o)) {
1464 o = SplitObj(o);
1465 return o;
1466 }
1467 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001468 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001469 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001470 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001471}
1472
1473static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001474Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001475{
Barry Warsawfa701a81997-01-16 00:15:11 +00001476 char *s = Merge(args);
1477 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001478
Barry Warsawfa701a81997-01-16 00:15:11 +00001479 if (s) {
1480 res = PyString_FromString(s);
1481 ckfree(s);
1482 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001483
1484 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001485}
1486
Barry Warsawfa701a81997-01-16 00:15:11 +00001487
1488
Guido van Rossum18468821994-06-20 07:49:28 +00001489/** Tcl Command **/
1490
Guido van Rossum00d93061998-05-28 23:06:38 +00001491/* Client data struct */
1492typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001493 PyObject *self;
1494 PyObject *func;
1495} PythonCmd_ClientData;
1496
1497static int
Fred Drake509d79a2000-07-08 04:04:38 +00001498PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001499{
1500 errorInCmd = 1;
1501 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1502 LEAVE_PYTHON
1503 return TCL_ERROR;
1504}
1505
Guido van Rossum18468821994-06-20 07:49:28 +00001506/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001507 * function or method.
1508 */
Guido van Rossum18468821994-06-20 07:49:28 +00001509static int
Fred Drake509d79a2000-07-08 04:04:38 +00001510PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001511{
Guido van Rossum00d93061998-05-28 23:06:38 +00001512 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001513 PyObject *self, *func, *arg, *res, *tmp;
Guido van Rossum2834b972000-10-06 16:58:26 +00001514 int i, rv;
1515 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +00001516
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001517 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001518
Barry Warsawfa701a81997-01-16 00:15:11 +00001519 /* TBD: no error checking here since we know, via the
1520 * Tkapp_CreateCommand() that the client data is a two-tuple
1521 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001522 self = data->self;
1523 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001524
Barry Warsawfa701a81997-01-16 00:15:11 +00001525 /* Create argument list (argv1, ..., argvN) */
1526 if (!(arg = PyTuple_New(argc - 1)))
1527 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001528
Barry Warsawfa701a81997-01-16 00:15:11 +00001529 for (i = 0; i < (argc - 1); i++) {
1530 PyObject *s = PyString_FromString(argv[i + 1]);
1531 if (!s || PyTuple_SetItem(arg, i, s)) {
1532 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001533 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001534 }
1535 }
1536 res = PyEval_CallObject(func, arg);
1537 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001538
Barry Warsawfa701a81997-01-16 00:15:11 +00001539 if (res == NULL)
1540 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001541
Barry Warsawfa701a81997-01-16 00:15:11 +00001542 if (!(tmp = PyList_New(0))) {
1543 Py_DECREF(res);
1544 return PythonCmd_Error(interp);
1545 }
1546
Guido van Rossum2834b972000-10-06 16:58:26 +00001547 s = AsString(res, tmp);
1548 if (s == NULL) {
1549 rv = PythonCmd_Error(interp);
1550 }
1551 else {
1552 Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
1553 rv = TCL_OK;
1554 }
1555
Barry Warsawfa701a81997-01-16 00:15:11 +00001556 Py_DECREF(res);
1557 Py_DECREF(tmp);
1558
Guido van Rossum00d93061998-05-28 23:06:38 +00001559 LEAVE_PYTHON
1560
Guido van Rossum2834b972000-10-06 16:58:26 +00001561 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00001562}
1563
1564static void
Fred Drake509d79a2000-07-08 04:04:38 +00001565PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00001566{
Guido van Rossum00d93061998-05-28 23:06:38 +00001567 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1568
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001569 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001570 Py_XDECREF(data->self);
1571 Py_XDECREF(data->func);
1572 PyMem_DEL(data);
1573 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001574}
1575
Barry Warsawfa701a81997-01-16 00:15:11 +00001576
1577
Guido van Rossum18468821994-06-20 07:49:28 +00001578static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001579Tkapp_CreateCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001580{
Guido van Rossum00d93061998-05-28 23:06:38 +00001581 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001582 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001583 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001584 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001585
Guido van Rossum43713e52000-02-29 13:59:29 +00001586 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001587 return NULL;
1588 if (!PyCallable_Check(func)) {
1589 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001590 return NULL;
1591 }
Guido van Rossum18468821994-06-20 07:49:28 +00001592
Guido van Rossum00d93061998-05-28 23:06:38 +00001593 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001594 if (!data)
1595 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001596 Py_XINCREF(self);
1597 Py_XINCREF(func);
1598 data->self = self;
1599 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001600
Guido van Rossum00d93061998-05-28 23:06:38 +00001601 ENTER_TCL
1602 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1603 (ClientData)data, PythonCmdDelete);
1604 LEAVE_TCL
1605 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001606 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001607 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001608 return NULL;
1609 }
Guido van Rossum18468821994-06-20 07:49:28 +00001610
Barry Warsawfa701a81997-01-16 00:15:11 +00001611 Py_INCREF(Py_None);
1612 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001613}
1614
Barry Warsawfa701a81997-01-16 00:15:11 +00001615
1616
Guido van Rossum18468821994-06-20 07:49:28 +00001617static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001618Tkapp_DeleteCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001619{
Barry Warsawfa701a81997-01-16 00:15:11 +00001620 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001621 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001622
Guido van Rossum43713e52000-02-29 13:59:29 +00001623 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001624 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001625 ENTER_TCL
1626 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1627 LEAVE_TCL
1628 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001629 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1630 return NULL;
1631 }
1632 Py_INCREF(Py_None);
1633 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001634}
1635
Barry Warsawfa701a81997-01-16 00:15:11 +00001636
1637
Guido van Rossum00d93061998-05-28 23:06:38 +00001638#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001639/** File Handler **/
1640
Guido van Rossum00d93061998-05-28 23:06:38 +00001641typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001642 PyObject *func;
1643 PyObject *file;
1644 int id;
1645 struct _fhcdata *next;
1646} FileHandler_ClientData;
1647
1648static FileHandler_ClientData *HeadFHCD;
1649
1650static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00001651NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001652{
1653 FileHandler_ClientData *p;
1654 p = PyMem_NEW(FileHandler_ClientData, 1);
1655 if (p != NULL) {
1656 Py_XINCREF(func);
1657 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001658 p->func = func;
1659 p->file = file;
1660 p->id = id;
1661 p->next = HeadFHCD;
1662 HeadFHCD = p;
1663 }
1664 return p;
1665}
1666
1667static void
Fred Drake509d79a2000-07-08 04:04:38 +00001668DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001669{
1670 FileHandler_ClientData *p, **pp;
1671
1672 pp = &HeadFHCD;
1673 while ((p = *pp) != NULL) {
1674 if (p->id == id) {
1675 *pp = p->next;
1676 Py_XDECREF(p->func);
1677 Py_XDECREF(p->file);
1678 PyMem_DEL(p);
1679 }
1680 else
1681 pp = &p->next;
1682 }
1683}
1684
Guido van Rossuma597dde1995-01-10 20:56:29 +00001685static void
Fred Drake509d79a2000-07-08 04:04:38 +00001686FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00001687{
Guido van Rossum00d93061998-05-28 23:06:38 +00001688 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001689 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001690
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001691 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001692 func = data->func;
1693 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001694
Barry Warsawfa701a81997-01-16 00:15:11 +00001695 arg = Py_BuildValue("(Oi)", file, (long) mask);
1696 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001697 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001698
1699 if (res == NULL) {
1700 errorInCmd = 1;
1701 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1702 }
1703 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001704 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001705}
1706
Guido van Rossum18468821994-06-20 07:49:28 +00001707static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001708Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
1709 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001710{
Guido van Rossum00d93061998-05-28 23:06:38 +00001711 FileHandler_ClientData *data;
1712 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001713 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001714
Guido van Rossum2834b972000-10-06 16:58:26 +00001715 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
1716 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001717 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001718 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001719 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001720 return NULL;
1721 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001722 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001723 return NULL;
1724 }
1725
Guido van Rossuma80649b2000-03-28 20:07:05 +00001726 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001727 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001728 return NULL;
1729
Barry Warsawfa701a81997-01-16 00:15:11 +00001730 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001731 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001732 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001733 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001734 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001735 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001736}
1737
1738static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001739Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001740{
Barry Warsawfa701a81997-01-16 00:15:11 +00001741 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001742 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001743
Guido van Rossum43713e52000-02-29 13:59:29 +00001744 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001745 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001746 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001747 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001748 return NULL;
1749
Guido van Rossuma80649b2000-03-28 20:07:05 +00001750 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001751
Barry Warsawfa701a81997-01-16 00:15:11 +00001752 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001753 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001754 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001755 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001756 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001757 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001758}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001759#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001760
Barry Warsawfa701a81997-01-16 00:15:11 +00001761
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001762/**** Tktt Object (timer token) ****/
1763
Jeremy Hylton938ace62002-07-17 16:30:39 +00001764static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001765
Guido van Rossum00d93061998-05-28 23:06:38 +00001766typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001767 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001768 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001769 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001770} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001771
1772static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001773Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001774{
Barry Warsawfa701a81997-01-16 00:15:11 +00001775 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001776 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001777
Guido van Rossum43713e52000-02-29 13:59:29 +00001778 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001779 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001780 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001781 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001782 v->token = NULL;
1783 }
1784 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001785 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001786 Py_DECREF(func);
1787 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001788 }
1789 Py_INCREF(Py_None);
1790 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001791}
1792
1793static PyMethodDef Tktt_methods[] =
1794{
Neal Norwitzb0493252002-03-31 14:44:22 +00001795 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00001796 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001797};
1798
1799static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001800Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001801{
Barry Warsawfa701a81997-01-16 00:15:11 +00001802 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001803
Guido van Rossumb18618d2000-05-03 23:44:39 +00001804 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00001805 if (v == NULL)
1806 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001807
Guido van Rossum00d93061998-05-28 23:06:38 +00001808 Py_INCREF(func);
1809 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001810 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001811
1812 /* Extra reference, deleted when called or when handler is deleted */
1813 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001814 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001815}
1816
1817static void
Fred Drake509d79a2000-07-08 04:04:38 +00001818Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001819{
Guido van Rossum00d93061998-05-28 23:06:38 +00001820 TkttObject *v = (TkttObject *)self;
1821 PyObject *func = v->func;
1822
1823 Py_XDECREF(func);
1824
Guido van Rossumb18618d2000-05-03 23:44:39 +00001825 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001826}
1827
Guido van Rossum597ac201998-05-12 14:36:19 +00001828static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001829Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001830{
Barry Warsawfa701a81997-01-16 00:15:11 +00001831 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001832 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001833
Tim Peters885d4572001-11-28 20:27:42 +00001834 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00001835 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001836 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001837}
1838
1839static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001840Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001841{
Barry Warsawfa701a81997-01-16 00:15:11 +00001842 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001843}
1844
1845static PyTypeObject Tktt_Type =
1846{
Guido van Rossum35d43371997-08-02 00:09:09 +00001847 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001848 0, /*ob_size */
1849 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001850 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001851 0, /*tp_itemsize */
1852 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001853 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001854 Tktt_GetAttr, /*tp_getattr */
1855 0, /*tp_setattr */
1856 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001857 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001858 0, /*tp_as_number */
1859 0, /*tp_as_sequence */
1860 0, /*tp_as_mapping */
1861 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001862};
1863
Barry Warsawfa701a81997-01-16 00:15:11 +00001864
1865
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001866/** Timer Handler **/
1867
1868static void
Fred Drake509d79a2000-07-08 04:04:38 +00001869TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001870{
Guido van Rossum00d93061998-05-28 23:06:38 +00001871 TkttObject *v = (TkttObject *)clientData;
1872 PyObject *func = v->func;
1873 PyObject *res;
1874
1875 if (func == NULL)
1876 return;
1877
1878 v->func = NULL;
1879
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001880 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001881
1882 res = PyEval_CallObject(func, NULL);
1883 Py_DECREF(func);
1884 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001885
Barry Warsawfa701a81997-01-16 00:15:11 +00001886 if (res == NULL) {
1887 errorInCmd = 1;
1888 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1889 }
1890 else
1891 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001892
1893 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001894}
1895
1896static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001897Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001898{
Barry Warsawfa701a81997-01-16 00:15:11 +00001899 int milliseconds;
1900 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001901 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001902
Guido van Rossum2834b972000-10-06 16:58:26 +00001903 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
1904 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001905 return NULL;
1906 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001907 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001908 return NULL;
1909 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001910 v = Tktt_New(func);
1911 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1912 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001913
Guido van Rossum00d93061998-05-28 23:06:38 +00001914 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001915}
1916
Barry Warsawfa701a81997-01-16 00:15:11 +00001917
Guido van Rossum18468821994-06-20 07:49:28 +00001918/** Event Loop **/
1919
Guido van Rossum18468821994-06-20 07:49:28 +00001920static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001921Tkapp_MainLoop(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001922{
Barry Warsawfa701a81997-01-16 00:15:11 +00001923 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001924#ifdef WITH_THREAD
1925 PyThreadState *tstate = PyThreadState_Get();
1926#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001927
Guido van Rossum43713e52000-02-29 13:59:29 +00001928 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001929 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001930
Barry Warsawfa701a81997-01-16 00:15:11 +00001931 quitMainLoop = 0;
1932 while (Tk_GetNumMainWindows() > threshold &&
1933 !quitMainLoop &&
1934 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001935 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001936 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001937
1938#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001939 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001940 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001941 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001942 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001943 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001944 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001945 if (result == 0)
1946 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001947 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001948#else
1949 result = Tcl_DoOneEvent(0);
1950#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001951
Guido van Rossum35d43371997-08-02 00:09:09 +00001952 if (PyErr_CheckSignals() != 0)
1953 return NULL;
1954 if (result < 0)
1955 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001956 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001957 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001958
Barry Warsawfa701a81997-01-16 00:15:11 +00001959 if (errorInCmd) {
1960 errorInCmd = 0;
1961 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1962 excInCmd = valInCmd = trbInCmd = NULL;
1963 return NULL;
1964 }
1965 Py_INCREF(Py_None);
1966 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001967}
1968
1969static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001970Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00001971{
Guido van Rossum35d43371997-08-02 00:09:09 +00001972 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001973 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001974
Guido van Rossum43713e52000-02-29 13:59:29 +00001975 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001976 return NULL;
1977
Guido van Rossum00d93061998-05-28 23:06:38 +00001978 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001979 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001980 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001981 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001982}
1983
1984static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001985Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001986{
1987
Guido van Rossum43713e52000-02-29 13:59:29 +00001988 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001989 return NULL;
1990
1991 quitMainLoop = 1;
1992 Py_INCREF(Py_None);
1993 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001994}
1995
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001996static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001997Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001998{
1999
Guido van Rossum43713e52000-02-29 13:59:29 +00002000 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00002001 return NULL;
2002
2003 return PyInt_FromLong((long)Tkapp_Interp(self));
2004}
2005
Barry Warsawfa701a81997-01-16 00:15:11 +00002006
Martin v. Löwisffad6332002-11-26 09:28:05 +00002007static PyObject *
2008Tkapp_WantObjects(PyObject *self, PyObject *args)
2009{
2010
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002011 int wantobjects;
2012 if (!PyArg_ParseTuple(args, "i:wantobjects", &wantobjects))
Martin v. Löwisffad6332002-11-26 09:28:05 +00002013 return NULL;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002014 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002015
2016 Py_INCREF(Py_None);
2017 return Py_None;
2018}
2019
2020
Barry Warsawfa701a81997-01-16 00:15:11 +00002021
Guido van Rossum18468821994-06-20 07:49:28 +00002022/**** Tkapp Method List ****/
2023
2024static PyMethodDef Tkapp_methods[] =
2025{
Martin v. Löwisffad6332002-11-26 09:28:05 +00002026 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002027 {"call", Tkapp_Call, METH_OLDARGS},
2028 {"globalcall", Tkapp_GlobalCall, METH_OLDARGS},
2029 {"eval", Tkapp_Eval, METH_VARARGS},
2030 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2031 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2032 {"record", Tkapp_Record, METH_VARARGS},
2033 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2034 {"setvar", Tkapp_SetVar, METH_VARARGS},
2035 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2036 {"getvar", Tkapp_GetVar, METH_VARARGS},
2037 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2038 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2039 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2040 {"getint", Tkapp_GetInt, METH_VARARGS},
2041 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2042 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2043 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2044 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2045 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2046 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2047 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2048 {"split", Tkapp_Split, METH_VARARGS},
2049 {"merge", Tkapp_Merge, METH_OLDARGS},
2050 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2051 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002052#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002053 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2054 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002055#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002056 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2057 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2058 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2059 {"quit", Tkapp_Quit, METH_VARARGS},
2060 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002061 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002062};
2063
Barry Warsawfa701a81997-01-16 00:15:11 +00002064
2065
Guido van Rossum18468821994-06-20 07:49:28 +00002066/**** Tkapp Type Methods ****/
2067
2068static void
Fred Drake509d79a2000-07-08 04:04:38 +00002069Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002070{
Guido van Rossum00d93061998-05-28 23:06:38 +00002071 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002072 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002073 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002074 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002075 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002076}
2077
2078static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002079Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00002080{
Guido van Rossum35d43371997-08-02 00:09:09 +00002081 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00002082}
2083
2084static PyTypeObject Tkapp_Type =
2085{
Guido van Rossum35d43371997-08-02 00:09:09 +00002086 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002087 0, /*ob_size */
2088 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002089 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002090 0, /*tp_itemsize */
2091 Tkapp_Dealloc, /*tp_dealloc */
2092 0, /*tp_print */
2093 Tkapp_GetAttr, /*tp_getattr */
2094 0, /*tp_setattr */
2095 0, /*tp_compare */
2096 0, /*tp_repr */
2097 0, /*tp_as_number */
2098 0, /*tp_as_sequence */
2099 0, /*tp_as_mapping */
2100 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00002101};
2102
Barry Warsawfa701a81997-01-16 00:15:11 +00002103
2104
Guido van Rossum18468821994-06-20 07:49:28 +00002105/**** Tkinter Module ****/
2106
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002107typedef struct {
2108 PyObject* tuple;
2109 int size; /* current size */
2110 int maxsize; /* allocated size */
2111} FlattenContext;
2112
2113static int
2114_bump(FlattenContext* context, int size)
2115{
Guido van Rossum2834b972000-10-06 16:58:26 +00002116 /* expand tuple to hold (at least) size new items.
2117 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002118
2119 int maxsize = context->maxsize * 2;
2120
2121 if (maxsize < context->size + size)
2122 maxsize = context->size + size;
2123
2124 context->maxsize = maxsize;
2125
Tim Peters4324aa32001-05-28 22:30:08 +00002126 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002127}
2128
2129static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002130_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002131{
2132 /* add tuple or list to argument tuple (recursively) */
2133
2134 int i, size;
2135
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002136 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002137 PyErr_SetString(PyExc_ValueError,
2138 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002139 return 0;
2140 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002141 size = PyList_GET_SIZE(item);
2142 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002143 if (context->size + size > context->maxsize &&
2144 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002145 return 0;
2146 /* copy items to output tuple */
2147 for (i = 0; i < size; i++) {
2148 PyObject *o = PyList_GET_ITEM(item, i);
2149 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002150 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002151 return 0;
2152 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002153 if (context->size + 1 > context->maxsize &&
2154 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002155 return 0;
2156 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002157 PyTuple_SET_ITEM(context->tuple,
2158 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002159 }
2160 }
2161 } else if (PyTuple_Check(item)) {
2162 /* same, for tuples */
2163 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002164 if (context->size + size > context->maxsize &&
2165 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002166 return 0;
2167 for (i = 0; i < size; i++) {
2168 PyObject *o = PyTuple_GET_ITEM(item, i);
2169 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002170 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002171 return 0;
2172 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002173 if (context->size + 1 > context->maxsize &&
2174 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002175 return 0;
2176 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002177 PyTuple_SET_ITEM(context->tuple,
2178 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002179 }
2180 }
2181 } else {
2182 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2183 return 0;
2184 }
2185 return 1;
2186}
2187
2188static PyObject *
2189Tkinter_Flatten(PyObject* self, PyObject* args)
2190{
2191 FlattenContext context;
2192 PyObject* item;
2193
2194 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2195 return NULL;
2196
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002197 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002198 if (context.maxsize <= 0)
2199 return PyTuple_New(0);
2200
2201 context.tuple = PyTuple_New(context.maxsize);
2202 if (!context.tuple)
2203 return NULL;
2204
2205 context.size = 0;
2206
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002207 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002208 return NULL;
2209
Tim Peters4324aa32001-05-28 22:30:08 +00002210 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002211 return NULL;
2212
2213 return context.tuple;
2214}
2215
Guido van Rossum18468821994-06-20 07:49:28 +00002216static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002217Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002218{
Barry Warsawfa701a81997-01-16 00:15:11 +00002219 char *screenName = NULL;
2220 char *baseName = NULL;
2221 char *className = NULL;
2222 int interactive = 0;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002223 int wantobjects = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002224
Guido van Rossum35d43371997-08-02 00:09:09 +00002225 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00002226 if (baseName != NULL)
2227 baseName++;
2228 else
2229 baseName = Py_GetProgramName();
2230 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00002231
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00002232 if (!PyArg_ParseTuple(args, "|zssii:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002233 &screenName, &baseName, &className,
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002234 &interactive, &wantobjects))
Barry Warsawfa701a81997-01-16 00:15:11 +00002235 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002236
Barry Warsawfa701a81997-01-16 00:15:11 +00002237 return (PyObject *) Tkapp_New(screenName, baseName, className,
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002238 interactive, wantobjects);
Guido van Rossum18468821994-06-20 07:49:28 +00002239}
2240
2241static PyMethodDef moduleMethods[] =
2242{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002243 {"_flatten", Tkinter_Flatten, METH_VARARGS},
2244 {"create", Tkinter_Create, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002245#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002246 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2247 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002248#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002249 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2250 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2251 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2252 {"quit", Tkapp_Quit, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002253 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002254};
2255
Guido van Rossum7bf15641998-05-22 18:28:17 +00002256#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002257
2258static int stdin_ready = 0;
2259
Guido van Rossumad4db171998-06-13 13:56:28 +00002260#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00002261static void
Fred Drake509d79a2000-07-08 04:04:38 +00002262MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002263{
2264 stdin_ready = 1;
2265}
Guido van Rossumad4db171998-06-13 13:56:28 +00002266#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002267
Guido van Rossum00d93061998-05-28 23:06:38 +00002268static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002269
Guido van Rossum18468821994-06-20 07:49:28 +00002270static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002271EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002272{
Guido van Rossumad4db171998-06-13 13:56:28 +00002273#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002274 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002275#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002276#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002277 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002278#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002279 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002280 errorInCmd = 0;
2281#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002282 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002283 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002284#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002285 while (!errorInCmd && !stdin_ready) {
2286 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002287#ifdef MS_WINDOWS
2288 if (_kbhit()) {
2289 stdin_ready = 1;
2290 break;
2291 }
2292#endif
2293#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002294 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00002295 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002296 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002297
Guido van Rossum00d93061998-05-28 23:06:38 +00002298 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002299
2300 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00002301 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002302 if (result == 0)
2303 Sleep(20);
2304 Py_END_ALLOW_THREADS
2305#else
2306 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002307#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002308
2309 if (result < 0)
2310 break;
2311 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002312#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002313 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002314#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002315 if (errorInCmd) {
2316 errorInCmd = 0;
2317 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2318 excInCmd = valInCmd = trbInCmd = NULL;
2319 PyErr_Print();
2320 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002321#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002322 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002323#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002324 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002325}
Guido van Rossum18468821994-06-20 07:49:28 +00002326
Guido van Rossum00d93061998-05-28 23:06:38 +00002327#endif
2328
Guido van Rossum7bf15641998-05-22 18:28:17 +00002329static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002330EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002331{
Guido van Rossum00d93061998-05-28 23:06:38 +00002332#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002333 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002334#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002335 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002336#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002337 PyOS_InputHook = EventHook;
2338 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002339#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002340}
2341
2342static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002343DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002344{
Guido van Rossum00d93061998-05-28 23:06:38 +00002345#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002346 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2347 PyOS_InputHook = NULL;
2348 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002349#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002350}
2351
Barry Warsawfa701a81997-01-16 00:15:11 +00002352
2353/* all errors will be checked in one fell swoop in init_tkinter() */
2354static void
Fred Drake509d79a2000-07-08 04:04:38 +00002355ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002356{
2357 PyObject *v = PyInt_FromLong(val);
2358 if (v) {
2359 PyDict_SetItemString(d, name, v);
2360 Py_DECREF(v);
2361 }
2362}
2363static void
Fred Drake509d79a2000-07-08 04:04:38 +00002364ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002365{
2366 PyObject *v = PyString_FromString(val);
2367 if (v) {
2368 PyDict_SetItemString(d, name, v);
2369 Py_DECREF(v);
2370 }
2371}
2372
2373
Mark Hammond62b1ab12002-07-23 06:31:15 +00002374PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002375init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002376{
Barry Warsawfa701a81997-01-16 00:15:11 +00002377 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002378
Barry Warsawfa701a81997-01-16 00:15:11 +00002379 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002380
2381#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002382 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002383#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002384
Barry Warsawfa701a81997-01-16 00:15:11 +00002385 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002386
Barry Warsawfa701a81997-01-16 00:15:11 +00002387 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00002388 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00002389 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002390
Guido van Rossum35d43371997-08-02 00:09:09 +00002391 ins_long(d, "READABLE", TCL_READABLE);
2392 ins_long(d, "WRITABLE", TCL_WRITABLE);
2393 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2394 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2395 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2396 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2397 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2398 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2399 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002400 ins_string(d, "TK_VERSION", TK_VERSION);
2401 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002402
Guido van Rossum83551bf1997-09-13 00:44:23 +00002403 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002404
2405 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002406 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2407
Martin v. Löwisffad6332002-11-26 09:28:05 +00002408 PyTclObject_Type.ob_type = &PyType_Type;
2409 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00002410
2411#ifdef TK_AQUA
2412 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
2413 * start waking up. Note that Tcl_FindExecutable will do this, this
2414 * code must be above it! The original warning from
2415 * tkMacOSXAppInit.c is copied below.
2416 *
2417 * NB - You have to swap in the Tk Notifier BEFORE you start up the
2418 * Tcl interpreter for now. It probably should work to do this
2419 * in the other order, but for now it doesn't seem to.
2420 *
2421 */
2422 Tk_MacOSXSetupTkNotifier();
2423#endif
2424
2425
Guido van Rossume187b0e2000-03-27 21:46:29 +00002426 /* This helps the dynamic loader; in Unicode aware Tcl versions
2427 it also helps Tcl find its encodings. */
2428 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002429
Barry Warsawfa701a81997-01-16 00:15:11 +00002430 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002431 return;
2432
Guido van Rossum43ff8681998-07-14 18:02:13 +00002433#if 0
2434 /* This was not a good idea; through <Destroy> bindings,
2435 Tcl_Finalize() may invoke Python code but at that point the
2436 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002437 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002438#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002439
Jack Jansen34cc5c31995-10-31 16:15:12 +00002440#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002441 /*
2442 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2443 ** Most of the initializations in that routine (toolbox init calls and
2444 ** such) have already been done for us, so we only need these.
2445 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002446 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002447
2448 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002449#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002450 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002451#endif /* GENERATINGCFM */
2452#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002453}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002454
Guido van Rossumec22c921996-02-25 04:50:29 +00002455
Barry Warsawfa701a81997-01-16 00:15:11 +00002456
Guido van Rossum9722ad81995-09-22 23:49:28 +00002457#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002458
2459/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002460** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002461*/
2462
Guido van Rossum9722ad81995-09-22 23:49:28 +00002463void
2464panic(char * format, ...)
2465{
Barry Warsawfa701a81997-01-16 00:15:11 +00002466 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002467
Barry Warsawfa701a81997-01-16 00:15:11 +00002468 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002469
Guido van Rossum227cf761998-08-05 13:53:32 +00002470 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002471 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002472
Barry Warsawfa701a81997-01-16 00:15:11 +00002473 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002474
Barry Warsawfa701a81997-01-16 00:15:11 +00002475 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002476}
Jack Jansen40b546d1995-11-14 10:34:45 +00002477
Guido van Rossumec22c921996-02-25 04:50:29 +00002478/*
2479** Pass events to SIOUX before passing them to Tk.
2480*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002481
Guido van Rossumec22c921996-02-25 04:50:29 +00002482static int
Fred Drake509d79a2000-07-08 04:04:38 +00002483PyMacConvertEvent(EventRecord *eventPtr)
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002484{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002485 WindowPtr frontwin;
2486 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002487 ** Sioux eats too many events, so we don't pass it everything. We
2488 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002489 ** the Sioux window is frontmost. This means that Tk menus don't work
2490 ** in that case, but at least we can scroll the sioux window.
2491 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2492 ** part of the external interface of Sioux...
2493 */
2494 frontwin = FrontWindow();
2495 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2496 if (SIOUXHandleOneEvent(eventPtr))
2497 return 0; /* Nothing happened to the Tcl event queue */
2498 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002499 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002500}
2501
Guido van Rossumec22c921996-02-25 04:50:29 +00002502#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002503
2504/*
2505** Additional Mac specific code for dealing with shared libraries.
2506*/
2507
2508#include <Resources.h>
2509#include <CodeFragments.h>
2510
2511static int loaded_from_shlib = 0;
2512static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002513
Jack Jansen34cc5c31995-10-31 16:15:12 +00002514/*
2515** If this module is dynamically loaded the following routine should
2516** be the init routine. It takes care of adding the shared library to
2517** the resource-file chain, so that the tk routines can find their
2518** resources.
2519*/
2520OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002521init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002522{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002523 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002524 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002525 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002526 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2527 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002528 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002529 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2530 loaded_from_shlib = 1;
2531 }
2532 return noErr;
2533}
2534
2535/*
2536** Insert the library resources into the search path. Put them after
2537** the resources from the application. Again, we ignore errors.
2538*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002539static
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002540mac_addlibresources(void)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002541{
2542 if ( !loaded_from_shlib )
2543 return;
2544 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2545}
2546
Guido van Rossumec22c921996-02-25 04:50:29 +00002547#endif /* GENERATINGCFM */
2548#endif /* macintosh */