blob: 7b4cf796bca3593567cc72e36897a9b90393114a [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) {
328 fprintf(stderr, "Tcl_Init error: %s\n", interp->result);
329 return TCL_ERROR;
330 }
331 if (Tk_Init(interp) == TCL_ERROR) {
332 fprintf(stderr, "Tk_Init error: %s\n", interp->result);
333 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++)
467 fprintf(stderr, "%s ", argv[i]);
468 }
469 if (argc < 1 ||
470 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
471 info.proc == NULL)
472 {
473 char *cmd;
474 if (Py_VerboseFlag >= 2)
475 fprintf(stderr, "... use TclEval ");
476 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)
486 fprintf(stderr, "... error: '%s'\n",
487 interp->result);
488 Tkinter_Error(self);
489 }
490 else {
491 if (Py_VerboseFlag >= 2)
492 fprintf(stderr, "-> '%s'\n", interp->result);
493 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
1289static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001290Tktt_Print(self, fp, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +00001291 PyObject *self;
1292 FILE *fp;
1293 int flags;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001294{
Barry Warsawfa701a81997-01-16 00:15:11 +00001295 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001296
Barry Warsawfa701a81997-01-16 00:15:11 +00001297 fprintf(fp, "<tktimertoken at 0x%lx%s>", (long)v,
1298 v->func == NULL ? ", handler deleted" : "");
1299 return 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001300}
1301
1302static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001303Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001304 PyObject *self;
1305 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001306{
Barry Warsawfa701a81997-01-16 00:15:11 +00001307 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001308}
1309
1310static PyTypeObject Tktt_Type =
1311{
Guido van Rossum35d43371997-08-02 00:09:09 +00001312 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001313 0, /*ob_size */
1314 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001315 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001316 0, /*tp_itemsize */
1317 Tktt_Dealloc, /*tp_dealloc */
1318 Tktt_Print, /*tp_print */
1319 Tktt_GetAttr, /*tp_getattr */
1320 0, /*tp_setattr */
1321 0, /*tp_compare */
1322 0, /*tp_repr */
1323 0, /*tp_as_number */
1324 0, /*tp_as_sequence */
1325 0, /*tp_as_mapping */
1326 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001327};
1328
Barry Warsawfa701a81997-01-16 00:15:11 +00001329
1330
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001331/** Timer Handler **/
1332
1333static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001334TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001335 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001336{
Barry Warsawfa701a81997-01-16 00:15:11 +00001337 PyObject *func = (PyObject *)clientData;
1338 PyObject *res = PyEval_CallObject(func, NULL);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001339
Barry Warsawfa701a81997-01-16 00:15:11 +00001340 if (res == NULL) {
1341 errorInCmd = 1;
1342 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1343 }
1344 else
1345 Py_DECREF(res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001346}
1347
1348static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001349Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001350 PyObject *self;
1351 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001352{
Barry Warsawfa701a81997-01-16 00:15:11 +00001353 int milliseconds;
1354 PyObject *func;
Guido van Rossum35d43371997-08-02 00:09:09 +00001355 Tcl_TimerToken token;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001356
Guido van Rossum35d43371997-08-02 00:09:09 +00001357 if (!PyArg_ParseTuple(args, "iO", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001358 return NULL;
1359 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001360 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001361 return NULL;
1362 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001363 token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1364 (ClientData)func);
Barry Warsawfa701a81997-01-16 00:15:11 +00001365
1366 return (PyObject *) Tktt_New(token, func);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001367}
1368
Barry Warsawfa701a81997-01-16 00:15:11 +00001369
1370
Guido van Rossum18468821994-06-20 07:49:28 +00001371/** Event Loop **/
1372
Guido van Rossum18468821994-06-20 07:49:28 +00001373static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001374Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001375 PyObject *self;
1376 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001377{
Barry Warsawfa701a81997-01-16 00:15:11 +00001378 int threshold = 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001379
Barry Warsawfa701a81997-01-16 00:15:11 +00001380 if (!PyArg_ParseTuple(args, "|i", &threshold))
1381 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001382
Barry Warsawfa701a81997-01-16 00:15:11 +00001383 quitMainLoop = 0;
1384 while (Tk_GetNumMainWindows() > threshold &&
1385 !quitMainLoop &&
1386 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001387 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001388 int result;
Guido van Rossum54e20911997-09-28 05:52:41 +00001389#ifdef HAVE_PYTCL_WAITUNTILEVENT
Guido van Rossum35d43371997-08-02 00:09:09 +00001390 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
1391 if (PyErr_CheckSignals() != 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001392 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001393 if (result)
1394 continue;
1395 /* XXX It's not *quite* certain that this is
1396 thread-safe, but it seems *rather* safe as long as
1397 no two threads call mainloop() simultaneously. */
1398 Py_BEGIN_ALLOW_THREADS
Guido van Rossum54e20911997-09-28 05:52:41 +00001399 result = PyTcl_WaitUntilEvent();
Guido van Rossum35d43371997-08-02 00:09:09 +00001400 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001401#else
1402 result = Tcl_DoOneEvent(0);
1403#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001404 if (PyErr_CheckSignals() != 0)
1405 return NULL;
1406 if (result < 0)
1407 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001408 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001409 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001410
Barry Warsawfa701a81997-01-16 00:15:11 +00001411 if (errorInCmd) {
1412 errorInCmd = 0;
1413 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1414 excInCmd = valInCmd = trbInCmd = NULL;
1415 return NULL;
1416 }
1417 Py_INCREF(Py_None);
1418 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001419}
1420
1421static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001422Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001423 PyObject *self;
1424 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001425{
Guido van Rossum35d43371997-08-02 00:09:09 +00001426 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001427 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001428
Barry Warsawfa701a81997-01-16 00:15:11 +00001429 if (!PyArg_ParseTuple(args, "|i", &flags))
1430 return NULL;
1431
Guido van Rossum35d43371997-08-02 00:09:09 +00001432 rv = Tcl_DoOneEvent(flags);
Barry Warsawfa701a81997-01-16 00:15:11 +00001433 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001434}
1435
1436static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001437Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001438 PyObject *self;
1439 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001440{
1441
Guido van Rossum35d43371997-08-02 00:09:09 +00001442 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001443 return NULL;
1444
1445 quitMainLoop = 1;
1446 Py_INCREF(Py_None);
1447 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001448}
1449
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001450static PyObject *
1451Tkapp_InterpAddr(self, args)
1452 PyObject *self;
1453 PyObject *args;
1454{
1455
1456 if (!PyArg_ParseTuple(args, ""))
1457 return NULL;
1458
1459 return PyInt_FromLong((long)Tkapp_Interp(self));
1460}
1461
Barry Warsawfa701a81997-01-16 00:15:11 +00001462
1463
Guido van Rossum18468821994-06-20 07:49:28 +00001464/**** Tkapp Method List ****/
1465
1466static PyMethodDef Tkapp_methods[] =
1467{
Guido van Rossum35d43371997-08-02 00:09:09 +00001468 {"call", Tkapp_Call, 0},
1469 {"globalcall", Tkapp_GlobalCall, 0},
1470 {"eval", Tkapp_Eval, 1},
1471 {"globaleval", Tkapp_GlobalEval, 1},
1472 {"evalfile", Tkapp_EvalFile, 1},
1473 {"record", Tkapp_Record, 1},
1474 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1475 {"setvar", Tkapp_SetVar, 1},
1476 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1477 {"getvar", Tkapp_GetVar, 1},
1478 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1479 {"unsetvar", Tkapp_UnsetVar, 1},
1480 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1481 {"getint", Tkapp_GetInt, 1},
1482 {"getdouble", Tkapp_GetDouble, 1},
1483 {"getboolean", Tkapp_GetBoolean, 1},
1484 {"exprstring", Tkapp_ExprString, 1},
1485 {"exprlong", Tkapp_ExprLong, 1},
1486 {"exprdouble", Tkapp_ExprDouble, 1},
1487 {"exprboolean", Tkapp_ExprBoolean, 1},
1488 {"splitlist", Tkapp_SplitList, 1},
1489 {"split", Tkapp_Split, 1},
1490 {"merge", Tkapp_Merge, 0},
1491 {"createcommand", Tkapp_CreateCommand, 1},
1492 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001493#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001494 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1495 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001496#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001497 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001498 {"mainloop", Tkapp_MainLoop, 1},
1499 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001500 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001501 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001502 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001503};
1504
Barry Warsawfa701a81997-01-16 00:15:11 +00001505
1506
Guido van Rossum18468821994-06-20 07:49:28 +00001507/**** Tkapp Type Methods ****/
1508
1509static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001510Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001511 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001512{
Guido van Rossum35d43371997-08-02 00:09:09 +00001513 Tcl_DeleteInterp(Tkapp_Interp(self));
1514 PyMem_DEL(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001515}
1516
1517static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001518Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001519 PyObject *self;
1520 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001521{
Guido van Rossum35d43371997-08-02 00:09:09 +00001522 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001523}
1524
1525static PyTypeObject Tkapp_Type =
1526{
Guido van Rossum35d43371997-08-02 00:09:09 +00001527 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001528 0, /*ob_size */
1529 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001530 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001531 0, /*tp_itemsize */
1532 Tkapp_Dealloc, /*tp_dealloc */
1533 0, /*tp_print */
1534 Tkapp_GetAttr, /*tp_getattr */
1535 0, /*tp_setattr */
1536 0, /*tp_compare */
1537 0, /*tp_repr */
1538 0, /*tp_as_number */
1539 0, /*tp_as_sequence */
1540 0, /*tp_as_mapping */
1541 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001542};
1543
Barry Warsawfa701a81997-01-16 00:15:11 +00001544
1545
Guido van Rossum18468821994-06-20 07:49:28 +00001546/**** Tkinter Module ****/
1547
1548static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001549Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001550 PyObject *self;
1551 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001552{
Barry Warsawfa701a81997-01-16 00:15:11 +00001553 char *screenName = NULL;
1554 char *baseName = NULL;
1555 char *className = NULL;
1556 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001557
Guido van Rossum35d43371997-08-02 00:09:09 +00001558 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001559 if (baseName != NULL)
1560 baseName++;
1561 else
1562 baseName = Py_GetProgramName();
1563 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001564
Barry Warsawfa701a81997-01-16 00:15:11 +00001565 if (!PyArg_ParseTuple(args, "|zssi",
1566 &screenName, &baseName, &className,
1567 &interactive))
1568 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001569
Barry Warsawfa701a81997-01-16 00:15:11 +00001570 return (PyObject *) Tkapp_New(screenName, baseName, className,
1571 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001572}
1573
1574static PyMethodDef moduleMethods[] =
1575{
Barry Warsawfa701a81997-01-16 00:15:11 +00001576 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001577#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001578 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1579 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001580#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001581 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001582 {"mainloop", Tkapp_MainLoop, 1},
1583 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001584 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001585 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001586};
1587
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001588static PyInterpreterState *event_interp = NULL;
1589
Guido van Rossum18468821994-06-20 07:49:28 +00001590static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001591EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00001592{
Guido van Rossuma59406a1997-10-10 17:39:19 +00001593 PyThreadState *tstate, *save_tstate;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001594
1595 if (Tk_GetNumMainWindows() == 0)
1596 return 0;
1597 if (event_interp == NULL)
1598 return 0;
1599 tstate = PyThreadState_New(event_interp);
Guido van Rossuma59406a1997-10-10 17:39:19 +00001600 save_tstate = PyThreadState_Swap(NULL);
1601 PyEval_RestoreThread(tstate);
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001602 if (!errorInCmd)
1603 Tcl_DoOneEvent(TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001604 if (errorInCmd) {
1605 errorInCmd = 0;
1606 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1607 excInCmd = valInCmd = trbInCmd = NULL;
1608 PyErr_Print();
1609 }
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001610 PyThreadState_Clear(tstate);
Guido van Rossuma59406a1997-10-10 17:39:19 +00001611 PyEval_SaveThread();
1612 PyThreadState_Swap(save_tstate);
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001613 PyThreadState_Delete(tstate);
Barry Warsawfa701a81997-01-16 00:15:11 +00001614 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001615}
Guido van Rossum18468821994-06-20 07:49:28 +00001616
Barry Warsawfa701a81997-01-16 00:15:11 +00001617
1618/* all errors will be checked in one fell swoop in init_tkinter() */
1619static void
1620ins_long(d, name, val)
1621 PyObject *d;
1622 char *name;
1623 long val;
1624{
1625 PyObject *v = PyInt_FromLong(val);
1626 if (v) {
1627 PyDict_SetItemString(d, name, v);
1628 Py_DECREF(v);
1629 }
1630}
1631static void
1632ins_string(d, name, val)
1633 PyObject *d;
1634 char *name;
1635 char *val;
1636{
1637 PyObject *v = PyString_FromString(val);
1638 if (v) {
1639 PyDict_SetItemString(d, name, v);
1640 Py_DECREF(v);
1641 }
1642}
1643
1644
Guido van Rossum18468821994-06-20 07:49:28 +00001645void
Guido van Rossum35d43371997-08-02 00:09:09 +00001646init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00001647{
Barry Warsawfa701a81997-01-16 00:15:11 +00001648 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001649
Barry Warsawfa701a81997-01-16 00:15:11 +00001650 Tkapp_Type.ob_type = &PyType_Type;
1651 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossumae92f011996-08-21 19:03:36 +00001652
Barry Warsawfa701a81997-01-16 00:15:11 +00001653 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001654
Barry Warsawfa701a81997-01-16 00:15:11 +00001655 d = PyModule_GetDict(m);
1656 Tkinter_TclError = Py_BuildValue("s", "TclError");
1657 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00001658
Guido van Rossum35d43371997-08-02 00:09:09 +00001659 ins_long(d, "READABLE", TCL_READABLE);
1660 ins_long(d, "WRITABLE", TCL_WRITABLE);
1661 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
1662 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
1663 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
1664 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
1665 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
1666 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
1667 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001668 ins_string(d, "TK_VERSION", TK_VERSION);
1669 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00001670
Guido van Rossum83551bf1997-09-13 00:44:23 +00001671 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
1672 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
1673
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001674 if (PyOS_InputHook == NULL) {
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001675 event_interp = PyThreadState_Get()->interp;
Guido van Rossum44620641997-08-11 18:57:29 +00001676 PyOS_InputHook = EventHook;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001677 }
Guido van Rossum18468821994-06-20 07:49:28 +00001678
Barry Warsawfa701a81997-01-16 00:15:11 +00001679 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001680 return;
1681
Guido van Rossum26216371998-04-20 18:47:52 +00001682#if TKMAJORMINOR >= 8000
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001683 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00001684#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001685
Jack Jansen34cc5c31995-10-31 16:15:12 +00001686#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001687 /*
1688 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
1689 ** Most of the initializations in that routine (toolbox init calls and
1690 ** such) have already been done for us, so we only need these.
1691 */
1692#if TKMAJORMINOR >= 8000
1693 tcl_macQdPtr = &qd;
1694#endif
1695
1696 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00001697#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00001698 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001699#endif /* GENERATINGCFM */
1700#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001701}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001702
Guido van Rossumec22c921996-02-25 04:50:29 +00001703
Barry Warsawfa701a81997-01-16 00:15:11 +00001704
Guido van Rossum9722ad81995-09-22 23:49:28 +00001705#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001706
1707/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001708** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001709*/
1710
Guido van Rossum9722ad81995-09-22 23:49:28 +00001711void
1712panic(char * format, ...)
1713{
Barry Warsawfa701a81997-01-16 00:15:11 +00001714 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001715
Barry Warsawfa701a81997-01-16 00:15:11 +00001716 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001717
Barry Warsawfa701a81997-01-16 00:15:11 +00001718 vfprintf(stderr, format, varg);
1719 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001720
Barry Warsawfa701a81997-01-16 00:15:11 +00001721 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001722
Barry Warsawfa701a81997-01-16 00:15:11 +00001723 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00001724}
Jack Jansen40b546d1995-11-14 10:34:45 +00001725
Guido van Rossumec22c921996-02-25 04:50:29 +00001726/*
1727** Pass events to SIOUX before passing them to Tk.
1728*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001729
Guido van Rossumec22c921996-02-25 04:50:29 +00001730static int
1731PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00001732 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001733{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00001734 WindowPtr frontwin;
1735 /*
1736 ** Sioux eats too many events, so we don't pass it everything.
1737 ** We always pass update events to Sioux, and we only pass other events if
1738 ** the Sioux window is frontmost. This means that Tk menus don't work
1739 ** in that case, but at least we can scroll the sioux window.
1740 ** Note that the SIOUXIsAppWindow() routine we use here is not really
1741 ** part of the external interface of Sioux...
1742 */
1743 frontwin = FrontWindow();
1744 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
1745 if (SIOUXHandleOneEvent(eventPtr))
1746 return 0; /* Nothing happened to the Tcl event queue */
1747 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001748 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001749}
1750
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001751#if defined(USE_GUSI) && TKMAJORMINOR < 8000
Guido van Rossum290283b1997-06-02 22:16:43 +00001752/*
1753 * For Python we have to override this routine (from TclMacNotify),
1754 * since we use GUSI for our sockets, not Tcl streams. Hence, we have
1755 * to use GUSI select to see whether our socket is ready. Note that
1756 * createfilehandler (above) sets the type to TCL_UNIX_FD for our
1757 * files and sockets.
1758 *
1759 * NOTE: this code was lifted from Tcl 7.6, it may need to be modified
1760 * for other versions. */
1761
1762int
1763Tcl_FileReady(file, mask)
1764 Tcl_File file; /* File handle for a stream. */
1765 int mask; /* OR'ed combination of TCL_READABLE,
1766 * TCL_WRITABLE, and TCL_EXCEPTION:
1767 * indicates conditions caller cares about. */
1768{
1769 int type;
1770 int fd;
1771
1772 fd = (int) Tcl_GetFileInfo(file, &type);
1773
1774 if (type == TCL_MAC_SOCKET) {
1775 return TclMacSocketReady(file, mask);
1776 } else if (type == TCL_MAC_FILE) {
1777 /*
1778 * Under the Macintosh, files are always ready, so we just
1779 * return the mask that was passed in.
1780 */
1781
1782 return mask;
1783 } else if (type == TCL_UNIX_FD) {
1784 fd_set readset, writeset, excset;
1785 struct timeval tv;
1786
1787 FD_ZERO(&readset);
1788 FD_ZERO(&writeset);
1789 FD_ZERO(&excset);
1790
1791 if ( mask & TCL_READABLE ) FD_SET(fd, &readset);
1792 if ( mask & TCL_WRITABLE ) FD_SET(fd, &writeset);
1793 if ( mask & TCL_EXCEPTION ) FD_SET(fd, &excset);
1794
1795 tv.tv_sec = tv.tv_usec = 0;
1796 if ( select(fd+1, &readset, &writeset, &excset, &tv) <= 0 )
1797 return 0;
1798
1799 mask = 0;
1800 if ( FD_ISSET(fd, &readset) ) mask |= TCL_READABLE;
1801 if ( FD_ISSET(fd, &writeset) ) mask |= TCL_WRITABLE;
1802 if ( FD_ISSET(fd, &excset) ) mask |= TCL_EXCEPTION;
1803
1804 return mask;
1805 }
1806
1807 return 0;
1808}
1809#endif /* USE_GUSI */
1810
Guido van Rossumec22c921996-02-25 04:50:29 +00001811#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001812
1813/*
1814** Additional Mac specific code for dealing with shared libraries.
1815*/
1816
1817#include <Resources.h>
1818#include <CodeFragments.h>
1819
1820static int loaded_from_shlib = 0;
1821static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001822
Jack Jansen34cc5c31995-10-31 16:15:12 +00001823/*
1824** If this module is dynamically loaded the following routine should
1825** be the init routine. It takes care of adding the shared library to
1826** the resource-file chain, so that the tk routines can find their
1827** resources.
1828*/
1829OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001830init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00001831{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00001832 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00001833 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001834 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001835 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1836 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001837 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001838 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1839 loaded_from_shlib = 1;
1840 }
1841 return noErr;
1842}
1843
1844/*
1845** Insert the library resources into the search path. Put them after
1846** the resources from the application. Again, we ignore errors.
1847*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001848static
Jack Jansen34cc5c31995-10-31 16:15:12 +00001849mac_addlibresources()
1850{
1851 if ( !loaded_from_shlib )
1852 return;
1853 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1854}
1855
Guido van Rossumec22c921996-02-25 04:50:29 +00001856#endif /* GENERATINGCFM */
1857#endif /* macintosh */