blob: 9b7330748f1cbf7ecd34554436920b5cab8655dc [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
Jack Jansen84c10b12001-07-16 19:32:52 +000060#if !(defined(MS_WINDOWS) || defined(__CYGWIN__) || defined(macintosh))
61/* Mac has it, but it doesn't really work:-( */
Guido van Rossum0d2390c1997-08-14 19:57:07 +000062#define HAVE_CREATEFILEHANDLER
63#endif
64
Guido van Rossum00d93061998-05-28 23:06:38 +000065#ifdef HAVE_CREATEFILEHANDLER
66
67/* Tcl_CreateFileHandler() changed several times; these macros deal with the
68 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
69 Unix, only because Jack added it back); when available on Windows, it only
70 applies to sockets. */
71
Guido van Rossum7bf15641998-05-22 18:28:17 +000072#ifdef MS_WINDOWS
73#define FHANDLETYPE TCL_WIN_SOCKET
74#else
75#define FHANDLETYPE TCL_UNIX_FD
76#endif
77
Guido van Rossum00d93061998-05-28 23:06:38 +000078/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
79 which uses this to handle Tcl events while the user is typing commands. */
80
81#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +000082#define WAIT_FOR_STDIN
83#endif
84
Guido van Rossum00d93061998-05-28 23:06:38 +000085#endif /* HAVE_CREATEFILEHANDLER */
86
Guido van Rossumad4db171998-06-13 13:56:28 +000087#ifdef MS_WINDOWS
88#include <conio.h>
89#define WAIT_FOR_STDIN
90#endif
91
Guido van Rossum00d93061998-05-28 23:06:38 +000092#ifdef WITH_THREAD
93
94/* The threading situation is complicated. Tcl is not thread-safe, except for
95 Tcl 8.1, which will probably remain in alpha status for another 6 months
96 (and the README says that Tk will probably remain thread-unsafe forever).
97 So we need to use a lock around all uses of Tcl. Previously, the Python
98 interpreter lock was used for this. However, this causes problems when
99 other Python threads need to run while Tcl is blocked waiting for events.
100
101 To solve this problem, a separate lock for Tcl is introduced. Holding it
102 is incompatible with holding Python's interpreter lock. The following four
103 macros manipulate both locks together.
104
105 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
106 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
107 that could call an event handler, or otherwise affect the state of a Tcl
108 interpreter. These assume that the surrounding code has the Python
109 interpreter lock; inside the brackets, the Python interpreter lock has been
110 released and the lock for Tcl has been acquired.
111
Guido van Rossum5e977831998-06-15 14:03:52 +0000112 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
113 (For example, when transferring data from the Tcl interpreter result to a
114 Python string object.) This can be done by using different macros to close
115 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
116 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
117 releases the Tcl lock.
118
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000119 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
Guido van Rossum00d93061998-05-28 23:06:38 +0000120 handlers when the handler needs to use Python. Such event handlers are
121 entered while the lock for Tcl is held; the event handler presumably needs
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000122 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
Guido van Rossum00d93061998-05-28 23:06:38 +0000123 the Python interpreter lock, restoring the appropriate thread state, and
124 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
125 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000126 the code between ENTER_PYTHON and LEAVE_PYTHON.
Guido van Rossum00d93061998-05-28 23:06:38 +0000127
128 These locks expand to several statements and brackets; they should not be
129 used in branches of if statements and the like.
130
131*/
132
Guido van Rossum65d5b571998-12-21 19:32:43 +0000133static PyThread_type_lock tcl_lock = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000134static PyThreadState *tcl_tstate = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000135
136#define ENTER_TCL \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000137 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000138 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
Guido van Rossum00d93061998-05-28 23:06:38 +0000139
140#define LEAVE_TCL \
Guido van Rossum2834b972000-10-06 16:58:26 +0000141 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
Guido van Rossum00d93061998-05-28 23:06:38 +0000142
Guido van Rossum62320c91998-06-15 04:36:09 +0000143#define ENTER_OVERLAP \
144 Py_END_ALLOW_THREADS
145
146#define LEAVE_OVERLAP_TCL \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000147 tcl_tstate = NULL; PyThread_release_lock(tcl_lock); }
Guido van Rossum62320c91998-06-15 04:36:09 +0000148
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000149#define ENTER_PYTHON \
150 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000151 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
Guido van Rossum00d93061998-05-28 23:06:38 +0000152
153#define LEAVE_PYTHON \
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000154 { PyThreadState *tstate = PyEval_SaveThread(); \
Guido van Rossum65d5b571998-12-21 19:32:43 +0000155 PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
Guido van Rossum00d93061998-05-28 23:06:38 +0000156
157#else
158
159#define ENTER_TCL
160#define LEAVE_TCL
Guido van Rossum62320c91998-06-15 04:36:09 +0000161#define ENTER_OVERLAP
162#define LEAVE_OVERLAP_TCL
Guido van Rossumdc1adab1998-10-09 20:51:18 +0000163#define ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +0000164#define LEAVE_PYTHON
165
166#endif
167
Guido van Rossumec22c921996-02-25 04:50:29 +0000168#ifdef macintosh
169
170/*
171** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000172** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000173*/
174
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000175/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000176#define FREECAST (char *)
177
Guido van Rossumec22c921996-02-25 04:50:29 +0000178#include <Events.h> /* For EventRecord */
179
Fred Drake509d79a2000-07-08 04:04:38 +0000180typedef int (*TclMacConvertEventPtr) (EventRecord *eventPtr);
Guido van Rossum2834b972000-10-06 16:58:26 +0000181void Tcl_MacSetEventProc(TclMacConvertEventPtr procPtr);
182int TkMacConvertEvent(EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000183
Guido van Rossum2834b972000-10-06 16:58:26 +0000184staticforward int PyMacConvertEvent(EventRecord *eventPtr);
Guido van Rossumec22c921996-02-25 04:50:29 +0000185
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000186#include <SIOUX.h>
187extern int SIOUXIsAppWindow(WindowPtr);
188
Guido van Rossumec22c921996-02-25 04:50:29 +0000189#endif /* macintosh */
190
Guido van Rossum97867b21996-08-08 19:09:53 +0000191#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000192#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000193#endif
194
Guido van Rossum18468821994-06-20 07:49:28 +0000195/**** Tkapp Object Declaration ****/
196
197staticforward PyTypeObject Tkapp_Type;
198
Guido van Rossum00d93061998-05-28 23:06:38 +0000199typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000200 PyObject_HEAD
201 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000202} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000203
204#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000205#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
Guido van Rossumada6d872000-10-12 17:14:46 +0000206#define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
Guido van Rossum18468821994-06-20 07:49:28 +0000207
Guido van Rossum35d43371997-08-02 00:09:09 +0000208#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000209(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000210
Barry Warsawfa701a81997-01-16 00:15:11 +0000211
212
Guido van Rossum18468821994-06-20 07:49:28 +0000213/**** Error Handling ****/
214
215static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000216static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000217static int errorInCmd = 0;
218static PyObject *excInCmd;
219static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000220static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000221
Barry Warsawfa701a81997-01-16 00:15:11 +0000222
223
Guido van Rossum18468821994-06-20 07:49:28 +0000224static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000225Tkinter_Error(PyObject *v)
Guido van Rossum18468821994-06-20 07:49:28 +0000226{
Barry Warsawfa701a81997-01-16 00:15:11 +0000227 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
228 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000229}
230
Barry Warsawfa701a81997-01-16 00:15:11 +0000231
Barry Warsawfa701a81997-01-16 00:15:11 +0000232
Guido van Rossum18468821994-06-20 07:49:28 +0000233/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000234
235#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000236#ifndef MS_WINDOWS
Guido van Rossum541f2411998-08-13 13:29:22 +0000237
Guido van Rossum00d93061998-05-28 23:06:38 +0000238/* Millisecond sleep() for Unix platforms. */
239
240static void
Fred Drake509d79a2000-07-08 04:04:38 +0000241Sleep(int milli)
Guido van Rossum00d93061998-05-28 23:06:38 +0000242{
243 /* XXX Too bad if you don't have select(). */
244 struct timeval t;
Guido van Rossum00d93061998-05-28 23:06:38 +0000245 t.tv_sec = milli/1000;
246 t.tv_usec = (milli%1000) * 1000;
247 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
248}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000249#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000250#endif /* WITH_THREAD */
251
252
Guido van Rossum18468821994-06-20 07:49:28 +0000253static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000254AsString(PyObject *value, PyObject *tmp)
Guido van Rossum18468821994-06-20 07:49:28 +0000255{
Guido van Rossum35d43371997-08-02 00:09:09 +0000256 if (PyString_Check(value))
257 return PyString_AsString(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000258 else if (PyUnicode_Check(value)) {
259 PyObject *v = PyUnicode_AsUTF8String(value);
260 if (v == NULL)
261 return NULL;
262 if (PyList_Append(tmp, v) != 0) {
263 Py_DECREF(v);
264 return NULL;
265 }
266 Py_DECREF(v);
267 return PyString_AsString(v);
268 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000269 else {
270 PyObject *v = PyObject_Str(value);
Guido van Rossum2834b972000-10-06 16:58:26 +0000271 if (v == NULL)
272 return NULL;
273 if (PyList_Append(tmp, v) != 0) {
274 Py_DECREF(v);
275 return NULL;
276 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000277 Py_DECREF(v);
278 return PyString_AsString(v);
279 }
Guido van Rossum18468821994-06-20 07:49:28 +0000280}
281
Barry Warsawfa701a81997-01-16 00:15:11 +0000282
283
Guido van Rossum18468821994-06-20 07:49:28 +0000284#define ARGSZ 64
285
286static char *
Fred Drake509d79a2000-07-08 04:04:38 +0000287Merge(PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000288{
Barry Warsawfa701a81997-01-16 00:15:11 +0000289 PyObject *tmp = NULL;
290 char *argvStore[ARGSZ];
291 char **argv = NULL;
292 int fvStore[ARGSZ];
293 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000294 int argc = 0, fvc = 0, i;
Barry Warsawfa701a81997-01-16 00:15:11 +0000295 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000296
Barry Warsawfa701a81997-01-16 00:15:11 +0000297 if (!(tmp = PyList_New(0)))
298 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000299
Barry Warsawfa701a81997-01-16 00:15:11 +0000300 argv = argvStore;
301 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000302
Barry Warsawfa701a81997-01-16 00:15:11 +0000303 if (args == NULL)
304 argc = 0;
305
306 else if (!PyTuple_Check(args)) {
307 argc = 1;
308 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000309 if (!(argv[0] = AsString(args, tmp)))
310 goto finally;
Guido van Rossum18468821994-06-20 07:49:28 +0000311 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000312 else {
313 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000314
Barry Warsawfa701a81997-01-16 00:15:11 +0000315 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000316 argv = (char **)ckalloc(argc * sizeof(char *));
317 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000318 if (argv == NULL || fv == NULL) {
319 PyErr_NoMemory();
320 goto finally;
321 }
322 }
323
324 for (i = 0; i < argc; i++) {
325 PyObject *v = PyTuple_GetItem(args, i);
326 if (PyTuple_Check(v)) {
327 fv[i] = 1;
328 if (!(argv[i] = Merge(v)))
329 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000330 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000331 }
332 else if (v == Py_None) {
333 argc = i;
334 break;
335 }
336 else {
337 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000338 if (!(argv[i] = AsString(v, tmp)))
339 goto finally;
340 fvc++;
Barry Warsawfa701a81997-01-16 00:15:11 +0000341 }
342 }
Guido van Rossum18468821994-06-20 07:49:28 +0000343 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000344 res = Tcl_Merge(argc, argv);
Guido van Rossum2834b972000-10-06 16:58:26 +0000345 if (res == NULL)
346 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000347
Barry Warsawfa701a81997-01-16 00:15:11 +0000348 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000349 for (i = 0; i < fvc; i++)
Barry Warsawfa701a81997-01-16 00:15:11 +0000350 if (fv[i]) {
351 ckfree(argv[i]);
352 }
353 if (argv != argvStore)
354 ckfree(FREECAST argv);
355 if (fv != fvStore)
356 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000357
Barry Warsawfa701a81997-01-16 00:15:11 +0000358 Py_DECREF(tmp);
359 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000360}
361
Barry Warsawfa701a81997-01-16 00:15:11 +0000362
363
Guido van Rossum18468821994-06-20 07:49:28 +0000364static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000365Split(char *list)
Guido van Rossum18468821994-06-20 07:49:28 +0000366{
Barry Warsawfa701a81997-01-16 00:15:11 +0000367 int argc;
368 char **argv;
369 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000370
Barry Warsawfa701a81997-01-16 00:15:11 +0000371 if (list == NULL) {
372 Py_INCREF(Py_None);
373 return Py_None;
374 }
Guido van Rossum18468821994-06-20 07:49:28 +0000375
Guido van Rossum00d93061998-05-28 23:06:38 +0000376 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000377 /* Not a list.
378 * Could be a quoted string containing funnies, e.g. {"}.
379 * Return the string itself.
380 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000381 return PyString_FromString(list);
382 }
Guido van Rossum18468821994-06-20 07:49:28 +0000383
Barry Warsawfa701a81997-01-16 00:15:11 +0000384 if (argc == 0)
385 v = PyString_FromString("");
386 else if (argc == 1)
387 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000388 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000389 int i;
390 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000391
Barry Warsawfa701a81997-01-16 00:15:11 +0000392 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000393 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000394 Py_DECREF(v);
395 v = NULL;
396 break;
397 }
398 PyTuple_SetItem(v, i, w);
399 }
400 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000401 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000402 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000403}
404
Barry Warsawfa701a81997-01-16 00:15:11 +0000405
406
Guido van Rossum18468821994-06-20 07:49:28 +0000407/**** Tkapp Object ****/
408
409#ifndef WITH_APPINIT
410int
Fred Drake509d79a2000-07-08 04:04:38 +0000411Tcl_AppInit(Tcl_Interp *interp)
Guido van Rossum18468821994-06-20 07:49:28 +0000412{
Barry Warsawfa701a81997-01-16 00:15:11 +0000413 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000414
Barry Warsawfa701a81997-01-16 00:15:11 +0000415 main = Tk_MainWindow(interp);
416 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000417 PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000418 return TCL_ERROR;
419 }
420 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumada6d872000-10-12 17:14:46 +0000421 PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp));
Barry Warsawfa701a81997-01-16 00:15:11 +0000422 return TCL_ERROR;
423 }
424 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000425}
426#endif /* !WITH_APPINIT */
427
Guido van Rossum18468821994-06-20 07:49:28 +0000428
Barry Warsawfa701a81997-01-16 00:15:11 +0000429
430
431/* Initialize the Tk application; see the `main' function in
432 * `tkMain.c'.
433 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000434
Thomas Wouters58d05102000-07-24 14:43:35 +0000435static void EnableEventHook(void); /* Forward */
436static void DisableEventHook(void); /* Forward */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000437
Barry Warsawfa701a81997-01-16 00:15:11 +0000438static TkappObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000439Tkapp_New(char *screenName, char *baseName, char *className, int interactive)
Barry Warsawfa701a81997-01-16 00:15:11 +0000440{
441 TkappObject *v;
442 char *argv0;
443
Guido van Rossumb18618d2000-05-03 23:44:39 +0000444 v = PyObject_New(TkappObject, &Tkapp_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +0000445 if (v == NULL)
446 return NULL;
447
448 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000449
Guido van Rossuma80649b2000-03-28 20:07:05 +0000450#if defined(macintosh)
451 /* This seems to be needed */
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000452 ClearMenuBar();
453 TkMacInitMenus(v->interp);
454#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000455 /* Delete the 'exit' command, which can screw things up */
456 Tcl_DeleteCommand(v->interp, "exit");
457
Barry Warsawfa701a81997-01-16 00:15:11 +0000458 if (screenName != NULL)
459 Tcl_SetVar2(v->interp, "env", "DISPLAY",
460 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000461
Barry Warsawfa701a81997-01-16 00:15:11 +0000462 if (interactive)
463 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
464 else
465 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000466
Barry Warsawfa701a81997-01-16 00:15:11 +0000467 /* This is used to get the application class for Tk 4.1 and up */
468 argv0 = (char*)ckalloc(strlen(className) + 1);
469 if (!argv0) {
470 PyErr_NoMemory();
471 Py_DECREF(v);
472 return NULL;
473 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000474
Barry Warsawfa701a81997-01-16 00:15:11 +0000475 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000476 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000477 argv0[0] = tolower(argv0[0]);
478 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
479 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000480
Barry Warsawfa701a81997-01-16 00:15:11 +0000481 if (Tcl_AppInit(v->interp) != TCL_OK)
Guido van Rossumc821d1e1998-07-07 22:25:47 +0000482 return (TkappObject *)Tkinter_Error((PyObject *)v);
Barry Warsawfa701a81997-01-16 00:15:11 +0000483
Guido van Rossum7bf15641998-05-22 18:28:17 +0000484 EnableEventHook();
485
Barry Warsawfa701a81997-01-16 00:15:11 +0000486 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000487}
488
Barry Warsawfa701a81997-01-16 00:15:11 +0000489
490
Guido van Rossum18468821994-06-20 07:49:28 +0000491/** Tcl Eval **/
492
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000493#if TKMAJORMINOR >= 8001
494#define USING_OBJECTS
495#endif
496
497#ifdef USING_OBJECTS
498
499static Tcl_Obj*
Fred Drake509d79a2000-07-08 04:04:38 +0000500AsObj(PyObject *value)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000501{
502 Tcl_Obj *result;
503
504 if (PyString_Check(value))
505 return Tcl_NewStringObj(PyString_AS_STRING(value),
506 PyString_GET_SIZE(value));
507 else if (PyInt_Check(value))
508 return Tcl_NewLongObj(PyInt_AS_LONG(value));
509 else if (PyFloat_Check(value))
510 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
511 else if (PyTuple_Check(value)) {
512 Tcl_Obj **argv = (Tcl_Obj**)
513 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
514 int i;
515 if(!argv)
516 return 0;
517 for(i=0;i<PyTuple_Size(value);i++)
518 argv[i] = AsObj(PyTuple_GetItem(value,i));
519 result = Tcl_NewListObj(PyTuple_Size(value), argv);
520 ckfree(FREECAST argv);
521 return result;
522 }
523 else if (PyUnicode_Check(value)) {
Guido van Rossum990f5c62000-05-04 15:07:16 +0000524#if TKMAJORMINOR <= 8001
525 /* In Tcl 8.1 we must use UTF-8 */
Guido van Rossum2834b972000-10-06 16:58:26 +0000526 PyObject* utf8 = PyUnicode_AsUTF8String(value);
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000527 if (!utf8)
528 return 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000529 result = Tcl_NewStringObj(PyString_AS_STRING(utf8),
530 PyString_GET_SIZE(utf8));
Guido van Rossum8823acc2000-04-27 20:14:31 +0000531 Py_DECREF(utf8);
532 return result;
Guido van Rossum990f5c62000-05-04 15:07:16 +0000533#else /* TKMAJORMINOR > 8001 */
534 /* In Tcl 8.2 and later, use Tcl_NewUnicodeObj() */
535 if (sizeof(Py_UNICODE) != sizeof(Tcl_UniChar)) {
536 /* XXX Should really test this at compile time */
537 PyErr_SetString(PyExc_SystemError,
Guido van Rossum2834b972000-10-06 16:58:26 +0000538 "Py_UNICODE and Tcl_UniChar differ in size");
Guido van Rossum990f5c62000-05-04 15:07:16 +0000539 return 0;
540 }
541 return Tcl_NewUnicodeObj(PyUnicode_AS_UNICODE(value),
542 PyUnicode_GET_SIZE(value));
543#endif /* TKMAJORMINOR > 8001 */
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000544 }
545 else {
546 PyObject *v = PyObject_Str(value);
547 if (!v)
548 return 0;
549 result = AsObj(v);
550 Py_DECREF(v);
551 return result;
552 }
553}
554
Guido van Rossum18468821994-06-20 07:49:28 +0000555static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000556Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000557{
Guido van Rossum632de272000-03-29 00:19:50 +0000558 Tcl_Obj *objStore[ARGSZ];
559 Tcl_Obj **objv = NULL;
560 int objc = 0, i;
561 PyObject *res = NULL;
562 Tcl_Interp *interp = Tkapp_Interp(self);
563 /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
564 int flags = TCL_EVAL_DIRECT;
Guido van Rossum18468821994-06-20 07:49:28 +0000565
Guido van Rossum632de272000-03-29 00:19:50 +0000566 objv = objStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000567
Guido van Rossum212643f1998-04-29 16:22:14 +0000568 if (args == NULL)
Martin v. Löwis02956012000-10-29 00:44:43 +0000569 /* do nothing */;
Barry Warsawfa701a81997-01-16 00:15:11 +0000570
Guido van Rossum212643f1998-04-29 16:22:14 +0000571 else if (!PyTuple_Check(args)) {
Guido van Rossum632de272000-03-29 00:19:50 +0000572 objv[0] = AsObj(args);
573 if (objv[0] == 0)
574 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000575 objc = 1;
Guido van Rossum632de272000-03-29 00:19:50 +0000576 Tcl_IncrRefCount(objv[0]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000577 }
578 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000579 objc = PyTuple_Size(args);
Guido van Rossum212643f1998-04-29 16:22:14 +0000580
Guido van Rossum632de272000-03-29 00:19:50 +0000581 if (objc > ARGSZ) {
582 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
583 if (objv == NULL) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000584 PyErr_NoMemory();
Martin v. Löwis02956012000-10-29 00:44:43 +0000585 objc = 0;
Guido van Rossum212643f1998-04-29 16:22:14 +0000586 goto finally;
587 }
588 }
589
Guido van Rossum632de272000-03-29 00:19:50 +0000590 for (i = 0; i < objc; i++) {
Guido van Rossum212643f1998-04-29 16:22:14 +0000591 PyObject *v = PyTuple_GetItem(args, i);
Guido van Rossum64231e52000-03-31 03:29:39 +0000592 if (v == Py_None) {
593 objc = i;
594 break;
595 }
Guido van Rossum632de272000-03-29 00:19:50 +0000596 objv[i] = AsObj(v);
Martin v. Löwis02956012000-10-29 00:44:43 +0000597 if (!objv[i]) {
598 /* Reset objc, so it attempts to clear
599 objects only up to i. */
600 objc = i;
Guido van Rossum632de272000-03-29 00:19:50 +0000601 goto finally;
Martin v. Löwis02956012000-10-29 00:44:43 +0000602 }
Guido van Rossum632de272000-03-29 00:19:50 +0000603 Tcl_IncrRefCount(objv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000604 }
605 }
Guido van Rossum212643f1998-04-29 16:22:14 +0000606
Guido van Rossum62320c91998-06-15 04:36:09 +0000607 ENTER_TCL
Guido van Rossum632de272000-03-29 00:19:50 +0000608
609 i = Tcl_EvalObjv(interp, objc, objv, flags);
610
Guido van Rossum62320c91998-06-15 04:36:09 +0000611 ENTER_OVERLAP
Guido van Rossum632de272000-03-29 00:19:50 +0000612 if (i == TCL_ERROR)
Guido van Rossum212643f1998-04-29 16:22:14 +0000613 Tkinter_Error(self);
Guido van Rossum990f5c62000-05-04 15:07:16 +0000614 else {
Guido van Rossum632de272000-03-29 00:19:50 +0000615 /* We could request the object result here, but doing
616 so would confuse applications that expect a string. */
Guido van Rossum990f5c62000-05-04 15:07:16 +0000617 char *s = Tcl_GetStringResult(interp);
618 char *p = s;
619 /* If the result contains any bytes with the top bit set,
620 it's UTF-8 and we should decode it to Unicode */
621 while (*p != '\0') {
622 if (*p & 0x80)
623 break;
624 p++;
625 }
626 if (*p == '\0')
627 res = PyString_FromStringAndSize(s, (int)(p-s));
628 else {
629 /* Convert UTF-8 to Unicode string */
630 p = strchr(p, '\0');
Guido van Rossum69529ad2000-05-04 15:55:17 +0000631 res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
632 if (res == NULL) {
Guido van Rossum2834b972000-10-06 16:58:26 +0000633 PyErr_Clear();
634 res = PyString_FromStringAndSize(s, (int)(p-s));
Guido van Rossum69529ad2000-05-04 15:55:17 +0000635 }
Guido van Rossum990f5c62000-05-04 15:07:16 +0000636 }
637 }
Guido van Rossum632de272000-03-29 00:19:50 +0000638
Guido van Rossum62320c91998-06-15 04:36:09 +0000639 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000640
Guido van Rossum212643f1998-04-29 16:22:14 +0000641 finally:
Guido van Rossum632de272000-03-29 00:19:50 +0000642 for (i = 0; i < objc; i++)
643 Tcl_DecrRefCount(objv[i]);
644 if (objv != objStore)
645 ckfree(FREECAST objv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000646 return res;
647}
648
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000649#else /* !USING_OBJECTS */
650
651static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000652Tkapp_Call(PyObject *self, PyObject *args)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000653{
654 /* This is copied from Merge() */
655 PyObject *tmp = NULL;
656 char *argvStore[ARGSZ];
657 char **argv = NULL;
658 int fvStore[ARGSZ];
659 int *fv = NULL;
Guido van Rossum2834b972000-10-06 16:58:26 +0000660 int argc = 0, fvc = 0, i;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000661 PyObject *res = NULL; /* except this has a different type */
662 Tcl_CmdInfo info; /* and this is added */
663 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
664
665 if (!(tmp = PyList_New(0)))
666 return NULL;
667
668 argv = argvStore;
669 fv = fvStore;
670
671 if (args == NULL)
672 argc = 0;
673
674 else if (!PyTuple_Check(args)) {
675 argc = 1;
676 fv[0] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000677 if (!(argv[0] = AsString(args, tmp)))
678 goto finally;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000679 }
680 else {
681 argc = PyTuple_Size(args);
682
683 if (argc > ARGSZ) {
684 argv = (char **)ckalloc(argc * sizeof(char *));
685 fv = (int *)ckalloc(argc * sizeof(int));
686 if (argv == NULL || fv == NULL) {
687 PyErr_NoMemory();
688 goto finally;
689 }
690 }
691
692 for (i = 0; i < argc; i++) {
693 PyObject *v = PyTuple_GetItem(args, i);
694 if (PyTuple_Check(v)) {
695 fv[i] = 1;
696 if (!(argv[i] = Merge(v)))
697 goto finally;
Guido van Rossum2834b972000-10-06 16:58:26 +0000698 fvc++;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000699 }
700 else if (v == Py_None) {
701 argc = i;
702 break;
703 }
704 else {
705 fv[i] = 0;
Guido van Rossum2834b972000-10-06 16:58:26 +0000706 if (!(argv[i] = AsString(v, tmp)))
707 goto finally;
708 fvc++;
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000709 }
710 }
711 }
712 /* End code copied from Merge() */
713
714 /* All this to avoid a call to Tcl_Merge() and the corresponding call
715 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
716 if (Py_VerboseFlag >= 2) {
717 for (i = 0; i < argc; i++)
718 PySys_WriteStderr("%s ", argv[i]);
719 }
720 ENTER_TCL
721 info.proc = NULL;
722 if (argc < 1 ||
723 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
724 info.proc == NULL)
725 {
726 char *cmd;
727 cmd = Tcl_Merge(argc, argv);
728 i = Tcl_Eval(interp, cmd);
729 ckfree(cmd);
730 }
731 else {
732 Tcl_ResetResult(interp);
733 i = (*info.proc)(info.clientData, interp, argc, argv);
734 }
735 ENTER_OVERLAP
736 if (info.proc == NULL && Py_VerboseFlag >= 2)
737 PySys_WriteStderr("... use TclEval ");
738 if (i == TCL_ERROR) {
739 if (Py_VerboseFlag >= 2)
740 PySys_WriteStderr("... error: '%s'\n",
Guido van Rossumada6d872000-10-12 17:14:46 +0000741 Tcl_GetStringResult(interp));
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000742 Tkinter_Error(self);
743 }
744 else {
745 if (Py_VerboseFlag >= 2)
Guido van Rossumada6d872000-10-12 17:14:46 +0000746 PySys_WriteStderr("-> '%s'\n", Tcl_GetStringResult(interp));
747 res = PyString_FromString(Tcl_GetStringResult(interp));
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000748 }
749 LEAVE_OVERLAP_TCL
750
751 /* Copied from Merge() again */
752 finally:
Guido van Rossum2834b972000-10-06 16:58:26 +0000753 for (i = 0; i < fvc; i++)
Guido van Rossuma1f0a8f2000-03-31 00:51:37 +0000754 if (fv[i]) {
755 ckfree(argv[i]);
756 }
757 if (argv != argvStore)
758 ckfree(FREECAST argv);
759 if (fv != fvStore)
760 ckfree(FREECAST fv);
761
762 Py_DECREF(tmp);
763 return res;
764}
765
766#endif /* !USING_OBJECTS */
Barry Warsawfa701a81997-01-16 00:15:11 +0000767
768static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000769Tkapp_GlobalCall(PyObject *self, PyObject *args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000770{
Guido van Rossum212643f1998-04-29 16:22:14 +0000771 /* Could do the same here as for Tkapp_Call(), but this is not used
772 much, so I can't be bothered. Unfortunately Tcl doesn't export a
773 way for the user to do what all its Global* variants do (save and
774 reset the scope pointer, call the local version, restore the saved
775 scope pointer). */
776
Guido van Rossum62320c91998-06-15 04:36:09 +0000777 char *cmd;
Barry Warsawfa701a81997-01-16 00:15:11 +0000778 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000779
Guido van Rossum62320c91998-06-15 04:36:09 +0000780 cmd = Merge(args);
Guido van Rossum2834b972000-10-06 16:58:26 +0000781 if (cmd) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000782 int err;
783 ENTER_TCL
784 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
Guido van Rossum62320c91998-06-15 04:36:09 +0000785 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000786 if (err == TCL_ERROR)
787 res = Tkinter_Error(self);
788 else
789 res = PyString_FromString(Tkapp_Result(self));
Guido van Rossum62320c91998-06-15 04:36:09 +0000790 LEAVE_OVERLAP_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000791 ckfree(cmd);
Guido van Rossum2834b972000-10-06 16:58:26 +0000792 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000793
794 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000795}
796
797static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000798Tkapp_Eval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000799{
Barry Warsawfa701a81997-01-16 00:15:11 +0000800 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000801 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000802 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000803
Guido van Rossum43713e52000-02-29 13:59:29 +0000804 if (!PyArg_ParseTuple(args, "s:eval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000805 return NULL;
806
Guido van Rossum00d93061998-05-28 23:06:38 +0000807 ENTER_TCL
808 err = Tcl_Eval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000809 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000810 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000811 res = Tkinter_Error(self);
812 else
813 res = PyString_FromString(Tkapp_Result(self));
814 LEAVE_OVERLAP_TCL
815 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000816}
817
818static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000819Tkapp_GlobalEval(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000820{
Barry Warsawfa701a81997-01-16 00:15:11 +0000821 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000822 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000823 int err;
Guido van Rossum62320c91998-06-15 04:36:09 +0000824
Guido van Rossum43713e52000-02-29 13:59:29 +0000825 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000826 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000827
Guido van Rossum00d93061998-05-28 23:06:38 +0000828 ENTER_TCL
829 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
Guido van Rossum62320c91998-06-15 04:36:09 +0000830 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000831 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000832 res = Tkinter_Error(self);
833 else
834 res = PyString_FromString(Tkapp_Result(self));
835 LEAVE_OVERLAP_TCL
836 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000837}
838
839static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000840Tkapp_EvalFile(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000841{
Barry Warsawfa701a81997-01-16 00:15:11 +0000842 char *fileName;
Guido van Rossum62320c91998-06-15 04:36:09 +0000843 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000844 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000845
Guido van Rossum43713e52000-02-29 13:59:29 +0000846 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000847 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000848
Guido van Rossum00d93061998-05-28 23:06:38 +0000849 ENTER_TCL
850 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
Guido van Rossum62320c91998-06-15 04:36:09 +0000851 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000852 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000853 res = Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000854
Guido van Rossum62320c91998-06-15 04:36:09 +0000855 else
856 res = PyString_FromString(Tkapp_Result(self));
857 LEAVE_OVERLAP_TCL
858 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000859}
860
861static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000862Tkapp_Record(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000863{
Barry Warsawfa701a81997-01-16 00:15:11 +0000864 char *script;
Guido van Rossum62320c91998-06-15 04:36:09 +0000865 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000866 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000867
Guido van Rossum35d43371997-08-02 00:09:09 +0000868 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000869 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000870
Guido van Rossum00d93061998-05-28 23:06:38 +0000871 ENTER_TCL
872 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
Guido van Rossum62320c91998-06-15 04:36:09 +0000873 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +0000874 if (err == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +0000875 res = Tkinter_Error(self);
876 else
877 res = PyString_FromString(Tkapp_Result(self));
878 LEAVE_OVERLAP_TCL
879 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000880}
881
882static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000883Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000884{
Barry Warsawfa701a81997-01-16 00:15:11 +0000885 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000886
Guido van Rossum43713e52000-02-29 13:59:29 +0000887 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000888 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000889 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000890 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000891 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000892
Barry Warsawfa701a81997-01-16 00:15:11 +0000893 Py_INCREF(Py_None);
894 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000895}
896
Barry Warsawfa701a81997-01-16 00:15:11 +0000897
898
Guido van Rossum18468821994-06-20 07:49:28 +0000899/** Tcl Variable **/
900
901static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000902SetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000903{
Guido van Rossum00d93061998-05-28 23:06:38 +0000904 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000905 PyObject *newValue;
Guido van Rossum62320c91998-06-15 04:36:09 +0000906 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000907
Guido van Rossum62320c91998-06-15 04:36:09 +0000908 tmp = PyList_New(0);
Barry Warsawfa701a81997-01-16 00:15:11 +0000909 if (!tmp)
910 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000911
Guido van Rossum43713e52000-02-29 13:59:29 +0000912 if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000913 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000914 s = AsString(newValue, tmp);
Guido van Rossum2834b972000-10-06 16:58:26 +0000915 if (s == NULL)
916 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000917 ENTER_TCL
918 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
919 LEAVE_TCL
920 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000921 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000922 PyErr_Clear();
Guido van Rossum2834b972000-10-06 16:58:26 +0000923 if (PyArg_ParseTuple(args, "ssO:setvar",
924 &name1, &name2, &newValue)) {
925 s = AsString(newValue, tmp);
926 if (s == NULL)
927 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000928 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000929 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000930 s, flags);
931 LEAVE_TCL
932 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000933 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000934 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000935 return NULL;
936 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000937 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000938 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000939
Barry Warsawfa701a81997-01-16 00:15:11 +0000940 if (!ok)
941 return Tkinter_Error(self);
942
943 Py_INCREF(Py_None);
944 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000945}
946
947static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000948Tkapp_SetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000949{
Barry Warsawfa701a81997-01-16 00:15:11 +0000950 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000951}
952
953static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000954Tkapp_GlobalSetVar(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 | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000957}
958
Barry Warsawfa701a81997-01-16 00:15:11 +0000959
960
Guido van Rossum18468821994-06-20 07:49:28 +0000961static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000962GetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +0000963{
Guido van Rossum35d43371997-08-02 00:09:09 +0000964 char *name1, *name2=NULL, *s;
Guido van Rossum62320c91998-06-15 04:36:09 +0000965 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000966
Guido van Rossum43713e52000-02-29 13:59:29 +0000967 if (!PyArg_ParseTuple(args, "s|s:getvar", &name1, &name2))
Guido van Rossum35d43371997-08-02 00:09:09 +0000968 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000969 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000970 if (name2 == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000971 s = Tcl_GetVar(Tkapp_Interp(self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000972
Barry Warsawfa701a81997-01-16 00:15:11 +0000973 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000974 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +0000975 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +0000976
Barry Warsawfa701a81997-01-16 00:15:11 +0000977 if (s == NULL)
Guido van Rossum62320c91998-06-15 04:36:09 +0000978 res = Tkinter_Error(self);
979 else
980 res = PyString_FromString(s);
981 LEAVE_OVERLAP_TCL
982 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000983}
984
985static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000986Tkapp_GetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +0000987{
Barry Warsawfa701a81997-01-16 00:15:11 +0000988 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000989}
990
991static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +0000992Tkapp_GlobalGetVar(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 | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000995}
996
Barry Warsawfa701a81997-01-16 00:15:11 +0000997
998
Guido van Rossum18468821994-06-20 07:49:28 +0000999static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001000UnsetVar(PyObject *self, PyObject *args, int flags)
Guido van Rossum18468821994-06-20 07:49:28 +00001001{
Guido van Rossum35d43371997-08-02 00:09:09 +00001002 char *name1, *name2=NULL;
Guido van Rossum62320c91998-06-15 04:36:09 +00001003 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001004 int code;
Guido van Rossum18468821994-06-20 07:49:28 +00001005
Guido van Rossum43713e52000-02-29 13:59:29 +00001006 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +00001007 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001008 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001009 if (name2 == NULL)
1010 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
1011
1012 else
1013 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum62320c91998-06-15 04:36:09 +00001014 ENTER_OVERLAP
Guido van Rossum18468821994-06-20 07:49:28 +00001015
Barry Warsawfa701a81997-01-16 00:15:11 +00001016 if (code == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001017 res = Tkinter_Error(self);
1018 else {
1019 Py_INCREF(Py_None);
1020 res = Py_None;
1021 }
1022 LEAVE_OVERLAP_TCL
1023 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001024}
1025
1026static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001027Tkapp_UnsetVar(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001028{
Barry Warsawfa701a81997-01-16 00:15:11 +00001029 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +00001030}
1031
1032static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001033Tkapp_GlobalUnsetVar(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 | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +00001036}
1037
Barry Warsawfa701a81997-01-16 00:15:11 +00001038
1039
Guido van Rossum18468821994-06-20 07:49:28 +00001040/** Tcl to Python **/
1041
1042static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001043Tkapp_GetInt(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001044{
Barry Warsawfa701a81997-01-16 00:15:11 +00001045 char *s;
1046 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001047
Guido van Rossum43713e52000-02-29 13:59:29 +00001048 if (!PyArg_ParseTuple(args, "s:getint", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001049 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001050 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001051 return Tkinter_Error(self);
1052 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001053}
1054
1055static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001056Tkapp_GetDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001057{
Barry Warsawfa701a81997-01-16 00:15:11 +00001058 char *s;
1059 double v;
Guido van Rossum18468821994-06-20 07:49:28 +00001060
Guido van Rossum43713e52000-02-29 13:59:29 +00001061 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001062 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001063 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001064 return Tkinter_Error(self);
1065 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001066}
1067
1068static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001069Tkapp_GetBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001070{
Barry Warsawfa701a81997-01-16 00:15:11 +00001071 char *s;
1072 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001073
Guido van Rossum43713e52000-02-29 13:59:29 +00001074 if (!PyArg_ParseTuple(args, "s:getboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001075 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001076 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1077 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +00001078 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001079}
1080
1081static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001082Tkapp_ExprString(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001083{
Barry Warsawfa701a81997-01-16 00:15:11 +00001084 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001085 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001086 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001087
Guido van Rossum43713e52000-02-29 13:59:29 +00001088 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001089 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001090 ENTER_TCL
1091 retval = Tcl_ExprString(Tkapp_Interp(self), s);
Guido van Rossum62320c91998-06-15 04:36:09 +00001092 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001093 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001094 res = Tkinter_Error(self);
1095 else
1096 res = Py_BuildValue("s", Tkapp_Result(self));
1097 LEAVE_OVERLAP_TCL
1098 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001099}
1100
1101static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001102Tkapp_ExprLong(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001103{
Barry Warsawfa701a81997-01-16 00:15:11 +00001104 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001105 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001106 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001107 long v;
Guido van Rossum18468821994-06-20 07:49:28 +00001108
Guido van Rossum43713e52000-02-29 13:59:29 +00001109 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001110 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001111 ENTER_TCL
1112 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001113 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001114 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001115 res = Tkinter_Error(self);
1116 else
1117 res = Py_BuildValue("l", v);
1118 LEAVE_OVERLAP_TCL
1119 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001120}
1121
1122static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001123Tkapp_ExprDouble(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001124{
Barry Warsawfa701a81997-01-16 00:15:11 +00001125 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001126 PyObject *res = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001127 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001128 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001129
Guido van Rossum43713e52000-02-29 13:59:29 +00001130 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001131 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001132 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001133 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001134 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001135 ENTER_OVERLAP
Guido van Rossum45b83911997-03-14 04:32:50 +00001136 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001137 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001138 res = Tkinter_Error(self);
1139 else
1140 res = Py_BuildValue("d", v);
1141 LEAVE_OVERLAP_TCL
1142 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001143}
1144
1145static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001146Tkapp_ExprBoolean(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001147{
Barry Warsawfa701a81997-01-16 00:15:11 +00001148 char *s;
Guido van Rossum62320c91998-06-15 04:36:09 +00001149 PyObject *res = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001150 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001151 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001152
Guido van Rossum43713e52000-02-29 13:59:29 +00001153 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001154 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001155 ENTER_TCL
1156 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
Guido van Rossum62320c91998-06-15 04:36:09 +00001157 ENTER_OVERLAP
Guido van Rossum00d93061998-05-28 23:06:38 +00001158 if (retval == TCL_ERROR)
Guido van Rossum62320c91998-06-15 04:36:09 +00001159 res = Tkinter_Error(self);
1160 else
1161 res = Py_BuildValue("i", v);
1162 LEAVE_OVERLAP_TCL
1163 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001164}
1165
Barry Warsawfa701a81997-01-16 00:15:11 +00001166
1167
Guido van Rossum18468821994-06-20 07:49:28 +00001168static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001169Tkapp_SplitList(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001170{
Barry Warsawfa701a81997-01-16 00:15:11 +00001171 char *list;
1172 int argc;
1173 char **argv;
1174 PyObject *v;
1175 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001176
Guido van Rossum43713e52000-02-29 13:59:29 +00001177 if (!PyArg_ParseTuple(args, "s:splitlist", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001178 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001179
Barry Warsawfa701a81997-01-16 00:15:11 +00001180 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1181 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001182
Barry Warsawfa701a81997-01-16 00:15:11 +00001183 if (!(v = PyTuple_New(argc)))
1184 return NULL;
1185
1186 for (i = 0; i < argc; i++) {
1187 PyObject *s = PyString_FromString(argv[i]);
1188 if (!s || PyTuple_SetItem(v, i, s)) {
1189 Py_DECREF(v);
1190 v = NULL;
1191 goto finally;
1192 }
1193 }
Guido van Rossum18468821994-06-20 07:49:28 +00001194
Barry Warsawfa701a81997-01-16 00:15:11 +00001195 finally:
1196 ckfree(FREECAST argv);
1197 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001198}
1199
1200static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001201Tkapp_Split(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001202{
Barry Warsawfa701a81997-01-16 00:15:11 +00001203 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001204
Guido van Rossum43713e52000-02-29 13:59:29 +00001205 if (!PyArg_ParseTuple(args, "s:split", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001206 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001207 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001208}
1209
1210static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001211Tkapp_Merge(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001212{
Barry Warsawfa701a81997-01-16 00:15:11 +00001213 char *s = Merge(args);
1214 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001215
Barry Warsawfa701a81997-01-16 00:15:11 +00001216 if (s) {
1217 res = PyString_FromString(s);
1218 ckfree(s);
1219 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001220
1221 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001222}
1223
Barry Warsawfa701a81997-01-16 00:15:11 +00001224
1225
Guido van Rossum18468821994-06-20 07:49:28 +00001226/** Tcl Command **/
1227
Guido van Rossum00d93061998-05-28 23:06:38 +00001228/* Client data struct */
1229typedef struct {
Guido van Rossum00d93061998-05-28 23:06:38 +00001230 PyObject *self;
1231 PyObject *func;
1232} PythonCmd_ClientData;
1233
1234static int
Fred Drake509d79a2000-07-08 04:04:38 +00001235PythonCmd_Error(Tcl_Interp *interp)
Guido van Rossum00d93061998-05-28 23:06:38 +00001236{
1237 errorInCmd = 1;
1238 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1239 LEAVE_PYTHON
1240 return TCL_ERROR;
1241}
1242
Guido van Rossum18468821994-06-20 07:49:28 +00001243/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001244 * function or method.
1245 */
Guido van Rossum18468821994-06-20 07:49:28 +00001246static int
Fred Drake509d79a2000-07-08 04:04:38 +00001247PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
Guido van Rossum18468821994-06-20 07:49:28 +00001248{
Guido van Rossum00d93061998-05-28 23:06:38 +00001249 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001250 PyObject *self, *func, *arg, *res, *tmp;
Guido van Rossum2834b972000-10-06 16:58:26 +00001251 int i, rv;
1252 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +00001253
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001254 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001255
Barry Warsawfa701a81997-01-16 00:15:11 +00001256 /* TBD: no error checking here since we know, via the
1257 * Tkapp_CreateCommand() that the client data is a two-tuple
1258 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001259 self = data->self;
1260 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001261
Barry Warsawfa701a81997-01-16 00:15:11 +00001262 /* Create argument list (argv1, ..., argvN) */
1263 if (!(arg = PyTuple_New(argc - 1)))
1264 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001265
Barry Warsawfa701a81997-01-16 00:15:11 +00001266 for (i = 0; i < (argc - 1); i++) {
1267 PyObject *s = PyString_FromString(argv[i + 1]);
1268 if (!s || PyTuple_SetItem(arg, i, s)) {
1269 Py_DECREF(arg);
Guido van Rossumf766e231998-06-19 04:28:10 +00001270 return PythonCmd_Error(interp);
Barry Warsawfa701a81997-01-16 00:15:11 +00001271 }
1272 }
1273 res = PyEval_CallObject(func, arg);
1274 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001275
Barry Warsawfa701a81997-01-16 00:15:11 +00001276 if (res == NULL)
1277 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001278
Barry Warsawfa701a81997-01-16 00:15:11 +00001279 if (!(tmp = PyList_New(0))) {
1280 Py_DECREF(res);
1281 return PythonCmd_Error(interp);
1282 }
1283
Guido van Rossum2834b972000-10-06 16:58:26 +00001284 s = AsString(res, tmp);
1285 if (s == NULL) {
1286 rv = PythonCmd_Error(interp);
1287 }
1288 else {
1289 Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
1290 rv = TCL_OK;
1291 }
1292
Barry Warsawfa701a81997-01-16 00:15:11 +00001293 Py_DECREF(res);
1294 Py_DECREF(tmp);
1295
Guido van Rossum00d93061998-05-28 23:06:38 +00001296 LEAVE_PYTHON
1297
Guido van Rossum2834b972000-10-06 16:58:26 +00001298 return rv;
Guido van Rossum18468821994-06-20 07:49:28 +00001299}
1300
1301static void
Fred Drake509d79a2000-07-08 04:04:38 +00001302PythonCmdDelete(ClientData clientData)
Guido van Rossum18468821994-06-20 07:49:28 +00001303{
Guido van Rossum00d93061998-05-28 23:06:38 +00001304 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1305
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001306 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001307 Py_XDECREF(data->self);
1308 Py_XDECREF(data->func);
1309 PyMem_DEL(data);
1310 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001311}
1312
Barry Warsawfa701a81997-01-16 00:15:11 +00001313
1314
Guido van Rossum18468821994-06-20 07:49:28 +00001315static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001316Tkapp_CreateCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001317{
Guido van Rossum00d93061998-05-28 23:06:38 +00001318 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001319 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001320 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001321 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001322
Guido van Rossum43713e52000-02-29 13:59:29 +00001323 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
Guido van Rossum35d43371997-08-02 00:09:09 +00001324 return NULL;
1325 if (!PyCallable_Check(func)) {
1326 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001327 return NULL;
1328 }
Guido van Rossum18468821994-06-20 07:49:28 +00001329
Guido van Rossum00d93061998-05-28 23:06:38 +00001330 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001331 if (!data)
1332 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001333 Py_XINCREF(self);
1334 Py_XINCREF(func);
1335 data->self = self;
1336 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001337
Guido van Rossum00d93061998-05-28 23:06:38 +00001338 ENTER_TCL
1339 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1340 (ClientData)data, PythonCmdDelete);
1341 LEAVE_TCL
1342 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001343 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001344 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001345 return NULL;
1346 }
Guido van Rossum18468821994-06-20 07:49:28 +00001347
Barry Warsawfa701a81997-01-16 00:15:11 +00001348 Py_INCREF(Py_None);
1349 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001350}
1351
Barry Warsawfa701a81997-01-16 00:15:11 +00001352
1353
Guido van Rossum18468821994-06-20 07:49:28 +00001354static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001355Tkapp_DeleteCommand(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001356{
Barry Warsawfa701a81997-01-16 00:15:11 +00001357 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001358 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001359
Guido van Rossum43713e52000-02-29 13:59:29 +00001360 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001361 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001362 ENTER_TCL
1363 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1364 LEAVE_TCL
1365 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001366 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1367 return NULL;
1368 }
1369 Py_INCREF(Py_None);
1370 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001371}
1372
Barry Warsawfa701a81997-01-16 00:15:11 +00001373
1374
Guido van Rossum00d93061998-05-28 23:06:38 +00001375#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001376/** File Handler **/
1377
Guido van Rossum00d93061998-05-28 23:06:38 +00001378typedef struct _fhcdata {
Guido van Rossum00d93061998-05-28 23:06:38 +00001379 PyObject *func;
1380 PyObject *file;
1381 int id;
1382 struct _fhcdata *next;
1383} FileHandler_ClientData;
1384
1385static FileHandler_ClientData *HeadFHCD;
1386
1387static FileHandler_ClientData *
Fred Drake509d79a2000-07-08 04:04:38 +00001388NewFHCD(PyObject *func, PyObject *file, int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001389{
1390 FileHandler_ClientData *p;
1391 p = PyMem_NEW(FileHandler_ClientData, 1);
1392 if (p != NULL) {
1393 Py_XINCREF(func);
1394 Py_XINCREF(file);
Guido van Rossum00d93061998-05-28 23:06:38 +00001395 p->func = func;
1396 p->file = file;
1397 p->id = id;
1398 p->next = HeadFHCD;
1399 HeadFHCD = p;
1400 }
1401 return p;
1402}
1403
1404static void
Fred Drake509d79a2000-07-08 04:04:38 +00001405DeleteFHCD(int id)
Guido van Rossum00d93061998-05-28 23:06:38 +00001406{
1407 FileHandler_ClientData *p, **pp;
1408
1409 pp = &HeadFHCD;
1410 while ((p = *pp) != NULL) {
1411 if (p->id == id) {
1412 *pp = p->next;
1413 Py_XDECREF(p->func);
1414 Py_XDECREF(p->file);
1415 PyMem_DEL(p);
1416 }
1417 else
1418 pp = &p->next;
1419 }
1420}
1421
Guido van Rossuma597dde1995-01-10 20:56:29 +00001422static void
Fred Drake509d79a2000-07-08 04:04:38 +00001423FileHandler(ClientData clientData, int mask)
Guido van Rossum18468821994-06-20 07:49:28 +00001424{
Guido van Rossum00d93061998-05-28 23:06:38 +00001425 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001426 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001427
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001428 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001429 func = data->func;
1430 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001431
Barry Warsawfa701a81997-01-16 00:15:11 +00001432 arg = Py_BuildValue("(Oi)", file, (long) mask);
1433 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001434 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001435
1436 if (res == NULL) {
1437 errorInCmd = 1;
1438 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1439 }
1440 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001441 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001442}
1443
Guido van Rossum18468821994-06-20 07:49:28 +00001444static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001445Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
1446 /* args is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001447{
Guido van Rossum00d93061998-05-28 23:06:38 +00001448 FileHandler_ClientData *data;
1449 PyObject *file, *func;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001450 int mask, tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001451
Guido van Rossum2834b972000-10-06 16:58:26 +00001452 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
1453 &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001454 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001455 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001456 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001457 return NULL;
1458 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001459 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001460 return NULL;
1461 }
1462
Guido van Rossuma80649b2000-03-28 20:07:05 +00001463 data = NewFHCD(func, file, tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001464 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001465 return NULL;
1466
Barry Warsawfa701a81997-01-16 00:15:11 +00001467 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001468 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001469 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001470 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001471 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001472 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001473}
1474
1475static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001476Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001477{
Barry Warsawfa701a81997-01-16 00:15:11 +00001478 PyObject *file;
Guido van Rossuma80649b2000-03-28 20:07:05 +00001479 int tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001480
Guido van Rossum43713e52000-02-29 13:59:29 +00001481 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001482 return NULL;
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +00001483 tfile = PyObject_AsFileDescriptor(file);
Guido van Rossuma80649b2000-03-28 20:07:05 +00001484 if (tfile < 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001485 return NULL;
1486
Guido van Rossuma80649b2000-03-28 20:07:05 +00001487 DeleteFHCD(tfile);
Guido van Rossum18468821994-06-20 07:49:28 +00001488
Barry Warsawfa701a81997-01-16 00:15:11 +00001489 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001490 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001491 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001492 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001493 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001494 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001495}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001496#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001497
Barry Warsawfa701a81997-01-16 00:15:11 +00001498
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001499/**** Tktt Object (timer token) ****/
1500
1501staticforward PyTypeObject Tktt_Type;
1502
Guido van Rossum00d93061998-05-28 23:06:38 +00001503typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001504 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001505 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001506 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001507} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001508
1509static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001510Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001511{
Barry Warsawfa701a81997-01-16 00:15:11 +00001512 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001513 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001514
Guido van Rossum43713e52000-02-29 13:59:29 +00001515 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001516 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001517 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001518 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001519 v->token = NULL;
1520 }
1521 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001522 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001523 Py_DECREF(func);
1524 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001525 }
1526 Py_INCREF(Py_None);
1527 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001528}
1529
1530static PyMethodDef Tktt_methods[] =
1531{
Guido van Rossum35d43371997-08-02 00:09:09 +00001532 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001533 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001534};
1535
1536static TkttObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001537Tktt_New(PyObject *func)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001538{
Barry Warsawfa701a81997-01-16 00:15:11 +00001539 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001540
Guido van Rossumb18618d2000-05-03 23:44:39 +00001541 v = PyObject_New(TkttObject, &Tktt_Type);
Barry Warsawfa701a81997-01-16 00:15:11 +00001542 if (v == NULL)
1543 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001544
Guido van Rossum00d93061998-05-28 23:06:38 +00001545 Py_INCREF(func);
1546 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001547 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001548
1549 /* Extra reference, deleted when called or when handler is deleted */
1550 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001551 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001552}
1553
1554static void
Fred Drake509d79a2000-07-08 04:04:38 +00001555Tktt_Dealloc(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001556{
Guido van Rossum00d93061998-05-28 23:06:38 +00001557 TkttObject *v = (TkttObject *)self;
1558 PyObject *func = v->func;
1559
1560 Py_XDECREF(func);
1561
Guido van Rossumb18618d2000-05-03 23:44:39 +00001562 PyObject_Del(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001563}
1564
Guido van Rossum597ac201998-05-12 14:36:19 +00001565static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001566Tktt_Repr(PyObject *self)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001567{
Barry Warsawfa701a81997-01-16 00:15:11 +00001568 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001569 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001570
Fred Drakea44d3532000-06-30 15:01:00 +00001571 sprintf(buf, "<tktimertoken at %p%s>", v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001572 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001573 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001574}
1575
1576static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001577Tktt_GetAttr(PyObject *self, char *name)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001578{
Barry Warsawfa701a81997-01-16 00:15:11 +00001579 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001580}
1581
1582static PyTypeObject Tktt_Type =
1583{
Guido van Rossum35d43371997-08-02 00:09:09 +00001584 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001585 0, /*ob_size */
1586 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001587 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001588 0, /*tp_itemsize */
1589 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001590 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001591 Tktt_GetAttr, /*tp_getattr */
1592 0, /*tp_setattr */
1593 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001594 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001595 0, /*tp_as_number */
1596 0, /*tp_as_sequence */
1597 0, /*tp_as_mapping */
1598 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001599};
1600
Barry Warsawfa701a81997-01-16 00:15:11 +00001601
1602
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001603/** Timer Handler **/
1604
1605static void
Fred Drake509d79a2000-07-08 04:04:38 +00001606TimerHandler(ClientData clientData)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001607{
Guido van Rossum00d93061998-05-28 23:06:38 +00001608 TkttObject *v = (TkttObject *)clientData;
1609 PyObject *func = v->func;
1610 PyObject *res;
1611
1612 if (func == NULL)
1613 return;
1614
1615 v->func = NULL;
1616
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001617 ENTER_PYTHON
Guido van Rossum00d93061998-05-28 23:06:38 +00001618
1619 res = PyEval_CallObject(func, NULL);
1620 Py_DECREF(func);
1621 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001622
Barry Warsawfa701a81997-01-16 00:15:11 +00001623 if (res == NULL) {
1624 errorInCmd = 1;
1625 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1626 }
1627 else
1628 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001629
1630 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001631}
1632
1633static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001634Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001635{
Barry Warsawfa701a81997-01-16 00:15:11 +00001636 int milliseconds;
1637 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001638 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001639
Guido van Rossum2834b972000-10-06 16:58:26 +00001640 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
1641 &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001642 return NULL;
1643 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001644 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001645 return NULL;
1646 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001647 v = Tktt_New(func);
1648 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1649 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001650
Guido van Rossum00d93061998-05-28 23:06:38 +00001651 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001652}
1653
Barry Warsawfa701a81997-01-16 00:15:11 +00001654
Guido van Rossum18468821994-06-20 07:49:28 +00001655/** Event Loop **/
1656
Guido van Rossum18468821994-06-20 07:49:28 +00001657static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001658Tkapp_MainLoop(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001659{
Barry Warsawfa701a81997-01-16 00:15:11 +00001660 int threshold = 0;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001661#ifdef WITH_THREAD
1662 PyThreadState *tstate = PyThreadState_Get();
1663#endif
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001664
Guido van Rossum43713e52000-02-29 13:59:29 +00001665 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
Barry Warsawfa701a81997-01-16 00:15:11 +00001666 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001667
Barry Warsawfa701a81997-01-16 00:15:11 +00001668 quitMainLoop = 0;
1669 while (Tk_GetNumMainWindows() > threshold &&
1670 !quitMainLoop &&
1671 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001672 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001673 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001674
1675#ifdef WITH_THREAD
Guido van Rossum62320c91998-06-15 04:36:09 +00001676 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00001677 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001678 tcl_tstate = tstate;
Guido van Rossum35d43371997-08-02 00:09:09 +00001679 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00001680 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00001681 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00001682 if (result == 0)
1683 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001684 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001685#else
1686 result = Tcl_DoOneEvent(0);
1687#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001688
Guido van Rossum35d43371997-08-02 00:09:09 +00001689 if (PyErr_CheckSignals() != 0)
1690 return NULL;
1691 if (result < 0)
1692 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001693 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001694 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001695
Barry Warsawfa701a81997-01-16 00:15:11 +00001696 if (errorInCmd) {
1697 errorInCmd = 0;
1698 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1699 excInCmd = valInCmd = trbInCmd = NULL;
1700 return NULL;
1701 }
1702 Py_INCREF(Py_None);
1703 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001704}
1705
1706static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001707Tkapp_DoOneEvent(PyObject *self, PyObject *args)
Guido van Rossum062cfb01995-01-10 17:42:51 +00001708{
Guido van Rossum35d43371997-08-02 00:09:09 +00001709 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001710 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001711
Guido van Rossum43713e52000-02-29 13:59:29 +00001712 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
Barry Warsawfa701a81997-01-16 00:15:11 +00001713 return NULL;
1714
Guido van Rossum00d93061998-05-28 23:06:38 +00001715 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001716 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001717 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001718 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001719}
1720
1721static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001722Tkapp_Quit(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001723{
1724
Guido van Rossum43713e52000-02-29 13:59:29 +00001725 if (!PyArg_ParseTuple(args, ":quit"))
Barry Warsawfa701a81997-01-16 00:15:11 +00001726 return NULL;
1727
1728 quitMainLoop = 1;
1729 Py_INCREF(Py_None);
1730 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001731}
1732
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001733static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001734Tkapp_InterpAddr(PyObject *self, PyObject *args)
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001735{
1736
Guido van Rossum43713e52000-02-29 13:59:29 +00001737 if (!PyArg_ParseTuple(args, ":interpaddr"))
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001738 return NULL;
1739
1740 return PyInt_FromLong((long)Tkapp_Interp(self));
1741}
1742
Barry Warsawfa701a81997-01-16 00:15:11 +00001743
1744
Guido van Rossum18468821994-06-20 07:49:28 +00001745/**** Tkapp Method List ****/
1746
1747static PyMethodDef Tkapp_methods[] =
1748{
Guido van Rossum35d43371997-08-02 00:09:09 +00001749 {"call", Tkapp_Call, 0},
1750 {"globalcall", Tkapp_GlobalCall, 0},
1751 {"eval", Tkapp_Eval, 1},
1752 {"globaleval", Tkapp_GlobalEval, 1},
1753 {"evalfile", Tkapp_EvalFile, 1},
1754 {"record", Tkapp_Record, 1},
1755 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1756 {"setvar", Tkapp_SetVar, 1},
1757 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1758 {"getvar", Tkapp_GetVar, 1},
1759 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1760 {"unsetvar", Tkapp_UnsetVar, 1},
1761 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1762 {"getint", Tkapp_GetInt, 1},
1763 {"getdouble", Tkapp_GetDouble, 1},
1764 {"getboolean", Tkapp_GetBoolean, 1},
1765 {"exprstring", Tkapp_ExprString, 1},
1766 {"exprlong", Tkapp_ExprLong, 1},
1767 {"exprdouble", Tkapp_ExprDouble, 1},
1768 {"exprboolean", Tkapp_ExprBoolean, 1},
1769 {"splitlist", Tkapp_SplitList, 1},
1770 {"split", Tkapp_Split, 1},
1771 {"merge", Tkapp_Merge, 0},
1772 {"createcommand", Tkapp_CreateCommand, 1},
1773 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001774#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001775 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1776 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001777#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001778 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001779 {"mainloop", Tkapp_MainLoop, 1},
1780 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001781 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001782 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001783 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001784};
1785
Barry Warsawfa701a81997-01-16 00:15:11 +00001786
1787
Guido van Rossum18468821994-06-20 07:49:28 +00001788/**** Tkapp Type Methods ****/
1789
1790static void
Fred Drake509d79a2000-07-08 04:04:38 +00001791Tkapp_Dealloc(PyObject *self)
Guido van Rossum18468821994-06-20 07:49:28 +00001792{
Guido van Rossum00d93061998-05-28 23:06:38 +00001793 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001794 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001795 LEAVE_TCL
Guido van Rossumb18618d2000-05-03 23:44:39 +00001796 PyObject_Del(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001797 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001798}
1799
1800static PyObject *
Fred Drake509d79a2000-07-08 04:04:38 +00001801Tkapp_GetAttr(PyObject *self, char *name)
Guido van Rossum18468821994-06-20 07:49:28 +00001802{
Guido van Rossum35d43371997-08-02 00:09:09 +00001803 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001804}
1805
1806static PyTypeObject Tkapp_Type =
1807{
Guido van Rossum35d43371997-08-02 00:09:09 +00001808 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001809 0, /*ob_size */
1810 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001811 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001812 0, /*tp_itemsize */
1813 Tkapp_Dealloc, /*tp_dealloc */
1814 0, /*tp_print */
1815 Tkapp_GetAttr, /*tp_getattr */
1816 0, /*tp_setattr */
1817 0, /*tp_compare */
1818 0, /*tp_repr */
1819 0, /*tp_as_number */
1820 0, /*tp_as_sequence */
1821 0, /*tp_as_mapping */
1822 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001823};
1824
Barry Warsawfa701a81997-01-16 00:15:11 +00001825
1826
Guido van Rossum18468821994-06-20 07:49:28 +00001827/**** Tkinter Module ****/
1828
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001829typedef struct {
1830 PyObject* tuple;
1831 int size; /* current size */
1832 int maxsize; /* allocated size */
1833} FlattenContext;
1834
1835static int
1836_bump(FlattenContext* context, int size)
1837{
Guido van Rossum2834b972000-10-06 16:58:26 +00001838 /* expand tuple to hold (at least) size new items.
1839 return true if successful, false if an exception was raised */
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001840
1841 int maxsize = context->maxsize * 2;
1842
1843 if (maxsize < context->size + size)
1844 maxsize = context->size + size;
1845
1846 context->maxsize = maxsize;
1847
Tim Peters4324aa32001-05-28 22:30:08 +00001848 return _PyTuple_Resize(&context->tuple, maxsize) >= 0;
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001849}
1850
1851static int
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001852_flatten1(FlattenContext* context, PyObject* item, int depth)
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001853{
1854 /* add tuple or list to argument tuple (recursively) */
1855
1856 int i, size;
1857
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001858 if (depth > 1000) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001859 PyErr_SetString(PyExc_ValueError,
1860 "nesting too deep in _flatten");
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001861 return 0;
1862 } else if (PyList_Check(item)) {
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001863 size = PyList_GET_SIZE(item);
1864 /* preallocate (assume no nesting) */
Guido van Rossum2834b972000-10-06 16:58:26 +00001865 if (context->size + size > context->maxsize &&
1866 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001867 return 0;
1868 /* copy items to output tuple */
1869 for (i = 0; i < size; i++) {
1870 PyObject *o = PyList_GET_ITEM(item, i);
1871 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001872 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001873 return 0;
1874 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001875 if (context->size + 1 > context->maxsize &&
1876 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001877 return 0;
1878 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00001879 PyTuple_SET_ITEM(context->tuple,
1880 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001881 }
1882 }
1883 } else if (PyTuple_Check(item)) {
1884 /* same, for tuples */
1885 size = PyTuple_GET_SIZE(item);
Guido van Rossum2834b972000-10-06 16:58:26 +00001886 if (context->size + size > context->maxsize &&
1887 !_bump(context, size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001888 return 0;
1889 for (i = 0; i < size; i++) {
1890 PyObject *o = PyTuple_GET_ITEM(item, i);
1891 if (PyList_Check(o) || PyTuple_Check(o)) {
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001892 if (!_flatten1(context, o, depth + 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001893 return 0;
1894 } else if (o != Py_None) {
Guido van Rossum2834b972000-10-06 16:58:26 +00001895 if (context->size + 1 > context->maxsize &&
1896 !_bump(context, 1))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001897 return 0;
1898 Py_INCREF(o);
Guido van Rossum2834b972000-10-06 16:58:26 +00001899 PyTuple_SET_ITEM(context->tuple,
1900 context->size++, o);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001901 }
1902 }
1903 } else {
1904 PyErr_SetString(PyExc_TypeError, "argument must be sequence");
1905 return 0;
1906 }
1907 return 1;
1908}
1909
1910static PyObject *
1911Tkinter_Flatten(PyObject* self, PyObject* args)
1912{
1913 FlattenContext context;
1914 PyObject* item;
1915
1916 if (!PyArg_ParseTuple(args, "O:_flatten", &item))
1917 return NULL;
1918
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001919 context.maxsize = PySequence_Size(item);
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001920 if (context.maxsize <= 0)
1921 return PyTuple_New(0);
1922
1923 context.tuple = PyTuple_New(context.maxsize);
1924 if (!context.tuple)
1925 return NULL;
1926
1927 context.size = 0;
1928
Andrew M. Kuchling288e97b2000-06-19 00:55:09 +00001929 if (!_flatten1(&context, item,0))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001930 return NULL;
1931
Tim Peters4324aa32001-05-28 22:30:08 +00001932 if (_PyTuple_Resize(&context.tuple, context.size))
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001933 return NULL;
1934
1935 return context.tuple;
1936}
1937
Guido van Rossum18468821994-06-20 07:49:28 +00001938static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001939Tkinter_Create(PyObject *self, PyObject *args)
Guido van Rossum18468821994-06-20 07:49:28 +00001940{
Barry Warsawfa701a81997-01-16 00:15:11 +00001941 char *screenName = NULL;
1942 char *baseName = NULL;
1943 char *className = NULL;
1944 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001945
Guido van Rossum35d43371997-08-02 00:09:09 +00001946 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001947 if (baseName != NULL)
1948 baseName++;
1949 else
1950 baseName = Py_GetProgramName();
1951 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001952
Guido van Rossum43713e52000-02-29 13:59:29 +00001953 if (!PyArg_ParseTuple(args, "|zssi:create",
Barry Warsawfa701a81997-01-16 00:15:11 +00001954 &screenName, &baseName, &className,
1955 &interactive))
1956 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001957
Barry Warsawfa701a81997-01-16 00:15:11 +00001958 return (PyObject *) Tkapp_New(screenName, baseName, className,
1959 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001960}
1961
1962static PyMethodDef moduleMethods[] =
1963{
Andrew M. Kuchlinge475e702000-06-18 18:45:50 +00001964 {"_flatten", Tkinter_Flatten, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001965 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001966#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001967 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1968 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001969#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001970 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001971 {"mainloop", Tkapp_MainLoop, 1},
1972 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001973 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001974 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001975};
1976
Guido van Rossum7bf15641998-05-22 18:28:17 +00001977#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001978
1979static int stdin_ready = 0;
1980
Guido van Rossumad4db171998-06-13 13:56:28 +00001981#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001982static void
Fred Drake509d79a2000-07-08 04:04:38 +00001983MyFileProc(void *clientData, int mask)
Guido van Rossum7bf15641998-05-22 18:28:17 +00001984{
1985 stdin_ready = 1;
1986}
Guido van Rossumad4db171998-06-13 13:56:28 +00001987#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001988
Guido van Rossum00d93061998-05-28 23:06:38 +00001989static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001990
Guido van Rossum18468821994-06-20 07:49:28 +00001991static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001992EventHook(void)
Guido van Rossum18468821994-06-20 07:49:28 +00001993{
Guido van Rossumad4db171998-06-13 13:56:28 +00001994#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00001995 int tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00001996#endif
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001997#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00001998 PyEval_RestoreThread(event_tstate);
Guido van Rossume9bc62d1998-11-17 03:45:24 +00001999#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002000 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00002001 errorInCmd = 0;
2002#ifndef MS_WINDOWS
Guido van Rossuma80649b2000-03-28 20:07:05 +00002003 tfile = fileno(stdin);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002004 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00002005#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002006 while (!errorInCmd && !stdin_ready) {
2007 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00002008#ifdef MS_WINDOWS
2009 if (_kbhit()) {
2010 stdin_ready = 1;
2011 break;
2012 }
2013#endif
2014#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum62320c91998-06-15 04:36:09 +00002015 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +00002016 PyThread_acquire_lock(tcl_lock, 1);
Guido van Rossum41f0a981998-10-12 16:26:22 +00002017 tcl_tstate = event_tstate;
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002018
Guido van Rossum00d93061998-05-28 23:06:38 +00002019 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossumdc1adab1998-10-09 20:51:18 +00002020
2021 tcl_tstate = NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +00002022 PyThread_release_lock(tcl_lock);
Guido van Rossum00d93061998-05-28 23:06:38 +00002023 if (result == 0)
2024 Sleep(20);
2025 Py_END_ALLOW_THREADS
2026#else
2027 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00002028#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00002029
2030 if (result < 0)
2031 break;
2032 }
Guido van Rossumad4db171998-06-13 13:56:28 +00002033#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00002034 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00002035#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002036 if (errorInCmd) {
2037 errorInCmd = 0;
2038 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2039 excInCmd = valInCmd = trbInCmd = NULL;
2040 PyErr_Print();
2041 }
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002042#ifdef WITH_THREAD
Guido van Rossumad4db171998-06-13 13:56:28 +00002043 PyEval_SaveThread();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002044#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00002045 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00002046}
Guido van Rossum18468821994-06-20 07:49:28 +00002047
Guido van Rossum00d93061998-05-28 23:06:38 +00002048#endif
2049
Guido van Rossum7bf15641998-05-22 18:28:17 +00002050static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002051EnableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002052{
Guido van Rossum00d93061998-05-28 23:06:38 +00002053#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002054 if (PyOS_InputHook == NULL) {
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002055#ifdef WITH_THREAD
Guido van Rossum00d93061998-05-28 23:06:38 +00002056 event_tstate = PyThreadState_Get();
Guido van Rossume9bc62d1998-11-17 03:45:24 +00002057#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002058 PyOS_InputHook = EventHook;
2059 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002060#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002061}
2062
2063static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002064DisableEventHook(void)
Guido van Rossum7bf15641998-05-22 18:28:17 +00002065{
Guido van Rossum00d93061998-05-28 23:06:38 +00002066#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00002067 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2068 PyOS_InputHook = NULL;
2069 }
Guido van Rossum00d93061998-05-28 23:06:38 +00002070#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00002071}
2072
Barry Warsawfa701a81997-01-16 00:15:11 +00002073
2074/* all errors will be checked in one fell swoop in init_tkinter() */
2075static void
Fred Drake509d79a2000-07-08 04:04:38 +00002076ins_long(PyObject *d, char *name, long val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002077{
2078 PyObject *v = PyInt_FromLong(val);
2079 if (v) {
2080 PyDict_SetItemString(d, name, v);
2081 Py_DECREF(v);
2082 }
2083}
2084static void
Fred Drake509d79a2000-07-08 04:04:38 +00002085ins_string(PyObject *d, char *name, char *val)
Barry Warsawfa701a81997-01-16 00:15:11 +00002086{
2087 PyObject *v = PyString_FromString(val);
2088 if (v) {
2089 PyDict_SetItemString(d, name, v);
2090 Py_DECREF(v);
2091 }
2092}
2093
2094
Guido van Rossum3886bb61998-12-04 18:50:17 +00002095DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002096init_tkinter(void)
Guido van Rossum18468821994-06-20 07:49:28 +00002097{
Barry Warsawfa701a81997-01-16 00:15:11 +00002098 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00002099
Barry Warsawfa701a81997-01-16 00:15:11 +00002100 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00002101
2102#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +00002103 tcl_lock = PyThread_allocate_lock();
Guido van Rossum00d93061998-05-28 23:06:38 +00002104#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00002105
Barry Warsawfa701a81997-01-16 00:15:11 +00002106 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00002107
Barry Warsawfa701a81997-01-16 00:15:11 +00002108 d = PyModule_GetDict(m);
2109 Tkinter_TclError = Py_BuildValue("s", "TclError");
2110 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00002111
Guido van Rossum35d43371997-08-02 00:09:09 +00002112 ins_long(d, "READABLE", TCL_READABLE);
2113 ins_long(d, "WRITABLE", TCL_WRITABLE);
2114 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2115 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2116 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2117 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2118 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2119 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2120 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00002121 ins_string(d, "TK_VERSION", TK_VERSION);
2122 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00002123
Guido van Rossum83551bf1997-09-13 00:44:23 +00002124 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00002125
2126 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00002127 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2128
Guido van Rossume187b0e2000-03-27 21:46:29 +00002129 /* This helps the dynamic loader; in Unicode aware Tcl versions
2130 it also helps Tcl find its encodings. */
2131 Tcl_FindExecutable(Py_GetProgramName());
Guido van Rossume187b0e2000-03-27 21:46:29 +00002132
Barry Warsawfa701a81997-01-16 00:15:11 +00002133 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002134 return;
2135
Guido van Rossum43ff8681998-07-14 18:02:13 +00002136#if 0
2137 /* This was not a good idea; through <Destroy> bindings,
2138 Tcl_Finalize() may invoke Python code but at that point the
2139 interpreter and thread state have already been destroyed! */
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002140 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00002141#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00002142
Jack Jansen34cc5c31995-10-31 16:15:12 +00002143#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002144 /*
2145 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
2146 ** Most of the initializations in that routine (toolbox init calls and
2147 ** such) have already been done for us, so we only need these.
2148 */
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002149 tcl_macQdPtr = &qd;
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002150
2151 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00002152#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00002153 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00002154#endif /* GENERATINGCFM */
2155#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00002156}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002157
Guido van Rossumec22c921996-02-25 04:50:29 +00002158
Barry Warsawfa701a81997-01-16 00:15:11 +00002159
Guido van Rossum9722ad81995-09-22 23:49:28 +00002160#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002161
2162/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002163** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002164*/
2165
Guido van Rossum9722ad81995-09-22 23:49:28 +00002166void
2167panic(char * format, ...)
2168{
Barry Warsawfa701a81997-01-16 00:15:11 +00002169 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002170
Barry Warsawfa701a81997-01-16 00:15:11 +00002171 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002172
Guido van Rossum227cf761998-08-05 13:53:32 +00002173 vfprintf(stderr, format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002174 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002175
Barry Warsawfa701a81997-01-16 00:15:11 +00002176 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002177
Barry Warsawfa701a81997-01-16 00:15:11 +00002178 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002179}
Jack Jansen40b546d1995-11-14 10:34:45 +00002180
Guido van Rossumec22c921996-02-25 04:50:29 +00002181/*
2182** Pass events to SIOUX before passing them to Tk.
2183*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002184
Guido van Rossumec22c921996-02-25 04:50:29 +00002185static int
Fred Drake509d79a2000-07-08 04:04:38 +00002186PyMacConvertEvent(EventRecord *eventPtr)
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002187{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002188 WindowPtr frontwin;
2189 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002190 ** Sioux eats too many events, so we don't pass it everything. We
2191 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002192 ** the Sioux window is frontmost. This means that Tk menus don't work
2193 ** in that case, but at least we can scroll the sioux window.
2194 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2195 ** part of the external interface of Sioux...
2196 */
2197 frontwin = FrontWindow();
2198 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2199 if (SIOUXHandleOneEvent(eventPtr))
2200 return 0; /* Nothing happened to the Tcl event queue */
2201 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002202 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002203}
2204
Guido van Rossumec22c921996-02-25 04:50:29 +00002205#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002206
2207/*
2208** Additional Mac specific code for dealing with shared libraries.
2209*/
2210
2211#include <Resources.h>
2212#include <CodeFragments.h>
2213
2214static int loaded_from_shlib = 0;
2215static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002216
Jack Jansen34cc5c31995-10-31 16:15:12 +00002217/*
2218** If this module is dynamically loaded the following routine should
2219** be the init routine. It takes care of adding the shared library to
2220** the resource-file chain, so that the tk routines can find their
2221** resources.
2222*/
2223OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002224init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002225{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002226 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002227 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002228 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002229 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2230 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002231 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002232 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2233 loaded_from_shlib = 1;
2234 }
2235 return noErr;
2236}
2237
2238/*
2239** Insert the library resources into the search path. Put them after
2240** the resources from the application. Again, we ignore errors.
2241*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002242static
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002243mac_addlibresources(void)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002244{
2245 if ( !loaded_from_shlib )
2246 return;
2247 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2248}
2249
Guido van Rossumec22c921996-02-25 04:50:29 +00002250#endif /* GENERATINGCFM */
2251#endif /* macintosh */