blob: b4f4d568ae46ffcff57032fdad665ef240ba23b6 [file] [log] [blame]
Guido van Rossum845547d1996-06-26 18:26:04 +00001/***********************************************************
2Copyright (C) 1994 Steen Lumholt.
3Copyright 1994-1995 by Stichting Mathematisch Centrum, Amsterdam,
4The Netherlands.
5
6 All Rights Reserved
7
Guido van Rossumd266eb41996-10-25 14:44:06 +00008Permission to use, copy, modify, and distribute this software and its
9documentation for any purpose and without fee is hereby granted,
Guido van Rossum845547d1996-06-26 18:26:04 +000010provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000011both that copyright notice and this permission notice appear in
Guido van Rossum845547d1996-06-26 18:26:04 +000012supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000013Centrum or CWI or Corporation for National Research Initiatives or
14CNRI not be used in advertising or publicity pertaining to
15distribution of the software without specific, written prior
16permission.
Guido van Rossum845547d1996-06-26 18:26:04 +000017
Guido van Rossumd266eb41996-10-25 14:44:06 +000018While CWI is the initial source for this software, a modified version
19is made available by the Corporation for National Research Initiatives
20(CNRI) at the Internet address ftp://ftp.python.org.
21
22STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
23REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
24MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
25CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
26DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
27PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
28TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum845547d1996-06-26 18:26:04 +000030
31******************************************************************/
32
33/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +000034
Guido van Rossum7ffa7611996-08-13 21:10:16 +000035/* TCL/TK VERSION INFO:
36
37 Unix:
Guido van Rossum496f8f61997-07-19 19:57:42 +000038 Tcl/Tk 8.0 (even alpha or beta) or 7.6/4.2 are recommended.
Guido van Rossum35d43371997-08-02 00:09:09 +000039 Versions 7.5/4.1 are the earliest versions still supported.
40 Versions 7.4/4.0 or Tk 3.x are no longer supported.
Guido van Rossum7ffa7611996-08-13 21:10:16 +000041
42 Mac and Windows:
Guido van Rossum496f8f61997-07-19 19:57:42 +000043 Use Tcl 8.0 if available (even alpha or beta).
44 The oldest usable version is 4.1p1/7.5p1.
45
Guido van Rossum212643f1998-04-29 16:22:14 +000046 XXX Further speed-up ideas, involving Tcl 8.0 features:
47
48 - In Tcl_Call(), create Tcl objects from the arguments, possibly using
49 intelligent mappings between Python objects and Tcl objects (e.g. ints,
50 floats and Tcl window pointers could be handled specially).
51
52 - Register a new Tcl type, "Python callable", which can be called more
53 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
54
Guido van Rossum7ffa7611996-08-13 21:10:16 +000055*/
56
Guido van Rossum35d43371997-08-02 00:09:09 +000057
Guido van Rossum9722ad81995-09-22 23:49:28 +000058#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000059#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000060
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000061#ifdef macintosh
62#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000063#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000064#endif
65
Guido van Rossum18468821994-06-20 07:49:28 +000066#include <tcl.h>
67#include <tk.h>
68
Guido van Rossum3e819a71997-08-01 19:29:02 +000069#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
70
Guido van Rossum0d2390c1997-08-14 19:57:07 +000071#if TKMAJORMINOR >= 8000 && defined(macintosh)
72/* Sigh, we have to include this to get at the tcl qd pointer */
73#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000074/* And this one we need to clear the menu bar */
75#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000076#endif
77
Guido van Rossum35d43371997-08-02 00:09:09 +000078#if TKMAJORMINOR < 4001
Guido van Rossum75626a31997-09-08 02:04:00 +000079 #error "Tk 4.0 or 3.x are not supported -- use 4.1 or higher"
Guido van Rossum9722ad81995-09-22 23:49:28 +000080#endif
81
Guido van Rossumb0105441997-10-08 15:25:37 +000082#if TKMAJORMINOR < 8000 || !defined(MS_WINDOWS)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000083#define HAVE_CREATEFILEHANDLER
84#endif
85
Guido van Rossum35d43371997-08-02 00:09:09 +000086extern int Tk_GetNumMainWindows();
87
Guido van Rossumec22c921996-02-25 04:50:29 +000088#ifdef macintosh
89
90/*
91** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +000092** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +000093*/
94
Guido van Rossum7ffa7611996-08-13 21:10:16 +000095/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +000096#define FREECAST (char *)
97
Guido van Rossumec22c921996-02-25 04:50:29 +000098#include <Events.h> /* For EventRecord */
99
100typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
Guido van Rossum0d2390c1997-08-14 19:57:07 +0000101/* They changed the name... */
102#if TKMAJORMINOR < 8000
103#define Tcl_MacSetEventProc TclMacSetEventProc
104#endif
105void Tcl_MacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
Guido van Rossumec22c921996-02-25 04:50:29 +0000106int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
107
108staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
109
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000110#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
111 #pragma import on
112#endif
113
114#include <SIOUX.h>
115extern int SIOUXIsAppWindow(WindowPtr);
116
117#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
118 #pragma import reset
119#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000120#endif /* macintosh */
121
Guido van Rossum97867b21996-08-08 19:09:53 +0000122#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000123#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000124#endif
125
Guido van Rossum18468821994-06-20 07:49:28 +0000126/**** Tkapp Object Declaration ****/
127
128staticforward PyTypeObject Tkapp_Type;
129
130typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +0000131{
132 PyObject_HEAD
133 Tcl_Interp *interp;
Barry Warsawfa701a81997-01-16 00:15:11 +0000134}
Guido van Rossum18468821994-06-20 07:49:28 +0000135TkappObject;
136
137#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000138#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
139#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
140
Guido van Rossum35d43371997-08-02 00:09:09 +0000141#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000142(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000143
Barry Warsawfa701a81997-01-16 00:15:11 +0000144
145
Guido van Rossum18468821994-06-20 07:49:28 +0000146/**** Error Handling ****/
147
148static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000149static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000150static int errorInCmd = 0;
151static PyObject *excInCmd;
152static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000153static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000154
Barry Warsawfa701a81997-01-16 00:15:11 +0000155
156
Guido van Rossum18468821994-06-20 07:49:28 +0000157static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000158Tkinter_Error(v)
159 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000160{
Barry Warsawfa701a81997-01-16 00:15:11 +0000161 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
162 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000163}
164
Barry Warsawfa701a81997-01-16 00:15:11 +0000165
Guido van Rossum18468821994-06-20 07:49:28 +0000166int
Barry Warsawfa701a81997-01-16 00:15:11 +0000167PythonCmd_Error(interp)
168 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000169{
Barry Warsawfa701a81997-01-16 00:15:11 +0000170 errorInCmd = 1;
171 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
172 return TCL_ERROR;
Guido van Rossum18468821994-06-20 07:49:28 +0000173}
174
Barry Warsawfa701a81997-01-16 00:15:11 +0000175
176
Guido van Rossum18468821994-06-20 07:49:28 +0000177/**** Utils ****/
Guido van Rossum18468821994-06-20 07:49:28 +0000178static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000179AsString(value, tmp)
180 PyObject *value;
181 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000182{
Guido van Rossum35d43371997-08-02 00:09:09 +0000183 if (PyString_Check(value))
184 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000185 else {
186 PyObject *v = PyObject_Str(value);
187 PyList_Append(tmp, v);
188 Py_DECREF(v);
189 return PyString_AsString(v);
190 }
Guido van Rossum18468821994-06-20 07:49:28 +0000191}
192
Barry Warsawfa701a81997-01-16 00:15:11 +0000193
194
Guido van Rossum18468821994-06-20 07:49:28 +0000195#define ARGSZ 64
196
197static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000198Merge(args)
199 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000200{
Barry Warsawfa701a81997-01-16 00:15:11 +0000201 PyObject *tmp = NULL;
202 char *argvStore[ARGSZ];
203 char **argv = NULL;
204 int fvStore[ARGSZ];
205 int *fv = NULL;
206 int argc = 0, i;
207 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000208
Barry Warsawfa701a81997-01-16 00:15:11 +0000209 if (!(tmp = PyList_New(0)))
210 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000211
Barry Warsawfa701a81997-01-16 00:15:11 +0000212 argv = argvStore;
213 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000214
Barry Warsawfa701a81997-01-16 00:15:11 +0000215 if (args == NULL)
216 argc = 0;
217
218 else if (!PyTuple_Check(args)) {
219 argc = 1;
220 fv[0] = 0;
221 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000222 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000223 else {
224 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000225
Barry Warsawfa701a81997-01-16 00:15:11 +0000226 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000227 argv = (char **)ckalloc(argc * sizeof(char *));
228 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000229 if (argv == NULL || fv == NULL) {
230 PyErr_NoMemory();
231 goto finally;
232 }
233 }
234
235 for (i = 0; i < argc; i++) {
236 PyObject *v = PyTuple_GetItem(args, i);
237 if (PyTuple_Check(v)) {
238 fv[i] = 1;
239 if (!(argv[i] = Merge(v)))
240 goto finally;
241 }
242 else if (v == Py_None) {
243 argc = i;
244 break;
245 }
246 else {
247 fv[i] = 0;
248 argv[i] = AsString(v, tmp);
249 }
250 }
Guido van Rossum18468821994-06-20 07:49:28 +0000251 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000252 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000253
Barry Warsawfa701a81997-01-16 00:15:11 +0000254 finally:
255 for (i = 0; i < argc; i++)
256 if (fv[i]) {
257 ckfree(argv[i]);
258 }
259 if (argv != argvStore)
260 ckfree(FREECAST argv);
261 if (fv != fvStore)
262 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000263
Barry Warsawfa701a81997-01-16 00:15:11 +0000264 Py_DECREF(tmp);
265 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000266}
267
Barry Warsawfa701a81997-01-16 00:15:11 +0000268
269
Guido van Rossum18468821994-06-20 07:49:28 +0000270static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000271Split(self, list)
272 PyObject *self;
273 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000274{
Barry Warsawfa701a81997-01-16 00:15:11 +0000275 int argc;
276 char **argv;
277 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000278
Barry Warsawfa701a81997-01-16 00:15:11 +0000279 if (list == NULL) {
280 Py_INCREF(Py_None);
281 return Py_None;
282 }
Guido van Rossum18468821994-06-20 07:49:28 +0000283
Barry Warsawfa701a81997-01-16 00:15:11 +0000284 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
285 {
286 /* Not a list.
287 * Could be a quoted string containing funnies, e.g. {"}.
288 * Return the string itself.
289 */
290 PyErr_Clear();
291 return PyString_FromString(list);
292 }
Guido van Rossum18468821994-06-20 07:49:28 +0000293
Barry Warsawfa701a81997-01-16 00:15:11 +0000294 if (argc == 0)
295 v = PyString_FromString("");
296 else if (argc == 1)
297 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000298 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000299 int i;
300 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000301
Barry Warsawfa701a81997-01-16 00:15:11 +0000302 for (i = 0; i < argc; i++) {
303 if ((w = Split(self, argv[i])) == NULL) {
304 Py_DECREF(v);
305 v = NULL;
306 break;
307 }
308 PyTuple_SetItem(v, i, w);
309 }
310 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000311 ckfree(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000312 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000313}
314
Barry Warsawfa701a81997-01-16 00:15:11 +0000315
316
Guido van Rossum18468821994-06-20 07:49:28 +0000317/**** Tkapp Object ****/
318
319#ifndef WITH_APPINIT
320int
Guido van Rossum35d43371997-08-02 00:09:09 +0000321Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000322 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000323{
Barry Warsawfa701a81997-01-16 00:15:11 +0000324 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000325
Barry Warsawfa701a81997-01-16 00:15:11 +0000326 main = Tk_MainWindow(interp);
327 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000328 PySys_WriteStderr("Tcl_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000329 return TCL_ERROR;
330 }
331 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000332 PySys_WriteStderr("Tk_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000333 return TCL_ERROR;
334 }
335 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000336}
337#endif /* !WITH_APPINIT */
338
Guido van Rossum18468821994-06-20 07:49:28 +0000339
Barry Warsawfa701a81997-01-16 00:15:11 +0000340
341
342/* Initialize the Tk application; see the `main' function in
343 * `tkMain.c'.
344 */
345static TkappObject *
346Tkapp_New(screenName, baseName, className, interactive)
347 char *screenName;
348 char *baseName;
349 char *className;
350 int interactive;
351{
352 TkappObject *v;
353 char *argv0;
354
355 v = PyObject_NEW(TkappObject, &Tkapp_Type);
356 if (v == NULL)
357 return NULL;
358
359 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000360
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000361#if defined(macintosh) && TKMAJORMINOR >= 8000
362 /* This seems to be needed since Tk 8.0 */
363 ClearMenuBar();
364 TkMacInitMenus(v->interp);
365#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000366 /* Delete the 'exit' command, which can screw things up */
367 Tcl_DeleteCommand(v->interp, "exit");
368
Barry Warsawfa701a81997-01-16 00:15:11 +0000369 if (screenName != NULL)
370 Tcl_SetVar2(v->interp, "env", "DISPLAY",
371 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000372
Barry Warsawfa701a81997-01-16 00:15:11 +0000373 if (interactive)
374 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
375 else
376 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000377
Barry Warsawfa701a81997-01-16 00:15:11 +0000378 /* This is used to get the application class for Tk 4.1 and up */
379 argv0 = (char*)ckalloc(strlen(className) + 1);
380 if (!argv0) {
381 PyErr_NoMemory();
382 Py_DECREF(v);
383 return NULL;
384 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000385
Barry Warsawfa701a81997-01-16 00:15:11 +0000386 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000387 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000388 argv0[0] = tolower(argv0[0]);
389 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
390 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000391
Barry Warsawfa701a81997-01-16 00:15:11 +0000392 if (Tcl_AppInit(v->interp) != TCL_OK)
393 return (TkappObject *)Tkinter_Error(v);
394
395 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000396}
397
Barry Warsawfa701a81997-01-16 00:15:11 +0000398
399
Guido van Rossum18468821994-06-20 07:49:28 +0000400/** Tcl Eval **/
401
402static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000403Tkapp_Call(self, args)
404 PyObject *self;
405 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000406{
Guido van Rossum212643f1998-04-29 16:22:14 +0000407 /* This is copied from Merge() */
408 PyObject *tmp = NULL;
409 char *argvStore[ARGSZ];
410 char **argv = NULL;
411 int fvStore[ARGSZ];
412 int *fv = NULL;
413 int argc = 0, i;
414 PyObject *res = NULL; /* except this has a different type */
415 Tcl_CmdInfo info; /* and this is added */
416 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
Guido van Rossum18468821994-06-20 07:49:28 +0000417
Guido van Rossum212643f1998-04-29 16:22:14 +0000418 if (!(tmp = PyList_New(0)))
419 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000420
Guido van Rossum212643f1998-04-29 16:22:14 +0000421 argv = argvStore;
422 fv = fvStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000423
Guido van Rossum212643f1998-04-29 16:22:14 +0000424 if (args == NULL)
425 argc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000426
Guido van Rossum212643f1998-04-29 16:22:14 +0000427 else if (!PyTuple_Check(args)) {
428 argc = 1;
429 fv[0] = 0;
430 argv[0] = AsString(args, tmp);
431 }
432 else {
433 argc = PyTuple_Size(args);
434
435 if (argc > ARGSZ) {
436 argv = (char **)ckalloc(argc * sizeof(char *));
437 fv = (int *)ckalloc(argc * sizeof(int));
438 if (argv == NULL || fv == NULL) {
439 PyErr_NoMemory();
440 goto finally;
441 }
442 }
443
444 for (i = 0; i < argc; i++) {
445 PyObject *v = PyTuple_GetItem(args, i);
446 if (PyTuple_Check(v)) {
447 fv[i] = 1;
448 if (!(argv[i] = Merge(v)))
449 goto finally;
450 }
451 else if (v == Py_None) {
452 argc = i;
453 break;
454 }
455 else {
456 fv[i] = 0;
457 argv[i] = AsString(v, tmp);
458 }
459 }
460 }
461 /* End code copied from Merge() */
462
463 /* All this to avoid a call to Tcl_Merge() and the corresponding call
464 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
465 if (Py_VerboseFlag >= 2) {
466 for (i = 0; i < argc; i++)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000467 PySys_WriteStderr("%s ", argv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000468 }
469 if (argc < 1 ||
470 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
471 info.proc == NULL)
472 {
473 char *cmd;
474 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000475 PySys_WriteStderr("... use TclEval ");
Guido van Rossum212643f1998-04-29 16:22:14 +0000476 cmd = Tcl_Merge(argc, argv);
477 i = Tcl_Eval(interp, cmd);
Barry Warsawfa701a81997-01-16 00:15:11 +0000478 ckfree(cmd);
Guido van Rossum212643f1998-04-29 16:22:14 +0000479 }
480 else {
481 Tcl_ResetResult(interp);
482 i = (*info.proc)(info.clientData, interp, argc, argv);
483 }
484 if (i == TCL_ERROR) {
485 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000486 PySys_WriteStderr("... error: '%s'\n",
Guido van Rossum212643f1998-04-29 16:22:14 +0000487 interp->result);
488 Tkinter_Error(self);
489 }
490 else {
491 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000492 PySys_WriteStderr("-> '%s'\n", interp->result);
Guido van Rossum212643f1998-04-29 16:22:14 +0000493 res = PyString_FromString(interp->result);
494 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000495
Guido van Rossum212643f1998-04-29 16:22:14 +0000496 /* Copied from Merge() again */
497 finally:
498 for (i = 0; i < argc; i++)
499 if (fv[i]) {
500 ckfree(argv[i]);
501 }
502 if (argv != argvStore)
503 ckfree(FREECAST argv);
504 if (fv != fvStore)
505 ckfree(FREECAST fv);
506
507 Py_DECREF(tmp);
Barry Warsawfa701a81997-01-16 00:15:11 +0000508 return res;
509}
510
511
512static PyObject *
513Tkapp_GlobalCall(self, args)
514 PyObject *self;
515 PyObject *args;
516{
Guido van Rossum212643f1998-04-29 16:22:14 +0000517 /* Could do the same here as for Tkapp_Call(), but this is not used
518 much, so I can't be bothered. Unfortunately Tcl doesn't export a
519 way for the user to do what all its Global* variants do (save and
520 reset the scope pointer, call the local version, restore the saved
521 scope pointer). */
522
Barry Warsawfa701a81997-01-16 00:15:11 +0000523 char *cmd = Merge(args);
524 PyObject *res = NULL;
525
526
527 if (!cmd)
528 PyErr_SetString(Tkinter_TclError, "merge failed");
529
530 else if (Tcl_GlobalEval(Tkapp_Interp(self), cmd) == TCL_ERROR)
531 res = Tkinter_Error(self);
532 else
533 res = PyString_FromString(Tkapp_Result(self));
534
535 if (cmd)
536 ckfree(cmd);
537
538 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000539}
540
541static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000542Tkapp_Eval(self, args)
543 PyObject *self;
544 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000545{
Barry Warsawfa701a81997-01-16 00:15:11 +0000546 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000547
Guido van Rossum35d43371997-08-02 00:09:09 +0000548 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000549 return NULL;
550
551 if (Tcl_Eval(Tkapp_Interp(self), script) == TCL_ERROR)
552 return Tkinter_Error(self);
553
554 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000555}
556
557static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000558Tkapp_GlobalEval(self, args)
559 PyObject *self;
560 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000561{
Barry Warsawfa701a81997-01-16 00:15:11 +0000562 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000563
Guido van Rossum35d43371997-08-02 00:09:09 +0000564 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000565 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000566
Barry Warsawfa701a81997-01-16 00:15:11 +0000567 if (Tcl_GlobalEval(Tkapp_Interp(self), script) == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000568 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000569
Barry Warsawfa701a81997-01-16 00:15:11 +0000570 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000571}
572
573static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000574Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000575 PyObject *self;
576 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000577{
Barry Warsawfa701a81997-01-16 00:15:11 +0000578 char *fileName;
Guido van Rossum18468821994-06-20 07:49:28 +0000579
Guido van Rossum35d43371997-08-02 00:09:09 +0000580 if (!PyArg_ParseTuple(args, "s", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000581 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000582
Barry Warsawfa701a81997-01-16 00:15:11 +0000583 if (Tcl_EvalFile(Tkapp_Interp(self), fileName) == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000584 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000585
Barry Warsawfa701a81997-01-16 00:15:11 +0000586 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000587}
588
589static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000590Tkapp_Record(self, args)
591 PyObject *self;
592 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000593{
Barry Warsawfa701a81997-01-16 00:15:11 +0000594 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000595
Guido van Rossum35d43371997-08-02 00:09:09 +0000596 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000597 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000598
Barry Warsawfa701a81997-01-16 00:15:11 +0000599 if (TCL_ERROR == Tcl_RecordAndEval(Tkapp_Interp(self),
600 script, TCL_NO_EVAL))
Guido van Rossum35d43371997-08-02 00:09:09 +0000601 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000602
Barry Warsawfa701a81997-01-16 00:15:11 +0000603 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000604}
605
606static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000607Tkapp_AddErrorInfo(self, args)
608 PyObject *self;
609 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000610{
Barry Warsawfa701a81997-01-16 00:15:11 +0000611 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000612
Guido van Rossum35d43371997-08-02 00:09:09 +0000613 if (!PyArg_ParseTuple(args, "s", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000614 return NULL;
615 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum18468821994-06-20 07:49:28 +0000616
Barry Warsawfa701a81997-01-16 00:15:11 +0000617 Py_INCREF(Py_None);
618 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000619}
620
Barry Warsawfa701a81997-01-16 00:15:11 +0000621
622
Guido van Rossum18468821994-06-20 07:49:28 +0000623/** Tcl Variable **/
624
625static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000626SetVar(self, args, flags)
627 PyObject *self;
628 PyObject *args;
629 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000630{
Barry Warsawfa701a81997-01-16 00:15:11 +0000631 char *name1, *name2, *ok;
632 PyObject *newValue;
633 PyObject *tmp = PyList_New(0);
Guido van Rossum18468821994-06-20 07:49:28 +0000634
Barry Warsawfa701a81997-01-16 00:15:11 +0000635 if (!tmp)
636 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000637
Guido van Rossum35d43371997-08-02 00:09:09 +0000638 if (PyArg_ParseTuple(args, "sO", &name1, &newValue))
Barry Warsawfa701a81997-01-16 00:15:11 +0000639 /* XXX Merge? */
Guido van Rossum35d43371997-08-02 00:09:09 +0000640 ok = Tcl_SetVar(Tkapp_Interp(self), name1,
641 AsString(newValue, tmp), flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000642
Barry Warsawfa701a81997-01-16 00:15:11 +0000643 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000644 PyErr_Clear();
645 if (PyArg_ParseTuple(args, "ssO", &name1, &name2, &newValue))
646 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
647 AsString (newValue, tmp), flags);
648 else {
649 Py_DECREF (tmp);
650 return NULL;
651 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000652 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000653 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000654
Barry Warsawfa701a81997-01-16 00:15:11 +0000655 if (!ok)
656 return Tkinter_Error(self);
657
658 Py_INCREF(Py_None);
659 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000660}
661
662static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000663Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000664 PyObject *self;
665 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000666{
Barry Warsawfa701a81997-01-16 00:15:11 +0000667 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000668}
669
670static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000671Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000672 PyObject *self;
673 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000674{
Barry Warsawfa701a81997-01-16 00:15:11 +0000675 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000676}
677
Barry Warsawfa701a81997-01-16 00:15:11 +0000678
679
Guido van Rossum18468821994-06-20 07:49:28 +0000680static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000681GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000682 PyObject *self;
683 PyObject *args;
684 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000685{
Guido van Rossum35d43371997-08-02 00:09:09 +0000686 char *name1, *name2=NULL, *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000687
Guido van Rossum35d43371997-08-02 00:09:09 +0000688 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
689 return NULL;
690 if (name2 == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +0000691 s = Tcl_GetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000692
Barry Warsawfa701a81997-01-16 00:15:11 +0000693 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000694 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000695
Barry Warsawfa701a81997-01-16 00:15:11 +0000696 if (s == NULL)
697 return Tkinter_Error(self);
698
Guido van Rossum35d43371997-08-02 00:09:09 +0000699 return PyString_FromString(s);
Guido van Rossum18468821994-06-20 07:49:28 +0000700}
701
702static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000703Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000704 PyObject *self;
705 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000706{
Barry Warsawfa701a81997-01-16 00:15:11 +0000707 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000708}
709
710static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000711Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000712 PyObject *self;
713 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000714{
Barry Warsawfa701a81997-01-16 00:15:11 +0000715 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000716}
717
Barry Warsawfa701a81997-01-16 00:15:11 +0000718
719
Guido van Rossum18468821994-06-20 07:49:28 +0000720static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000721UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000722 PyObject *self;
723 PyObject *args;
724 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000725{
Guido van Rossum35d43371997-08-02 00:09:09 +0000726 char *name1, *name2=NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000727 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000728
Guido van Rossum35d43371997-08-02 00:09:09 +0000729 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000730 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000731 if (name2 == NULL)
732 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
733
734 else
735 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000736
Barry Warsawfa701a81997-01-16 00:15:11 +0000737 if (code == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000738 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000739
740 Py_INCREF(Py_None);
741 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000742}
743
744static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000745Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000746 PyObject *self;
747 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000748{
Barry Warsawfa701a81997-01-16 00:15:11 +0000749 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000750}
751
752static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000753Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000754 PyObject *self;
755 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000756{
Barry Warsawfa701a81997-01-16 00:15:11 +0000757 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000758}
759
Barry Warsawfa701a81997-01-16 00:15:11 +0000760
761
Guido van Rossum18468821994-06-20 07:49:28 +0000762/** Tcl to Python **/
763
764static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000765Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000766 PyObject *self;
767 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000768{
Barry Warsawfa701a81997-01-16 00:15:11 +0000769 char *s;
770 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000771
Guido van Rossum35d43371997-08-02 00:09:09 +0000772 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000773 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000774 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000775 return Tkinter_Error(self);
776 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000777}
778
779static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000780Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000781 PyObject *self;
782 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000783{
Barry Warsawfa701a81997-01-16 00:15:11 +0000784 char *s;
785 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000786
Guido van Rossum35d43371997-08-02 00:09:09 +0000787 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000788 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000789 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000790 return Tkinter_Error(self);
791 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000792}
793
794static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000795Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000796 PyObject *self;
797 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000798{
Barry Warsawfa701a81997-01-16 00:15:11 +0000799 char *s;
800 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000801
Guido van Rossum35d43371997-08-02 00:09:09 +0000802 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000803 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000804 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
805 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000806 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000807}
808
809static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000810Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000811 PyObject *self;
812 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000813{
Barry Warsawfa701a81997-01-16 00:15:11 +0000814 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000815
Guido van Rossum35d43371997-08-02 00:09:09 +0000816 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000817 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000818 if (Tcl_ExprString(Tkapp_Interp(self), s) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000819 return Tkinter_Error(self);
820 return Py_BuildValue("s", Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000821}
822
823static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000824Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000825 PyObject *self;
826 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000827{
Barry Warsawfa701a81997-01-16 00:15:11 +0000828 char *s;
829 long v;
Guido van Rossum18468821994-06-20 07:49:28 +0000830
Guido van Rossum35d43371997-08-02 00:09:09 +0000831 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000832 return NULL;
833 if (Tcl_ExprLong(Tkapp_Interp(self), s, &v) == TCL_ERROR)
834 return Tkinter_Error(self);
835 return Py_BuildValue("l", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000836}
837
838static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000839Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000840 PyObject *self;
841 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000842{
Barry Warsawfa701a81997-01-16 00:15:11 +0000843 char *s;
844 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000845 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000846
Guido van Rossum35d43371997-08-02 00:09:09 +0000847 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000848 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000849 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum35d43371997-08-02 00:09:09 +0000850 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum45b83911997-03-14 04:32:50 +0000851 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000852 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000853 return Tkinter_Error(self);
854 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000855}
856
857static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000858Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000859 PyObject *self;
860 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000861{
Barry Warsawfa701a81997-01-16 00:15:11 +0000862 char *s;
863 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000864
Guido van Rossum35d43371997-08-02 00:09:09 +0000865 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000866 return NULL;
867 if (Tcl_ExprBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
868 return Tkinter_Error(self);
869 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000870}
871
Barry Warsawfa701a81997-01-16 00:15:11 +0000872
873
Guido van Rossum18468821994-06-20 07:49:28 +0000874static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000875Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000876 PyObject *self;
877 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000878{
Barry Warsawfa701a81997-01-16 00:15:11 +0000879 char *list;
880 int argc;
881 char **argv;
882 PyObject *v;
883 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000884
Guido van Rossum35d43371997-08-02 00:09:09 +0000885 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +0000886 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000887
Barry Warsawfa701a81997-01-16 00:15:11 +0000888 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
889 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000890
Barry Warsawfa701a81997-01-16 00:15:11 +0000891 if (!(v = PyTuple_New(argc)))
892 return NULL;
893
894 for (i = 0; i < argc; i++) {
895 PyObject *s = PyString_FromString(argv[i]);
896 if (!s || PyTuple_SetItem(v, i, s)) {
897 Py_DECREF(v);
898 v = NULL;
899 goto finally;
900 }
901 }
Guido van Rossum18468821994-06-20 07:49:28 +0000902
Barry Warsawfa701a81997-01-16 00:15:11 +0000903 finally:
904 ckfree(FREECAST argv);
905 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000906}
907
908static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000909Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000910 PyObject *self;
911 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000912{
Barry Warsawfa701a81997-01-16 00:15:11 +0000913 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000914
Guido van Rossum35d43371997-08-02 00:09:09 +0000915 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +0000916 return NULL;
917 return Split(self, list);
Guido van Rossum18468821994-06-20 07:49:28 +0000918}
919
920static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000921Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000922 PyObject *self;
923 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000924{
Barry Warsawfa701a81997-01-16 00:15:11 +0000925 char *s = Merge(args);
926 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000927
Barry Warsawfa701a81997-01-16 00:15:11 +0000928 if (s) {
929 res = PyString_FromString(s);
930 ckfree(s);
931 }
932 else
933 PyErr_SetString(Tkinter_TclError, "merge failed");
934
935 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000936}
937
Barry Warsawfa701a81997-01-16 00:15:11 +0000938
939
Guido van Rossum18468821994-06-20 07:49:28 +0000940/** Tcl Command **/
941
942/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +0000943 * function or method.
944 */
Guido van Rossum18468821994-06-20 07:49:28 +0000945static int
Guido van Rossum35d43371997-08-02 00:09:09 +0000946PythonCmd(clientData, interp, argc, argv)
Barry Warsawfa701a81997-01-16 00:15:11 +0000947 ClientData clientData; /* Is (self, func) */
948 Tcl_Interp *interp;
949 int argc;
950 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +0000951{
Barry Warsawfa701a81997-01-16 00:15:11 +0000952 PyObject *self, *func, *arg, *res, *tmp;
953 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000954
Barry Warsawfa701a81997-01-16 00:15:11 +0000955 /* TBD: no error checking here since we know, via the
956 * Tkapp_CreateCommand() that the client data is a two-tuple
957 */
958 self = PyTuple_GetItem((PyObject *) clientData, 0);
959 func = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000960
Barry Warsawfa701a81997-01-16 00:15:11 +0000961 /* Create argument list (argv1, ..., argvN) */
962 if (!(arg = PyTuple_New(argc - 1)))
963 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000964
Barry Warsawfa701a81997-01-16 00:15:11 +0000965 for (i = 0; i < (argc - 1); i++) {
966 PyObject *s = PyString_FromString(argv[i + 1]);
967 if (!s || PyTuple_SetItem(arg, i, s)) {
968 Py_DECREF(arg);
969 PythonCmd_Error(interp);
970 }
971 }
972 res = PyEval_CallObject(func, arg);
973 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +0000974
Barry Warsawfa701a81997-01-16 00:15:11 +0000975 if (res == NULL)
976 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +0000977
Barry Warsawfa701a81997-01-16 00:15:11 +0000978 if (!(tmp = PyList_New(0))) {
979 Py_DECREF(res);
980 return PythonCmd_Error(interp);
981 }
982
983 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
984 Py_DECREF(res);
985 Py_DECREF(tmp);
986
987 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000988}
989
990static void
Guido van Rossum35d43371997-08-02 00:09:09 +0000991PythonCmdDelete(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +0000992 ClientData clientData; /* Is (self, func) */
Guido van Rossum18468821994-06-20 07:49:28 +0000993{
Barry Warsawfa701a81997-01-16 00:15:11 +0000994 Py_DECREF((PyObject *) clientData);
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 *
Guido van Rossum35d43371997-08-02 00:09:09 +00001000Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001001 PyObject *self;
1002 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001003{
Barry Warsawfa701a81997-01-16 00:15:11 +00001004 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001005 PyObject *func;
Guido van Rossum35d43371997-08-02 00:09:09 +00001006 PyObject *data;
1007
1008 if (!PyArg_ParseTuple(args, "sO", &cmdName, &func))
1009 return NULL;
1010 if (!PyCallable_Check(func)) {
1011 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001012 return NULL;
1013 }
Guido van Rossum18468821994-06-20 07:49:28 +00001014
Guido van Rossum35d43371997-08-02 00:09:09 +00001015 data = Py_BuildValue("OO", self, func);
Barry Warsawfa701a81997-01-16 00:15:11 +00001016 if (!data)
1017 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001018
Guido van Rossum35d43371997-08-02 00:09:09 +00001019 if (Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1020 (ClientData) data, PythonCmdDelete) == NULL)
1021 {
1022 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
1023 Py_DECREF(data);
1024 return NULL;
1025 }
Guido van Rossum18468821994-06-20 07:49:28 +00001026
Barry Warsawfa701a81997-01-16 00:15:11 +00001027 Py_INCREF(Py_None);
1028 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001029}
1030
Barry Warsawfa701a81997-01-16 00:15:11 +00001031
1032
Guido van Rossum18468821994-06-20 07:49:28 +00001033static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001034Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001035 PyObject *self;
1036 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001037{
Barry Warsawfa701a81997-01-16 00:15:11 +00001038 char *cmdName;
Guido van Rossum18468821994-06-20 07:49:28 +00001039
Guido van Rossum35d43371997-08-02 00:09:09 +00001040 if (!PyArg_ParseTuple(args, "s", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001041 return NULL;
1042 if (Tcl_DeleteCommand(Tkapp_Interp(self), cmdName) == -1)
1043 {
1044 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1045 return NULL;
1046 }
1047 Py_INCREF(Py_None);
1048 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001049}
1050
Barry Warsawfa701a81997-01-16 00:15:11 +00001051
1052
Guido van Rossum18468821994-06-20 07:49:28 +00001053/** File Handler **/
1054
Guido van Rossuma597dde1995-01-10 20:56:29 +00001055static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001056FileHandler(clientData, mask)
Barry Warsawfa701a81997-01-16 00:15:11 +00001057 ClientData clientData; /* Is: (func, file) */
1058 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +00001059{
Barry Warsawfa701a81997-01-16 00:15:11 +00001060 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001061
Barry Warsawfa701a81997-01-16 00:15:11 +00001062 func = PyTuple_GetItem((PyObject *) clientData, 0);
1063 file = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +00001064
Barry Warsawfa701a81997-01-16 00:15:11 +00001065 arg = Py_BuildValue("(Oi)", file, (long) mask);
1066 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001067 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001068
1069 if (res == NULL) {
1070 errorInCmd = 1;
1071 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1072 }
1073 Py_XDECREF(res);
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001074}
1075
1076static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001077GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +00001078 /* Either an int >= 0 or an object with a
1079 *.fileno() method that returns an int >= 0
1080 */
1081 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001082{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001083 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001084 int id;
1085 if (PyInt_Check(file)) {
1086 id = PyInt_AsLong(file);
1087 if (id < 0)
1088 PyErr_SetString(PyExc_ValueError, "invalid file id");
1089 return id;
1090 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001091 args = PyTuple_New(0);
1092 if (args == NULL)
1093 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001094
1095 meth = PyObject_GetAttrString(file, "fileno");
1096 if (meth == NULL) {
1097 Py_DECREF(args);
1098 return -1;
1099 }
1100
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001101 res = PyEval_CallObject(meth, args);
1102 Py_DECREF(args);
1103 Py_DECREF(meth);
1104 if (res == NULL)
1105 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001106
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001107 if (PyInt_Check(res))
1108 id = PyInt_AsLong(res);
1109 else
1110 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001111
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001112 if (id < 0)
1113 PyErr_SetString(PyExc_ValueError,
1114 "invalid fileno() return value");
1115 Py_DECREF(res);
1116 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001117}
1118
Barry Warsawfa701a81997-01-16 00:15:11 +00001119
1120static PyObject* Tkapp_ClientDataDict = NULL;
1121
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001122#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001123static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001124Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001125 PyObject *self;
1126 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001127{
Barry Warsawfa701a81997-01-16 00:15:11 +00001128 PyObject *file, *func, *data;
1129 PyObject *idkey;
1130 int mask, id;
Guido van Rossum3e819a71997-08-01 19:29:02 +00001131#if TKMAJORMINOR < 8000
Barry Warsawfa701a81997-01-16 00:15:11 +00001132 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001133#endif
Guido van Rossum18468821994-06-20 07:49:28 +00001134
Barry Warsawfa701a81997-01-16 00:15:11 +00001135 if (!Tkapp_ClientDataDict) {
1136 if (!(Tkapp_ClientDataDict = PyDict_New()))
1137 return NULL;
1138 }
Guido van Rossum18468821994-06-20 07:49:28 +00001139
Guido van Rossum35d43371997-08-02 00:09:09 +00001140 if (!PyArg_ParseTuple(args, "OiO", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001141 return NULL;
1142 id = GetFileNo(file);
1143 if (id < 0)
1144 return NULL;
1145 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001146 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001147 return NULL;
1148 }
1149
1150 if (!(idkey = PyInt_FromLong(id)))
1151 return NULL;
1152
1153 /* ClientData is: (func, file) */
Guido van Rossum35d43371997-08-02 00:09:09 +00001154 data = Py_BuildValue("(OO)", func, file);
Barry Warsawfa701a81997-01-16 00:15:11 +00001155 if (!data || PyDict_SetItem(Tkapp_ClientDataDict, idkey, data)) {
1156 Py_DECREF(idkey);
1157 Py_XDECREF(data);
1158 return NULL;
1159 }
1160 Py_DECREF(idkey);
Guido van Rossum76875221994-06-27 07:59:42 +00001161
Guido van Rossum3e819a71997-08-01 19:29:02 +00001162#if TKMAJORMINOR < 8000
Guido van Rossum07886d01996-09-11 23:31:42 +00001163#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001164 /* We assume this is a socket... */
1165 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum3e819a71997-08-01 19:29:02 +00001166#else /* !MS_WINDOWS */
Barry Warsawfa701a81997-01-16 00:15:11 +00001167 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum3e819a71997-08-01 19:29:02 +00001168#endif /* !MS_WINDOWS */
Barry Warsawfa701a81997-01-16 00:15:11 +00001169 /* Ought to check for null Tcl_File object... */
1170 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001171#else /* >= 8000 */
Guido van Rossum3e819a71997-08-01 19:29:02 +00001172 Tcl_CreateFileHandler(id, mask, FileHandler, (ClientData) data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001173#endif /* >= 8000 */
Barry Warsawfa701a81997-01-16 00:15:11 +00001174 /* XXX fileHandlerDict */
Guido van Rossum35d43371997-08-02 00:09:09 +00001175 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001176 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001177}
1178
Barry Warsawfa701a81997-01-16 00:15:11 +00001179
Guido van Rossum18468821994-06-20 07:49:28 +00001180static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001181Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001182 PyObject *self;
1183 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001184{
Barry Warsawfa701a81997-01-16 00:15:11 +00001185 PyObject *file;
1186 PyObject *idkey;
1187 PyObject *data;
1188 int id;
Guido van Rossum3e819a71997-08-01 19:29:02 +00001189#if TKMAJORMINOR < 8000
Barry Warsawfa701a81997-01-16 00:15:11 +00001190 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001191#endif
1192
Guido van Rossum35d43371997-08-02 00:09:09 +00001193 if (!PyArg_ParseTuple(args, "O", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001194 return NULL;
1195 id = GetFileNo(file);
1196 if (id < 0)
1197 return NULL;
1198
1199 if (!(idkey = PyInt_FromLong(id)))
1200 return NULL;
1201
1202 /* find and free the object created in the
1203 * Tkapp_CreateFileHandler() call
1204 */
1205 data = PyDict_GetItem(Tkapp_ClientDataDict, idkey);
1206 Py_XDECREF(data);
1207 PyDict_DelItem(Tkapp_ClientDataDict, idkey);
1208 Py_DECREF(idkey);
Guido van Rossum18468821994-06-20 07:49:28 +00001209
Guido van Rossum3e819a71997-08-01 19:29:02 +00001210#if TKMAJORMINOR < 8000
Guido van Rossum07886d01996-09-11 23:31:42 +00001211#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001212 /* We assume this is a socket... */
1213 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum845547d1996-06-26 18:26:04 +00001214#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001215 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +00001216#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001217 /* Ought to check for null Tcl_File object... */
1218 Tcl_DeleteFileHandler(tfile);
Guido van Rossum35d43371997-08-02 00:09:09 +00001219#else /* >= 8000 */
Guido van Rossum3e819a71997-08-01 19:29:02 +00001220 Tcl_DeleteFileHandler(id);
Guido van Rossum35d43371997-08-02 00:09:09 +00001221#endif /* >= 8000 */
Barry Warsawfa701a81997-01-16 00:15:11 +00001222 /* XXX fileHandlerDict */
Guido van Rossum35d43371997-08-02 00:09:09 +00001223 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001224 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001225}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001226#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001227
Barry Warsawfa701a81997-01-16 00:15:11 +00001228
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001229/**** Tktt Object (timer token) ****/
1230
1231staticforward PyTypeObject Tktt_Type;
1232
1233typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +00001234{
1235 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001236 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001237 PyObject *func;
1238}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001239TkttObject;
1240
1241static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001242Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001243 PyObject *self;
1244 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001245{
Barry Warsawfa701a81997-01-16 00:15:11 +00001246 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001247
Guido van Rossum35d43371997-08-02 00:09:09 +00001248 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001249 return NULL;
1250 if (v->func != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001251 Tcl_DeleteTimerHandler(v->token);
Barry Warsawfa701a81997-01-16 00:15:11 +00001252 PyMem_DEL(v->func);
1253 v->func = NULL;
1254 }
1255 Py_INCREF(Py_None);
1256 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001257}
1258
1259static PyMethodDef Tktt_methods[] =
1260{
Guido van Rossum35d43371997-08-02 00:09:09 +00001261 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001262 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001263};
1264
1265static TkttObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001266Tktt_New(token, func)
1267 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001268 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001269{
Barry Warsawfa701a81997-01-16 00:15:11 +00001270 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001271
Barry Warsawfa701a81997-01-16 00:15:11 +00001272 v = PyObject_NEW(TkttObject, &Tktt_Type);
1273 if (v == NULL)
1274 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001275
Barry Warsawfa701a81997-01-16 00:15:11 +00001276 v->token = token;
1277 v->func = func;
1278 Py_INCREF(v->func);
1279 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001280}
1281
1282static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001283Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001284 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001285{
Guido van Rossum35d43371997-08-02 00:09:09 +00001286 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001287}
1288
Guido van Rossum597ac201998-05-12 14:36:19 +00001289static PyObject *
1290Tktt_Repr(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001291 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001292{
Barry Warsawfa701a81997-01-16 00:15:11 +00001293 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001294 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001295
Guido van Rossum597ac201998-05-12 14:36:19 +00001296 sprintf(buf, "<tktimertoken at 0x%lx%s>", (long)v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001297 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001298 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001299}
1300
1301static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001302Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001303 PyObject *self;
1304 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001305{
Barry Warsawfa701a81997-01-16 00:15:11 +00001306 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001307}
1308
1309static PyTypeObject Tktt_Type =
1310{
Guido van Rossum35d43371997-08-02 00:09:09 +00001311 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001312 0, /*ob_size */
1313 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001314 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001315 0, /*tp_itemsize */
1316 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001317 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001318 Tktt_GetAttr, /*tp_getattr */
1319 0, /*tp_setattr */
1320 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001321 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001322 0, /*tp_as_number */
1323 0, /*tp_as_sequence */
1324 0, /*tp_as_mapping */
1325 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001326};
1327
Barry Warsawfa701a81997-01-16 00:15:11 +00001328
1329
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001330/** Timer Handler **/
1331
1332static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001333TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001334 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001335{
Barry Warsawfa701a81997-01-16 00:15:11 +00001336 PyObject *func = (PyObject *)clientData;
1337 PyObject *res = PyEval_CallObject(func, NULL);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001338
Barry Warsawfa701a81997-01-16 00:15:11 +00001339 if (res == NULL) {
1340 errorInCmd = 1;
1341 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1342 }
1343 else
1344 Py_DECREF(res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001345}
1346
1347static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001348Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001349 PyObject *self;
1350 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001351{
Barry Warsawfa701a81997-01-16 00:15:11 +00001352 int milliseconds;
1353 PyObject *func;
Guido van Rossum35d43371997-08-02 00:09:09 +00001354 Tcl_TimerToken token;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001355
Guido van Rossum35d43371997-08-02 00:09:09 +00001356 if (!PyArg_ParseTuple(args, "iO", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001357 return NULL;
1358 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001359 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001360 return NULL;
1361 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001362 token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1363 (ClientData)func);
Barry Warsawfa701a81997-01-16 00:15:11 +00001364
1365 return (PyObject *) Tktt_New(token, func);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001366}
1367
Barry Warsawfa701a81997-01-16 00:15:11 +00001368
1369
Guido van Rossum18468821994-06-20 07:49:28 +00001370/** Event Loop **/
1371
Guido van Rossum18468821994-06-20 07:49:28 +00001372static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001373Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001374 PyObject *self;
1375 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001376{
Barry Warsawfa701a81997-01-16 00:15:11 +00001377 int threshold = 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001378
Barry Warsawfa701a81997-01-16 00:15:11 +00001379 if (!PyArg_ParseTuple(args, "|i", &threshold))
1380 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001381
Barry Warsawfa701a81997-01-16 00:15:11 +00001382 quitMainLoop = 0;
1383 while (Tk_GetNumMainWindows() > threshold &&
1384 !quitMainLoop &&
1385 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001386 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001387 int result;
Guido van Rossum54e20911997-09-28 05:52:41 +00001388#ifdef HAVE_PYTCL_WAITUNTILEVENT
Guido van Rossum35d43371997-08-02 00:09:09 +00001389 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
1390 if (PyErr_CheckSignals() != 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001391 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001392 if (result)
1393 continue;
1394 /* XXX It's not *quite* certain that this is
1395 thread-safe, but it seems *rather* safe as long as
1396 no two threads call mainloop() simultaneously. */
1397 Py_BEGIN_ALLOW_THREADS
Guido van Rossum54e20911997-09-28 05:52:41 +00001398 result = PyTcl_WaitUntilEvent();
Guido van Rossum35d43371997-08-02 00:09:09 +00001399 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001400#else
1401 result = Tcl_DoOneEvent(0);
1402#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001403 if (PyErr_CheckSignals() != 0)
1404 return NULL;
1405 if (result < 0)
1406 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001407 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001408 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001409
Barry Warsawfa701a81997-01-16 00:15:11 +00001410 if (errorInCmd) {
1411 errorInCmd = 0;
1412 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1413 excInCmd = valInCmd = trbInCmd = NULL;
1414 return NULL;
1415 }
1416 Py_INCREF(Py_None);
1417 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001418}
1419
1420static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001421Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001422 PyObject *self;
1423 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001424{
Guido van Rossum35d43371997-08-02 00:09:09 +00001425 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001426 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001427
Barry Warsawfa701a81997-01-16 00:15:11 +00001428 if (!PyArg_ParseTuple(args, "|i", &flags))
1429 return NULL;
1430
Guido van Rossum35d43371997-08-02 00:09:09 +00001431 rv = Tcl_DoOneEvent(flags);
Barry Warsawfa701a81997-01-16 00:15:11 +00001432 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001433}
1434
1435static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001436Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001437 PyObject *self;
1438 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001439{
1440
Guido van Rossum35d43371997-08-02 00:09:09 +00001441 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001442 return NULL;
1443
1444 quitMainLoop = 1;
1445 Py_INCREF(Py_None);
1446 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001447}
1448
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001449static PyObject *
1450Tkapp_InterpAddr(self, args)
1451 PyObject *self;
1452 PyObject *args;
1453{
1454
1455 if (!PyArg_ParseTuple(args, ""))
1456 return NULL;
1457
1458 return PyInt_FromLong((long)Tkapp_Interp(self));
1459}
1460
Barry Warsawfa701a81997-01-16 00:15:11 +00001461
1462
Guido van Rossum18468821994-06-20 07:49:28 +00001463/**** Tkapp Method List ****/
1464
1465static PyMethodDef Tkapp_methods[] =
1466{
Guido van Rossum35d43371997-08-02 00:09:09 +00001467 {"call", Tkapp_Call, 0},
1468 {"globalcall", Tkapp_GlobalCall, 0},
1469 {"eval", Tkapp_Eval, 1},
1470 {"globaleval", Tkapp_GlobalEval, 1},
1471 {"evalfile", Tkapp_EvalFile, 1},
1472 {"record", Tkapp_Record, 1},
1473 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1474 {"setvar", Tkapp_SetVar, 1},
1475 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1476 {"getvar", Tkapp_GetVar, 1},
1477 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1478 {"unsetvar", Tkapp_UnsetVar, 1},
1479 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1480 {"getint", Tkapp_GetInt, 1},
1481 {"getdouble", Tkapp_GetDouble, 1},
1482 {"getboolean", Tkapp_GetBoolean, 1},
1483 {"exprstring", Tkapp_ExprString, 1},
1484 {"exprlong", Tkapp_ExprLong, 1},
1485 {"exprdouble", Tkapp_ExprDouble, 1},
1486 {"exprboolean", Tkapp_ExprBoolean, 1},
1487 {"splitlist", Tkapp_SplitList, 1},
1488 {"split", Tkapp_Split, 1},
1489 {"merge", Tkapp_Merge, 0},
1490 {"createcommand", Tkapp_CreateCommand, 1},
1491 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001492#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001493 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1494 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001495#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001496 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001497 {"mainloop", Tkapp_MainLoop, 1},
1498 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001499 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001500 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001501 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001502};
1503
Barry Warsawfa701a81997-01-16 00:15:11 +00001504
1505
Guido van Rossum18468821994-06-20 07:49:28 +00001506/**** Tkapp Type Methods ****/
1507
1508static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001509Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001510 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001511{
Guido van Rossum35d43371997-08-02 00:09:09 +00001512 Tcl_DeleteInterp(Tkapp_Interp(self));
1513 PyMem_DEL(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001514}
1515
1516static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001517Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001518 PyObject *self;
1519 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001520{
Guido van Rossum35d43371997-08-02 00:09:09 +00001521 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001522}
1523
1524static PyTypeObject Tkapp_Type =
1525{
Guido van Rossum35d43371997-08-02 00:09:09 +00001526 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001527 0, /*ob_size */
1528 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001529 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001530 0, /*tp_itemsize */
1531 Tkapp_Dealloc, /*tp_dealloc */
1532 0, /*tp_print */
1533 Tkapp_GetAttr, /*tp_getattr */
1534 0, /*tp_setattr */
1535 0, /*tp_compare */
1536 0, /*tp_repr */
1537 0, /*tp_as_number */
1538 0, /*tp_as_sequence */
1539 0, /*tp_as_mapping */
1540 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001541};
1542
Barry Warsawfa701a81997-01-16 00:15:11 +00001543
1544
Guido van Rossum18468821994-06-20 07:49:28 +00001545/**** Tkinter Module ****/
1546
1547static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001548Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001549 PyObject *self;
1550 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001551{
Barry Warsawfa701a81997-01-16 00:15:11 +00001552 char *screenName = NULL;
1553 char *baseName = NULL;
1554 char *className = NULL;
1555 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001556
Guido van Rossum35d43371997-08-02 00:09:09 +00001557 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001558 if (baseName != NULL)
1559 baseName++;
1560 else
1561 baseName = Py_GetProgramName();
1562 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001563
Barry Warsawfa701a81997-01-16 00:15:11 +00001564 if (!PyArg_ParseTuple(args, "|zssi",
1565 &screenName, &baseName, &className,
1566 &interactive))
1567 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001568
Barry Warsawfa701a81997-01-16 00:15:11 +00001569 return (PyObject *) Tkapp_New(screenName, baseName, className,
1570 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001571}
1572
1573static PyMethodDef moduleMethods[] =
1574{
Barry Warsawfa701a81997-01-16 00:15:11 +00001575 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001576#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001577 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1578 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001579#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001580 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001581 {"mainloop", Tkapp_MainLoop, 1},
1582 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001583 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001584 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001585};
1586
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001587static PyInterpreterState *event_interp = NULL;
1588
Guido van Rossum18468821994-06-20 07:49:28 +00001589static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001590EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00001591{
Guido van Rossuma59406a1997-10-10 17:39:19 +00001592 PyThreadState *tstate, *save_tstate;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001593
1594 if (Tk_GetNumMainWindows() == 0)
1595 return 0;
1596 if (event_interp == NULL)
1597 return 0;
1598 tstate = PyThreadState_New(event_interp);
Guido van Rossuma59406a1997-10-10 17:39:19 +00001599 save_tstate = PyThreadState_Swap(NULL);
1600 PyEval_RestoreThread(tstate);
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001601 if (!errorInCmd)
1602 Tcl_DoOneEvent(TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001603 if (errorInCmd) {
1604 errorInCmd = 0;
1605 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1606 excInCmd = valInCmd = trbInCmd = NULL;
1607 PyErr_Print();
1608 }
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001609 PyThreadState_Clear(tstate);
Guido van Rossuma59406a1997-10-10 17:39:19 +00001610 PyEval_SaveThread();
1611 PyThreadState_Swap(save_tstate);
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001612 PyThreadState_Delete(tstate);
Barry Warsawfa701a81997-01-16 00:15:11 +00001613 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001614}
Guido van Rossum18468821994-06-20 07:49:28 +00001615
Barry Warsawfa701a81997-01-16 00:15:11 +00001616
1617/* all errors will be checked in one fell swoop in init_tkinter() */
1618static void
1619ins_long(d, name, val)
1620 PyObject *d;
1621 char *name;
1622 long val;
1623{
1624 PyObject *v = PyInt_FromLong(val);
1625 if (v) {
1626 PyDict_SetItemString(d, name, v);
1627 Py_DECREF(v);
1628 }
1629}
1630static void
1631ins_string(d, name, val)
1632 PyObject *d;
1633 char *name;
1634 char *val;
1635{
1636 PyObject *v = PyString_FromString(val);
1637 if (v) {
1638 PyDict_SetItemString(d, name, v);
1639 Py_DECREF(v);
1640 }
1641}
1642
1643
Guido van Rossum18468821994-06-20 07:49:28 +00001644void
Guido van Rossum35d43371997-08-02 00:09:09 +00001645init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00001646{
Barry Warsawfa701a81997-01-16 00:15:11 +00001647 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001648
Barry Warsawfa701a81997-01-16 00:15:11 +00001649 Tkapp_Type.ob_type = &PyType_Type;
1650 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossumae92f011996-08-21 19:03:36 +00001651
Barry Warsawfa701a81997-01-16 00:15:11 +00001652 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001653
Barry Warsawfa701a81997-01-16 00:15:11 +00001654 d = PyModule_GetDict(m);
1655 Tkinter_TclError = Py_BuildValue("s", "TclError");
1656 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00001657
Guido van Rossum35d43371997-08-02 00:09:09 +00001658 ins_long(d, "READABLE", TCL_READABLE);
1659 ins_long(d, "WRITABLE", TCL_WRITABLE);
1660 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
1661 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
1662 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
1663 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
1664 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
1665 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
1666 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001667 ins_string(d, "TK_VERSION", TK_VERSION);
1668 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00001669
Guido van Rossum83551bf1997-09-13 00:44:23 +00001670 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
1671 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
1672
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001673 if (PyOS_InputHook == NULL) {
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001674 event_interp = PyThreadState_Get()->interp;
Guido van Rossum44620641997-08-11 18:57:29 +00001675 PyOS_InputHook = EventHook;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001676 }
Guido van Rossum18468821994-06-20 07:49:28 +00001677
Barry Warsawfa701a81997-01-16 00:15:11 +00001678 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001679 return;
1680
Guido van Rossum26216371998-04-20 18:47:52 +00001681#if TKMAJORMINOR >= 8000
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001682 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00001683#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001684
Jack Jansen34cc5c31995-10-31 16:15:12 +00001685#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001686 /*
1687 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
1688 ** Most of the initializations in that routine (toolbox init calls and
1689 ** such) have already been done for us, so we only need these.
1690 */
1691#if TKMAJORMINOR >= 8000
1692 tcl_macQdPtr = &qd;
1693#endif
1694
1695 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00001696#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00001697 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001698#endif /* GENERATINGCFM */
1699#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001700}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001701
Guido van Rossumec22c921996-02-25 04:50:29 +00001702
Barry Warsawfa701a81997-01-16 00:15:11 +00001703
Guido van Rossum9722ad81995-09-22 23:49:28 +00001704#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001705
1706/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001707** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001708*/
1709
Guido van Rossum9722ad81995-09-22 23:49:28 +00001710void
1711panic(char * format, ...)
1712{
Barry Warsawfa701a81997-01-16 00:15:11 +00001713 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001714
Barry Warsawfa701a81997-01-16 00:15:11 +00001715 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001716
Guido van Rossumb41addf1998-05-12 15:02:41 +00001717 vPySys_WriteStderr(format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001718 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001719
Barry Warsawfa701a81997-01-16 00:15:11 +00001720 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001721
Barry Warsawfa701a81997-01-16 00:15:11 +00001722 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00001723}
Jack Jansen40b546d1995-11-14 10:34:45 +00001724
Guido van Rossumec22c921996-02-25 04:50:29 +00001725/*
1726** Pass events to SIOUX before passing them to Tk.
1727*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001728
Guido van Rossumec22c921996-02-25 04:50:29 +00001729static int
1730PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00001731 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001732{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00001733 WindowPtr frontwin;
1734 /*
1735 ** Sioux eats too many events, so we don't pass it everything.
1736 ** We always pass update events to Sioux, and we only pass other events if
1737 ** the Sioux window is frontmost. This means that Tk menus don't work
1738 ** in that case, but at least we can scroll the sioux window.
1739 ** Note that the SIOUXIsAppWindow() routine we use here is not really
1740 ** part of the external interface of Sioux...
1741 */
1742 frontwin = FrontWindow();
1743 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
1744 if (SIOUXHandleOneEvent(eventPtr))
1745 return 0; /* Nothing happened to the Tcl event queue */
1746 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001747 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001748}
1749
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001750#if defined(USE_GUSI) && TKMAJORMINOR < 8000
Guido van Rossum290283b1997-06-02 22:16:43 +00001751/*
1752 * For Python we have to override this routine (from TclMacNotify),
1753 * since we use GUSI for our sockets, not Tcl streams. Hence, we have
1754 * to use GUSI select to see whether our socket is ready. Note that
1755 * createfilehandler (above) sets the type to TCL_UNIX_FD for our
1756 * files and sockets.
1757 *
1758 * NOTE: this code was lifted from Tcl 7.6, it may need to be modified
1759 * for other versions. */
1760
1761int
1762Tcl_FileReady(file, mask)
1763 Tcl_File file; /* File handle for a stream. */
1764 int mask; /* OR'ed combination of TCL_READABLE,
1765 * TCL_WRITABLE, and TCL_EXCEPTION:
1766 * indicates conditions caller cares about. */
1767{
1768 int type;
1769 int fd;
1770
1771 fd = (int) Tcl_GetFileInfo(file, &type);
1772
1773 if (type == TCL_MAC_SOCKET) {
1774 return TclMacSocketReady(file, mask);
1775 } else if (type == TCL_MAC_FILE) {
1776 /*
1777 * Under the Macintosh, files are always ready, so we just
1778 * return the mask that was passed in.
1779 */
1780
1781 return mask;
1782 } else if (type == TCL_UNIX_FD) {
1783 fd_set readset, writeset, excset;
1784 struct timeval tv;
1785
1786 FD_ZERO(&readset);
1787 FD_ZERO(&writeset);
1788 FD_ZERO(&excset);
1789
1790 if ( mask & TCL_READABLE ) FD_SET(fd, &readset);
1791 if ( mask & TCL_WRITABLE ) FD_SET(fd, &writeset);
1792 if ( mask & TCL_EXCEPTION ) FD_SET(fd, &excset);
1793
1794 tv.tv_sec = tv.tv_usec = 0;
1795 if ( select(fd+1, &readset, &writeset, &excset, &tv) <= 0 )
1796 return 0;
1797
1798 mask = 0;
1799 if ( FD_ISSET(fd, &readset) ) mask |= TCL_READABLE;
1800 if ( FD_ISSET(fd, &writeset) ) mask |= TCL_WRITABLE;
1801 if ( FD_ISSET(fd, &excset) ) mask |= TCL_EXCEPTION;
1802
1803 return mask;
1804 }
1805
1806 return 0;
1807}
1808#endif /* USE_GUSI */
1809
Guido van Rossumec22c921996-02-25 04:50:29 +00001810#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001811
1812/*
1813** Additional Mac specific code for dealing with shared libraries.
1814*/
1815
1816#include <Resources.h>
1817#include <CodeFragments.h>
1818
1819static int loaded_from_shlib = 0;
1820static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001821
Jack Jansen34cc5c31995-10-31 16:15:12 +00001822/*
1823** If this module is dynamically loaded the following routine should
1824** be the init routine. It takes care of adding the shared library to
1825** the resource-file chain, so that the tk routines can find their
1826** resources.
1827*/
1828OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001829init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00001830{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00001831 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00001832 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001833 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001834 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1835 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001836 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001837 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1838 loaded_from_shlib = 1;
1839 }
1840 return noErr;
1841}
1842
1843/*
1844** Insert the library resources into the search path. Put them after
1845** the resources from the application. Again, we ignore errors.
1846*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001847static
Jack Jansen34cc5c31995-10-31 16:15:12 +00001848mac_addlibresources()
1849{
1850 if ( !loaded_from_shlib )
1851 return;
1852 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1853}
1854
Guido van Rossumec22c921996-02-25 04:50:29 +00001855#endif /* GENERATINGCFM */
1856#endif /* macintosh */