blob: 86b5c220e319dc796bd1590b828b33bac2faa6bf [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
Guido van Rossum18468821994-06-20 07:49:28 +000044#include <tcl.h>
45#include <tk.h>
46
Guido van Rossum3e819a71997-08-01 19:29:02 +000047#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
48
Guido van Rossuma80649b2000-03-28 20:07:05 +000049#if TKMAJORMINOR < 8000
50#error "Tk older than 8.0 not supported"
Guido van Rossum00d93061998-05-28 23:06:38 +000051#endif
52
Guido van Rossuma80649b2000-03-28 20:07:05 +000053#if defined(macintosh)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000054/* Sigh, we have to include this to get at the tcl qd pointer */
55#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000056/* And this one we need to clear the menu bar */
57#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000058#endif
59
Tim Peters98dc0652000-10-05 19:24:26 +000060#if !(defined(MS_WINDOWS) || defined(__CYGWIN__))
Guido van Rossum0d2390c1997-08-14 19:57:07 +000061#define HAVE_CREATEFILEHANDLER
62#endif
63
Guido van Rossum00d93061998-05-28 23:06:38 +000064#ifdef HAVE_CREATEFILEHANDLER
65
66/* Tcl_CreateFileHandler() changed several times; these macros deal with the
67 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
68 Unix, only because Jack added it back); when available on Windows, it only
69 applies to sockets. */
70
Guido van Rossum7bf15641998-05-22 18:28:17 +000071#ifdef MS_WINDOWS
72#define FHANDLETYPE TCL_WIN_SOCKET
73#else
74#define FHANDLETYPE TCL_UNIX_FD
75#endif
76
Guido van Rossum00d93061998-05-28 23:06:38 +000077/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
78 which uses this to handle Tcl events while the user is typing commands. */
79
80#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +000081#define WAIT_FOR_STDIN
82#endif
83
Guido van Rossum00d93061998-05-28 23:06:38 +000084#endif /* HAVE_CREATEFILEHANDLER */
85
Guido van Rossumad4db171998-06-13 13:56:28 +000086#ifdef MS_WINDOWS
87#include <conio.h>
88#define WAIT_FOR_STDIN
89#endif
90
Guido van Rossum00d93061998-05-28 23:06:38 +000091#ifdef WITH_THREAD
92
93/* The threading situation is complicated. Tcl is not thread-safe, except for
94 Tcl 8.1, which will probably remain in alpha status for another 6 months
95 (and the README says that Tk will probably remain thread-unsafe forever).
96 So we need to use a lock around all uses of Tcl. Previously, the Python
97 interpreter lock was used for this. However, this causes problems when
98 other Python threads need to run while Tcl is blocked waiting for events.
99
100 To solve this problem, a separate lock for Tcl is introduced. Holding it
101 is incompatible with holding Python's interpreter lock. The following four
102 macros manipulate both locks together.
103
104 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
105 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
106 that could call an event handler, or otherwise affect the state of a Tcl
107 interpreter. These assume that the surrounding code has the Python
108 interpreter lock; inside the brackets, the Python interpreter lock has been
109 released and the lock for Tcl has been acquired.
110
Guido van Rossum5e977831998-06-15 14:03:52 +0000111 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
112 (For example, when transferring data from the Tcl interpreter result to a
113 Python string object.) This can be done by using different macros to close
114 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
115 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
116 releases the Tcl lock.
117
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000118 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000119 handlers when the handler needs to use Python. Such event handlers are
120 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000121 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000122 the Python interpreter lock, restoring the appropriate thread state, and
123 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
124 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000125 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000126
127 These locks expand to several statements and brackets; they should not be
128 used in branches of if statements and the like.
129
130*/
131
Guido van Rossum65d5b571998-12-21 19:32:43 +0000132static PyThread_type_lock tcl_lock = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000133static PyThreadState *tcl_tstate = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000134
135#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000136 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000137 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000138
139#define LEAVE_TCL \
Guido van Rossum2834b972000-10-06 16:58:26 +0000140 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000141
Guido van Rossum62320c91998-06-15 04:36:09 +0000142#define ENTER_OVERLAP \
143 Py_END_ALLOW_THREADS
144
145#define LEAVE_OVERLAP_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000146 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000147
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000148#define ENTER_PYTHON \
149 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000150 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000151
152#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000153 { PyThreadState *tstate = PyEval_SaveThread(); \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000154 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Guido van Rossum00d93061998-05-28 23:06:38 +0000155
156#else
157
158#define ENTER_TCL
159#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000160#define ENTER_OVERLAP
161#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000162#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000163#define LEAVE_PYTHON
164
165#endif
166
Guido van Rossumec22c921996-02-25 04:50:29 +0000167#ifdef macintosh
168
169/*
170** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000171** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000172*/
173
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000174/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000175#define FREECAST (char *)
176
Guido van Rossumec22c921996-02-25 04:50:29 +0000177#include <Events.h> /* For EventRecord */
178
Fred Drake509d79a2000-07-08 04:04:38 +0000179typedef int (*TclMacConvertEventPtr) (EventRecord *eventPtr);
Guido van Rossum2834b972000-10-06 16:58:26 +0000180void Tcl_MacSetEventProc(TclMacConvertEventPtr procPtr);
181int TkMacConvertEvent(EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000182
Guido van Rossum2834b972000-10-06 16:58:26 +0000183staticforward int PyMacConvertEvent(EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000184
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000185#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
186 #pragma import on
187#endif
188
189#include <SIOUX.h>
190extern int SIOUXIsAppWindow(WindowPtr);
191
192#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
193 #pragma import reset
194#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000195#endif /* macintosh */
196
Guido van Rossum97867b21996-08-08 19:09:53 +0000197#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000198#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000199#endif
200
Guido van Rossum18468821994-06-20 07:49:28 +0000201/**** Tkapp Object Declaration ****/
202
203staticforward PyTypeObject Tkapp_Type;
204
Guido van Rossum00d93061998-05-28 23:06:38 +0000205typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000206 PyObject_HEAD
207 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000208} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000209
210#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000211#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000212#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000213
Guido van Rossum35d43371997-08-02 00:09:09 +0000214#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000215(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000216
Barry Warsawfa701a81997-01-16 00:15:11 +0000217
218
Guido van Rossum18468821994-06-20 07:49:28 +0000219/**** Error Handling ****/
220
221static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000222static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000223static int errorInCmd = 0;
224static PyObject *excInCmd;
225static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000226static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000227
Barry Warsawfa701a81997-01-16 00:15:11 +0000228
229
Guido van Rossum18468821994-06-20 07:49:28 +0000230static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000231Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000232{
Barry Warsawfa701a81997-01-16 00:15:11 +0000233 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
234 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000235}
236
Barry Warsawfa701a81997-01-16 00:15:11 +0000237
Barry Warsawfa701a81997-01-16 00:15:11 +0000238
Guido van Rossum18468821994-06-20 07:49:28 +0000239/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000240
241#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000242#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000243
Guido van Rossum00d93061998-05-28 23:06:38 +0000244/* Millisecond sleep() for Unix platforms. */
245
246static void
Fred Drake509d79a2000-07-08 04:04:38 +0000247Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000248{
249 /* XXX Too bad if you don't have select(). */
250 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000251 t.tv_sec = milli/1000;
252 t.tv_usec = (milli%1000) * 1000;
253 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
254}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000255#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000256#endif /* WITH_THREAD */
257
258
Guido van Rossum18468821994-06-20 07:49:28 +0000259static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000260AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000261{
Guido van Rossum35d43371997-08-02 00:09:09 +0000262 if (PyString_Check(value))
263 return PyString_AsString(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000264 else if (PyUnicode_Check(value)) {
265 PyObject *v = PyUnicode_AsUTF8String(value);
266 if (v == NULL)
267 return NULL;
268 if (PyList_Append(tmp, v) != 0) {
269 Py_DECREF(v);
270 return NULL;
271 }
272 Py_DECREF(v);
273 return PyString_AsString(v);
274 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000275 else {
276 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000277 if (v == NULL)
278 return NULL;
279 if (PyList_Append(tmp, v) != 0) {
280 Py_DECREF(v);
281 return NULL;
282 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000283 Py_DECREF(v);
284 return PyString_AsString(v);
285 }
Guido van Rossum18468821994-06-20 07:49:28 +0000286}
287
Barry Warsawfa701a81997-01-16 00:15:11 +0000288
289
Guido van Rossum18468821994-06-20 07:49:28 +0000290#define ARGSZ 64
291
292static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000293Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000294{
Barry Warsawfa701a81997-01-16 00:15:11 +0000295 PyObject *tmp = NULL;
296 char *argvStore[ARGSZ];
297 char **argv = NULL;
298 int fvStore[ARGSZ];
299 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000300 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000301 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000302
Barry Warsawfa701a81997-01-16 00:15:11 +0000303 if (!(tmp = PyList_New(0)))
304 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000305
Barry Warsawfa701a81997-01-16 00:15:11 +0000306 argv = argvStore;
307 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000308
Barry Warsawfa701a81997-01-16 00:15:11 +0000309 if (args == NULL)
310 argc = 0;
311
312 else if (!PyTuple_Check(args)) {
313 argc = 1;
314 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000315 if (!(argv[0] = AsString(args, tmp)))
316 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000317 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000318 else {
319 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000320
Barry Warsawfa701a81997-01-16 00:15:11 +0000321 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000322 argv = (char **)ckalloc(argc * sizeof(char *));
323 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000324 if (argv == NULL || fv == NULL) {
325 PyErr_NoMemory();
326 goto finally;
327 }
328 }
329
330 for (i = 0; i < argc; i++) {
331 PyObject *v = PyTuple_GetItem(args, i);
332 if (PyTuple_Check(v)) {
333 fv[i] = 1;
334 if (!(argv[i] = Merge(v)))
335 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000336 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000337 }
338 else if (v == Py_None) {
339 argc = i;
340 break;
341 }
342 else {
343 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000344 if (!(argv[i] = AsString(v, tmp)))
345 goto finally;
346 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000347 }
348 }
Guido van Rossum18468821994-06-20 07:49:28 +0000349 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000350 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000351 if (res == NULL)
352 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000353
Barry Warsawfa701a81997-01-16 00:15:11 +0000354 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000355 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000356 if (fv[i]) {
357 ckfree(argv[i]);
358 }
359 if (argv != argvStore)
360 ckfree(FREECAST argv);
361 if (fv != fvStore)
362 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000363
Barry Warsawfa701a81997-01-16 00:15:11 +0000364 Py_DECREF(tmp);
365 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000366}
367
Barry Warsawfa701a81997-01-16 00:15:11 +0000368
369
Guido van Rossum18468821994-06-20 07:49:28 +0000370static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000371Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000372{
Barry Warsawfa701a81997-01-16 00:15:11 +0000373 int argc;
374 char **argv;
375 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000376
Barry Warsawfa701a81997-01-16 00:15:11 +0000377 if (list == NULL) {
378 Py_INCREF(Py_None);
379 return Py_None;
380 }
Guido van Rossum18468821994-06-20 07:49:28 +0000381
Guido van Rossum00d93061998-05-28 23:06:38 +0000382 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000383 /* Not a list.
384 * Could be a quoted string containing funnies, e.g. {"}.
385 * Return the string itself.
386 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000387 return PyString_FromString(list);
388 }
Guido van Rossum18468821994-06-20 07:49:28 +0000389
Barry Warsawfa701a81997-01-16 00:15:11 +0000390 if (argc == 0)
391 v = PyString_FromString("");
392 else if (argc == 1)
393 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000394 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000395 int i;
396 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000397
Barry Warsawfa701a81997-01-16 00:15:11 +0000398 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000399 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000400 Py_DECREF(v);
401 v = NULL;
402 break;
403 }
404 PyTuple_SetItem(v, i, w);
405 }
406 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000407 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000408 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000409}
410
Barry Warsawfa701a81997-01-16 00:15:11 +0000411
412
Guido van Rossum18468821994-06-20 07:49:28 +0000413/**** Tkapp Object ****/
414
415#ifndef WITH_APPINIT
416int
Fred Drake509d79a2000-07-08 04:04:38 +0000417Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000418{
Barry Warsawfa701a81997-01-16 00:15:11 +0000419 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000420
Barry Warsawfa701a81997-01-16 00:15:11 +0000421 main = Tk_MainWindow(interp);
422 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000423 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000424 return TCL_ERROR;
425 }
426 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000427 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000428 return TCL_ERROR;
429 }
430 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000431}
432#endif /* !WITH_APPINIT */
433
Guido van Rossum18468821994-06-20 07:49:28 +0000434
Barry Warsawfa701a81997-01-16 00:15:11 +0000435
436
437/* Initialize the Tk application; see the `main' function in
438 * `tkMain.c'.
439 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000440
Thomas Wouters58d05102000-07-24 14:43:35 +0000441static void EnableEventHook(void); /* Forward */
442static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000443
Barry Warsawfa701a81997-01-16 00:15:11 +0000444static TkappObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000445Tkapp_New(char *screenName, char *baseName, char *className, int interactive)
Barry Warsawfa701a81997-01-16 00:15:11 +0000446{
447 TkappObject *v;
448 char *argv0;
449
Guido van Rossumb18618d2000-05-03 23:44:39 +0000450 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000451 if (v == NULL)
452 return NULL;
453
454 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000455
Guido van Rossuma80649b2000-03-28 20:07:05 +0000456#if defined(macintosh)
457 /* This seems to be needed */
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000458 ClearMenuBar();
459 TkMacInitMenus(v->interp);
460#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000461 /* Delete the 'exit' command, which can screw things up */
462 Tcl_DeleteCommand(v->interp, "exit");
463
Barry Warsawfa701a81997-01-16 00:15:11 +0000464 if (screenName != NULL)
465 Tcl_SetVar2(v->interp, "env", "DISPLAY",
466 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000467
Barry Warsawfa701a81997-01-16 00:15:11 +0000468 if (interactive)
469 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
470 else
471 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000472
Barry Warsawfa701a81997-01-16 00:15:11 +0000473 /* This is used to get the application class for Tk 4.1 and up */
474 argv0 = (char*)ckalloc(strlen(className) + 1);
475 if (!argv0) {
476 PyErr_NoMemory();
477 Py_DECREF(v);
478 return NULL;
479 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000480
Barry Warsawfa701a81997-01-16 00:15:11 +0000481 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000482 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000483 argv0[0] = tolower(argv0[0]);
484 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
485 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000486
Barry Warsawfa701a81997-01-16 00:15:11 +0000487 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000488 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000489
Guido van Rossum7bf15641998-05-22 18:28:17 +0000490 EnableEventHook();
491
Barry Warsawfa701a81997-01-16 00:15:11 +0000492 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000493}
494
Barry Warsawfa701a81997-01-16 00:15:11 +0000495
496
Guido van Rossum18468821994-06-20 07:49:28 +0000497/** Tcl Eval **/
498
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000499#if TKMAJORMINOR >= 8001
500#define USING_OBJECTS
501#endif
502
503#ifdef USING_OBJECTS
504
505static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000506AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000507{
508 Tcl_Obj *result;
509
510 if (PyString_Check(value))
511 return Tcl_NewStringObj(PyString_AS_STRING(value),
512 PyString_GET_SIZE(value));
513 else if (PyInt_Check(value))
514 return Tcl_NewLongObj(PyInt_AS_LONG(value));
515 else if (PyFloat_Check(value))
516 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
517 else if (PyTuple_Check(value)) {
518 Tcl_Obj **argv = (Tcl_Obj**)
519 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
520 int i;
521 if(!argv)
522 return 0;
523 for(i=0;i<PyTuple_Size(value);i++)
524 argv[i] = AsObj(PyTuple_GetItem(value,i));
525 result = Tcl_NewListObj(PyTuple_Size(value), argv);
526 ckfree(FREECAST argv);
527 return result;
528 }
529 else if (PyUnicode_Check(value)) {
Guido van Rossum990f5c62000-05-04 15:07:16 +0000530#if TKMAJORMINOR <= 8001
531 /* In Tcl 8.1 we must use UTF-8 */
Guido van Rossum2834b972000-10-06 16:58:26 +0000532 PyObject* utf8 = PyUnicode_AsUTF8String(value);
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000533 if (!utf8)
534 return 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000535 result = Tcl_NewStringObj(PyString_AS_STRING(utf8),
536 PyString_GET_SIZE(utf8));
Guido van Rossum8823acc2000-04-27 20:14:31 +0000537 Py_DECREF(utf8);
538 return result;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000539#else /* TKMAJORMINOR > 8001 */
540 /* In Tcl 8.2 and later, use Tcl_NewUnicodeObj() */
541 if (sizeof(Py_UNICODE) != sizeof(Tcl_UniChar)) {
542 /* XXX Should really test this at compile time */
543 PyErr_SetString(PyExc_SystemError,
Guido van Rossum2834b972000-10-06 16:58:26 +0000544 "Py_UNICODE and Tcl_UniChar differ in size");
Guido van Rossum990f5c62000-05-04 15:07:16 +0000545 return 0;
546 }
547 return Tcl_NewUnicodeObj(PyUnicode_AS_UNICODE(value),
548 PyUnicode_GET_SIZE(value));
549#endif /* TKMAJORMINOR > 8001 */
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000550 }
551 else {
552 PyObject *v = PyObject_Str(value);
553 if (!v)
554 return 0;
555 result = AsObj(v);
556 Py_DECREF(v);
557 return result;
558 }
559}
560
Guido van Rossum18468821994-06-20 07:49:28 +0000561static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000562Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000563{
Guido van Rossum632de272000-03-29 00:19:50 +0000564 Tcl_Obj *objStore[ARGSZ];
565 Tcl_Obj **objv = NULL;
566 int objc = 0, i;
567 PyObject *res = NULL;
568 Tcl_Interp *interp = Tkapp_Interp(self);
569 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
570 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000571
Guido van Rossum632de272000-03-29 00:19:50 +0000572 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000573
Guido van Rossum212643f1998-04-29 16:22:14 +0000574 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +0000575 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +0000576
Guido van Rossum212643f1998-04-29 16:22:14 +0000577 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000578 objv[0] = AsObj(args);
579 if (objv[0] == 0)
580 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000581 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +0000582 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000583 }
584 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000585 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000586
Guido van Rossum632de272000-03-29 00:19:50 +0000587 if (objc > ARGSZ) {
588 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
589 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000590 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +0000591 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +0000592 goto finally;
593 }
594 }
595
Guido van Rossum632de272000-03-29 00:19:50 +0000596 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000597 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +0000598 if (v == Py_None) {
599 objc = i;
600 break;
601 }
Guido van Rossum632de272000-03-29 00:19:50 +0000602 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +0000603 if (!objv[i]) {
604 /* Reset objc, so it attempts to clear
605 objects only up to i. */
606 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +0000607 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000608 }
Guido van Rossum632de272000-03-29 00:19:50 +0000609 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000610 }
611 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000612
Guido van Rossum62320c91998-06-15 04:36:09 +0000613 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000614
615 i = Tcl_EvalObjv(interp, objc, objv, flags);
616
Guido van Rossum62320c91998-06-15 04:36:09 +0000617 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000618 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000619 Tkinter_Error(self);
Guido van Rossum990f5c62000-05-04 15:07:16 +0000620 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000621 /* We could request the object result here, but doing
622 so would confuse applications that expect a string. */
Guido van Rossum990f5c62000-05-04 15:07:16 +0000623 char *s = Tcl_GetStringResult(interp);
624 char *p = s;
625 /* If the result contains any bytes with the top bit set,
626 it's UTF-8 and we should decode it to Unicode */
627 while (*p != '\0') {
628 if (*p & 0x80)
629 break;
630 p++;
631 }
632 if (*p == '\0')
633 res = PyString_FromStringAndSize(s, (int)(p-s));
634 else {
635 /* Convert UTF-8 to Unicode string */
636 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +0000637 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
638 if (res == NULL) {
Guido van Rossum2834b972000-10-06 16:58:26 +0000639 PyErr_Clear();
640 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum69529ad2000-05-04 15:55:17 +0000641 }
Guido van Rossum990f5c62000-05-04 15:07:16 +0000642 }
643 }
Guido van Rossum632de272000-03-29 00:19:50 +0000644
Guido van Rossum62320c91998-06-15 04:36:09 +0000645 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000646
Guido van Rossum212643f1998-04-29 16:22:14 +0000647 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000648 for (i = 0; i < objc; i++)
649 Tcl_DecrRefCount(objv[i]);
650 if (objv != objStore)
651 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000652 return res;
653}
654
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000655#else /* !USING_OBJECTS */
656
657static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000658Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000659{
660 /* This is copied from Merge() */
661 PyObject *tmp = NULL;
662 char *argvStore[ARGSZ];
663 char **argv = NULL;
664 int fvStore[ARGSZ];
665 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000666 int argc = 0, fvc = 0, i;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000667 PyObject *res = NULL; /* except this has a different type */
668 Tcl_CmdInfo info; /* and this is added */
669 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
670
671 if (!(tmp = PyList_New(0)))
672 return NULL;
673
674 argv = argvStore;
675 fv = fvStore;
676
677 if (args == NULL)
678 argc = 0;
679
680 else if (!PyTuple_Check(args)) {
681 argc = 1;
682 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000683 if (!(argv[0] = AsString(args, tmp)))
684 goto finally;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000685 }
686 else {
687 argc = PyTuple_Size(args);
688
689 if (argc > ARGSZ) {
690 argv = (char **)ckalloc(argc * sizeof(char *));
691 fv = (int *)ckalloc(argc * sizeof(int));
692 if (argv == NULL || fv == NULL) {
693 PyErr_NoMemory();
694 goto finally;
695 }
696 }
697
698 for (i = 0; i < argc; i++) {
699 PyObject *v = PyTuple_GetItem(args, i);
700 if (PyTuple_Check(v)) {
701 fv[i] = 1;
702 if (!(argv[i] = Merge(v)))
703 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000704 fvc++;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000705 }
706 else if (v == Py_None) {
707 argc = i;
708 break;
709 }
710 else {
711 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000712 if (!(argv[i] = AsString(v, tmp)))
713 goto finally;
714 fvc++;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000715 }
716 }
717 }
718 /* End code copied from Merge() */
719
720 /* All this to avoid a call to Tcl_Merge() and the corresponding call
721 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
722 if (Py_VerboseFlag >= 2) {
723 for (i = 0; i < argc; i++)
724 PySys_WriteStderr("%s ", argv[i]);
725 }
726 ENTER_TCL
727 info.proc = NULL;
728 if (argc < 1 ||
729 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
730 info.proc == NULL)
731 {
732 char *cmd;
733 cmd = Tcl_Merge(argc, argv);
734 i = Tcl_Eval(interp, cmd);
735 ckfree(cmd);
736 }
737 else {
738 Tcl_ResetResult(interp);
739 i = (*info.proc)(info.clientData, interp, argc, argv);
740 }
741 ENTER_OVERLAP
742 if (info.proc == NULL && Py_VerboseFlag >= 2)
743 PySys_WriteStderr("... use TclEval ");
744 if (i == TCL_ERROR) {
745 if (Py_VerboseFlag >= 2)
746 PySys_WriteStderr("... error: '%s'\n",
Guido van Rossumada6d872000-10-12 17:14:46 +0000747 Tcl_GetStringResult(interp));
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000748 Tkinter_Error(self);
749 }
750 else {
751 if (Py_VerboseFlag >= 2)
Guido van Rossumada6d872000-10-12 17:14:46 +0000752 PySys_WriteStderr("-> '%s'\n", Tcl_GetStringResult(interp));
753 res = PyString_FromString(Tcl_GetStringResult(interp));
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000754 }
755 LEAVE_OVERLAP_TCL
756
757 /* Copied from Merge() again */
758 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000759 for (i = 0; i < fvc; i++)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000760 if (fv[i]) {
761 ckfree(argv[i]);
762 }
763 if (argv != argvStore)
764 ckfree(FREECAST argv);
765 if (fv != fvStore)
766 ckfree(FREECAST fv);
767
768 Py_DECREF(tmp);
769 return res;
770}
771
772#endif /* !USING_OBJECTS */
Barry Warsawfa701a81997-01-16 00:15:11 +0000773
774static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000775Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000776{
Guido van Rossum212643f1998-04-29 16:22:14 +0000777 /* Could do the same here as for Tkapp_Call(), but this is not used
778 much, so I can't be bothered. Unfortunately Tcl doesn't export a
779 way for the user to do what all its Global* variants do (save and
780 reset the scope pointer, call the local version, restore the saved
781 scope pointer). */
782
Guido van Rossum62320c91998-06-15 04:36:09 +0000783 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000784 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000785
Guido van Rossum62320c91998-06-15 04:36:09 +0000786 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +0000787 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000788 int err;
789 ENTER_TCL
790 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000791 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000792 if (err == TCL_ERROR)
793 res = Tkinter_Error(self);
794 else
795 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000796 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000797 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +0000798 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000799
800 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000801}
802
803static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000804Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000805{
Barry Warsawfa701a81997-01-16 00:15:11 +0000806 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000807 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000808 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000809
Guido van Rossum43713e52000-02-29 13:59:29 +0000810 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000811 return NULL;
812
Guido van Rossum00d93061998-05-28 23:06:38 +0000813 ENTER_TCL
814 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000815 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000816 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000817 res = Tkinter_Error(self);
818 else
819 res = PyString_FromString(Tkapp_Result(self));
820 LEAVE_OVERLAP_TCL
821 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000822}
823
824static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000825Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000826{
Barry Warsawfa701a81997-01-16 00:15:11 +0000827 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000828 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000829 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000830
Guido van Rossum43713e52000-02-29 13:59:29 +0000831 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000832 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000833
Guido van Rossum00d93061998-05-28 23:06:38 +0000834 ENTER_TCL
835 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000836 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000837 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000838 res = Tkinter_Error(self);
839 else
840 res = PyString_FromString(Tkapp_Result(self));
841 LEAVE_OVERLAP_TCL
842 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000843}
844
845static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000846Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000847{
Barry Warsawfa701a81997-01-16 00:15:11 +0000848 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000849 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000850 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000851
Guido van Rossum43713e52000-02-29 13:59:29 +0000852 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000853 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000854
Guido van Rossum00d93061998-05-28 23:06:38 +0000855 ENTER_TCL
856 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000857 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000858 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000859 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000860
Guido van Rossum62320c91998-06-15 04:36:09 +0000861 else
862 res = PyString_FromString(Tkapp_Result(self));
863 LEAVE_OVERLAP_TCL
864 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000865}
866
867static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000868Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000869{
Barry Warsawfa701a81997-01-16 00:15:11 +0000870 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000871 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000872 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000873
Guido van Rossum35d43371997-08-02 00:09:09 +0000874 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000875 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000876
Guido van Rossum00d93061998-05-28 23:06:38 +0000877 ENTER_TCL
878 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000879 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000880 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000881 res = Tkinter_Error(self);
882 else
883 res = PyString_FromString(Tkapp_Result(self));
884 LEAVE_OVERLAP_TCL
885 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000886}
887
888static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000889Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000890{
Barry Warsawfa701a81997-01-16 00:15:11 +0000891 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000892
Guido van Rossum43713e52000-02-29 13:59:29 +0000893 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000894 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000895 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000896 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000897 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000898
Barry Warsawfa701a81997-01-16 00:15:11 +0000899 Py_INCREF(Py_None);
900 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000901}
902
Barry Warsawfa701a81997-01-16 00:15:11 +0000903
904
Guido van Rossum18468821994-06-20 07:49:28 +0000905/** Tcl Variable **/
906
907static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000908SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000909{
Guido van Rossum00d93061998-05-28 23:06:38 +0000910 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000911 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000912 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000913
Guido van Rossum62320c91998-06-15 04:36:09 +0000914 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000915 if (!tmp)
916 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000917
Guido van Rossum43713e52000-02-29 13:59:29 +0000918 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000919 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000920 s = AsString(newValue, tmp);
Guido van Rossum2834b972000-10-06 16:58:26 +0000921 if (s == NULL)
922 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000923 ENTER_TCL
924 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
925 LEAVE_TCL
926 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000927 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000928 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +0000929 if (PyArg_ParseTuple(args, "ssO:setvar",
930 &name1, &name2, &newValue)) {
931 s = AsString(newValue, tmp);
932 if (s == NULL)
933 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000934 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000935 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000936 s, flags);
937 LEAVE_TCL
938 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000939 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000940 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000941 return NULL;
942 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000943 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000944 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000945
Barry Warsawfa701a81997-01-16 00:15:11 +0000946 if (!ok)
947 return Tkinter_Error(self);
948
949 Py_INCREF(Py_None);
950 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000951}
952
953static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000954Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000955{
Barry Warsawfa701a81997-01-16 00:15:11 +0000956 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000957}
958
959static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000960Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000961{
Barry Warsawfa701a81997-01-16 00:15:11 +0000962 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000963}
964
Barry Warsawfa701a81997-01-16 00:15:11 +0000965
966
Guido van Rossum18468821994-06-20 07:49:28 +0000967static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000968GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000969{
Guido van Rossum35d43371997-08-02 00:09:09 +0000970 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000971 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000972
Guido van Rossum43713e52000-02-29 13:59:29 +0000973 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +0000974 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000975 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000976 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000977 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000978
Barry Warsawfa701a81997-01-16 00:15:11 +0000979 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000980 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000981 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000982
Barry Warsawfa701a81997-01-16 00:15:11 +0000983 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000984 res = Tkinter_Error(self);
985 else
986 res = PyString_FromString(s);
987 LEAVE_OVERLAP_TCL
988 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000989}
990
991static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000992Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000993{
Barry Warsawfa701a81997-01-16 00:15:11 +0000994 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000995}
996
997static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000998Tkapp_GlobalGetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000999{
Barry Warsawfa701a81997-01-16 00:15:11 +00001000 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001001}
1002
Barry Warsawfa701a81997-01-16 00:15:11 +00001003
1004
Guido van Rossum18468821994-06-20 07:49:28 +00001005static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001006UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001007{
Guido van Rossum35d43371997-08-02 00:09:09 +00001008 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001009 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001010 int code;
Guido van Rossum18468821994-06-20 07:49:28 +00001011
Guido van Rossum43713e52000-02-29 13:59:29 +00001012 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001013 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001014 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001015 if (name2 == NULL)
1016 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
1017
1018 else
1019 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001020 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001021
Barry Warsawfa701a81997-01-16 00:15:11 +00001022 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001023 res = Tkinter_Error(self);
1024 else {
1025 Py_INCREF(Py_None);
1026 res = Py_None;
1027 }
1028 LEAVE_OVERLAP_TCL
1029 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001030}
1031
1032static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001033Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001034{
Barry Warsawfa701a81997-01-16 00:15:11 +00001035 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001036}
1037
1038static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001039Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001040{
Barry Warsawfa701a81997-01-16 00:15:11 +00001041 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001042}
1043
Barry Warsawfa701a81997-01-16 00:15:11 +00001044
1045
Guido van Rossum18468821994-06-20 07:49:28 +00001046/** Tcl to Python **/
1047
1048static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001049Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001050{
Barry Warsawfa701a81997-01-16 00:15:11 +00001051 char *s;
1052 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001053
Guido van Rossum43713e52000-02-29 13:59:29 +00001054 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001055 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001056 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001057 return Tkinter_Error(self);
1058 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001059}
1060
1061static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001062Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001063{
Barry Warsawfa701a81997-01-16 00:15:11 +00001064 char *s;
1065 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001066
Guido van Rossum43713e52000-02-29 13:59:29 +00001067 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001068 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001069 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001070 return Tkinter_Error(self);
1071 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001072}
1073
1074static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001075Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001076{
Barry Warsawfa701a81997-01-16 00:15:11 +00001077 char *s;
1078 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001079
Guido van Rossum43713e52000-02-29 13:59:29 +00001080 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001081 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001082 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1083 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001084 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001085}
1086
1087static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001088Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001089{
Barry Warsawfa701a81997-01-16 00:15:11 +00001090 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001091 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001092 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001093
Guido van Rossum43713e52000-02-29 13:59:29 +00001094 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001095 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001096 ENTER_TCL
1097 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001098 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001099 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001100 res = Tkinter_Error(self);
1101 else
1102 res = Py_BuildValue("s", Tkapp_Result(self));
1103 LEAVE_OVERLAP_TCL
1104 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001105}
1106
1107static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001108Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001109{
Barry Warsawfa701a81997-01-16 00:15:11 +00001110 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001111 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001112 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001113 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001114
Guido van Rossum43713e52000-02-29 13:59:29 +00001115 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001116 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001117 ENTER_TCL
1118 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001119 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001120 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001121 res = Tkinter_Error(self);
1122 else
1123 res = Py_BuildValue("l", v);
1124 LEAVE_OVERLAP_TCL
1125 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001126}
1127
1128static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001129Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001130{
Barry Warsawfa701a81997-01-16 00:15:11 +00001131 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001132 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001133 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001134 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001135
Guido van Rossum43713e52000-02-29 13:59:29 +00001136 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001137 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001138 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001139 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001140 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001141 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001142 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001143 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001144 res = Tkinter_Error(self);
1145 else
1146 res = Py_BuildValue("d", v);
1147 LEAVE_OVERLAP_TCL
1148 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001149}
1150
1151static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001152Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001153{
Barry Warsawfa701a81997-01-16 00:15:11 +00001154 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001155 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001156 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001157 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001158
Guido van Rossum43713e52000-02-29 13:59:29 +00001159 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001160 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001161 ENTER_TCL
1162 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001163 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001164 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001165 res = Tkinter_Error(self);
1166 else
1167 res = Py_BuildValue("i", v);
1168 LEAVE_OVERLAP_TCL
1169 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001170}
1171
Barry Warsawfa701a81997-01-16 00:15:11 +00001172
1173
Guido van Rossum18468821994-06-20 07:49:28 +00001174static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001175Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001176{
Barry Warsawfa701a81997-01-16 00:15:11 +00001177 char *list;
1178 int argc;
1179 char **argv;
1180 PyObject *v;
1181 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001182
Guido van Rossum43713e52000-02-29 13:59:29 +00001183 if (!PyArg_ParseTuple(args, "s:splitlist", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001184 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001185
Barry Warsawfa701a81997-01-16 00:15:11 +00001186 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1187 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001188
Barry Warsawfa701a81997-01-16 00:15:11 +00001189 if (!(v = PyTuple_New(argc)))
1190 return NULL;
1191
1192 for (i = 0; i < argc; i++) {
1193 PyObject *s = PyString_FromString(argv[i]);
1194 if (!s || PyTuple_SetItem(v, i, s)) {
1195 Py_DECREF(v);
1196 v = NULL;
1197 goto finally;
1198 }
1199 }
Guido van Rossum18468821994-06-20 07:49:28 +00001200
Barry Warsawfa701a81997-01-16 00:15:11 +00001201 finally:
1202 ckfree(FREECAST argv);
1203 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001204}
1205
1206static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001207Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001208{
Barry Warsawfa701a81997-01-16 00:15:11 +00001209 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001210
Guido van Rossum43713e52000-02-29 13:59:29 +00001211 if (!PyArg_ParseTuple(args, "s:split", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001212 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001213 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001214}
1215
1216static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001217Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001218{
Barry Warsawfa701a81997-01-16 00:15:11 +00001219 char *s = Merge(args);
1220 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001221
Barry Warsawfa701a81997-01-16 00:15:11 +00001222 if (s) {
1223 res = PyString_FromString(s);
1224 ckfree(s);
1225 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001226
1227 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001228}
1229
Barry Warsawfa701a81997-01-16 00:15:11 +00001230
1231
Guido van Rossum18468821994-06-20 07:49:28 +00001232/** Tcl Command **/
1233
Guido van Rossum00d93061998-05-28 23:06:38 +00001234/* Client data struct */
1235typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001236 PyObject *self;
1237 PyObject *func;
1238} PythonCmd_ClientData;
1239
1240static int
Fred Drake509d79a2000-07-08 04:04:38 +00001241PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001242{
1243 errorInCmd = 1;
1244 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1245 LEAVE_PYTHON
1246 return TCL_ERROR;
1247}
1248
Guido van Rossum18468821994-06-20 07:49:28 +00001249/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001250 * function or method.
1251 */
Guido van Rossum18468821994-06-20 07:49:28 +00001252static int
Fred Drake509d79a2000-07-08 04:04:38 +00001253PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001254{
Guido van Rossum00d93061998-05-28 23:06:38 +00001255 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001256 PyObject *self, *func, *arg, *res, *tmp;
Guido van Rossum2834b972000-10-06 16:58:26 +00001257 int i, rv;
1258 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +00001259
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001260 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001261
Barry Warsawfa701a81997-01-16 00:15:11 +00001262 /* TBD: no error checking here since we know, via the
1263 * Tkapp_CreateCommand() that the client data is a two-tuple
1264 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001265 self = data->self;
1266 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001267
Barry Warsawfa701a81997-01-16 00:15:11 +00001268 /* Create argument list (argv1, ..., argvN) */
1269 if (!(arg = PyTuple_New(argc - 1)))
1270 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001271
Barry Warsawfa701a81997-01-16 00:15:11 +00001272 for (i = 0; i < (argc - 1); i++) {
1273 PyObject *s = PyString_FromString(argv[i + 1]);
1274 if (!s || PyTuple_SetItem(arg, i, s)) {
1275 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001276 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001277 }
1278 }
1279 res = PyEval_CallObject(func, arg);
1280 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001281
Barry Warsawfa701a81997-01-16 00:15:11 +00001282 if (res == NULL)
1283 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001284
Barry Warsawfa701a81997-01-16 00:15:11 +00001285 if (!(tmp = PyList_New(0))) {
1286 Py_DECREF(res);
1287 return PythonCmd_Error(interp);
1288 }
1289
Guido van Rossum2834b972000-10-06 16:58:26 +00001290 s = AsString(res, tmp);
1291 if (s == NULL) {
1292 rv = PythonCmd_Error(interp);
1293 }
1294 else {
1295 Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
1296 rv = TCL_OK;
1297 }
1298
Barry Warsawfa701a81997-01-16 00:15:11 +00001299 Py_DECREF(res);
1300 Py_DECREF(tmp);
1301
Guido van Rossum00d93061998-05-28 23:06:38 +00001302 LEAVE_PYTHON
1303
Guido van Rossum2834b972000-10-06 16:58:26 +00001304 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00001305}
1306
1307static void
Fred Drake509d79a2000-07-08 04:04:38 +00001308PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00001309{
Guido van Rossum00d93061998-05-28 23:06:38 +00001310 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1311
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001312 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001313 Py_XDECREF(data->self);
1314 Py_XDECREF(data->func);
1315 PyMem_DEL(data);
1316 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001317}
1318
Barry Warsawfa701a81997-01-16 00:15:11 +00001319
1320
Guido van Rossum18468821994-06-20 07:49:28 +00001321static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001322Tkapp_CreateCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001323{
Guido van Rossum00d93061998-05-28 23:06:38 +00001324 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001325 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001326 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001327 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001328
Guido van Rossum43713e52000-02-29 13:59:29 +00001329 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001330 return NULL;
1331 if (!PyCallable_Check(func)) {
1332 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001333 return NULL;
1334 }
Guido van Rossum18468821994-06-20 07:49:28 +00001335
Guido van Rossum00d93061998-05-28 23:06:38 +00001336 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001337 if (!data)
1338 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001339 Py_XINCREF(self);
1340 Py_XINCREF(func);
1341 data->self = self;
1342 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001343
Guido van Rossum00d93061998-05-28 23:06:38 +00001344 ENTER_TCL
1345 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1346 (ClientData)data, PythonCmdDelete);
1347 LEAVE_TCL
1348 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001349 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001350 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001351 return NULL;
1352 }
Guido van Rossum18468821994-06-20 07:49:28 +00001353
Barry Warsawfa701a81997-01-16 00:15:11 +00001354 Py_INCREF(Py_None);
1355 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001356}
1357
Barry Warsawfa701a81997-01-16 00:15:11 +00001358
1359
Guido van Rossum18468821994-06-20 07:49:28 +00001360static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001361Tkapp_DeleteCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001362{
Barry Warsawfa701a81997-01-16 00:15:11 +00001363 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001364 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001365
Guido van Rossum43713e52000-02-29 13:59:29 +00001366 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001367 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001368 ENTER_TCL
1369 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1370 LEAVE_TCL
1371 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001372 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1373 return NULL;
1374 }
1375 Py_INCREF(Py_None);
1376 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001377}
1378
Barry Warsawfa701a81997-01-16 00:15:11 +00001379
1380
Guido van Rossum00d93061998-05-28 23:06:38 +00001381#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001382/** File Handler **/
1383
Guido van Rossum00d93061998-05-28 23:06:38 +00001384typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001385 PyObject *func;
1386 PyObject *file;
1387 int id;
1388 struct _fhcdata *next;
1389} FileHandler_ClientData;
1390
1391static FileHandler_ClientData *HeadFHCD;
1392
1393static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00001394NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001395{
1396 FileHandler_ClientData *p;
1397 p = PyMem_NEW(FileHandler_ClientData, 1);
1398 if (p != NULL) {
1399 Py_XINCREF(func);
1400 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001401 p->func = func;
1402 p->file = file;
1403 p->id = id;
1404 p->next = HeadFHCD;
1405 HeadFHCD = p;
1406 }
1407 return p;
1408}
1409
1410static void
Fred Drake509d79a2000-07-08 04:04:38 +00001411DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001412{
1413 FileHandler_ClientData *p, **pp;
1414
1415 pp = &HeadFHCD;
1416 while ((p = *pp) != NULL) {
1417 if (p->id == id) {
1418 *pp = p->next;
1419 Py_XDECREF(p->func);
1420 Py_XDECREF(p->file);
1421 PyMem_DEL(p);
1422 }
1423 else
1424 pp = &p->next;
1425 }
1426}
1427
Guido van Rossuma597dde1995-01-10 20:56:29 +00001428static void
Fred Drake509d79a2000-07-08 04:04:38 +00001429FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00001430{
Guido van Rossum00d93061998-05-28 23:06:38 +00001431 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001432 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001433
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001434 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001435 func = data->func;
1436 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001437
Barry Warsawfa701a81997-01-16 00:15:11 +00001438 arg = Py_BuildValue("(Oi)", file, (long) mask);
1439 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001440 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001441
1442 if (res == NULL) {
1443 errorInCmd = 1;
1444 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1445 }
1446 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001447 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001448}
1449
Guido van Rossum18468821994-06-20 07:49:28 +00001450static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001451Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
1452 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001453{
Guido van Rossum00d93061998-05-28 23:06:38 +00001454 FileHandler_ClientData *data;
1455 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001456 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001457
Guido van Rossum2834b972000-10-06 16:58:26 +00001458 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
1459 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001460 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001461 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001462 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001463 return NULL;
1464 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001465 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001466 return NULL;
1467 }
1468
Guido van Rossuma80649b2000-03-28 20:07:05 +00001469 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001470 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001471 return NULL;
1472
Barry Warsawfa701a81997-01-16 00:15:11 +00001473 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001474 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001475 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001476 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001477 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001478 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001479}
1480
1481static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001482Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001483{
Barry Warsawfa701a81997-01-16 00:15:11 +00001484 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001485 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001486
Guido van Rossum43713e52000-02-29 13:59:29 +00001487 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001488 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001489 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001490 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001491 return NULL;
1492
Guido van Rossuma80649b2000-03-28 20:07:05 +00001493 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001494
Barry Warsawfa701a81997-01-16 00:15:11 +00001495 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001496 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001497 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001498 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001499 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001500 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001501}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001502#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001503
Barry Warsawfa701a81997-01-16 00:15:11 +00001504
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001505/**** Tktt Object (timer token) ****/
1506
1507staticforward PyTypeObject Tktt_Type;
1508
Guido van Rossum00d93061998-05-28 23:06:38 +00001509typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001510 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001511 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001512 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001513} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001514
1515static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001516Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001517{
Barry Warsawfa701a81997-01-16 00:15:11 +00001518 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001519 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001520
Guido van Rossum43713e52000-02-29 13:59:29 +00001521 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001522 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001523 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001524 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001525 v->token = NULL;
1526 }
1527 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001528 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001529 Py_DECREF(func);
1530 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001531 }
1532 Py_INCREF(Py_None);
1533 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001534}
1535
1536static PyMethodDef Tktt_methods[] =
1537{
Guido van Rossum35d43371997-08-02 00:09:09 +00001538 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001539 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001540};
1541
1542static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001543Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001544{
Barry Warsawfa701a81997-01-16 00:15:11 +00001545 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001546
Guido van Rossumb18618d2000-05-03 23:44:39 +00001547 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00001548 if (v == NULL)
1549 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001550
Guido van Rossum00d93061998-05-28 23:06:38 +00001551 Py_INCREF(func);
1552 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001553 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001554
1555 /* Extra reference, deleted when called or when handler is deleted */
1556 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001557 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001558}
1559
1560static void
Fred Drake509d79a2000-07-08 04:04:38 +00001561Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001562{
Guido van Rossum00d93061998-05-28 23:06:38 +00001563 TkttObject *v = (TkttObject *)self;
1564 PyObject *func = v->func;
1565
1566 Py_XDECREF(func);
1567
Guido van Rossumb18618d2000-05-03 23:44:39 +00001568 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001569}
1570
Guido van Rossum597ac201998-05-12 14:36:19 +00001571static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001572Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001573{
Barry Warsawfa701a81997-01-16 00:15:11 +00001574 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001575 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001576
Fred Drakea44d3532000-06-30 15:01:00 +00001577 sprintf(buf, "<tktimertoken at %p%s>", v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001578 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001579 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001580}
1581
1582static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001583Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001584{
Barry Warsawfa701a81997-01-16 00:15:11 +00001585 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001586}
1587
1588static PyTypeObject Tktt_Type =
1589{
Guido van Rossum35d43371997-08-02 00:09:09 +00001590 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001591 0, /*ob_size */
1592 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001593 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001594 0, /*tp_itemsize */
1595 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001596 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001597 Tktt_GetAttr, /*tp_getattr */
1598 0, /*tp_setattr */
1599 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001600 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001601 0, /*tp_as_number */
1602 0, /*tp_as_sequence */
1603 0, /*tp_as_mapping */
1604 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001605};
1606
Barry Warsawfa701a81997-01-16 00:15:11 +00001607
1608
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001609/** Timer Handler **/
1610
1611static void
Fred Drake509d79a2000-07-08 04:04:38 +00001612TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001613{
Guido van Rossum00d93061998-05-28 23:06:38 +00001614 TkttObject *v = (TkttObject *)clientData;
1615 PyObject *func = v->func;
1616 PyObject *res;
1617
1618 if (func == NULL)
1619 return;
1620
1621 v->func = NULL;
1622
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001623 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001624
1625 res = PyEval_CallObject(func, NULL);
1626 Py_DECREF(func);
1627 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001628
Barry Warsawfa701a81997-01-16 00:15:11 +00001629 if (res == NULL) {
1630 errorInCmd = 1;
1631 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1632 }
1633 else
1634 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001635
1636 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001637}
1638
1639static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001640Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001641{
Barry Warsawfa701a81997-01-16 00:15:11 +00001642 int milliseconds;
1643 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001644 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001645
Guido van Rossum2834b972000-10-06 16:58:26 +00001646 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
1647 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001648 return NULL;
1649 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001650 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001651 return NULL;
1652 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001653 v = Tktt_New(func);
1654 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1655 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001656
Guido van Rossum00d93061998-05-28 23:06:38 +00001657 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001658}
1659
Barry Warsawfa701a81997-01-16 00:15:11 +00001660
Guido van Rossum18468821994-06-20 07:49:28 +00001661/** Event Loop **/
1662
Guido van Rossum18468821994-06-20 07:49:28 +00001663static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001664Tkapp_MainLoop(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001665{
Barry Warsawfa701a81997-01-16 00:15:11 +00001666 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001667#ifdef WITH_THREAD
1668 PyThreadState *tstate = PyThreadState_Get();
1669#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001670
Guido van Rossum43713e52000-02-29 13:59:29 +00001671 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001672 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001673
Barry Warsawfa701a81997-01-16 00:15:11 +00001674 quitMainLoop = 0;
1675 while (Tk_GetNumMainWindows() > threshold &&
1676 !quitMainLoop &&
1677 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001678 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001679 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001680
1681#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001682 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001683 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001684 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001685 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001686 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001687 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001688 if (result == 0)
1689 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001690 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001691#else
1692 result = Tcl_DoOneEvent(0);
1693#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001694
Guido van Rossum35d43371997-08-02 00:09:09 +00001695 if (PyErr_CheckSignals() != 0)
1696 return NULL;
1697 if (result < 0)
1698 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001699 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001700 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001701
Barry Warsawfa701a81997-01-16 00:15:11 +00001702 if (errorInCmd) {
1703 errorInCmd = 0;
1704 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1705 excInCmd = valInCmd = trbInCmd = NULL;
1706 return NULL;
1707 }
1708 Py_INCREF(Py_None);
1709 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001710}
1711
1712static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001713Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00001714{
Guido van Rossum35d43371997-08-02 00:09:09 +00001715 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001716 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001717
Guido van Rossum43713e52000-02-29 13:59:29 +00001718 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001719 return NULL;
1720
Guido van Rossum00d93061998-05-28 23:06:38 +00001721 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001722 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001723 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001724 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001725}
1726
1727static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001728Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001729{
1730
Guido van Rossum43713e52000-02-29 13:59:29 +00001731 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001732 return NULL;
1733
1734 quitMainLoop = 1;
1735 Py_INCREF(Py_None);
1736 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001737}
1738
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001739static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001740Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001741{
1742
Guido van Rossum43713e52000-02-29 13:59:29 +00001743 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001744 return NULL;
1745
1746 return PyInt_FromLong((long)Tkapp_Interp(self));
1747}
1748
Barry Warsawfa701a81997-01-16 00:15:11 +00001749
1750
Guido van Rossum18468821994-06-20 07:49:28 +00001751/**** Tkapp Method List ****/
1752
1753static PyMethodDef Tkapp_methods[] =
1754{
Guido van Rossum35d43371997-08-02 00:09:09 +00001755 {"call", Tkapp_Call, 0},
1756 {"globalcall", Tkapp_GlobalCall, 0},
1757 {"eval", Tkapp_Eval, 1},
1758 {"globaleval", Tkapp_GlobalEval, 1},
1759 {"evalfile", Tkapp_EvalFile, 1},
1760 {"record", Tkapp_Record, 1},
1761 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1762 {"setvar", Tkapp_SetVar, 1},
1763 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1764 {"getvar", Tkapp_GetVar, 1},
1765 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1766 {"unsetvar", Tkapp_UnsetVar, 1},
1767 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1768 {"getint", Tkapp_GetInt, 1},
1769 {"getdouble", Tkapp_GetDouble, 1},
1770 {"getboolean", Tkapp_GetBoolean, 1},
1771 {"exprstring", Tkapp_ExprString, 1},
1772 {"exprlong", Tkapp_ExprLong, 1},
1773 {"exprdouble", Tkapp_ExprDouble, 1},
1774 {"exprboolean", Tkapp_ExprBoolean, 1},
1775 {"splitlist", Tkapp_SplitList, 1},
1776 {"split", Tkapp_Split, 1},
1777 {"merge", Tkapp_Merge, 0},
1778 {"createcommand", Tkapp_CreateCommand, 1},
1779 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001780#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001781 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1782 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001783#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001784 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001785 {"mainloop", Tkapp_MainLoop, 1},
1786 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001787 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001788 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001789 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001790};
1791
Barry Warsawfa701a81997-01-16 00:15:11 +00001792
1793
Guido van Rossum18468821994-06-20 07:49:28 +00001794/**** Tkapp Type Methods ****/
1795
1796static void
Fred Drake509d79a2000-07-08 04:04:38 +00001797Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00001798{
Guido van Rossum00d93061998-05-28 23:06:38 +00001799 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001800 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001801 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00001802 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001803 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001804}
1805
1806static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001807Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00001808{
Guido van Rossum35d43371997-08-02 00:09:09 +00001809 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001810}
1811
1812static PyTypeObject Tkapp_Type =
1813{
Guido van Rossum35d43371997-08-02 00:09:09 +00001814 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001815 0, /*ob_size */
1816 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001817 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001818 0, /*tp_itemsize */
1819 Tkapp_Dealloc, /*tp_dealloc */
1820 0, /*tp_print */
1821 Tkapp_GetAttr, /*tp_getattr */
1822 0, /*tp_setattr */
1823 0, /*tp_compare */
1824 0, /*tp_repr */
1825 0, /*tp_as_number */
1826 0, /*tp_as_sequence */
1827 0, /*tp_as_mapping */
1828 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001829};
1830
Barry Warsawfa701a81997-01-16 00:15:11 +00001831
1832
Guido van Rossum18468821994-06-20 07:49:28 +00001833/**** Tkinter Module ****/
1834
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001835typedef struct {
1836 PyObject* tuple;
1837 int size; /* current size */
1838 int maxsize; /* allocated size */
1839} FlattenContext;
1840
1841static int
1842_bump(FlattenContext* context, int size)
1843{
Guido van Rossum2834b972000-10-06 16:58:26 +00001844 /* expand tuple to hold (at least) size new items.
1845 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001846
1847 int maxsize = context->maxsize * 2;
1848
1849 if (maxsize < context->size + size)
1850 maxsize = context->size + size;
1851
1852 context->maxsize = maxsize;
1853
1854 return _PyTuple_Resize(&context->tuple, maxsize, 0) >= 0;
1855}
1856
1857static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001858_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001859{
1860 /* add tuple or list to argument tuple (recursively) */
1861
1862 int i, size;
1863
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001864 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001865 PyErr_SetString(PyExc_ValueError,
1866 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001867 return 0;
1868 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001869 size = PyList_GET_SIZE(item);
1870 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00001871 if (context->size + size > context->maxsize &&
1872 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001873 return 0;
1874 /* copy items to output tuple */
1875 for (i = 0; i < size; i++) {
1876 PyObject *o = PyList_GET_ITEM(item, i);
1877 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001878 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001879 return 0;
1880 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001881 if (context->size + 1 > context->maxsize &&
1882 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001883 return 0;
1884 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00001885 PyTuple_SET_ITEM(context->tuple,
1886 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001887 }
1888 }
1889 } else if (PyTuple_Check(item)) {
1890 /* same, for tuples */
1891 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00001892 if (context->size + size > context->maxsize &&
1893 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001894 return 0;
1895 for (i = 0; i < size; i++) {
1896 PyObject *o = PyTuple_GET_ITEM(item, i);
1897 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001898 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001899 return 0;
1900 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001901 if (context->size + 1 > context->maxsize &&
1902 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001903 return 0;
1904 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00001905 PyTuple_SET_ITEM(context->tuple,
1906 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001907 }
1908 }
1909 } else {
1910 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
1911 return 0;
1912 }
1913 return 1;
1914}
1915
1916static PyObject *
1917Tkinter_Flatten(PyObject* self, PyObject* args)
1918{
1919 FlattenContext context;
1920 PyObject* item;
1921
1922 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
1923 return NULL;
1924
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001925 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001926 if (context.maxsize <= 0)
1927 return PyTuple_New(0);
1928
1929 context.tuple = PyTuple_New(context.maxsize);
1930 if (!context.tuple)
1931 return NULL;
1932
1933 context.size = 0;
1934
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001935 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001936 return NULL;
1937
1938 if (_PyTuple_Resize(&context.tuple, context.size, 0))
1939 return NULL;
1940
1941 return context.tuple;
1942}
1943
Guido van Rossum18468821994-06-20 07:49:28 +00001944static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001945Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001946{
Barry Warsawfa701a81997-01-16 00:15:11 +00001947 char *screenName = NULL;
1948 char *baseName = NULL;
1949 char *className = NULL;
1950 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001951
Guido van Rossum35d43371997-08-02 00:09:09 +00001952 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001953 if (baseName != NULL)
1954 baseName++;
1955 else
1956 baseName = Py_GetProgramName();
1957 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001958
Guido van Rossum43713e52000-02-29 13:59:29 +00001959 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00001960 &screenName, &baseName, &className,
1961 &interactive))
1962 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001963
Barry Warsawfa701a81997-01-16 00:15:11 +00001964 return (PyObject *) Tkapp_New(screenName, baseName, className,
1965 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001966}
1967
1968static PyMethodDef moduleMethods[] =
1969{
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001970 {"_flatten", Tkinter_Flatten, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001971 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001972#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001973 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1974 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001975#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001976 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001977 {"mainloop", Tkapp_MainLoop, 1},
1978 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001979 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001980 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001981};
1982
Guido van Rossum7bf15641998-05-22 18:28:17 +00001983#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001984
1985static int stdin_ready = 0;
1986
Guido van Rossumad4db171998-06-13 13:56:28 +00001987#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001988static void
Fred Drake509d79a2000-07-08 04:04:38 +00001989MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00001990{
1991 stdin_ready = 1;
1992}
Guido van Rossumad4db171998-06-13 13:56:28 +00001993#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001994
Guido van Rossum00d93061998-05-28 23:06:38 +00001995static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001996
Guido van Rossum18468821994-06-20 07:49:28 +00001997static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001998EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00001999{
Guido van Rossumad4db171998-06-13 13:56:28 +00002000#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002001 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00002002#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002003#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002004 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002005#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002006 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002007 errorInCmd = 0;
2008#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002009 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002010 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002011#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002012 while (!errorInCmd && !stdin_ready) {
2013 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002014#ifdef MS_WINDOWS
2015 if (_kbhit()) {
2016 stdin_ready = 1;
2017 break;
2018 }
2019#endif
2020#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002021 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00002022 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002023 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002024
Guido van Rossum00d93061998-05-28 23:06:38 +00002025 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002026
2027 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00002028 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002029 if (result == 0)
2030 Sleep(20);
2031 Py_END_ALLOW_THREADS
2032#else
2033 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002034#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002035
2036 if (result < 0)
2037 break;
2038 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002039#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002040 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002041#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002042 if (errorInCmd) {
2043 errorInCmd = 0;
2044 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2045 excInCmd = valInCmd = trbInCmd = NULL;
2046 PyErr_Print();
2047 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002048#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002049 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002050#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002051 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002052}
Guido van Rossum18468821994-06-20 07:49:28 +00002053
Guido van Rossum00d93061998-05-28 23:06:38 +00002054#endif
2055
Guido van Rossum7bf15641998-05-22 18:28:17 +00002056static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002057EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002058{
Guido van Rossum00d93061998-05-28 23:06:38 +00002059#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002060 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002061#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002062 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002063#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002064 PyOS_InputHook = EventHook;
2065 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002066#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002067}
2068
2069static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002070DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002071{
Guido van Rossum00d93061998-05-28 23:06:38 +00002072#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002073 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2074 PyOS_InputHook = NULL;
2075 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002076#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002077}
2078
Barry Warsawfa701a81997-01-16 00:15:11 +00002079
2080/* all errors will be checked in one fell swoop in init_tkinter() */
2081static void
Fred Drake509d79a2000-07-08 04:04:38 +00002082ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002083{
2084 PyObject *v = PyInt_FromLong(val);
2085 if (v) {
2086 PyDict_SetItemString(d, name, v);
2087 Py_DECREF(v);
2088 }
2089}
2090static void
Fred Drake509d79a2000-07-08 04:04:38 +00002091ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002092{
2093 PyObject *v = PyString_FromString(val);
2094 if (v) {
2095 PyDict_SetItemString(d, name, v);
2096 Py_DECREF(v);
2097 }
2098}
2099
2100
Guido van Rossum3886bb61998-12-04 18:50:17 +00002101DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002102init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002103{
Barry Warsawfa701a81997-01-16 00:15:11 +00002104 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002105
Barry Warsawfa701a81997-01-16 00:15:11 +00002106 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002107
2108#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002109 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002110#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002111
Barry Warsawfa701a81997-01-16 00:15:11 +00002112 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002113
Barry Warsawfa701a81997-01-16 00:15:11 +00002114 d = PyModule_GetDict(m);
2115 Tkinter_TclError = Py_BuildValue("s", "TclError");
2116 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002117
Guido van Rossum35d43371997-08-02 00:09:09 +00002118 ins_long(d, "READABLE", TCL_READABLE);
2119 ins_long(d, "WRITABLE", TCL_WRITABLE);
2120 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2121 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2122 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2123 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2124 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2125 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2126 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002127 ins_string(d, "TK_VERSION", TK_VERSION);
2128 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002129
Guido van Rossum83551bf1997-09-13 00:44:23 +00002130 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002131
2132 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002133 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2134
Guido van Rossume187b0e2000-03-27 21:46:29 +00002135 /* This helps the dynamic loader; in Unicode aware Tcl versions
2136 it also helps Tcl find its encodings. */
2137 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002138
Barry Warsawfa701a81997-01-16 00:15:11 +00002139 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002140 return;
2141
Guido van Rossum43ff8681998-07-14 18:02:13 +00002142#if 0
2143 /* This was not a good idea; through <Destroy> bindings,
2144 Tcl_Finalize() may invoke Python code but at that point the
2145 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002146 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002147#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002148
Jack Jansen34cc5c31995-10-31 16:15:12 +00002149#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002150 /*
2151 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2152 ** Most of the initializations in that routine (toolbox init calls and
2153 ** such) have already been done for us, so we only need these.
2154 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002155 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002156
2157 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002158#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002159 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002160#endif /* GENERATINGCFM */
2161#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002162}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002163
Guido van Rossumec22c921996-02-25 04:50:29 +00002164
Barry Warsawfa701a81997-01-16 00:15:11 +00002165
Guido van Rossum9722ad81995-09-22 23:49:28 +00002166#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002167
2168/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002169** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002170*/
2171
Guido van Rossum9722ad81995-09-22 23:49:28 +00002172void
2173panic(char * format, ...)
2174{
Barry Warsawfa701a81997-01-16 00:15:11 +00002175 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002176
Barry Warsawfa701a81997-01-16 00:15:11 +00002177 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002178
Guido van Rossum227cf761998-08-05 13:53:32 +00002179 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002180 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002181
Barry Warsawfa701a81997-01-16 00:15:11 +00002182 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002183
Barry Warsawfa701a81997-01-16 00:15:11 +00002184 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002185}
Jack Jansen40b546d1995-11-14 10:34:45 +00002186
Guido van Rossumec22c921996-02-25 04:50:29 +00002187/*
2188** Pass events to SIOUX before passing them to Tk.
2189*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002190
Guido van Rossumec22c921996-02-25 04:50:29 +00002191static int
Fred Drake509d79a2000-07-08 04:04:38 +00002192PyMacConvertEvent(EventRecord *eventPtr)
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002193{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002194 WindowPtr frontwin;
2195 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002196 ** Sioux eats too many events, so we don't pass it everything. We
2197 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002198 ** the Sioux window is frontmost. This means that Tk menus don't work
2199 ** in that case, but at least we can scroll the sioux window.
2200 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2201 ** part of the external interface of Sioux...
2202 */
2203 frontwin = FrontWindow();
2204 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2205 if (SIOUXHandleOneEvent(eventPtr))
2206 return 0; /* Nothing happened to the Tcl event queue */
2207 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002208 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002209}
2210
Guido van Rossumec22c921996-02-25 04:50:29 +00002211#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002212
2213/*
2214** Additional Mac specific code for dealing with shared libraries.
2215*/
2216
2217#include <Resources.h>
2218#include <CodeFragments.h>
2219
2220static int loaded_from_shlib = 0;
2221static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002222
Jack Jansen34cc5c31995-10-31 16:15:12 +00002223/*
2224** If this module is dynamically loaded the following routine should
2225** be the init routine. It takes care of adding the shared library to
2226** the resource-file chain, so that the tk routines can find their
2227** resources.
2228*/
2229OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002230init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002231{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002232 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002233 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002234 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002235 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2236 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002237 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002238 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2239 loaded_from_shlib = 1;
2240 }
2241 return noErr;
2242}
2243
2244/*
2245** Insert the library resources into the search path. Put them after
2246** the resources from the application. Again, we ignore errors.
2247*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002248static
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002249mac_addlibresources(void)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002250{
2251 if ( !loaded_from_shlib )
2252 return;
2253 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2254}
2255
Guido van Rossumec22c921996-02-25 04:50:29 +00002256#endif /* GENERATINGCFM */
2257#endif /* macintosh */