blob: b74641e07eaf55481c4306a6c3067b19c5ccd4b1 [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>
Martin v. Löwisffad6332002-11-26 09:28:05 +000053#include <Tcl/tclInt.h>
Jack Jansencb852442001-12-09 23:15:56 +000054#include <Tk/tk.h>
55#else
Guido van Rossum18468821994-06-20 07:49:28 +000056#include <tcl.h>
Martin v. Löwisffad6332002-11-26 09:28:05 +000057#include <tclInt.h>
Guido van Rossum18468821994-06-20 07:49:28 +000058#include <tk.h>
Jack Jansencb852442001-12-09 23:15:56 +000059#endif
Guido van Rossum18468821994-06-20 07:49:28 +000060
Guido van Rossum3e819a71997-08-01 19:29:02 +000061#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
62
Martin v. Löwis6bfa2e62002-10-01 17:48:31 +000063#if TKMAJORMINOR < 8002
64#error "Tk older than 8.2 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000065#endif
66
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +000067/* Unicode conversion assumes that Tcl_UniChar is two bytes.
68 We cannot test this directly, so we test UTF-8 size instead,
69 expecting that TCL_UTF_MAX is changed if Tcl ever supports
70 either UTF-16 or UCS-4. */
71#if TCL_UTF_MAX != 3
72#error "unsupported Tcl configuration"
73#endif
74
Guido van Rossuma80649b2000-03-28 20:07:05 +000075#if defined(macintosh)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000076/* Sigh, we have to include this to get at the tcl qd pointer */
77#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000078/* And this one we need to clear the menu bar */
79#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000080#endif
81
Jack Jansen84c10b12001-07-16 19:32:52 +000082#if !(defined(MS_WINDOWS) || defined(__CYGWIN__) || defined(macintosh))
83/* Mac has it, but it doesn't really work:-( */
Guido van Rossum0d2390c1997-08-14 19:57:07 +000084#define HAVE_CREATEFILEHANDLER
85#endif
86
Guido van Rossum00d93061998-05-28 23:06:38 +000087#ifdef HAVE_CREATEFILEHANDLER
88
89/* Tcl_CreateFileHandler() changed several times; these macros deal with the
90 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
91 Unix, only because Jack added it back); when available on Windows, it only
92 applies to sockets. */
93
Guido van Rossum7bf15641998-05-22 18:28:17 +000094#ifdef MS_WINDOWS
95#define FHANDLETYPE TCL_WIN_SOCKET
96#else
97#define FHANDLETYPE TCL_UNIX_FD
98#endif
99
Guido van Rossum00d93061998-05-28 23:06:38 +0000100/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
101 which uses this to handle Tcl events while the user is typing commands. */
102
103#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000104#define WAIT_FOR_STDIN
105#endif
106
Guido van Rossum00d93061998-05-28 23:06:38 +0000107#endif /* HAVE_CREATEFILEHANDLER */
108
Guido van Rossumad4db171998-06-13 13:56:28 +0000109#ifdef MS_WINDOWS
110#include <conio.h>
111#define WAIT_FOR_STDIN
112#endif
113
Guido van Rossum00d93061998-05-28 23:06:38 +0000114#ifdef WITH_THREAD
115
116/* The threading situation is complicated. Tcl is not thread-safe, except for
117 Tcl 8.1, which will probably remain in alpha status for another 6 months
118 (and the README says that Tk will probably remain thread-unsafe forever).
119 So we need to use a lock around all uses of Tcl. Previously, the Python
120 interpreter lock was used for this. However, this causes problems when
121 other Python threads need to run while Tcl is blocked waiting for events.
122
123 To solve this problem, a separate lock for Tcl is introduced. Holding it
124 is incompatible with holding Python's interpreter lock. The following four
125 macros manipulate both locks together.
126
127 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
128 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
129 that could call an event handler, or otherwise affect the state of a Tcl
130 interpreter. These assume that the surrounding code has the Python
131 interpreter lock; inside the brackets, the Python interpreter lock has been
132 released and the lock for Tcl has been acquired.
133
Guido van Rossum5e977831998-06-15 14:03:52 +0000134 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
135 (For example, when transferring data from the Tcl interpreter result to a
136 Python string object.) This can be done by using different macros to close
137 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
138 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
139 releases the Tcl lock.
140
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000141 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000142 handlers when the handler needs to use Python. Such event handlers are
143 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000144 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000145 the Python interpreter lock, restoring the appropriate thread state, and
146 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
147 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000148 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000149
150 These locks expand to several statements and brackets; they should not be
151 used in branches of if statements and the like.
152
153*/
154
Guido van Rossum65d5b571998-12-21 19:32:43 +0000155static PyThread_type_lock tcl_lock = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000156static PyThreadState *tcl_tstate = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000157
158#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000159 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000160 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000161
162#define LEAVE_TCL \
Guido van Rossum2834b972000-10-06 16:58:26 +0000163 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000164
Guido van Rossum62320c91998-06-15 04:36:09 +0000165#define ENTER_OVERLAP \
166 Py_END_ALLOW_THREADS
167
168#define LEAVE_OVERLAP_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000169 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000170
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000171#define ENTER_PYTHON \
172 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000173 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000174
175#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000176 { PyThreadState *tstate = PyEval_SaveThread(); \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000177 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Guido van Rossum00d93061998-05-28 23:06:38 +0000178
179#else
180
181#define ENTER_TCL
182#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000183#define ENTER_OVERLAP
184#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000185#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000186#define LEAVE_PYTHON
187
188#endif
189
Guido van Rossumec22c921996-02-25 04:50:29 +0000190#ifdef macintosh
191
192/*
193** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000194** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000195*/
196
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000197/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000198#define FREECAST (char *)
199
Guido van Rossumec22c921996-02-25 04:50:29 +0000200#include <Events.h> /* For EventRecord */
201
Fred Drake509d79a2000-07-08 04:04:38 +0000202typedef int (*TclMacConvertEventPtr) (EventRecord *eventPtr);
Guido van Rossum2834b972000-10-06 16:58:26 +0000203void Tcl_MacSetEventProc(TclMacConvertEventPtr procPtr);
204int TkMacConvertEvent(EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000205
Jeremy Hylton938ace62002-07-17 16:30:39 +0000206static int PyMacConvertEvent(EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000207
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000208#include <SIOUX.h>
209extern int SIOUXIsAppWindow(WindowPtr);
210
Guido van Rossumec22c921996-02-25 04:50:29 +0000211#endif /* macintosh */
212
Guido van Rossum97867b21996-08-08 19:09:53 +0000213#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000214#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000215#endif
216
Guido van Rossum18468821994-06-20 07:49:28 +0000217/**** Tkapp Object Declaration ****/
218
Jeremy Hylton938ace62002-07-17 16:30:39 +0000219static PyTypeObject Tkapp_Type;
Guido van Rossum18468821994-06-20 07:49:28 +0000220
Guido van Rossum00d93061998-05-28 23:06:38 +0000221typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000222 PyObject_HEAD
223 Tcl_Interp *interp;
Martin v. Löwisffad6332002-11-26 09:28:05 +0000224 int want_objects;
Guido van Rossum00d93061998-05-28 23:06:38 +0000225} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000226
227#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000228#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000229#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000230
Guido van Rossum35d43371997-08-02 00:09:09 +0000231#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000232(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000233
Barry Warsawfa701a81997-01-16 00:15:11 +0000234
235
Guido van Rossum18468821994-06-20 07:49:28 +0000236/**** Error Handling ****/
237
238static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000239static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000240static int errorInCmd = 0;
241static PyObject *excInCmd;
242static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000243static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000244
Barry Warsawfa701a81997-01-16 00:15:11 +0000245
246
Guido van Rossum18468821994-06-20 07:49:28 +0000247static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000248Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000249{
Barry Warsawfa701a81997-01-16 00:15:11 +0000250 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
251 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000252}
253
Barry Warsawfa701a81997-01-16 00:15:11 +0000254
Barry Warsawfa701a81997-01-16 00:15:11 +0000255
Guido van Rossum18468821994-06-20 07:49:28 +0000256/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000257
258#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000259#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000260
Guido van Rossum00d93061998-05-28 23:06:38 +0000261/* Millisecond sleep() for Unix platforms. */
262
263static void
Fred Drake509d79a2000-07-08 04:04:38 +0000264Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000265{
266 /* XXX Too bad if you don't have select(). */
267 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000268 t.tv_sec = milli/1000;
269 t.tv_usec = (milli%1000) * 1000;
270 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
271}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000272#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000273#endif /* WITH_THREAD */
274
275
Guido van Rossum18468821994-06-20 07:49:28 +0000276static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000277AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000278{
Guido van Rossum35d43371997-08-02 00:09:09 +0000279 if (PyString_Check(value))
280 return PyString_AsString(value);
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000281#ifdef Py_USING_UNICODE
Guido van Rossum2834b972000-10-06 16:58:26 +0000282 else if (PyUnicode_Check(value)) {
283 PyObject *v = PyUnicode_AsUTF8String(value);
284 if (v == NULL)
285 return NULL;
286 if (PyList_Append(tmp, v) != 0) {
287 Py_DECREF(v);
288 return NULL;
289 }
290 Py_DECREF(v);
291 return PyString_AsString(v);
292 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000293#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000294 else {
295 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000296 if (v == NULL)
297 return NULL;
298 if (PyList_Append(tmp, v) != 0) {
299 Py_DECREF(v);
300 return NULL;
301 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000302 Py_DECREF(v);
303 return PyString_AsString(v);
304 }
Guido van Rossum18468821994-06-20 07:49:28 +0000305}
306
Barry Warsawfa701a81997-01-16 00:15:11 +0000307
308
Guido van Rossum18468821994-06-20 07:49:28 +0000309#define ARGSZ 64
310
311static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000312Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000313{
Barry Warsawfa701a81997-01-16 00:15:11 +0000314 PyObject *tmp = NULL;
315 char *argvStore[ARGSZ];
316 char **argv = NULL;
317 int fvStore[ARGSZ];
318 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000319 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000320 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000321
Barry Warsawfa701a81997-01-16 00:15:11 +0000322 if (!(tmp = PyList_New(0)))
323 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000324
Barry Warsawfa701a81997-01-16 00:15:11 +0000325 argv = argvStore;
326 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000327
Barry Warsawfa701a81997-01-16 00:15:11 +0000328 if (args == NULL)
329 argc = 0;
330
331 else if (!PyTuple_Check(args)) {
332 argc = 1;
333 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000334 if (!(argv[0] = AsString(args, tmp)))
335 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000336 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000337 else {
338 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000339
Barry Warsawfa701a81997-01-16 00:15:11 +0000340 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000341 argv = (char **)ckalloc(argc * sizeof(char *));
342 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000343 if (argv == NULL || fv == NULL) {
344 PyErr_NoMemory();
345 goto finally;
346 }
347 }
348
349 for (i = 0; i < argc; i++) {
350 PyObject *v = PyTuple_GetItem(args, i);
351 if (PyTuple_Check(v)) {
352 fv[i] = 1;
353 if (!(argv[i] = Merge(v)))
354 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000355 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000356 }
357 else if (v == Py_None) {
358 argc = i;
359 break;
360 }
361 else {
362 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000363 if (!(argv[i] = AsString(v, tmp)))
364 goto finally;
365 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000366 }
367 }
Guido van Rossum18468821994-06-20 07:49:28 +0000368 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000369 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000370 if (res == NULL)
371 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000372
Barry Warsawfa701a81997-01-16 00:15:11 +0000373 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000374 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000375 if (fv[i]) {
376 ckfree(argv[i]);
377 }
378 if (argv != argvStore)
379 ckfree(FREECAST argv);
380 if (fv != fvStore)
381 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000382
Barry Warsawfa701a81997-01-16 00:15:11 +0000383 Py_DECREF(tmp);
384 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000385}
386
Barry Warsawfa701a81997-01-16 00:15:11 +0000387
388
Guido van Rossum18468821994-06-20 07:49:28 +0000389static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000390Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000391{
Barry Warsawfa701a81997-01-16 00:15:11 +0000392 int argc;
393 char **argv;
394 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000395
Barry Warsawfa701a81997-01-16 00:15:11 +0000396 if (list == NULL) {
397 Py_INCREF(Py_None);
398 return Py_None;
399 }
Guido van Rossum18468821994-06-20 07:49:28 +0000400
Guido van Rossum00d93061998-05-28 23:06:38 +0000401 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000402 /* Not a list.
403 * Could be a quoted string containing funnies, e.g. {"}.
404 * Return the string itself.
405 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000406 return PyString_FromString(list);
407 }
Guido van Rossum18468821994-06-20 07:49:28 +0000408
Barry Warsawfa701a81997-01-16 00:15:11 +0000409 if (argc == 0)
410 v = PyString_FromString("");
411 else if (argc == 1)
412 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000413 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000414 int i;
415 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000416
Barry Warsawfa701a81997-01-16 00:15:11 +0000417 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000418 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000419 Py_DECREF(v);
420 v = NULL;
421 break;
422 }
423 PyTuple_SetItem(v, i, w);
424 }
425 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000426 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000427 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000428}
429
Martin v. Löwisffad6332002-11-26 09:28:05 +0000430/* In some cases, Tcl will still return strings that are supposed to be
431 lists. SplitObj walks through a nested tuple, finding string objects that
432 need to be split. */
433
434PyObject *
435SplitObj(PyObject *arg)
436{
437 if (PyTuple_Check(arg)) {
438 int i, size;
439 PyObject *elem, *newelem, *result;
440
441 size = PyTuple_Size(arg);
442 result = NULL;
443 /* Recursively invoke SplitObj for all tuple items.
444 If this does not return a new object, no action is
445 needed. */
446 for(i = 0; i < size; i++) {
447 elem = PyTuple_GetItem(arg, i);
448 newelem = SplitObj(elem);
449 if (!newelem) {
450 Py_XDECREF(result);
451 return NULL;
452 }
453 if (!result) {
454 int k;
455 if (newelem == elem) {
456 Py_DECREF(newelem);
457 continue;
458 }
459 result = PyTuple_New(size);
460 if (!result)
461 return NULL;
462 for(k = 0; k < i; k++) {
463 elem = PyTuple_GetItem(arg, k);
464 Py_INCREF(elem);
465 PyTuple_SetItem(result, k, elem);
466 }
467 }
468 PyTuple_SetItem(result, i, newelem);
469 }
470 if (result)
471 return result;
472 /* Fall through, returning arg. */
473 }
474 else if (PyString_Check(arg)) {
475 int argc;
476 char **argv;
477 char *list = PyString_AsString(arg);
478
479 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
480 Py_INCREF(arg);
481 return arg;
482 }
483 Tcl_Free(FREECAST argv);
484 if (argc > 1)
485 return Split(PyString_AsString(arg));
486 /* Fall through, returning arg. */
487 }
488 Py_INCREF(arg);
489 return arg;
490}
Barry Warsawfa701a81997-01-16 00:15:11 +0000491
492
Guido van Rossum18468821994-06-20 07:49:28 +0000493/**** Tkapp Object ****/
494
495#ifndef WITH_APPINIT
496int
Fred Drake509d79a2000-07-08 04:04:38 +0000497Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000498{
Barry Warsawfa701a81997-01-16 00:15:11 +0000499 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000500
Barry Warsawfa701a81997-01-16 00:15:11 +0000501 main = Tk_MainWindow(interp);
502 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000503 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000504 return TCL_ERROR;
505 }
506 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000507 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000508 return TCL_ERROR;
509 }
510 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000511}
512#endif /* !WITH_APPINIT */
513
Guido van Rossum18468821994-06-20 07:49:28 +0000514
Barry Warsawfa701a81997-01-16 00:15:11 +0000515
516
517/* Initialize the Tk application; see the `main' function in
518 * `tkMain.c'.
519 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000520
Thomas Wouters58d05102000-07-24 14:43:35 +0000521static void EnableEventHook(void); /* Forward */
522static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000523
Barry Warsawfa701a81997-01-16 00:15:11 +0000524static TkappObject *
Martin v. Löwisffad6332002-11-26 09:28:05 +0000525Tkapp_New(char *screenName, char *baseName, char *className,
526 int interactive, int want_objects)
Barry Warsawfa701a81997-01-16 00:15:11 +0000527{
528 TkappObject *v;
529 char *argv0;
530
Guido van Rossumb18618d2000-05-03 23:44:39 +0000531 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000532 if (v == NULL)
533 return NULL;
534
535 v->interp = Tcl_CreateInterp();
Martin v. Löwisffad6332002-11-26 09:28:05 +0000536 v->want_objects = want_objects;
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000537
Guido van Rossuma80649b2000-03-28 20:07:05 +0000538#if defined(macintosh)
539 /* This seems to be needed */
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000540 ClearMenuBar();
541 TkMacInitMenus(v->interp);
542#endif
Jack Jansencb852442001-12-09 23:15:56 +0000543
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000544 /* Delete the 'exit' command, which can screw things up */
545 Tcl_DeleteCommand(v->interp, "exit");
546
Barry Warsawfa701a81997-01-16 00:15:11 +0000547 if (screenName != NULL)
548 Tcl_SetVar2(v->interp, "env", "DISPLAY",
549 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000550
Barry Warsawfa701a81997-01-16 00:15:11 +0000551 if (interactive)
552 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
553 else
554 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000555
Barry Warsawfa701a81997-01-16 00:15:11 +0000556 /* This is used to get the application class for Tk 4.1 and up */
557 argv0 = (char*)ckalloc(strlen(className) + 1);
558 if (!argv0) {
559 PyErr_NoMemory();
560 Py_DECREF(v);
561 return NULL;
562 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000563
Barry Warsawfa701a81997-01-16 00:15:11 +0000564 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000565 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000566 argv0[0] = tolower(argv0[0]);
567 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
568 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000569
Barry Warsawfa701a81997-01-16 00:15:11 +0000570 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000571 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000572
Guido van Rossum7bf15641998-05-22 18:28:17 +0000573 EnableEventHook();
574
Barry Warsawfa701a81997-01-16 00:15:11 +0000575 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000576}
577
Barry Warsawfa701a81997-01-16 00:15:11 +0000578
579
Guido van Rossum18468821994-06-20 07:49:28 +0000580/** Tcl Eval **/
581
Martin v. Löwisffad6332002-11-26 09:28:05 +0000582typedef struct {
583 PyObject_HEAD
584 Tcl_Obj *value;
585} PyTclObject;
586
587staticforward PyTypeObject PyTclObject_Type;
588#define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type)
589
590static PyObject *
591newPyTclObject(Tcl_Obj *arg)
592{
593 PyTclObject *self;
594 self = PyObject_New(PyTclObject, &PyTclObject_Type);
595 if (self == NULL)
596 return NULL;
597 Tcl_IncrRefCount(arg);
598 self->value = arg;
599 return (PyObject*)self;
600}
601
602static void
603PyTclObject_dealloc(PyTclObject *self)
604{
605 Tcl_DecrRefCount(self->value);
606 PyObject_Del(self);
607}
608
609static PyObject *
610PyTclObject_str(PyTclObject *self)
611{
612 return PyString_FromString(Tcl_GetString(self->value));
613}
614
615static PyObject *
616PyTclObject_repr(PyTclObject *self)
617{
618 char buf[50];
619 PyOS_snprintf(buf, 50, "<%s object at 0x%.8x>",
620 self->value->typePtr->name, (int)self->value);
621 return PyString_FromString(buf);
622}
623
624static PyObject*
625get_typename(PyTclObject* obj, void* ignored)
626{
627 return PyString_FromString(obj->value->typePtr->name);
628}
629
630static PyGetSetDef PyTclObject_getsetlist[] = {
631 {"typename", (getter)get_typename, NULL, "name of the Tcl type"},
632 {0},
633};
634
635statichere PyTypeObject PyTclObject_Type = {
636 PyObject_HEAD_INIT(NULL)
637 0, /*ob_size*/
638 "_tkinter.Tcl_Obj", /*tp_name*/
639 sizeof(PyTclObject), /*tp_basicsize*/
640 0, /*tp_itemsize*/
641 /* methods */
642 (destructor)PyTclObject_dealloc, /*tp_dealloc*/
643 0, /*tp_print*/
644 0, /*tp_getattr*/
645 0, /*tp_setattr*/
646 0, /*tp_compare*/
647 (reprfunc)PyTclObject_repr, /*tp_repr*/
648 0, /*tp_as_number*/
649 0, /*tp_as_sequence*/
650 0, /*tp_as_mapping*/
651 0, /*tp_hash*/
652 0, /*tp_call*/
653 (reprfunc)PyTclObject_str, /*tp_str*/
654 PyObject_GenericGetAttr,/*tp_getattro*/
655 0, /*tp_setattro*/
656 0, /*tp_as_buffer*/
657 Py_TPFLAGS_DEFAULT, /*tp_flags*/
658 0, /*tp_doc*/
659 0, /*tp_traverse*/
660 0, /*tp_clear*/
661 0, /*tp_richcompare*/
662 0, /*tp_weaklistoffset*/
663 0, /*tp_iter*/
664 0, /*tp_iternext*/
665 0, /*tp_methods*/
666 0, /*tp_members*/
667 PyTclObject_getsetlist, /*tp_getset*/
668 0, /*tp_base*/
669 0, /*tp_dict*/
670 0, /*tp_descr_get*/
671 0, /*tp_descr_set*/
672 0, /*tp_dictoffset*/
673 0, /*tp_init*/
674 0, /*tp_alloc*/
675 0, /*tp_new*/
676 0, /*tp_free*/
677 0, /*tp_is_gc*/
678};
679
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000680static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000681AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000682{
683 Tcl_Obj *result;
684
685 if (PyString_Check(value))
686 return Tcl_NewStringObj(PyString_AS_STRING(value),
687 PyString_GET_SIZE(value));
688 else if (PyInt_Check(value))
689 return Tcl_NewLongObj(PyInt_AS_LONG(value));
690 else if (PyFloat_Check(value))
691 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
692 else if (PyTuple_Check(value)) {
693 Tcl_Obj **argv = (Tcl_Obj**)
694 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
695 int i;
696 if(!argv)
697 return 0;
698 for(i=0;i<PyTuple_Size(value);i++)
699 argv[i] = AsObj(PyTuple_GetItem(value,i));
700 result = Tcl_NewListObj(PyTuple_Size(value), argv);
701 ckfree(FREECAST argv);
702 return result;
703 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000704#ifdef Py_USING_UNICODE
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000705 else if (PyUnicode_Check(value)) {
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000706 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
707 int size = PyUnicode_GET_SIZE(value);
708 /* This #ifdef assumes that Tcl uses UCS-2.
709 See TCL_UTF_MAX test above. */
710#ifdef Py_UNICODE_WIDE
711 Tcl_UniChar *outbuf;
712 int i;
713 outbuf = (Tcl_UniChar*)ckalloc(size * sizeof(Tcl_UniChar));
714 if (!outbuf) {
715 PyErr_NoMemory();
716 return NULL;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000717 }
Martin v. Löwis3c6d6f22002-10-01 18:50:56 +0000718 for (i = 0; i < size; i++) {
719 if (inbuf[i] >= 0x10000) {
720 /* Tcl doesn't do UTF-16, yet. */
721 PyErr_SetString(PyExc_ValueError,
722 "unsupported character");
723 ckfree(FREECAST outbuf);
724 return NULL;
725 }
726 outbuf[i] = inbuf[i];
727 }
728 result = Tcl_NewUnicodeObj(outbuf, size);
729 ckfree(FREECAST outbuf);
730 return result;
731#else
732 return Tcl_NewUnicodeObj(inbuf, size);
733#endif
734
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000735 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000736#endif
Martin v. Löwisffad6332002-11-26 09:28:05 +0000737 else if(PyTclObject_Check(value)) {
738 Tcl_Obj *v = ((PyTclObject*)value)->value;
739 Tcl_IncrRefCount(v);
740 return v;
741 }
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000742 else {
743 PyObject *v = PyObject_Str(value);
744 if (!v)
745 return 0;
746 result = AsObj(v);
747 Py_DECREF(v);
748 return result;
749 }
750}
751
Martin v. Löwisffad6332002-11-26 09:28:05 +0000752static PyObject*
753FromObj(PyObject* tkapp, Tcl_Obj *value)
754{
755 PyObject *result = NULL;
756
757 if (value->typePtr == NULL)
758 return PyString_FromStringAndSize(value->bytes, value->length);
759
760 if (value->typePtr == &tclBooleanType) {
761 result = value->internalRep.longValue ? Py_True : Py_False;
762 Py_INCREF(result);
763 return result;
764 }
765
766 if (value->typePtr == &tclByteArrayType) {
767 int size;
768 char *data = Tcl_GetByteArrayFromObj(value, &size);
769 return PyString_FromStringAndSize(data, size);
770 }
771
772 if (value->typePtr == &tclDoubleType) {
773 return PyFloat_FromDouble(value->internalRep.doubleValue);
774 }
775
776 if (value->typePtr == &tclIntType) {
777 return PyInt_FromLong(value->internalRep.longValue);
778 }
779
780 if (value->typePtr == &tclListType) {
781 int size;
782 int i, status;
783 PyObject *elem;
784 Tcl_Obj *tcl_elem;
785
786 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
787 if (status == TCL_ERROR)
788 return Tkinter_Error(tkapp);
789 result = PyTuple_New(size);
790 if (!result)
791 return NULL;
792 for (i = 0; i < size; i++) {
793 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
794 value, i, &tcl_elem);
795 if (status == TCL_ERROR) {
796 Py_DECREF(result);
797 return Tkinter_Error(tkapp);
798 }
799 elem = FromObj(tkapp, tcl_elem);
800 if (!elem) {
801 Py_DECREF(result);
802 return NULL;
803 }
804 PyTuple_SetItem(result, i, elem);
805 }
806 return result;
807 }
808
809 if (value->typePtr == &tclProcBodyType) {
810 // fall through: return tcl object
811 }
812
813 if (value->typePtr == &tclStringType) {
814#ifdef Py_USING_UNICODE
815#ifdef Py_UNICODE_WIDE
816 PyObject *result;
817 int size;
818 Tcl_UniChar *input;
819 Py_UNICODE *output;
820
821 size = Tcl_GetCharLength(value);
822 result = PyUnicode_FromUnicode(NULL, size);
823 if (!result)
824 return NULL;
825 input = Tcl_GetUnicode(value);
826 output = PyUnicode_AS_UNICODE(result);
827 while (size--)
828 *output++ = *input++;
829 return result;
830#else
831 return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
832 Tcl_GetCharLength(value));
833#endif
834#else
835 int size;
836 char *c;
837 c = Tcl_GetStringFromObj(value, &size);
838 return PyString_FromStringAndSize(c, size);
839#endif
840 }
841
842 return newPyTclObject(value);
843}
844
Guido van Rossum18468821994-06-20 07:49:28 +0000845static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000846Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000847{
Guido van Rossum632de272000-03-29 00:19:50 +0000848 Tcl_Obj *objStore[ARGSZ];
849 Tcl_Obj **objv = NULL;
850 int objc = 0, i;
851 PyObject *res = NULL;
852 Tcl_Interp *interp = Tkapp_Interp(self);
853 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
854 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000855
Guido van Rossum632de272000-03-29 00:19:50 +0000856 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000857
Guido van Rossum212643f1998-04-29 16:22:14 +0000858 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +0000859 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +0000860
Guido van Rossum212643f1998-04-29 16:22:14 +0000861 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000862 objv[0] = AsObj(args);
863 if (objv[0] == 0)
864 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000865 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +0000866 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000867 }
868 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000869 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000870
Guido van Rossum632de272000-03-29 00:19:50 +0000871 if (objc > ARGSZ) {
872 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
873 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000874 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +0000875 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +0000876 goto finally;
877 }
878 }
879
Guido van Rossum632de272000-03-29 00:19:50 +0000880 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000881 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +0000882 if (v == Py_None) {
883 objc = i;
884 break;
885 }
Guido van Rossum632de272000-03-29 00:19:50 +0000886 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +0000887 if (!objv[i]) {
888 /* Reset objc, so it attempts to clear
889 objects only up to i. */
890 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +0000891 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000892 }
Guido van Rossum632de272000-03-29 00:19:50 +0000893 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000894 }
895 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000896
Guido van Rossum62320c91998-06-15 04:36:09 +0000897 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000898
899 i = Tcl_EvalObjv(interp, objc, objv, flags);
900
Guido van Rossum62320c91998-06-15 04:36:09 +0000901 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000902 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000903 Tkinter_Error(self);
Martin v. Löwisffad6332002-11-26 09:28:05 +0000904 else if(((TkappObject*)self)->want_objects) {
905 Tcl_Obj *value = Tcl_GetObjResult(interp);
906 /* Not sure whether the IncrRef is necessary, but something
907 may overwrite the interpreter result while we are
908 converting it. */
909 Tcl_IncrRefCount(value);
910 res = FromObj(self, value);
911 Tcl_DecrRefCount(value);
912 } else {
Martin v. Löwis71e25a02002-10-01 18:08:06 +0000913 const char *s = Tcl_GetStringResult(interp);
914 const char *p = s;
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000915
Guido van Rossum990f5c62000-05-04 15:07:16 +0000916 /* If the result contains any bytes with the top bit set,
917 it's UTF-8 and we should decode it to Unicode */
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000918#ifdef Py_USING_UNICODE
Guido van Rossum990f5c62000-05-04 15:07:16 +0000919 while (*p != '\0') {
920 if (*p & 0x80)
921 break;
922 p++;
923 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000924
Guido van Rossum990f5c62000-05-04 15:07:16 +0000925 if (*p == '\0')
926 res = PyString_FromStringAndSize(s, (int)(p-s));
927 else {
928 /* Convert UTF-8 to Unicode string */
929 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +0000930 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
931 if (res == NULL) {
Guido van Rossum2834b972000-10-06 16:58:26 +0000932 PyErr_Clear();
933 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum69529ad2000-05-04 15:55:17 +0000934 }
Guido van Rossum990f5c62000-05-04 15:07:16 +0000935 }
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000936#else
937 p = strchr(p, '\0');
938 res = PyString_FromStringAndSize(s, (int)(p-s));
939#endif
Guido van Rossum990f5c62000-05-04 15:07:16 +0000940 }
Guido van Rossum632de272000-03-29 00:19:50 +0000941
Guido van Rossum62320c91998-06-15 04:36:09 +0000942 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000943
Guido van Rossum212643f1998-04-29 16:22:14 +0000944 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000945 for (i = 0; i < objc; i++)
946 Tcl_DecrRefCount(objv[i]);
947 if (objv != objStore)
948 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000949 return res;
950}
951
952
953static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000954Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000955{
Guido van Rossum212643f1998-04-29 16:22:14 +0000956 /* Could do the same here as for Tkapp_Call(), but this is not used
957 much, so I can't be bothered. Unfortunately Tcl doesn't export a
958 way for the user to do what all its Global* variants do (save and
959 reset the scope pointer, call the local version, restore the saved
960 scope pointer). */
961
Guido van Rossum62320c91998-06-15 04:36:09 +0000962 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000963 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000964
Guido van Rossum62320c91998-06-15 04:36:09 +0000965 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +0000966 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000967 int err;
968 ENTER_TCL
969 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000970 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000971 if (err == TCL_ERROR)
972 res = Tkinter_Error(self);
973 else
974 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000975 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000976 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +0000977 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000978
979 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000980}
981
982static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000983Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000984{
Barry Warsawfa701a81997-01-16 00:15:11 +0000985 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000986 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000987 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000988
Guido van Rossum43713e52000-02-29 13:59:29 +0000989 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000990 return NULL;
991
Guido van Rossum00d93061998-05-28 23:06:38 +0000992 ENTER_TCL
993 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000994 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000995 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000996 res = Tkinter_Error(self);
997 else
998 res = PyString_FromString(Tkapp_Result(self));
999 LEAVE_OVERLAP_TCL
1000 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001001}
1002
1003static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001004Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001005{
Barry Warsawfa701a81997-01-16 00:15:11 +00001006 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001007 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001008 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +00001009
Guido van Rossum43713e52000-02-29 13:59:29 +00001010 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001011 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001012
Guido van Rossum00d93061998-05-28 23:06:38 +00001013 ENTER_TCL
1014 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +00001015 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001016 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001017 res = Tkinter_Error(self);
1018 else
1019 res = PyString_FromString(Tkapp_Result(self));
1020 LEAVE_OVERLAP_TCL
1021 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001022}
1023
1024static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001025Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001026{
Barry Warsawfa701a81997-01-16 00:15:11 +00001027 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +00001028 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001029 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001030
Guido van Rossum43713e52000-02-29 13:59:29 +00001031 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001032 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001033
Guido van Rossum00d93061998-05-28 23:06:38 +00001034 ENTER_TCL
1035 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +00001036 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001037 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001038 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001039
Guido van Rossum62320c91998-06-15 04:36:09 +00001040 else
1041 res = PyString_FromString(Tkapp_Result(self));
1042 LEAVE_OVERLAP_TCL
1043 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001044}
1045
1046static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001047Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001048{
Barry Warsawfa701a81997-01-16 00:15:11 +00001049 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +00001050 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001051 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001052
Guido van Rossum35d43371997-08-02 00:09:09 +00001053 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +00001054 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001055
Guido van Rossum00d93061998-05-28 23:06:38 +00001056 ENTER_TCL
1057 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +00001058 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001059 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001060 res = Tkinter_Error(self);
1061 else
1062 res = PyString_FromString(Tkapp_Result(self));
1063 LEAVE_OVERLAP_TCL
1064 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001065}
1066
1067static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001068Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001069{
Barry Warsawfa701a81997-01-16 00:15:11 +00001070 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +00001071
Guido van Rossum43713e52000-02-29 13:59:29 +00001072 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +00001073 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001074 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001075 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +00001076 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +00001077
Barry Warsawfa701a81997-01-16 00:15:11 +00001078 Py_INCREF(Py_None);
1079 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001080}
1081
Barry Warsawfa701a81997-01-16 00:15:11 +00001082
1083
Guido van Rossum18468821994-06-20 07:49:28 +00001084/** Tcl Variable **/
1085
1086static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001087SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001088{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001089 char *name1, *name2, *s;
1090 const char *ok;
Barry Warsawfa701a81997-01-16 00:15:11 +00001091 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +00001092 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +00001093
Guido van Rossum62320c91998-06-15 04:36:09 +00001094 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +00001095 if (!tmp)
1096 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001097
Guido van Rossum43713e52000-02-29 13:59:29 +00001098 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001099 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +00001100 s = AsString(newValue, tmp);
Guido van Rossum2834b972000-10-06 16:58:26 +00001101 if (s == NULL)
1102 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001103 ENTER_TCL
1104 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
1105 LEAVE_TCL
1106 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001107 else {
Guido van Rossum35d43371997-08-02 00:09:09 +00001108 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +00001109 if (PyArg_ParseTuple(args, "ssO:setvar",
1110 &name1, &name2, &newValue)) {
1111 s = AsString(newValue, tmp);
1112 if (s == NULL)
1113 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001114 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001115 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +00001116 s, flags);
1117 LEAVE_TCL
1118 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001119 else {
Guido van Rossum00d93061998-05-28 23:06:38 +00001120 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +00001121 return NULL;
1122 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001123 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001124 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +00001125
Barry Warsawfa701a81997-01-16 00:15:11 +00001126 if (!ok)
1127 return Tkinter_Error(self);
1128
1129 Py_INCREF(Py_None);
1130 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001131}
1132
1133static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001134Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001135{
Barry Warsawfa701a81997-01-16 00:15:11 +00001136 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001137}
1138
1139static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001140Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001141{
Barry Warsawfa701a81997-01-16 00:15:11 +00001142 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001143}
1144
Barry Warsawfa701a81997-01-16 00:15:11 +00001145
1146
Guido van Rossum18468821994-06-20 07:49:28 +00001147static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001148GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001149{
Martin v. Löwis71e25a02002-10-01 18:08:06 +00001150 char *name1, *name2=NULL;
1151 const char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001152 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001153
Guido van Rossum43713e52000-02-29 13:59:29 +00001154 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +00001155 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001156 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001157 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +00001158 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +00001159
Barry Warsawfa701a81997-01-16 00:15:11 +00001160 else
Guido van Rossum35d43371997-08-02 00:09:09 +00001161 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001162 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001163
Barry Warsawfa701a81997-01-16 00:15:11 +00001164 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +00001165 res = Tkinter_Error(self);
1166 else
1167 res = PyString_FromString(s);
1168 LEAVE_OVERLAP_TCL
1169 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001170}
1171
1172static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001173Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001174{
Barry Warsawfa701a81997-01-16 00:15:11 +00001175 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001176}
1177
1178static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001179Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001180{
Barry Warsawfa701a81997-01-16 00:15:11 +00001181 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001182}
1183
Barry Warsawfa701a81997-01-16 00:15:11 +00001184
1185
Guido van Rossum18468821994-06-20 07:49:28 +00001186static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001187UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001188{
Guido van Rossum35d43371997-08-02 00:09:09 +00001189 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001190 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001191 int code;
Guido van Rossum18468821994-06-20 07:49:28 +00001192
Guido van Rossum43713e52000-02-29 13:59:29 +00001193 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001194 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001195 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001196 if (name2 == NULL)
1197 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
1198
1199 else
1200 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001201 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001202
Barry Warsawfa701a81997-01-16 00:15:11 +00001203 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001204 res = Tkinter_Error(self);
1205 else {
1206 Py_INCREF(Py_None);
1207 res = Py_None;
1208 }
1209 LEAVE_OVERLAP_TCL
1210 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001211}
1212
1213static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001214Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001215{
Barry Warsawfa701a81997-01-16 00:15:11 +00001216 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001217}
1218
1219static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001220Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001221{
Barry Warsawfa701a81997-01-16 00:15:11 +00001222 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001223}
1224
Barry Warsawfa701a81997-01-16 00:15:11 +00001225
1226
Guido van Rossum18468821994-06-20 07:49:28 +00001227/** Tcl to Python **/
1228
1229static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001230Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001231{
Barry Warsawfa701a81997-01-16 00:15:11 +00001232 char *s;
1233 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001234
Martin v. Löwisffad6332002-11-26 09:28:05 +00001235 if (PyTuple_Size(args) == 1) {
1236 PyObject* o = PyTuple_GetItem(args, 0);
1237 if (PyInt_Check(o)) {
1238 Py_INCREF(o);
1239 return o;
1240 }
1241 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001242 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001243 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001244 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001245 return Tkinter_Error(self);
1246 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001247}
1248
1249static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001250Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001251{
Barry Warsawfa701a81997-01-16 00:15:11 +00001252 char *s;
1253 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001254
Martin v. Löwisffad6332002-11-26 09:28:05 +00001255 if (PyTuple_Size(args) == 1) {
1256 PyObject *o = PyTuple_GetItem(args, 0);
1257 if (PyFloat_Check(o)) {
1258 Py_INCREF(o);
1259 return o;
1260 }
1261 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001262 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001263 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001264 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001265 return Tkinter_Error(self);
1266 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001267}
1268
1269static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001270Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001271{
Barry Warsawfa701a81997-01-16 00:15:11 +00001272 char *s;
1273 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001274
Martin v. Löwisffad6332002-11-26 09:28:05 +00001275 if (PyTuple_Size(args) == 1) {
1276 PyObject *o = PyTuple_GetItem(args, 0);
1277 if (PyInt_Check(o)) {
1278 Py_INCREF(o);
1279 return o;
1280 }
1281 }
Guido van Rossum43713e52000-02-29 13:59:29 +00001282 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001283 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001284 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1285 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001286 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001287}
1288
1289static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001290Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001291{
Barry Warsawfa701a81997-01-16 00:15:11 +00001292 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001293 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001294 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001295
Guido van Rossum43713e52000-02-29 13:59:29 +00001296 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001297 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001298 ENTER_TCL
1299 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001300 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001301 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001302 res = Tkinter_Error(self);
1303 else
1304 res = Py_BuildValue("s", Tkapp_Result(self));
1305 LEAVE_OVERLAP_TCL
1306 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001307}
1308
1309static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001310Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001311{
Barry Warsawfa701a81997-01-16 00:15:11 +00001312 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001313 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001314 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001315 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001316
Guido van Rossum43713e52000-02-29 13:59:29 +00001317 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001318 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001319 ENTER_TCL
1320 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001321 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001322 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001323 res = Tkinter_Error(self);
1324 else
1325 res = Py_BuildValue("l", v);
1326 LEAVE_OVERLAP_TCL
1327 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001328}
1329
1330static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001331Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001332{
Barry Warsawfa701a81997-01-16 00:15:11 +00001333 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001334 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001335 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001336 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001337
Guido van Rossum43713e52000-02-29 13:59:29 +00001338 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001339 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001340 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001341 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001342 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001343 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001344 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001345 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001346 res = Tkinter_Error(self);
1347 else
1348 res = Py_BuildValue("d", v);
1349 LEAVE_OVERLAP_TCL
1350 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001351}
1352
1353static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001354Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001355{
Barry Warsawfa701a81997-01-16 00:15:11 +00001356 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001357 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001358 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001359 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001360
Guido van Rossum43713e52000-02-29 13:59:29 +00001361 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001362 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001363 ENTER_TCL
1364 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001365 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001366 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001367 res = Tkinter_Error(self);
1368 else
1369 res = Py_BuildValue("i", v);
1370 LEAVE_OVERLAP_TCL
1371 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001372}
1373
Barry Warsawfa701a81997-01-16 00:15:11 +00001374
1375
Guido van Rossum18468821994-06-20 07:49:28 +00001376static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001377Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001378{
Barry Warsawfa701a81997-01-16 00:15:11 +00001379 char *list;
1380 int argc;
1381 char **argv;
1382 PyObject *v;
1383 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001384
Martin v. Löwisffad6332002-11-26 09:28:05 +00001385 if (PyTuple_Size(args) == 1) {
1386 v = PyTuple_GetItem(args, 0);
1387 if (PyTuple_Check(v)) {
1388 Py_INCREF(v);
1389 return v;
1390 }
1391 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001392 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001393 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001394
Barry Warsawfa701a81997-01-16 00:15:11 +00001395 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1396 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001397
Barry Warsawfa701a81997-01-16 00:15:11 +00001398 if (!(v = PyTuple_New(argc)))
1399 return NULL;
1400
1401 for (i = 0; i < argc; i++) {
1402 PyObject *s = PyString_FromString(argv[i]);
1403 if (!s || PyTuple_SetItem(v, i, s)) {
1404 Py_DECREF(v);
1405 v = NULL;
1406 goto finally;
1407 }
1408 }
Guido van Rossum18468821994-06-20 07:49:28 +00001409
Barry Warsawfa701a81997-01-16 00:15:11 +00001410 finally:
1411 ckfree(FREECAST argv);
1412 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001413}
1414
1415static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001416Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001417{
Barry Warsawfa701a81997-01-16 00:15:11 +00001418 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001419
Martin v. Löwisffad6332002-11-26 09:28:05 +00001420 if (PyTuple_Size(args) == 1) {
1421 PyObject* o = PyTuple_GetItem(args, 0);
1422 if (PyTuple_Check(o)) {
1423 o = SplitObj(o);
1424 return o;
1425 }
1426 }
Martin v. Löwis84432eb2002-01-26 20:21:50 +00001427 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001428 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001429 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001430}
1431
1432static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001433Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001434{
Barry Warsawfa701a81997-01-16 00:15:11 +00001435 char *s = Merge(args);
1436 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001437
Barry Warsawfa701a81997-01-16 00:15:11 +00001438 if (s) {
1439 res = PyString_FromString(s);
1440 ckfree(s);
1441 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001442
1443 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001444}
1445
Barry Warsawfa701a81997-01-16 00:15:11 +00001446
1447
Guido van Rossum18468821994-06-20 07:49:28 +00001448/** Tcl Command **/
1449
Guido van Rossum00d93061998-05-28 23:06:38 +00001450/* Client data struct */
1451typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001452 PyObject *self;
1453 PyObject *func;
1454} PythonCmd_ClientData;
1455
1456static int
Fred Drake509d79a2000-07-08 04:04:38 +00001457PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001458{
1459 errorInCmd = 1;
1460 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1461 LEAVE_PYTHON
1462 return TCL_ERROR;
1463}
1464
Guido van Rossum18468821994-06-20 07:49:28 +00001465/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001466 * function or method.
1467 */
Guido van Rossum18468821994-06-20 07:49:28 +00001468static int
Fred Drake509d79a2000-07-08 04:04:38 +00001469PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001470{
Guido van Rossum00d93061998-05-28 23:06:38 +00001471 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001472 PyObject *self, *func, *arg, *res, *tmp;
Guido van Rossum2834b972000-10-06 16:58:26 +00001473 int i, rv;
1474 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +00001475
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001476 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001477
Barry Warsawfa701a81997-01-16 00:15:11 +00001478 /* TBD: no error checking here since we know, via the
1479 * Tkapp_CreateCommand() that the client data is a two-tuple
1480 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001481 self = data->self;
1482 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001483
Barry Warsawfa701a81997-01-16 00:15:11 +00001484 /* Create argument list (argv1, ..., argvN) */
1485 if (!(arg = PyTuple_New(argc - 1)))
1486 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001487
Barry Warsawfa701a81997-01-16 00:15:11 +00001488 for (i = 0; i < (argc - 1); i++) {
1489 PyObject *s = PyString_FromString(argv[i + 1]);
1490 if (!s || PyTuple_SetItem(arg, i, s)) {
1491 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001492 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001493 }
1494 }
1495 res = PyEval_CallObject(func, arg);
1496 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001497
Barry Warsawfa701a81997-01-16 00:15:11 +00001498 if (res == NULL)
1499 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001500
Barry Warsawfa701a81997-01-16 00:15:11 +00001501 if (!(tmp = PyList_New(0))) {
1502 Py_DECREF(res);
1503 return PythonCmd_Error(interp);
1504 }
1505
Guido van Rossum2834b972000-10-06 16:58:26 +00001506 s = AsString(res, tmp);
1507 if (s == NULL) {
1508 rv = PythonCmd_Error(interp);
1509 }
1510 else {
1511 Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
1512 rv = TCL_OK;
1513 }
1514
Barry Warsawfa701a81997-01-16 00:15:11 +00001515 Py_DECREF(res);
1516 Py_DECREF(tmp);
1517
Guido van Rossum00d93061998-05-28 23:06:38 +00001518 LEAVE_PYTHON
1519
Guido van Rossum2834b972000-10-06 16:58:26 +00001520 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00001521}
1522
1523static void
Fred Drake509d79a2000-07-08 04:04:38 +00001524PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00001525{
Guido van Rossum00d93061998-05-28 23:06:38 +00001526 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1527
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001528 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001529 Py_XDECREF(data->self);
1530 Py_XDECREF(data->func);
1531 PyMem_DEL(data);
1532 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001533}
1534
Barry Warsawfa701a81997-01-16 00:15:11 +00001535
1536
Guido van Rossum18468821994-06-20 07:49:28 +00001537static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001538Tkapp_CreateCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001539{
Guido van Rossum00d93061998-05-28 23:06:38 +00001540 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001541 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001542 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001543 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001544
Guido van Rossum43713e52000-02-29 13:59:29 +00001545 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001546 return NULL;
1547 if (!PyCallable_Check(func)) {
1548 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001549 return NULL;
1550 }
Guido van Rossum18468821994-06-20 07:49:28 +00001551
Guido van Rossum00d93061998-05-28 23:06:38 +00001552 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001553 if (!data)
1554 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001555 Py_XINCREF(self);
1556 Py_XINCREF(func);
1557 data->self = self;
1558 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001559
Guido van Rossum00d93061998-05-28 23:06:38 +00001560 ENTER_TCL
1561 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1562 (ClientData)data, PythonCmdDelete);
1563 LEAVE_TCL
1564 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001565 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001566 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001567 return NULL;
1568 }
Guido van Rossum18468821994-06-20 07:49:28 +00001569
Barry Warsawfa701a81997-01-16 00:15:11 +00001570 Py_INCREF(Py_None);
1571 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001572}
1573
Barry Warsawfa701a81997-01-16 00:15:11 +00001574
1575
Guido van Rossum18468821994-06-20 07:49:28 +00001576static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001577Tkapp_DeleteCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001578{
Barry Warsawfa701a81997-01-16 00:15:11 +00001579 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001580 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001581
Guido van Rossum43713e52000-02-29 13:59:29 +00001582 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001583 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001584 ENTER_TCL
1585 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1586 LEAVE_TCL
1587 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001588 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1589 return NULL;
1590 }
1591 Py_INCREF(Py_None);
1592 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001593}
1594
Barry Warsawfa701a81997-01-16 00:15:11 +00001595
1596
Guido van Rossum00d93061998-05-28 23:06:38 +00001597#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001598/** File Handler **/
1599
Guido van Rossum00d93061998-05-28 23:06:38 +00001600typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001601 PyObject *func;
1602 PyObject *file;
1603 int id;
1604 struct _fhcdata *next;
1605} FileHandler_ClientData;
1606
1607static FileHandler_ClientData *HeadFHCD;
1608
1609static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00001610NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001611{
1612 FileHandler_ClientData *p;
1613 p = PyMem_NEW(FileHandler_ClientData, 1);
1614 if (p != NULL) {
1615 Py_XINCREF(func);
1616 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001617 p->func = func;
1618 p->file = file;
1619 p->id = id;
1620 p->next = HeadFHCD;
1621 HeadFHCD = p;
1622 }
1623 return p;
1624}
1625
1626static void
Fred Drake509d79a2000-07-08 04:04:38 +00001627DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001628{
1629 FileHandler_ClientData *p, **pp;
1630
1631 pp = &HeadFHCD;
1632 while ((p = *pp) != NULL) {
1633 if (p->id == id) {
1634 *pp = p->next;
1635 Py_XDECREF(p->func);
1636 Py_XDECREF(p->file);
1637 PyMem_DEL(p);
1638 }
1639 else
1640 pp = &p->next;
1641 }
1642}
1643
Guido van Rossuma597dde1995-01-10 20:56:29 +00001644static void
Fred Drake509d79a2000-07-08 04:04:38 +00001645FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00001646{
Guido van Rossum00d93061998-05-28 23:06:38 +00001647 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001648 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001649
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001650 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001651 func = data->func;
1652 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001653
Barry Warsawfa701a81997-01-16 00:15:11 +00001654 arg = Py_BuildValue("(Oi)", file, (long) mask);
1655 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001656 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001657
1658 if (res == NULL) {
1659 errorInCmd = 1;
1660 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1661 }
1662 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001663 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001664}
1665
Guido van Rossum18468821994-06-20 07:49:28 +00001666static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001667Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
1668 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001669{
Guido van Rossum00d93061998-05-28 23:06:38 +00001670 FileHandler_ClientData *data;
1671 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001672 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001673
Guido van Rossum2834b972000-10-06 16:58:26 +00001674 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
1675 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001676 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001677 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001678 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001679 return NULL;
1680 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001681 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001682 return NULL;
1683 }
1684
Guido van Rossuma80649b2000-03-28 20:07:05 +00001685 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001686 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001687 return NULL;
1688
Barry Warsawfa701a81997-01-16 00:15:11 +00001689 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001690 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001691 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001692 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001693 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001694 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001695}
1696
1697static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001698Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001699{
Barry Warsawfa701a81997-01-16 00:15:11 +00001700 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001701 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001702
Guido van Rossum43713e52000-02-29 13:59:29 +00001703 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001704 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001705 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001706 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001707 return NULL;
1708
Guido van Rossuma80649b2000-03-28 20:07:05 +00001709 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001710
Barry Warsawfa701a81997-01-16 00:15:11 +00001711 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001712 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001713 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001714 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001715 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001716 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001717}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001718#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001719
Barry Warsawfa701a81997-01-16 00:15:11 +00001720
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001721/**** Tktt Object (timer token) ****/
1722
Jeremy Hylton938ace62002-07-17 16:30:39 +00001723static PyTypeObject Tktt_Type;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001724
Guido van Rossum00d93061998-05-28 23:06:38 +00001725typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001726 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001727 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001728 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001729} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001730
1731static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001732Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001733{
Barry Warsawfa701a81997-01-16 00:15:11 +00001734 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001735 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001736
Guido van Rossum43713e52000-02-29 13:59:29 +00001737 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001738 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001739 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001740 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001741 v->token = NULL;
1742 }
1743 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001744 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001745 Py_DECREF(func);
1746 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001747 }
1748 Py_INCREF(Py_None);
1749 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001750}
1751
1752static PyMethodDef Tktt_methods[] =
1753{
Neal Norwitzb0493252002-03-31 14:44:22 +00001754 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00001755 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001756};
1757
1758static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001759Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001760{
Barry Warsawfa701a81997-01-16 00:15:11 +00001761 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001762
Guido van Rossumb18618d2000-05-03 23:44:39 +00001763 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00001764 if (v == NULL)
1765 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001766
Guido van Rossum00d93061998-05-28 23:06:38 +00001767 Py_INCREF(func);
1768 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001769 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001770
1771 /* Extra reference, deleted when called or when handler is deleted */
1772 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001773 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001774}
1775
1776static void
Fred Drake509d79a2000-07-08 04:04:38 +00001777Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001778{
Guido van Rossum00d93061998-05-28 23:06:38 +00001779 TkttObject *v = (TkttObject *)self;
1780 PyObject *func = v->func;
1781
1782 Py_XDECREF(func);
1783
Guido van Rossumb18618d2000-05-03 23:44:39 +00001784 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001785}
1786
Guido van Rossum597ac201998-05-12 14:36:19 +00001787static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001788Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001789{
Barry Warsawfa701a81997-01-16 00:15:11 +00001790 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001791 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001792
Tim Peters885d4572001-11-28 20:27:42 +00001793 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
Jack Jansencb852442001-12-09 23:15:56 +00001794 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001795 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001796}
1797
1798static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001799Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001800{
Barry Warsawfa701a81997-01-16 00:15:11 +00001801 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001802}
1803
1804static PyTypeObject Tktt_Type =
1805{
Guido van Rossum35d43371997-08-02 00:09:09 +00001806 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001807 0, /*ob_size */
1808 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001809 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001810 0, /*tp_itemsize */
1811 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001812 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001813 Tktt_GetAttr, /*tp_getattr */
1814 0, /*tp_setattr */
1815 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001816 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001817 0, /*tp_as_number */
1818 0, /*tp_as_sequence */
1819 0, /*tp_as_mapping */
1820 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001821};
1822
Barry Warsawfa701a81997-01-16 00:15:11 +00001823
1824
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001825/** Timer Handler **/
1826
1827static void
Fred Drake509d79a2000-07-08 04:04:38 +00001828TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001829{
Guido van Rossum00d93061998-05-28 23:06:38 +00001830 TkttObject *v = (TkttObject *)clientData;
1831 PyObject *func = v->func;
1832 PyObject *res;
1833
1834 if (func == NULL)
1835 return;
1836
1837 v->func = NULL;
1838
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001839 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001840
1841 res = PyEval_CallObject(func, NULL);
1842 Py_DECREF(func);
1843 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001844
Barry Warsawfa701a81997-01-16 00:15:11 +00001845 if (res == NULL) {
1846 errorInCmd = 1;
1847 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1848 }
1849 else
1850 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001851
1852 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001853}
1854
1855static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001856Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001857{
Barry Warsawfa701a81997-01-16 00:15:11 +00001858 int milliseconds;
1859 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001860 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001861
Guido van Rossum2834b972000-10-06 16:58:26 +00001862 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
1863 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001864 return NULL;
1865 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001866 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001867 return NULL;
1868 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001869 v = Tktt_New(func);
1870 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1871 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001872
Guido van Rossum00d93061998-05-28 23:06:38 +00001873 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001874}
1875
Barry Warsawfa701a81997-01-16 00:15:11 +00001876
Guido van Rossum18468821994-06-20 07:49:28 +00001877/** Event Loop **/
1878
Guido van Rossum18468821994-06-20 07:49:28 +00001879static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001880Tkapp_MainLoop(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001881{
Barry Warsawfa701a81997-01-16 00:15:11 +00001882 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001883#ifdef WITH_THREAD
1884 PyThreadState *tstate = PyThreadState_Get();
1885#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001886
Guido van Rossum43713e52000-02-29 13:59:29 +00001887 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001888 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001889
Barry Warsawfa701a81997-01-16 00:15:11 +00001890 quitMainLoop = 0;
1891 while (Tk_GetNumMainWindows() > threshold &&
1892 !quitMainLoop &&
1893 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001894 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001895 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001896
1897#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001898 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001899 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001900 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001901 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001902 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001903 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001904 if (result == 0)
1905 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001906 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001907#else
1908 result = Tcl_DoOneEvent(0);
1909#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001910
Guido van Rossum35d43371997-08-02 00:09:09 +00001911 if (PyErr_CheckSignals() != 0)
1912 return NULL;
1913 if (result < 0)
1914 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001915 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001916 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001917
Barry Warsawfa701a81997-01-16 00:15:11 +00001918 if (errorInCmd) {
1919 errorInCmd = 0;
1920 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1921 excInCmd = valInCmd = trbInCmd = NULL;
1922 return NULL;
1923 }
1924 Py_INCREF(Py_None);
1925 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001926}
1927
1928static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001929Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00001930{
Guido van Rossum35d43371997-08-02 00:09:09 +00001931 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001932 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001933
Guido van Rossum43713e52000-02-29 13:59:29 +00001934 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001935 return NULL;
1936
Guido van Rossum00d93061998-05-28 23:06:38 +00001937 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001938 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001939 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001940 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001941}
1942
1943static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001944Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001945{
1946
Guido van Rossum43713e52000-02-29 13:59:29 +00001947 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001948 return NULL;
1949
1950 quitMainLoop = 1;
1951 Py_INCREF(Py_None);
1952 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001953}
1954
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001955static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001956Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001957{
1958
Guido van Rossum43713e52000-02-29 13:59:29 +00001959 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001960 return NULL;
1961
1962 return PyInt_FromLong((long)Tkapp_Interp(self));
1963}
1964
Barry Warsawfa701a81997-01-16 00:15:11 +00001965
Martin v. Löwisffad6332002-11-26 09:28:05 +00001966static PyObject *
1967Tkapp_WantObjects(PyObject *self, PyObject *args)
1968{
1969
1970 int want_objects;
1971 if (!PyArg_ParseTuple(args, "i:wantobjects", &want_objects))
1972 return NULL;
1973 ((TkappObject*)self)->want_objects = want_objects;
1974
1975 Py_INCREF(Py_None);
1976 return Py_None;
1977}
1978
1979
Barry Warsawfa701a81997-01-16 00:15:11 +00001980
Guido van Rossum18468821994-06-20 07:49:28 +00001981/**** Tkapp Method List ****/
1982
1983static PyMethodDef Tkapp_methods[] =
1984{
Martin v. Löwisffad6332002-11-26 09:28:05 +00001985 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
Martin v. Löwis43b936d2002-01-17 23:15:58 +00001986 {"call", Tkapp_Call, METH_OLDARGS},
1987 {"globalcall", Tkapp_GlobalCall, METH_OLDARGS},
1988 {"eval", Tkapp_Eval, METH_VARARGS},
1989 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
1990 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
1991 {"record", Tkapp_Record, METH_VARARGS},
1992 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
1993 {"setvar", Tkapp_SetVar, METH_VARARGS},
1994 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
1995 {"getvar", Tkapp_GetVar, METH_VARARGS},
1996 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
1997 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
1998 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
1999 {"getint", Tkapp_GetInt, METH_VARARGS},
2000 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2001 {"getboolean", Tkapp_GetBoolean, METH_VARARGS},
2002 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2003 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2004 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2005 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2006 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2007 {"split", Tkapp_Split, METH_VARARGS},
2008 {"merge", Tkapp_Merge, METH_OLDARGS},
2009 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2010 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002011#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002012 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2013 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002014#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002015 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2016 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2017 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2018 {"quit", Tkapp_Quit, METH_VARARGS},
2019 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002020 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002021};
2022
Barry Warsawfa701a81997-01-16 00:15:11 +00002023
2024
Guido van Rossum18468821994-06-20 07:49:28 +00002025/**** Tkapp Type Methods ****/
2026
2027static void
Fred Drake509d79a2000-07-08 04:04:38 +00002028Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00002029{
Guido van Rossum00d93061998-05-28 23:06:38 +00002030 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00002031 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00002032 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00002033 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002034 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00002035}
2036
2037static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00002038Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00002039{
Guido van Rossum35d43371997-08-02 00:09:09 +00002040 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00002041}
2042
2043static PyTypeObject Tkapp_Type =
2044{
Guido van Rossum35d43371997-08-02 00:09:09 +00002045 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00002046 0, /*ob_size */
2047 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00002048 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00002049 0, /*tp_itemsize */
2050 Tkapp_Dealloc, /*tp_dealloc */
2051 0, /*tp_print */
2052 Tkapp_GetAttr, /*tp_getattr */
2053 0, /*tp_setattr */
2054 0, /*tp_compare */
2055 0, /*tp_repr */
2056 0, /*tp_as_number */
2057 0, /*tp_as_sequence */
2058 0, /*tp_as_mapping */
2059 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00002060};
2061
Barry Warsawfa701a81997-01-16 00:15:11 +00002062
2063
Guido van Rossum18468821994-06-20 07:49:28 +00002064/**** Tkinter Module ****/
2065
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002066typedef struct {
2067 PyObject* tuple;
2068 int size; /* current size */
2069 int maxsize; /* allocated size */
2070} FlattenContext;
2071
2072static int
2073_bump(FlattenContext* context, int size)
2074{
Guido van Rossum2834b972000-10-06 16:58:26 +00002075 /* expand tuple to hold (at least) size new items.
2076 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002077
2078 int maxsize = context->maxsize * 2;
2079
2080 if (maxsize < context->size + size)
2081 maxsize = context->size + size;
2082
2083 context->maxsize = maxsize;
2084
Tim Peters4324aa32001-05-28 22:30:08 +00002085 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002086}
2087
2088static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002089_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002090{
2091 /* add tuple or list to argument tuple (recursively) */
2092
2093 int i, size;
2094
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002095 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002096 PyErr_SetString(PyExc_ValueError,
2097 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002098 return 0;
2099 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002100 size = PyList_GET_SIZE(item);
2101 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00002102 if (context->size + size > context->maxsize &&
2103 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002104 return 0;
2105 /* copy items to output tuple */
2106 for (i = 0; i < size; i++) {
2107 PyObject *o = PyList_GET_ITEM(item, i);
2108 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002109 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002110 return 0;
2111 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002112 if (context->size + 1 > context->maxsize &&
2113 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002114 return 0;
2115 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002116 PyTuple_SET_ITEM(context->tuple,
2117 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002118 }
2119 }
2120 } else if (PyTuple_Check(item)) {
2121 /* same, for tuples */
2122 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00002123 if (context->size + size > context->maxsize &&
2124 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002125 return 0;
2126 for (i = 0; i < size; i++) {
2127 PyObject *o = PyTuple_GET_ITEM(item, i);
2128 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002129 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002130 return 0;
2131 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00002132 if (context->size + 1 > context->maxsize &&
2133 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002134 return 0;
2135 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00002136 PyTuple_SET_ITEM(context->tuple,
2137 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002138 }
2139 }
2140 } else {
2141 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
2142 return 0;
2143 }
2144 return 1;
2145}
2146
2147static PyObject *
2148Tkinter_Flatten(PyObject* self, PyObject* args)
2149{
2150 FlattenContext context;
2151 PyObject* item;
2152
2153 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
2154 return NULL;
2155
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002156 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002157 if (context.maxsize <= 0)
2158 return PyTuple_New(0);
2159
2160 context.tuple = PyTuple_New(context.maxsize);
2161 if (!context.tuple)
2162 return NULL;
2163
2164 context.size = 0;
2165
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00002166 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002167 return NULL;
2168
Tim Peters4324aa32001-05-28 22:30:08 +00002169 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00002170 return NULL;
2171
2172 return context.tuple;
2173}
2174
Guido van Rossum18468821994-06-20 07:49:28 +00002175static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002176Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00002177{
Barry Warsawfa701a81997-01-16 00:15:11 +00002178 char *screenName = NULL;
2179 char *baseName = NULL;
2180 char *className = NULL;
2181 int interactive = 0;
Martin v. Löwisffad6332002-11-26 09:28:05 +00002182 int want_objects = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002183
Guido van Rossum35d43371997-08-02 00:09:09 +00002184 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00002185 if (baseName != NULL)
2186 baseName++;
2187 else
2188 baseName = Py_GetProgramName();
2189 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00002190
Guido van Rossum43713e52000-02-29 13:59:29 +00002191 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00002192 &screenName, &baseName, &className,
Martin v. Löwisffad6332002-11-26 09:28:05 +00002193 &interactive, &want_objects))
Barry Warsawfa701a81997-01-16 00:15:11 +00002194 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00002195
Barry Warsawfa701a81997-01-16 00:15:11 +00002196 return (PyObject *) Tkapp_New(screenName, baseName, className,
Martin v. Löwisffad6332002-11-26 09:28:05 +00002197 interactive, want_objects);
Guido van Rossum18468821994-06-20 07:49:28 +00002198}
2199
2200static PyMethodDef moduleMethods[] =
2201{
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002202 {"_flatten", Tkinter_Flatten, METH_VARARGS},
2203 {"create", Tkinter_Create, METH_VARARGS},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002204#ifdef HAVE_CREATEFILEHANDLER
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002205 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2206 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
Guido van Rossum02c04671997-08-07 00:12:22 +00002207#endif
Martin v. Löwis43b936d2002-01-17 23:15:58 +00002208 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2209 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2210 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2211 {"quit", Tkapp_Quit, METH_VARARGS},
Barry Warsawfa701a81997-01-16 00:15:11 +00002212 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00002213};
2214
Guido van Rossum7bf15641998-05-22 18:28:17 +00002215#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002216
2217static int stdin_ready = 0;
2218
Guido van Rossumad4db171998-06-13 13:56:28 +00002219#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00002220static void
Fred Drake509d79a2000-07-08 04:04:38 +00002221MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002222{
2223 stdin_ready = 1;
2224}
Guido van Rossumad4db171998-06-13 13:56:28 +00002225#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002226
Guido van Rossum00d93061998-05-28 23:06:38 +00002227static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00002228
Guido van Rossum18468821994-06-20 07:49:28 +00002229static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002230EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002231{
Guido van Rossumad4db171998-06-13 13:56:28 +00002232#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002233 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002234#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002235#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002236 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002237#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002238 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002239 errorInCmd = 0;
2240#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002241 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002242 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002243#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002244 while (!errorInCmd && !stdin_ready) {
2245 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002246#ifdef MS_WINDOWS
2247 if (_kbhit()) {
2248 stdin_ready = 1;
2249 break;
2250 }
2251#endif
2252#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002253 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00002254 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002255 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002256
Guido van Rossum00d93061998-05-28 23:06:38 +00002257 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002258
2259 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00002260 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002261 if (result == 0)
2262 Sleep(20);
2263 Py_END_ALLOW_THREADS
2264#else
2265 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002266#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002267
2268 if (result < 0)
2269 break;
2270 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002271#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002272 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002273#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002274 if (errorInCmd) {
2275 errorInCmd = 0;
2276 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2277 excInCmd = valInCmd = trbInCmd = NULL;
2278 PyErr_Print();
2279 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002280#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002281 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002282#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002283 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002284}
Guido van Rossum18468821994-06-20 07:49:28 +00002285
Guido van Rossum00d93061998-05-28 23:06:38 +00002286#endif
2287
Guido van Rossum7bf15641998-05-22 18:28:17 +00002288static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002289EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002290{
Guido van Rossum00d93061998-05-28 23:06:38 +00002291#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002292 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002293#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002294 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002295#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002296 PyOS_InputHook = EventHook;
2297 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002298#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002299}
2300
2301static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002302DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002303{
Guido van Rossum00d93061998-05-28 23:06:38 +00002304#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002305 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2306 PyOS_InputHook = NULL;
2307 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002308#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002309}
2310
Barry Warsawfa701a81997-01-16 00:15:11 +00002311
2312/* all errors will be checked in one fell swoop in init_tkinter() */
2313static void
Fred Drake509d79a2000-07-08 04:04:38 +00002314ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002315{
2316 PyObject *v = PyInt_FromLong(val);
2317 if (v) {
2318 PyDict_SetItemString(d, name, v);
2319 Py_DECREF(v);
2320 }
2321}
2322static void
Fred Drake509d79a2000-07-08 04:04:38 +00002323ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002324{
2325 PyObject *v = PyString_FromString(val);
2326 if (v) {
2327 PyDict_SetItemString(d, name, v);
2328 Py_DECREF(v);
2329 }
2330}
2331
2332
Mark Hammond62b1ab12002-07-23 06:31:15 +00002333PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002334init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002335{
Barry Warsawfa701a81997-01-16 00:15:11 +00002336 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002337
Barry Warsawfa701a81997-01-16 00:15:11 +00002338 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002339
2340#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002341 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002342#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002343
Barry Warsawfa701a81997-01-16 00:15:11 +00002344 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002345
Barry Warsawfa701a81997-01-16 00:15:11 +00002346 d = PyModule_GetDict(m);
Neal Norwitzb5b5a262002-06-04 17:14:07 +00002347 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
Barry Warsawfa701a81997-01-16 00:15:11 +00002348 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002349
Guido van Rossum35d43371997-08-02 00:09:09 +00002350 ins_long(d, "READABLE", TCL_READABLE);
2351 ins_long(d, "WRITABLE", TCL_WRITABLE);
2352 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2353 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2354 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2355 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2356 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2357 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2358 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002359 ins_string(d, "TK_VERSION", TK_VERSION);
2360 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002361
Guido van Rossum83551bf1997-09-13 00:44:23 +00002362 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002363
2364 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002365 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2366
Martin v. Löwisffad6332002-11-26 09:28:05 +00002367 PyTclObject_Type.ob_type = &PyType_Type;
2368 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
Jack Jansencb852442001-12-09 23:15:56 +00002369
2370#ifdef TK_AQUA
2371 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
2372 * start waking up. Note that Tcl_FindExecutable will do this, this
2373 * code must be above it! The original warning from
2374 * tkMacOSXAppInit.c is copied below.
2375 *
2376 * NB - You have to swap in the Tk Notifier BEFORE you start up the
2377 * Tcl interpreter for now. It probably should work to do this
2378 * in the other order, but for now it doesn't seem to.
2379 *
2380 */
2381 Tk_MacOSXSetupTkNotifier();
2382#endif
2383
2384
Guido van Rossume187b0e2000-03-27 21:46:29 +00002385 /* This helps the dynamic loader; in Unicode aware Tcl versions
2386 it also helps Tcl find its encodings. */
2387 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002388
Barry Warsawfa701a81997-01-16 00:15:11 +00002389 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002390 return;
2391
Guido van Rossum43ff8681998-07-14 18:02:13 +00002392#if 0
2393 /* This was not a good idea; through <Destroy> bindings,
2394 Tcl_Finalize() may invoke Python code but at that point the
2395 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002396 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002397#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002398
Jack Jansen34cc5c31995-10-31 16:15:12 +00002399#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002400 /*
2401 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2402 ** Most of the initializations in that routine (toolbox init calls and
2403 ** such) have already been done for us, so we only need these.
2404 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002405 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002406
2407 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002408#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002409 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002410#endif /* GENERATINGCFM */
2411#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002412}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002413
Guido van Rossumec22c921996-02-25 04:50:29 +00002414
Barry Warsawfa701a81997-01-16 00:15:11 +00002415
Guido van Rossum9722ad81995-09-22 23:49:28 +00002416#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002417
2418/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002419** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002420*/
2421
Guido van Rossum9722ad81995-09-22 23:49:28 +00002422void
2423panic(char * format, ...)
2424{
Barry Warsawfa701a81997-01-16 00:15:11 +00002425 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002426
Barry Warsawfa701a81997-01-16 00:15:11 +00002427 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002428
Guido van Rossum227cf761998-08-05 13:53:32 +00002429 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002430 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002431
Barry Warsawfa701a81997-01-16 00:15:11 +00002432 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002433
Barry Warsawfa701a81997-01-16 00:15:11 +00002434 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002435}
Jack Jansen40b546d1995-11-14 10:34:45 +00002436
Guido van Rossumec22c921996-02-25 04:50:29 +00002437/*
2438** Pass events to SIOUX before passing them to Tk.
2439*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002440
Guido van Rossumec22c921996-02-25 04:50:29 +00002441static int
Fred Drake509d79a2000-07-08 04:04:38 +00002442PyMacConvertEvent(EventRecord *eventPtr)
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002443{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002444 WindowPtr frontwin;
2445 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002446 ** Sioux eats too many events, so we don't pass it everything. We
2447 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002448 ** the Sioux window is frontmost. This means that Tk menus don't work
2449 ** in that case, but at least we can scroll the sioux window.
2450 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2451 ** part of the external interface of Sioux...
2452 */
2453 frontwin = FrontWindow();
2454 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2455 if (SIOUXHandleOneEvent(eventPtr))
2456 return 0; /* Nothing happened to the Tcl event queue */
2457 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002458 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002459}
2460
Guido van Rossumec22c921996-02-25 04:50:29 +00002461#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002462
2463/*
2464** Additional Mac specific code for dealing with shared libraries.
2465*/
2466
2467#include <Resources.h>
2468#include <CodeFragments.h>
2469
2470static int loaded_from_shlib = 0;
2471static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002472
Jack Jansen34cc5c31995-10-31 16:15:12 +00002473/*
2474** If this module is dynamically loaded the following routine should
2475** be the init routine. It takes care of adding the shared library to
2476** the resource-file chain, so that the tk routines can find their
2477** resources.
2478*/
2479OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002480init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002481{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002482 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002483 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002484 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002485 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2486 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002487 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002488 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2489 loaded_from_shlib = 1;
2490 }
2491 return noErr;
2492}
2493
2494/*
2495** Insert the library resources into the search path. Put them after
2496** the resources from the application. Again, we ignore errors.
2497*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002498static
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002499mac_addlibresources(void)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002500{
2501 if ( !loaded_from_shlib )
2502 return;
2503 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2504}
2505
Guido van Rossumec22c921996-02-25 04:50:29 +00002506#endif /* GENERATINGCFM */
2507#endif /* macintosh */