blob: 22850a4ff52b728eeb126a2b4a5b436056aabbad [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
773 if (value->typePtr == NULL)
774 return PyString_FromStringAndSize(value->bytes, value->length);
775
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000776 if (value->typePtr == app->BooleanType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000777 result = value->internalRep.longValue ? Py_True : Py_False;
778 Py_INCREF(result);
779 return result;
780 }
781
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000782 if (value->typePtr == app->ByteArrayType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000783 int size;
784 char *data = Tcl_GetByteArrayFromObj(value, &size);
785 return PyString_FromStringAndSize(data, size);
786 }
787
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000788 if (value->typePtr == app->DoubleType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000789 return PyFloat_FromDouble(value->internalRep.doubleValue);
790 }
791
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000792 if (value->typePtr == app->IntType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000793 return PyInt_FromLong(value->internalRep.longValue);
794 }
795
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000796 if (value->typePtr == app->ListType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000797 int size;
798 int i, status;
799 PyObject *elem;
800 Tcl_Obj *tcl_elem;
801
802 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
803 if (status == TCL_ERROR)
804 return Tkinter_Error(tkapp);
805 result = PyTuple_New(size);
806 if (!result)
807 return NULL;
808 for (i = 0; i < size; i++) {
809 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
810 value, i, &tcl_elem);
811 if (status == TCL_ERROR) {
812 Py_DECREF(result);
813 return Tkinter_Error(tkapp);
814 }
815 elem = FromObj(tkapp, tcl_elem);
816 if (!elem) {
817 Py_DECREF(result);
818 return NULL;
819 }
820 PyTuple_SetItem(result, i, elem);
821 }
822 return result;
823 }
824
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000825 if (value->typePtr == app->ProcBodyType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000826 // fall through: return tcl object
827 }
828
Martin v. Löwis4ec2e702002-11-26 22:12:12 +0000829 if (value->typePtr == app->StringType) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000830#ifdef Py_USING_UNICODE
831#ifdef Py_UNICODE_WIDE
832 PyObject *result;
833 int size;
834 Tcl_UniChar *input;
835 Py_UNICODE *output;
836
837 size = Tcl_GetCharLength(value);
838 result = PyUnicode_FromUnicode(NULL, size);
839 if (!result)
840 return NULL;
841 input = Tcl_GetUnicode(value);
842 output = PyUnicode_AS_UNICODE(result);
843 while (size--)
844 *output++ = *input++;
845 return result;
846#else
847 return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
848 Tcl_GetCharLength(value));
849#endif
850#else
851 int size;
852 char *c;
853 c = Tcl_GetStringFromObj(value, &size);
854 return PyString_FromStringAndSize(c, size);
855#endif
856 }
857
858 return newPyTclObject(value);
859}
860
Guido van Rossum18468821994-06-20 07:49:28 +0000861static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000862Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000863{
Guido van Rossum632de272000-03-29 00:19:50 +0000864 Tcl_Obj *objStore[ARGSZ];
865 Tcl_Obj **objv = NULL;
866 int objc = 0, i;
867 PyObject *res = NULL;
868 Tcl_Interp *interp = Tkapp_Interp(self);
869 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
870 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000871
Guido van Rossum632de272000-03-29 00:19:50 +0000872 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000873
Guido van Rossum212643f1998-04-29 16:22:14 +0000874 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +0000875 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +0000876
Guido van Rossum212643f1998-04-29 16:22:14 +0000877 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000878 objv[0] = AsObj(args);
879 if (objv[0] == 0)
880 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000881 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +0000882 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000883 }
884 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000885 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000886
Guido van Rossum632de272000-03-29 00:19:50 +0000887 if (objc > ARGSZ) {
888 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
889 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000890 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +0000891 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +0000892 goto finally;
893 }
894 }
895
Guido van Rossum632de272000-03-29 00:19:50 +0000896 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000897 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +0000898 if (v == Py_None) {
899 objc = i;
900 break;
901 }
Guido van Rossum632de272000-03-29 00:19:50 +0000902 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +0000903 if (!objv[i]) {
904 /* Reset objc, so it attempts to clear
905 objects only up to i. */
906 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +0000907 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000908 }
Guido van Rossum632de272000-03-29 00:19:50 +0000909 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000910 }
911 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000912
Guido van Rossum62320c91998-06-15 04:36:09 +0000913 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000914
915 i = Tcl_EvalObjv(interp, objc, objv, flags);
916
Guido van Rossum62320c91998-06-15 04:36:09 +0000917 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000918 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000919 Tkinter_Error(self);
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +0000920 else if(((TkappObject*)self)->wantobjects) {
Martin v. Löwisffad6332002-11-26 09:28:05 +0000921 Tcl_Obj *value = Tcl_GetObjResult(interp);
922 /* Not sure whether the IncrRef is necessary, but something
923 may overwrite the interpreter result while we are
924 converting it. */
925 Tcl_IncrRefCount(value);
926 res = FromObj(self, value);
927 Tcl_DecrRefCount(value);
928 } else {
Martin v. Löwis71e25a02002-10-01 18:08:06 +0000929 const char *s = Tcl_GetStringResult(interp);
930 const char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000931
Guido van Rossum990f5c62000-05-04 15:07:16 +0000932 /* If the result contains any bytes with the top bit set,
933 it's UTF-8 and we should decode it to Unicode */
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000934#ifdef Py_USING_UNICODE
Guido van Rossum990f5c62000-05-04 15:07:16 +0000935 while (*p != '\0') {
936 if (*p & 0x80)
937 break;
938 p++;
939 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000940
Guido van Rossum990f5c62000-05-04 15:07:16 +0000941 if (*p == '\0')
942 res = PyString_FromStringAndSize(s, (int)(p-s));
943 else {
944 /* Convert UTF-8 to Unicode string */
945 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +0000946 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
947 if (res == NULL) {
Guido van Rossum2834b972000-10-06 16:58:26 +0000948 PyErr_Clear();
949 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum69529ad2000-05-04 15:55:17 +0000950 }
Guido van Rossum990f5c62000-05-04 15:07:16 +0000951 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000952#else
953 p = strchr(p, '\0');
954 res = PyString_FromStringAndSize(s, (int)(p-s));
955#endif
Guido van Rossum990f5c62000-05-04 15:07:16 +0000956 }
Guido van Rossum632de272000-03-29 00:19:50 +0000957
Guido van Rossum62320c91998-06-15 04:36:09 +0000958 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000959
Guido van Rossum212643f1998-04-29 16:22:14 +0000960 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000961 for (i = 0; i < objc; i++)
962 Tcl_DecrRefCount(objv[i]);
963 if (objv != objStore)
964 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000965 return res;
966}
967
968
969static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000970Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000971{
Guido van Rossum212643f1998-04-29 16:22:14 +0000972 /* Could do the same here as for Tkapp_Call(), but this is not used
973 much, so I can't be bothered. Unfortunately Tcl doesn't export a
974 way for the user to do what all its Global* variants do (save and
975 reset the scope pointer, call the local version, restore the saved
976 scope pointer). */
977
Guido van Rossum62320c91998-06-15 04:36:09 +0000978 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000979 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000980
Guido van Rossum62320c91998-06-15 04:36:09 +0000981 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +0000982 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000983 int err;
984 ENTER_TCL
985 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000986 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000987 if (err == TCL_ERROR)
988 res = Tkinter_Error(self);
989 else
990 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000991 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000992 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +0000993 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000994
995 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000996}
997
998static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000999Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001000{
Barry Warsawfa701a81997-01-16 00:15:11 +00001001 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001002 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001003 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001004
Guido van Rossum43713e52000-02-29 13:59:29 +00001005 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001006 return NULL;
1007
Guido van Rossum00d93061998-05-28 23:06:38 +00001008 ENTER_TCL
1009 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001010 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001011 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001012 res = Tkinter_Error(self);
1013 else
1014 res = PyString_FromString(Tkapp_Result(self));
1015 LEAVE_OVERLAP_TCL
1016 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001017}
1018
1019static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001020Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001021{
Barry Warsawfa701a81997-01-16 00:15:11 +00001022 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001023 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001024 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +00001025
Guido van Rossum43713e52000-02-29 13:59:29 +00001026 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001027 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001028
Guido van Rossum00d93061998-05-28 23:06:38 +00001029 ENTER_TCL
1030 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001031 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001032 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001033 res = Tkinter_Error(self);
1034 else
1035 res = PyString_FromString(Tkapp_Result(self));
1036 LEAVE_OVERLAP_TCL
1037 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001038}
1039
1040static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001041Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001042{
Barry Warsawfa701a81997-01-16 00:15:11 +00001043 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +00001044 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001045 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001046
Guido van Rossum43713e52000-02-29 13:59:29 +00001047 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001048 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001049
Guido van Rossum00d93061998-05-28 23:06:38 +00001050 ENTER_TCL
1051 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +00001052 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001053 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001054 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001055
Guido van Rossum62320c91998-06-15 04:36:09 +00001056 else
1057 res = PyString_FromString(Tkapp_Result(self));
1058 LEAVE_OVERLAP_TCL
1059 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001060}
1061
1062static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001063Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001064{
Barry Warsawfa701a81997-01-16 00:15:11 +00001065 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001066 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001067 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001068
Guido van Rossum35d43371997-08-02 00:09:09 +00001069 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001070 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001071
Guido van Rossum00d93061998-05-28 23:06:38 +00001072 ENTER_TCL
1073 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +00001074 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001075 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001076 res = Tkinter_Error(self);
1077 else
1078 res = PyString_FromString(Tkapp_Result(self));
1079 LEAVE_OVERLAP_TCL
1080 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001081}
1082
1083static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001084Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001085{
Barry Warsawfa701a81997-01-16 00:15:11 +00001086 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +00001087
Guido van Rossum43713e52000-02-29 13:59:29 +00001088 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +00001089 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001090 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001091 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +00001092 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001093
Barry Warsawfa701a81997-01-16 00:15:11 +00001094 Py_INCREF(Py_None);
1095 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001096}
1097
Barry Warsawfa701a81997-01-16 00:15:11 +00001098
1099
Guido van Rossum18468821994-06-20 07:49:28 +00001100/** Tcl Variable **/
1101
1102static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001103SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001104{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001105 char *name1, *name2, *s;
1106 const char *ok;
Barry Warsawfa701a81997-01-16 00:15:11 +00001107 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +00001108 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +00001109
Guido van Rossum62320c91998-06-15 04:36:09 +00001110 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +00001111 if (!tmp)
1112 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001113
Guido van Rossum43713e52000-02-29 13:59:29 +00001114 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001115 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +00001116 s = AsString(newValue, tmp);
Guido van Rossum2834b972000-10-06 16:58:26 +00001117 if (s == NULL)
1118 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001119 ENTER_TCL
1120 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
1121 LEAVE_TCL
1122 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001123 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001124 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +00001125 if (PyArg_ParseTuple(args, "ssO:setvar",
1126 &name1, &name2, &newValue)) {
1127 s = AsString(newValue, tmp);
1128 if (s == NULL)
1129 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001130 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001131 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +00001132 s, flags);
1133 LEAVE_TCL
1134 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001135 else {
Guido van Rossum00d93061998-05-28 23:06:38 +00001136 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +00001137 return NULL;
1138 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001139 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001140 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +00001141
Barry Warsawfa701a81997-01-16 00:15:11 +00001142 if (!ok)
1143 return Tkinter_Error(self);
1144
1145 Py_INCREF(Py_None);
1146 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001147}
1148
1149static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001150Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001151{
Barry Warsawfa701a81997-01-16 00:15:11 +00001152 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001153}
1154
1155static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001156Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001157{
Barry Warsawfa701a81997-01-16 00:15:11 +00001158 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001159}
1160
Barry Warsawfa701a81997-01-16 00:15:11 +00001161
1162
Guido van Rossum18468821994-06-20 07:49:28 +00001163static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001164GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001165{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001166 char *name1, *name2=NULL;
1167 const char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001168 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001169
Guido van Rossum43713e52000-02-29 13:59:29 +00001170 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +00001171 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001172 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001173 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +00001174 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +00001175
Barry Warsawfa701a81997-01-16 00:15:11 +00001176 else
Guido van Rossum35d43371997-08-02 00:09:09 +00001177 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001178 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001179
Barry Warsawfa701a81997-01-16 00:15:11 +00001180 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +00001181 res = Tkinter_Error(self);
1182 else
1183 res = PyString_FromString(s);
1184 LEAVE_OVERLAP_TCL
1185 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001186}
1187
1188static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001189Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001190{
Barry Warsawfa701a81997-01-16 00:15:11 +00001191 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001192}
1193
1194static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001195Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001196{
Barry Warsawfa701a81997-01-16 00:15:11 +00001197 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001198}
1199
Barry Warsawfa701a81997-01-16 00:15:11 +00001200
1201
Guido van Rossum18468821994-06-20 07:49:28 +00001202static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001203UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001204{
Guido van Rossum35d43371997-08-02 00:09:09 +00001205 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001206 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001207 int code;
Guido van Rossum18468821994-06-20 07:49:28 +00001208
Guido van Rossum43713e52000-02-29 13:59:29 +00001209 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001210 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001211 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001212 if (name2 == NULL)
1213 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
1214
1215 else
1216 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001217 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001218
Barry Warsawfa701a81997-01-16 00:15:11 +00001219 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001220 res = Tkinter_Error(self);
1221 else {
1222 Py_INCREF(Py_None);
1223 res = Py_None;
1224 }
1225 LEAVE_OVERLAP_TCL
1226 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001227}
1228
1229static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001230Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001231{
Barry Warsawfa701a81997-01-16 00:15:11 +00001232 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001233}
1234
1235static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001236Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001237{
Barry Warsawfa701a81997-01-16 00:15:11 +00001238 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001239}
1240
Barry Warsawfa701a81997-01-16 00:15:11 +00001241
1242
Guido van Rossum18468821994-06-20 07:49:28 +00001243/** Tcl to Python **/
1244
1245static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001246Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001247{
Barry Warsawfa701a81997-01-16 00:15:11 +00001248 char *s;
1249 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001250
Martin v. Löwisffad6332002-11-26 09:28:05 +00001251 if (PyTuple_Size(args) == 1) {
1252 PyObject* o = PyTuple_GetItem(args, 0);
1253 if (PyInt_Check(o)) {
1254 Py_INCREF(o);
1255 return o;
1256 }
1257 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001258 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001259 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001260 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001261 return Tkinter_Error(self);
1262 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001263}
1264
1265static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001266Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001267{
Barry Warsawfa701a81997-01-16 00:15:11 +00001268 char *s;
1269 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001270
Martin v. Löwisffad6332002-11-26 09:28:05 +00001271 if (PyTuple_Size(args) == 1) {
1272 PyObject *o = PyTuple_GetItem(args, 0);
1273 if (PyFloat_Check(o)) {
1274 Py_INCREF(o);
1275 return o;
1276 }
1277 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001278 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001279 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001280 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001281 return Tkinter_Error(self);
1282 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001283}
1284
1285static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001286Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001287{
Barry Warsawfa701a81997-01-16 00:15:11 +00001288 char *s;
1289 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001290
Martin v. Löwisffad6332002-11-26 09:28:05 +00001291 if (PyTuple_Size(args) == 1) {
1292 PyObject *o = PyTuple_GetItem(args, 0);
1293 if (PyInt_Check(o)) {
1294 Py_INCREF(o);
1295 return o;
1296 }
1297 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001298 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001299 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001300 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1301 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001302 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001303}
1304
1305static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001306Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001307{
Barry Warsawfa701a81997-01-16 00:15:11 +00001308 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001309 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001310 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001311
Guido van Rossum43713e52000-02-29 13:59:29 +00001312 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001313 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001314 ENTER_TCL
1315 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001316 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001317 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001318 res = Tkinter_Error(self);
1319 else
1320 res = Py_BuildValue("s", Tkapp_Result(self));
1321 LEAVE_OVERLAP_TCL
1322 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001323}
1324
1325static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001326Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001327{
Barry Warsawfa701a81997-01-16 00:15:11 +00001328 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001329 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001330 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001331 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001332
Guido van Rossum43713e52000-02-29 13:59:29 +00001333 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001334 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001335 ENTER_TCL
1336 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001337 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001338 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001339 res = Tkinter_Error(self);
1340 else
1341 res = Py_BuildValue("l", v);
1342 LEAVE_OVERLAP_TCL
1343 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001344}
1345
1346static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001347Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001348{
Barry Warsawfa701a81997-01-16 00:15:11 +00001349 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001350 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001351 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001352 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001353
Guido van Rossum43713e52000-02-29 13:59:29 +00001354 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001355 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001356 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001357 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001358 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001359 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001360 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001361 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001362 res = Tkinter_Error(self);
1363 else
1364 res = Py_BuildValue("d", v);
1365 LEAVE_OVERLAP_TCL
1366 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001367}
1368
1369static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001370Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001371{
Barry Warsawfa701a81997-01-16 00:15:11 +00001372 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001373 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001374 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001375 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001376
Guido van Rossum43713e52000-02-29 13:59:29 +00001377 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001378 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001379 ENTER_TCL
1380 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001381 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001382 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001383 res = Tkinter_Error(self);
1384 else
1385 res = Py_BuildValue("i", v);
1386 LEAVE_OVERLAP_TCL
1387 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001388}
1389
Barry Warsawfa701a81997-01-16 00:15:11 +00001390
1391
Guido van Rossum18468821994-06-20 07:49:28 +00001392static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001393Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001394{
Barry Warsawfa701a81997-01-16 00:15:11 +00001395 char *list;
1396 int argc;
1397 char **argv;
1398 PyObject *v;
1399 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001400
Martin v. Löwisffad6332002-11-26 09:28:05 +00001401 if (PyTuple_Size(args) == 1) {
1402 v = PyTuple_GetItem(args, 0);
1403 if (PyTuple_Check(v)) {
1404 Py_INCREF(v);
1405 return v;
1406 }
1407 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001408 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001409 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001410
Barry Warsawfa701a81997-01-16 00:15:11 +00001411 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1412 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001413
Barry Warsawfa701a81997-01-16 00:15:11 +00001414 if (!(v = PyTuple_New(argc)))
1415 return NULL;
1416
1417 for (i = 0; i < argc; i++) {
1418 PyObject *s = PyString_FromString(argv[i]);
1419 if (!s || PyTuple_SetItem(v, i, s)) {
1420 Py_DECREF(v);
1421 v = NULL;
1422 goto finally;
1423 }
1424 }
Guido van Rossum18468821994-06-20 07:49:28 +00001425
Barry Warsawfa701a81997-01-16 00:15:11 +00001426 finally:
1427 ckfree(FREECAST argv);
1428 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001429}
1430
1431static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001432Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001433{
Barry Warsawfa701a81997-01-16 00:15:11 +00001434 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001435
Martin v. Löwisffad6332002-11-26 09:28:05 +00001436 if (PyTuple_Size(args) == 1) {
1437 PyObject* o = PyTuple_GetItem(args, 0);
1438 if (PyTuple_Check(o)) {
1439 o = SplitObj(o);
1440 return o;
1441 }
1442 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001443 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001444 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001445 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001446}
1447
1448static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001449Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001450{
Barry Warsawfa701a81997-01-16 00:15:11 +00001451 char *s = Merge(args);
1452 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001453
Barry Warsawfa701a81997-01-16 00:15:11 +00001454 if (s) {
1455 res = PyString_FromString(s);
1456 ckfree(s);
1457 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001458
1459 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001460}
1461
Barry Warsawfa701a81997-01-16 00:15:11 +00001462
1463
Guido van Rossum18468821994-06-20 07:49:28 +00001464/** Tcl Command **/
1465
Guido van Rossum00d93061998-05-28 23:06:38 +00001466/* Client data struct */
1467typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001468 PyObject *self;
1469 PyObject *func;
1470} PythonCmd_ClientData;
1471
1472static int
Fred Drake509d79a2000-07-08 04:04:38 +00001473PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001474{
1475 errorInCmd = 1;
1476 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1477 LEAVE_PYTHON
1478 return TCL_ERROR;
1479}
1480
Guido van Rossum18468821994-06-20 07:49:28 +00001481/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001482 * function or method.
1483 */
Guido van Rossum18468821994-06-20 07:49:28 +00001484static int
Fred Drake509d79a2000-07-08 04:04:38 +00001485PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001486{
Guido van Rossum00d93061998-05-28 23:06:38 +00001487 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001488 PyObject *self, *func, *arg, *res, *tmp;
Guido van Rossum2834b972000-10-06 16:58:26 +00001489 int i, rv;
1490 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +00001491
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001492 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001493
Barry Warsawfa701a81997-01-16 00:15:11 +00001494 /* TBD: no error checking here since we know, via the
1495 * Tkapp_CreateCommand() that the client data is a two-tuple
1496 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001497 self = data->self;
1498 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001499
Barry Warsawfa701a81997-01-16 00:15:11 +00001500 /* Create argument list (argv1, ..., argvN) */
1501 if (!(arg = PyTuple_New(argc - 1)))
1502 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001503
Barry Warsawfa701a81997-01-16 00:15:11 +00001504 for (i = 0; i < (argc - 1); i++) {
1505 PyObject *s = PyString_FromString(argv[i + 1]);
1506 if (!s || PyTuple_SetItem(arg, i, s)) {
1507 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001508 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001509 }
1510 }
1511 res = PyEval_CallObject(func, arg);
1512 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001513
Barry Warsawfa701a81997-01-16 00:15:11 +00001514 if (res == NULL)
1515 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001516
Barry Warsawfa701a81997-01-16 00:15:11 +00001517 if (!(tmp = PyList_New(0))) {
1518 Py_DECREF(res);
1519 return PythonCmd_Error(interp);
1520 }
1521
Guido van Rossum2834b972000-10-06 16:58:26 +00001522 s = AsString(res, tmp);
1523 if (s == NULL) {
1524 rv = PythonCmd_Error(interp);
1525 }
1526 else {
1527 Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
1528 rv = TCL_OK;
1529 }
1530
Barry Warsawfa701a81997-01-16 00:15:11 +00001531 Py_DECREF(res);
1532 Py_DECREF(tmp);
1533
Guido van Rossum00d93061998-05-28 23:06:38 +00001534 LEAVE_PYTHON
1535
Guido van Rossum2834b972000-10-06 16:58:26 +00001536 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00001537}
1538
1539static void
Fred Drake509d79a2000-07-08 04:04:38 +00001540PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00001541{
Guido van Rossum00d93061998-05-28 23:06:38 +00001542 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1543
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001544 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001545 Py_XDECREF(data->self);
1546 Py_XDECREF(data->func);
1547 PyMem_DEL(data);
1548 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001549}
1550
Barry Warsawfa701a81997-01-16 00:15:11 +00001551
1552
Guido van Rossum18468821994-06-20 07:49:28 +00001553static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001554Tkapp_CreateCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001555{
Guido van Rossum00d93061998-05-28 23:06:38 +00001556 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001557 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001558 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001559 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001560
Guido van Rossum43713e52000-02-29 13:59:29 +00001561 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001562 return NULL;
1563 if (!PyCallable_Check(func)) {
1564 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001565 return NULL;
1566 }
Guido van Rossum18468821994-06-20 07:49:28 +00001567
Guido van Rossum00d93061998-05-28 23:06:38 +00001568 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001569 if (!data)
1570 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001571 Py_XINCREF(self);
1572 Py_XINCREF(func);
1573 data->self = self;
1574 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001575
Guido van Rossum00d93061998-05-28 23:06:38 +00001576 ENTER_TCL
1577 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1578 (ClientData)data, PythonCmdDelete);
1579 LEAVE_TCL
1580 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001581 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001582 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001583 return NULL;
1584 }
Guido van Rossum18468821994-06-20 07:49:28 +00001585
Barry Warsawfa701a81997-01-16 00:15:11 +00001586 Py_INCREF(Py_None);
1587 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001588}
1589
Barry Warsawfa701a81997-01-16 00:15:11 +00001590
1591
Guido van Rossum18468821994-06-20 07:49:28 +00001592static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001593Tkapp_DeleteCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001594{
Barry Warsawfa701a81997-01-16 00:15:11 +00001595 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001596 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001597
Guido van Rossum43713e52000-02-29 13:59:29 +00001598 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001599 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001600 ENTER_TCL
1601 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1602 LEAVE_TCL
1603 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001604 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1605 return NULL;
1606 }
1607 Py_INCREF(Py_None);
1608 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001609}
1610
Barry Warsawfa701a81997-01-16 00:15:11 +00001611
1612
Guido van Rossum00d93061998-05-28 23:06:38 +00001613#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001614/** File Handler **/
1615
Guido van Rossum00d93061998-05-28 23:06:38 +00001616typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001617 PyObject *func;
1618 PyObject *file;
1619 int id;
1620 struct _fhcdata *next;
1621} FileHandler_ClientData;
1622
1623static FileHandler_ClientData *HeadFHCD;
1624
1625static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00001626NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001627{
1628 FileHandler_ClientData *p;
1629 p = PyMem_NEW(FileHandler_ClientData, 1);
1630 if (p != NULL) {
1631 Py_XINCREF(func);
1632 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001633 p->func = func;
1634 p->file = file;
1635 p->id = id;
1636 p->next = HeadFHCD;
1637 HeadFHCD = p;
1638 }
1639 return p;
1640}
1641
1642static void
Fred Drake509d79a2000-07-08 04:04:38 +00001643DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001644{
1645 FileHandler_ClientData *p, **pp;
1646
1647 pp = &HeadFHCD;
1648 while ((p = *pp) != NULL) {
1649 if (p->id == id) {
1650 *pp = p->next;
1651 Py_XDECREF(p->func);
1652 Py_XDECREF(p->file);
1653 PyMem_DEL(p);
1654 }
1655 else
1656 pp = &p->next;
1657 }
1658}
1659
Guido van Rossuma597dde1995-01-10 20:56:29 +00001660static void
Fred Drake509d79a2000-07-08 04:04:38 +00001661FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00001662{
Guido van Rossum00d93061998-05-28 23:06:38 +00001663 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001664 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001665
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001666 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001667 func = data->func;
1668 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001669
Barry Warsawfa701a81997-01-16 00:15:11 +00001670 arg = Py_BuildValue("(Oi)", file, (long) mask);
1671 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001672 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001673
1674 if (res == NULL) {
1675 errorInCmd = 1;
1676 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1677 }
1678 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001679 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001680}
1681
Guido van Rossum18468821994-06-20 07:49:28 +00001682static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001683Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
1684 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001685{
Guido van Rossum00d93061998-05-28 23:06:38 +00001686 FileHandler_ClientData *data;
1687 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001688 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001689
Guido van Rossum2834b972000-10-06 16:58:26 +00001690 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
1691 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001692 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001693 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001694 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001695 return NULL;
1696 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001697 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001698 return NULL;
1699 }
1700
Guido van Rossuma80649b2000-03-28 20:07:05 +00001701 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001702 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001703 return NULL;
1704
Barry Warsawfa701a81997-01-16 00:15:11 +00001705 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001706 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001707 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001708 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001709 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001710 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001711}
1712
1713static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001714Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001715{
Barry Warsawfa701a81997-01-16 00:15:11 +00001716 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001717 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001718
Guido van Rossum43713e52000-02-29 13:59:29 +00001719 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001720 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001721 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001722 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001723 return NULL;
1724
Guido van Rossuma80649b2000-03-28 20:07:05 +00001725 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001726
Barry Warsawfa701a81997-01-16 00:15:11 +00001727 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001728 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001729 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001730 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001731 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001732 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001733}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001734#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001735
Barry Warsawfa701a81997-01-16 00:15:11 +00001736
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001737/**** Tktt Object (timer token) ****/
1738
Jeremy Hylton938ace62002-07-17 16:30:39 +00001739static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001740
Guido van Rossum00d93061998-05-28 23:06:38 +00001741typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001742 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001743 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001744 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001745} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001746
1747static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001748Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001749{
Barry Warsawfa701a81997-01-16 00:15:11 +00001750 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001751 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001752
Guido van Rossum43713e52000-02-29 13:59:29 +00001753 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001754 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001755 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001756 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001757 v->token = NULL;
1758 }
1759 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001760 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001761 Py_DECREF(func);
1762 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001763 }
1764 Py_INCREF(Py_None);
1765 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001766}
1767
1768static PyMethodDef Tktt_methods[] =
1769{
Neal Norwitzb0493252002-03-31 14:44:22 +00001770 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00001771 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001772};
1773
1774static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001775Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001776{
Barry Warsawfa701a81997-01-16 00:15:11 +00001777 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001778
Guido van Rossumb18618d2000-05-03 23:44:39 +00001779 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00001780 if (v == NULL)
1781 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001782
Guido van Rossum00d93061998-05-28 23:06:38 +00001783 Py_INCREF(func);
1784 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001785 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001786
1787 /* Extra reference, deleted when called or when handler is deleted */
1788 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001789 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001790}
1791
1792static void
Fred Drake509d79a2000-07-08 04:04:38 +00001793Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001794{
Guido van Rossum00d93061998-05-28 23:06:38 +00001795 TkttObject *v = (TkttObject *)self;
1796 PyObject *func = v->func;
1797
1798 Py_XDECREF(func);
1799
Guido van Rossumb18618d2000-05-03 23:44:39 +00001800 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001801}
1802
Guido van Rossum597ac201998-05-12 14:36:19 +00001803static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001804Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001805{
Barry Warsawfa701a81997-01-16 00:15:11 +00001806 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001807 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001808
Tim Peters885d4572001-11-28 20:27:42 +00001809 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00001810 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001811 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001812}
1813
1814static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001815Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001816{
Barry Warsawfa701a81997-01-16 00:15:11 +00001817 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001818}
1819
1820static PyTypeObject Tktt_Type =
1821{
Guido van Rossum35d43371997-08-02 00:09:09 +00001822 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001823 0, /*ob_size */
1824 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001825 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001826 0, /*tp_itemsize */
1827 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001828 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001829 Tktt_GetAttr, /*tp_getattr */
1830 0, /*tp_setattr */
1831 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001832 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001833 0, /*tp_as_number */
1834 0, /*tp_as_sequence */
1835 0, /*tp_as_mapping */
1836 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001837};
1838
Barry Warsawfa701a81997-01-16 00:15:11 +00001839
1840
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001841/** Timer Handler **/
1842
1843static void
Fred Drake509d79a2000-07-08 04:04:38 +00001844TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001845{
Guido van Rossum00d93061998-05-28 23:06:38 +00001846 TkttObject *v = (TkttObject *)clientData;
1847 PyObject *func = v->func;
1848 PyObject *res;
1849
1850 if (func == NULL)
1851 return;
1852
1853 v->func = NULL;
1854
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001855 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001856
1857 res = PyEval_CallObject(func, NULL);
1858 Py_DECREF(func);
1859 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001860
Barry Warsawfa701a81997-01-16 00:15:11 +00001861 if (res == NULL) {
1862 errorInCmd = 1;
1863 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1864 }
1865 else
1866 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001867
1868 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001869}
1870
1871static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001872Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001873{
Barry Warsawfa701a81997-01-16 00:15:11 +00001874 int milliseconds;
1875 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001876 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001877
Guido van Rossum2834b972000-10-06 16:58:26 +00001878 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
1879 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001880 return NULL;
1881 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001882 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001883 return NULL;
1884 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001885 v = Tktt_New(func);
1886 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1887 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001888
Guido van Rossum00d93061998-05-28 23:06:38 +00001889 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001890}
1891
Barry Warsawfa701a81997-01-16 00:15:11 +00001892
Guido van Rossum18468821994-06-20 07:49:28 +00001893/** Event Loop **/
1894
Guido van Rossum18468821994-06-20 07:49:28 +00001895static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001896Tkapp_MainLoop(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001897{
Barry Warsawfa701a81997-01-16 00:15:11 +00001898 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001899#ifdef WITH_THREAD
1900 PyThreadState *tstate = PyThreadState_Get();
1901#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001902
Guido van Rossum43713e52000-02-29 13:59:29 +00001903 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001904 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001905
Barry Warsawfa701a81997-01-16 00:15:11 +00001906 quitMainLoop = 0;
1907 while (Tk_GetNumMainWindows() > threshold &&
1908 !quitMainLoop &&
1909 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001910 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001911 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001912
1913#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001914 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001915 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001916 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001917 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001918 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001919 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001920 if (result == 0)
1921 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001922 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001923#else
1924 result = Tcl_DoOneEvent(0);
1925#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001926
Guido van Rossum35d43371997-08-02 00:09:09 +00001927 if (PyErr_CheckSignals() != 0)
1928 return NULL;
1929 if (result < 0)
1930 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001931 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001932 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001933
Barry Warsawfa701a81997-01-16 00:15:11 +00001934 if (errorInCmd) {
1935 errorInCmd = 0;
1936 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1937 excInCmd = valInCmd = trbInCmd = NULL;
1938 return NULL;
1939 }
1940 Py_INCREF(Py_None);
1941 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001942}
1943
1944static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001945Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00001946{
Guido van Rossum35d43371997-08-02 00:09:09 +00001947 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001948 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001949
Guido van Rossum43713e52000-02-29 13:59:29 +00001950 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001951 return NULL;
1952
Guido van Rossum00d93061998-05-28 23:06:38 +00001953 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001954 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001955 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001956 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001957}
1958
1959static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001960Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001961{
1962
Guido van Rossum43713e52000-02-29 13:59:29 +00001963 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001964 return NULL;
1965
1966 quitMainLoop = 1;
1967 Py_INCREF(Py_None);
1968 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001969}
1970
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001971static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001972Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001973{
1974
Guido van Rossum43713e52000-02-29 13:59:29 +00001975 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001976 return NULL;
1977
1978 return PyInt_FromLong((long)Tkapp_Interp(self));
1979}
1980
Barry Warsawfa701a81997-01-16 00:15:11 +00001981
Martin v. Löwisffad6332002-11-26 09:28:05 +00001982static PyObject *
1983Tkapp_WantObjects(PyObject *self, PyObject *args)
1984{
1985
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00001986 int wantobjects;
1987 if (!PyArg_ParseTuple(args, "i:wantobjects", &wantobjects))
Martin v. Löwisffad6332002-11-26 09:28:05 +00001988 return NULL;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00001989 ((TkappObject*)self)->wantobjects = wantobjects;
Martin v. Löwisffad6332002-11-26 09:28:05 +00001990
1991 Py_INCREF(Py_None);
1992 return Py_None;
1993}
1994
1995
Barry Warsawfa701a81997-01-16 00:15:11 +00001996
Guido van Rossum18468821994-06-20 07:49:28 +00001997/**** Tkapp Method List ****/
1998
1999static PyMethodDef Tkapp_methods[] =
2000{
Martin v. Löwisffad6332002-11-26 09:28:05 +00002001 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002002 {"call", Tkapp_Call, METH_OLDARGS},
2003 {"globalcall", Tkapp_GlobalCall, METH_OLDARGS},
2004 {"eval", Tkapp_Eval, METH_VARARGS},
2005 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2006 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2007 {"record", Tkapp_Record, METH_VARARGS},
2008 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2009 {"setvar", Tkapp_SetVar, METH_VARARGS},
2010 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2011 {"getvar", Tkapp_GetVar, METH_VARARGS},
2012 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2013 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2014 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2015 {"getint", Tkapp_GetInt, METH_VARARGS},
2016 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2017 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2018 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2019 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2020 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2021 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2022 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2023 {"split", Tkapp_Split, METH_VARARGS},
2024 {"merge", Tkapp_Merge, METH_OLDARGS},
2025 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2026 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002027#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002028 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2029 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002030#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002031 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2032 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2033 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2034 {"quit", Tkapp_Quit, METH_VARARGS},
2035 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002036 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002037};
2038
Barry Warsawfa701a81997-01-16 00:15:11 +00002039
2040
Guido van Rossum18468821994-06-20 07:49:28 +00002041/**** Tkapp Type Methods ****/
2042
2043static void
Fred Drake509d79a2000-07-08 04:04:38 +00002044Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002045{
Guido van Rossum00d93061998-05-28 23:06:38 +00002046 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002047 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002048 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002049 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002050 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002051}
2052
2053static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002054Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00002055{
Guido van Rossum35d43371997-08-02 00:09:09 +00002056 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00002057}
2058
2059static PyTypeObject Tkapp_Type =
2060{
Guido van Rossum35d43371997-08-02 00:09:09 +00002061 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002062 0, /*ob_size */
2063 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002064 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002065 0, /*tp_itemsize */
2066 Tkapp_Dealloc, /*tp_dealloc */
2067 0, /*tp_print */
2068 Tkapp_GetAttr, /*tp_getattr */
2069 0, /*tp_setattr */
2070 0, /*tp_compare */
2071 0, /*tp_repr */
2072 0, /*tp_as_number */
2073 0, /*tp_as_sequence */
2074 0, /*tp_as_mapping */
2075 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00002076};
2077
Barry Warsawfa701a81997-01-16 00:15:11 +00002078
2079
Guido van Rossum18468821994-06-20 07:49:28 +00002080/**** Tkinter Module ****/
2081
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002082typedef struct {
2083 PyObject* tuple;
2084 int size; /* current size */
2085 int maxsize; /* allocated size */
2086} FlattenContext;
2087
2088static int
2089_bump(FlattenContext* context, int size)
2090{
Guido van Rossum2834b972000-10-06 16:58:26 +00002091 /* expand tuple to hold (at least) size new items.
2092 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002093
2094 int maxsize = context->maxsize * 2;
2095
2096 if (maxsize < context->size + size)
2097 maxsize = context->size + size;
2098
2099 context->maxsize = maxsize;
2100
Tim Peters4324aa32001-05-28 22:30:08 +00002101 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002102}
2103
2104static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002105_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002106{
2107 /* add tuple or list to argument tuple (recursively) */
2108
2109 int i, size;
2110
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002111 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002112 PyErr_SetString(PyExc_ValueError,
2113 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002114 return 0;
2115 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002116 size = PyList_GET_SIZE(item);
2117 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002118 if (context->size + size > context->maxsize &&
2119 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002120 return 0;
2121 /* copy items to output tuple */
2122 for (i = 0; i < size; i++) {
2123 PyObject *o = PyList_GET_ITEM(item, i);
2124 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002125 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002126 return 0;
2127 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002128 if (context->size + 1 > context->maxsize &&
2129 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002130 return 0;
2131 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002132 PyTuple_SET_ITEM(context->tuple,
2133 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002134 }
2135 }
2136 } else if (PyTuple_Check(item)) {
2137 /* same, for tuples */
2138 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002139 if (context->size + size > context->maxsize &&
2140 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002141 return 0;
2142 for (i = 0; i < size; i++) {
2143 PyObject *o = PyTuple_GET_ITEM(item, i);
2144 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002145 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002146 return 0;
2147 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002148 if (context->size + 1 > context->maxsize &&
2149 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002150 return 0;
2151 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002152 PyTuple_SET_ITEM(context->tuple,
2153 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002154 }
2155 }
2156 } else {
2157 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2158 return 0;
2159 }
2160 return 1;
2161}
2162
2163static PyObject *
2164Tkinter_Flatten(PyObject* self, PyObject* args)
2165{
2166 FlattenContext context;
2167 PyObject* item;
2168
2169 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2170 return NULL;
2171
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002172 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002173 if (context.maxsize <= 0)
2174 return PyTuple_New(0);
2175
2176 context.tuple = PyTuple_New(context.maxsize);
2177 if (!context.tuple)
2178 return NULL;
2179
2180 context.size = 0;
2181
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002182 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002183 return NULL;
2184
Tim Peters4324aa32001-05-28 22:30:08 +00002185 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002186 return NULL;
2187
2188 return context.tuple;
2189}
2190
Guido van Rossum18468821994-06-20 07:49:28 +00002191static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002192Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002193{
Barry Warsawfa701a81997-01-16 00:15:11 +00002194 char *screenName = NULL;
2195 char *baseName = NULL;
2196 char *className = NULL;
2197 int interactive = 0;
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002198 int wantobjects = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002199
Guido van Rossum35d43371997-08-02 00:09:09 +00002200 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00002201 if (baseName != NULL)
2202 baseName++;
2203 else
2204 baseName = Py_GetProgramName();
2205 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00002206
Martin v. Löwis4ec2e702002-11-26 22:12:12 +00002207 if (!PyArg_ParseTuple(args, "|zssii:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002208 &screenName, &baseName, &className,
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002209 &interactive, &wantobjects))
Barry Warsawfa701a81997-01-16 00:15:11 +00002210 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002211
Barry Warsawfa701a81997-01-16 00:15:11 +00002212 return (PyObject *) Tkapp_New(screenName, baseName, className,
Martin v. Löwis8c8aa5d2002-11-26 21:39:48 +00002213 interactive, wantobjects);
Guido van Rossum18468821994-06-20 07:49:28 +00002214}
2215
2216static PyMethodDef moduleMethods[] =
2217{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002218 {"_flatten", Tkinter_Flatten, METH_VARARGS},
2219 {"create", Tkinter_Create, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002220#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002221 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2222 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002223#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002224 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2225 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2226 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2227 {"quit", Tkapp_Quit, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002228 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002229};
2230
Guido van Rossum7bf15641998-05-22 18:28:17 +00002231#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002232
2233static int stdin_ready = 0;
2234
Guido van Rossumad4db171998-06-13 13:56:28 +00002235#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00002236static void
Fred Drake509d79a2000-07-08 04:04:38 +00002237MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002238{
2239 stdin_ready = 1;
2240}
Guido van Rossumad4db171998-06-13 13:56:28 +00002241#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002242
Guido van Rossum00d93061998-05-28 23:06:38 +00002243static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002244
Guido van Rossum18468821994-06-20 07:49:28 +00002245static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002246EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002247{
Guido van Rossumad4db171998-06-13 13:56:28 +00002248#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002249 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002250#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002251#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002252 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002253#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002254 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002255 errorInCmd = 0;
2256#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002257 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002258 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002259#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002260 while (!errorInCmd && !stdin_ready) {
2261 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002262#ifdef MS_WINDOWS
2263 if (_kbhit()) {
2264 stdin_ready = 1;
2265 break;
2266 }
2267#endif
2268#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002269 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00002270 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002271 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002272
Guido van Rossum00d93061998-05-28 23:06:38 +00002273 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002274
2275 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00002276 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002277 if (result == 0)
2278 Sleep(20);
2279 Py_END_ALLOW_THREADS
2280#else
2281 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002282#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002283
2284 if (result < 0)
2285 break;
2286 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002287#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002288 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002289#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002290 if (errorInCmd) {
2291 errorInCmd = 0;
2292 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2293 excInCmd = valInCmd = trbInCmd = NULL;
2294 PyErr_Print();
2295 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002296#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002297 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002298#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002299 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002300}
Guido van Rossum18468821994-06-20 07:49:28 +00002301
Guido van Rossum00d93061998-05-28 23:06:38 +00002302#endif
2303
Guido van Rossum7bf15641998-05-22 18:28:17 +00002304static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002305EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002306{
Guido van Rossum00d93061998-05-28 23:06:38 +00002307#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002308 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002309#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002310 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002311#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002312 PyOS_InputHook = EventHook;
2313 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002314#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002315}
2316
2317static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002318DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002319{
Guido van Rossum00d93061998-05-28 23:06:38 +00002320#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002321 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2322 PyOS_InputHook = NULL;
2323 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002324#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002325}
2326
Barry Warsawfa701a81997-01-16 00:15:11 +00002327
2328/* all errors will be checked in one fell swoop in init_tkinter() */
2329static void
Fred Drake509d79a2000-07-08 04:04:38 +00002330ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002331{
2332 PyObject *v = PyInt_FromLong(val);
2333 if (v) {
2334 PyDict_SetItemString(d, name, v);
2335 Py_DECREF(v);
2336 }
2337}
2338static void
Fred Drake509d79a2000-07-08 04:04:38 +00002339ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002340{
2341 PyObject *v = PyString_FromString(val);
2342 if (v) {
2343 PyDict_SetItemString(d, name, v);
2344 Py_DECREF(v);
2345 }
2346}
2347
2348
Mark Hammond62b1ab12002-07-23 06:31:15 +00002349PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002350init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002351{
Barry Warsawfa701a81997-01-16 00:15:11 +00002352 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002353
Barry Warsawfa701a81997-01-16 00:15:11 +00002354 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002355
2356#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002357 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002358#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002359
Barry Warsawfa701a81997-01-16 00:15:11 +00002360 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002361
Barry Warsawfa701a81997-01-16 00:15:11 +00002362 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00002363 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00002364 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002365
Guido van Rossum35d43371997-08-02 00:09:09 +00002366 ins_long(d, "READABLE", TCL_READABLE);
2367 ins_long(d, "WRITABLE", TCL_WRITABLE);
2368 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2369 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2370 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2371 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2372 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2373 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2374 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002375 ins_string(d, "TK_VERSION", TK_VERSION);
2376 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002377
Guido van Rossum83551bf1997-09-13 00:44:23 +00002378 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002379
2380 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002381 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2382
Martin v. Löwisffad6332002-11-26 09:28:05 +00002383 PyTclObject_Type.ob_type = &PyType_Type;
2384 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00002385
2386#ifdef TK_AQUA
2387 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
2388 * start waking up. Note that Tcl_FindExecutable will do this, this
2389 * code must be above it! The original warning from
2390 * tkMacOSXAppInit.c is copied below.
2391 *
2392 * NB - You have to swap in the Tk Notifier BEFORE you start up the
2393 * Tcl interpreter for now. It probably should work to do this
2394 * in the other order, but for now it doesn't seem to.
2395 *
2396 */
2397 Tk_MacOSXSetupTkNotifier();
2398#endif
2399
2400
Guido van Rossume187b0e2000-03-27 21:46:29 +00002401 /* This helps the dynamic loader; in Unicode aware Tcl versions
2402 it also helps Tcl find its encodings. */
2403 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002404
Barry Warsawfa701a81997-01-16 00:15:11 +00002405 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002406 return;
2407
Guido van Rossum43ff8681998-07-14 18:02:13 +00002408#if 0
2409 /* This was not a good idea; through <Destroy> bindings,
2410 Tcl_Finalize() may invoke Python code but at that point the
2411 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002412 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002413#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002414
Jack Jansen34cc5c31995-10-31 16:15:12 +00002415#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002416 /*
2417 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2418 ** Most of the initializations in that routine (toolbox init calls and
2419 ** such) have already been done for us, so we only need these.
2420 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002421 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002422
2423 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002424#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002425 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002426#endif /* GENERATINGCFM */
2427#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002428}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002429
Guido van Rossumec22c921996-02-25 04:50:29 +00002430
Barry Warsawfa701a81997-01-16 00:15:11 +00002431
Guido van Rossum9722ad81995-09-22 23:49:28 +00002432#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002433
2434/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002435** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002436*/
2437
Guido van Rossum9722ad81995-09-22 23:49:28 +00002438void
2439panic(char * format, ...)
2440{
Barry Warsawfa701a81997-01-16 00:15:11 +00002441 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002442
Barry Warsawfa701a81997-01-16 00:15:11 +00002443 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002444
Guido van Rossum227cf761998-08-05 13:53:32 +00002445 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002446 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002447
Barry Warsawfa701a81997-01-16 00:15:11 +00002448 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002449
Barry Warsawfa701a81997-01-16 00:15:11 +00002450 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002451}
Jack Jansen40b546d1995-11-14 10:34:45 +00002452
Guido van Rossumec22c921996-02-25 04:50:29 +00002453/*
2454** Pass events to SIOUX before passing them to Tk.
2455*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002456
Guido van Rossumec22c921996-02-25 04:50:29 +00002457static int
Fred Drake509d79a2000-07-08 04:04:38 +00002458PyMacConvertEvent(EventRecord *eventPtr)
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002459{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002460 WindowPtr frontwin;
2461 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002462 ** Sioux eats too many events, so we don't pass it everything. We
2463 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002464 ** the Sioux window is frontmost. This means that Tk menus don't work
2465 ** in that case, but at least we can scroll the sioux window.
2466 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2467 ** part of the external interface of Sioux...
2468 */
2469 frontwin = FrontWindow();
2470 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2471 if (SIOUXHandleOneEvent(eventPtr))
2472 return 0; /* Nothing happened to the Tcl event queue */
2473 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002474 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002475}
2476
Guido van Rossumec22c921996-02-25 04:50:29 +00002477#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002478
2479/*
2480** Additional Mac specific code for dealing with shared libraries.
2481*/
2482
2483#include <Resources.h>
2484#include <CodeFragments.h>
2485
2486static int loaded_from_shlib = 0;
2487static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002488
Jack Jansen34cc5c31995-10-31 16:15:12 +00002489/*
2490** If this module is dynamically loaded the following routine should
2491** be the init routine. It takes care of adding the shared library to
2492** the resource-file chain, so that the tk routines can find their
2493** resources.
2494*/
2495OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002496init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002497{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002498 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002499 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002500 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002501 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2502 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002503 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002504 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2505 loaded_from_shlib = 1;
2506 }
2507 return noErr;
2508}
2509
2510/*
2511** Insert the library resources into the search path. Put them after
2512** the resources from the application. Again, we ignore errors.
2513*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002514static
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002515mac_addlibresources(void)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002516{
2517 if ( !loaded_from_shlib )
2518 return;
2519 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2520}
2521
Guido van Rossumec22c921996-02-25 04:50:29 +00002522#endif /* GENERATINGCFM */
2523#endif /* macintosh */