blob: d6506b4173247d13931fb602e3382a4105a9f1a0 [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:
38 This should work with any version from Tcl 4.0 / Tck 7.4.
39 Do not use older versions.
40
41 Mac and Windows:
42 Use Tcl 4.1p1 / Tk 7.5p1 or possibly newer.
43 It does not seem to work reliably with the original 4.1/7.5
44 release. (4.0/7.4 were never released for these platforms.)
45*/
46
Guido van Rossum9722ad81995-09-22 23:49:28 +000047#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000048#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000049
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000050#ifdef macintosh
51#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000052#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000053#endif
54
Guido van Rossum18468821994-06-20 07:49:28 +000055#include <tcl.h>
56#include <tk.h>
57
Guido van Rossum32aa1a71996-07-31 19:51:15 +000058extern char *Py_GetProgramName ();
Guido van Rossumd308e2b1994-07-07 09:25:12 +000059
Guido van Rossum9722ad81995-09-22 23:49:28 +000060/* Internal declarations from tkInt.h. */
61#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
62extern int Tk_GetNumMainWindows();
63#else
Guido van Rossum18468821994-06-20 07:49:28 +000064extern int tk_NumMainWindows;
Guido van Rossum9722ad81995-09-22 23:49:28 +000065#define Tk_GetNumMainWindows() (tk_NumMainWindows)
Guido van Rossumdfd428d1996-02-25 04:46:40 +000066#define NEED_TKCREATEMAINWINDOW 1
Guido van Rossum9722ad81995-09-22 23:49:28 +000067#endif
68
69#if TK_MAJOR_VERSION < 4
Guido van Rossumd308e2b1994-07-07 09:25:12 +000070extern struct { Tk_Window win; } *tkMainWindowList;
Guido van Rossum9722ad81995-09-22 23:49:28 +000071#endif
Guido van Rossum18468821994-06-20 07:49:28 +000072
Guido van Rossumec22c921996-02-25 04:50:29 +000073#ifdef macintosh
74
75/*
76** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +000077** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +000078*/
79
Guido van Rossum7ffa7611996-08-13 21:10:16 +000080/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +000081#define FREECAST (char *)
82
Guido van Rossumec22c921996-02-25 04:50:29 +000083#include <Events.h> /* For EventRecord */
84
85typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
86void TclMacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
87int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
88
89staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
90
91#endif /* macintosh */
92
Guido van Rossum97867b21996-08-08 19:09:53 +000093#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +000094#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +000095#endif
96
Guido van Rossum18468821994-06-20 07:49:28 +000097/**** Tkapp Object Declaration ****/
98
99staticforward PyTypeObject Tkapp_Type;
100
101typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +0000102{
103 PyObject_HEAD
104 Tcl_Interp *interp;
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000105#ifdef NEED_TKCREATEMAINWINDOW
Barry Warsawfa701a81997-01-16 00:15:11 +0000106 Tk_Window tkwin;
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000107#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000108}
Guido van Rossum18468821994-06-20 07:49:28 +0000109TkappObject;
110
111#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000112#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +0000113#define Tkapp_Tkwin(v) (((TkappObject *) (v))->tkwin)
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000114#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000115#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
116#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
117
118#define DEBUG_REFCNT(v) (printf ("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000119(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000120
Barry Warsawfa701a81997-01-16 00:15:11 +0000121
122
Guido van Rossum18468821994-06-20 07:49:28 +0000123/**** Error Handling ****/
124
125static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000126static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000127static int errorInCmd = 0;
128static PyObject *excInCmd;
129static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000130static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000131
Barry Warsawfa701a81997-01-16 00:15:11 +0000132
133
Guido van Rossum18468821994-06-20 07:49:28 +0000134static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000135Tkinter_Error(v)
136 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000137{
Barry Warsawfa701a81997-01-16 00:15:11 +0000138 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
139 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000140}
141
Barry Warsawfa701a81997-01-16 00:15:11 +0000142
Guido van Rossum18468821994-06-20 07:49:28 +0000143int
Barry Warsawfa701a81997-01-16 00:15:11 +0000144PythonCmd_Error(interp)
145 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000146{
Barry Warsawfa701a81997-01-16 00:15:11 +0000147 errorInCmd = 1;
148 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
149 return TCL_ERROR;
Guido van Rossum18468821994-06-20 07:49:28 +0000150}
151
Barry Warsawfa701a81997-01-16 00:15:11 +0000152
153
Guido van Rossum18468821994-06-20 07:49:28 +0000154/**** Utils ****/
Guido van Rossum18468821994-06-20 07:49:28 +0000155static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000156AsString(value, tmp)
157 PyObject *value;
158 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000159{
Barry Warsawfa701a81997-01-16 00:15:11 +0000160 if (PyString_Check (value))
161 return PyString_AsString (value);
162 else {
163 PyObject *v = PyObject_Str(value);
164 PyList_Append(tmp, v);
165 Py_DECREF(v);
166 return PyString_AsString(v);
167 }
Guido van Rossum18468821994-06-20 07:49:28 +0000168}
169
Barry Warsawfa701a81997-01-16 00:15:11 +0000170
171
Guido van Rossum18468821994-06-20 07:49:28 +0000172#define ARGSZ 64
173
174static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000175Merge(args)
176 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000177{
Barry Warsawfa701a81997-01-16 00:15:11 +0000178 PyObject *tmp = NULL;
179 char *argvStore[ARGSZ];
180 char **argv = NULL;
181 int fvStore[ARGSZ];
182 int *fv = NULL;
183 int argc = 0, i;
184 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000185
Barry Warsawfa701a81997-01-16 00:15:11 +0000186 if (!(tmp = PyList_New(0)))
187 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000188
Barry Warsawfa701a81997-01-16 00:15:11 +0000189 argv = argvStore;
190 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000191
Barry Warsawfa701a81997-01-16 00:15:11 +0000192 if (args == NULL)
193 argc = 0;
194
195 else if (!PyTuple_Check(args)) {
196 argc = 1;
197 fv[0] = 0;
198 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000199 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000200 else {
201 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000202
Barry Warsawfa701a81997-01-16 00:15:11 +0000203 if (argc > ARGSZ) {
204 argv = (char **)ckalloc(argc * sizeof (char *));
205 fv = (int *)ckalloc(argc * sizeof (int));
206 if (argv == NULL || fv == NULL) {
207 PyErr_NoMemory();
208 goto finally;
209 }
210 }
211
212 for (i = 0; i < argc; i++) {
213 PyObject *v = PyTuple_GetItem(args, i);
214 if (PyTuple_Check(v)) {
215 fv[i] = 1;
216 if (!(argv[i] = Merge(v)))
217 goto finally;
218 }
219 else if (v == Py_None) {
220 argc = i;
221 break;
222 }
223 else {
224 fv[i] = 0;
225 argv[i] = AsString(v, tmp);
226 }
227 }
Guido van Rossum18468821994-06-20 07:49:28 +0000228 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000229 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000230
Barry Warsawfa701a81997-01-16 00:15:11 +0000231 finally:
232 for (i = 0; i < argc; i++)
233 if (fv[i]) {
234 ckfree(argv[i]);
235 }
236 if (argv != argvStore)
237 ckfree(FREECAST argv);
238 if (fv != fvStore)
239 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000240
Barry Warsawfa701a81997-01-16 00:15:11 +0000241 Py_DECREF(tmp);
242 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000243}
244
Barry Warsawfa701a81997-01-16 00:15:11 +0000245
246
Guido van Rossum18468821994-06-20 07:49:28 +0000247static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000248Split(self, list)
249 PyObject *self;
250 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000251{
Barry Warsawfa701a81997-01-16 00:15:11 +0000252 int argc;
253 char **argv;
254 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000255
Barry Warsawfa701a81997-01-16 00:15:11 +0000256 if (list == NULL) {
257 Py_INCREF(Py_None);
258 return Py_None;
259 }
Guido van Rossum18468821994-06-20 07:49:28 +0000260
Barry Warsawfa701a81997-01-16 00:15:11 +0000261 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
262 {
263 /* Not a list.
264 * Could be a quoted string containing funnies, e.g. {"}.
265 * Return the string itself.
266 */
267 PyErr_Clear();
268 return PyString_FromString(list);
269 }
Guido van Rossum18468821994-06-20 07:49:28 +0000270
Barry Warsawfa701a81997-01-16 00:15:11 +0000271 if (argc == 0)
272 v = PyString_FromString("");
273 else if (argc == 1)
274 v = PyString_FromString(argv[0]);
275 else if ((v = PyTuple_New (argc)) != NULL) {
276 int i;
277 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000278
Barry Warsawfa701a81997-01-16 00:15:11 +0000279 for (i = 0; i < argc; i++) {
280 if ((w = Split(self, argv[i])) == NULL) {
281 Py_DECREF(v);
282 v = NULL;
283 break;
284 }
285 PyTuple_SetItem(v, i, w);
286 }
287 }
288 ckfree (FREECAST argv);
289 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000290}
291
Barry Warsawfa701a81997-01-16 00:15:11 +0000292
293
Guido van Rossum18468821994-06-20 07:49:28 +0000294/**** Tkapp Object ****/
295
296#ifndef WITH_APPINIT
297int
298Tcl_AppInit (interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000299 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000300{
Barry Warsawfa701a81997-01-16 00:15:11 +0000301 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000302
Barry Warsawfa701a81997-01-16 00:15:11 +0000303 main = Tk_MainWindow(interp);
304 if (Tcl_Init(interp) == TCL_ERROR) {
305 fprintf(stderr, "Tcl_Init error: %s\n", interp->result);
306 return TCL_ERROR;
307 }
308 if (Tk_Init(interp) == TCL_ERROR) {
309 fprintf(stderr, "Tk_Init error: %s\n", interp->result);
310 return TCL_ERROR;
311 }
312 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000313}
314#endif /* !WITH_APPINIT */
315
Guido van Rossum18468821994-06-20 07:49:28 +0000316
Barry Warsawfa701a81997-01-16 00:15:11 +0000317
318
319/* Initialize the Tk application; see the `main' function in
320 * `tkMain.c'.
321 */
322static TkappObject *
323Tkapp_New(screenName, baseName, className, interactive)
324 char *screenName;
325 char *baseName;
326 char *className;
327 int interactive;
328{
329 TkappObject *v;
330 char *argv0;
331
332 v = PyObject_NEW(TkappObject, &Tkapp_Type);
333 if (v == NULL)
334 return NULL;
335
336 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000337
338#ifdef NEED_TKCREATEMAINWINDOW
Barry Warsawfa701a81997-01-16 00:15:11 +0000339 v->tkwin = Tk_CreateMainWindow(v->interp, screenName,
340 baseName, className);
341 if (v->tkwin == NULL)
342 return (TkappObject *)Tkinter_Error((PyObject *) v);
Guido van Rossum18468821994-06-20 07:49:28 +0000343
Barry Warsawfa701a81997-01-16 00:15:11 +0000344 Tk_GeometryRequest(v->tkwin, 200, 200);
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000345#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000346
Barry Warsawfa701a81997-01-16 00:15:11 +0000347 if (screenName != NULL)
348 Tcl_SetVar2(v->interp, "env", "DISPLAY",
349 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000350
Barry Warsawfa701a81997-01-16 00:15:11 +0000351 if (interactive)
352 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
353 else
354 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000355
Barry Warsawfa701a81997-01-16 00:15:11 +0000356 /* This is used to get the application class for Tk 4.1 and up */
357 argv0 = (char*)ckalloc(strlen(className) + 1);
358 if (!argv0) {
359 PyErr_NoMemory();
360 Py_DECREF(v);
361 return NULL;
362 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000363
Barry Warsawfa701a81997-01-16 00:15:11 +0000364 strcpy(argv0, className);
365 if (isupper(argv0[0]))
366 argv0[0] = tolower(argv0[0]);
367 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
368 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000369
Barry Warsawfa701a81997-01-16 00:15:11 +0000370 if (Tcl_AppInit(v->interp) != TCL_OK)
371 return (TkappObject *)Tkinter_Error(v);
372
373 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000374}
375
Barry Warsawfa701a81997-01-16 00:15:11 +0000376
377
Guido van Rossum18468821994-06-20 07:49:28 +0000378/** Tcl Eval **/
379
380static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000381Tkapp_Call(self, args)
382 PyObject *self;
383 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000384{
Barry Warsawfa701a81997-01-16 00:15:11 +0000385 char *cmd = Merge(args);
386 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000387
Barry Warsawfa701a81997-01-16 00:15:11 +0000388 if (!cmd)
389 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000390
Barry Warsawfa701a81997-01-16 00:15:11 +0000391 else if (Tcl_Eval(Tkapp_Interp(self), cmd) == TCL_ERROR)
392 res = Tkinter_Error(self);
393
394 else
395 res = PyString_FromString(Tkapp_Result(self));
396
397 if (cmd)
398 ckfree(cmd);
399
400 return res;
401}
402
403
404static PyObject *
405Tkapp_GlobalCall(self, args)
406 PyObject *self;
407 PyObject *args;
408{
409 char *cmd = Merge(args);
410 PyObject *res = NULL;
411
412
413 if (!cmd)
414 PyErr_SetString(Tkinter_TclError, "merge failed");
415
416 else if (Tcl_GlobalEval(Tkapp_Interp(self), cmd) == TCL_ERROR)
417 res = Tkinter_Error(self);
418 else
419 res = PyString_FromString(Tkapp_Result(self));
420
421 if (cmd)
422 ckfree(cmd);
423
424 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000425}
426
427static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000428Tkapp_Eval(self, args)
429 PyObject *self;
430 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000431{
Barry Warsawfa701a81997-01-16 00:15:11 +0000432 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000433
Barry Warsawfa701a81997-01-16 00:15:11 +0000434 if (!PyArg_Parse (args, "s", &script))
435 return NULL;
436
437 if (Tcl_Eval(Tkapp_Interp(self), script) == TCL_ERROR)
438 return Tkinter_Error(self);
439
440 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000441}
442
443static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000444Tkapp_GlobalEval(self, args)
445 PyObject *self;
446 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000447{
Barry Warsawfa701a81997-01-16 00:15:11 +0000448 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000449
Barry Warsawfa701a81997-01-16 00:15:11 +0000450 if (!PyArg_Parse(args, "s", &script))
451 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000452
Barry Warsawfa701a81997-01-16 00:15:11 +0000453 if (Tcl_GlobalEval(Tkapp_Interp(self), script) == TCL_ERROR)
454 return Tkinter_Error (self);
Guido van Rossum18468821994-06-20 07:49:28 +0000455
Barry Warsawfa701a81997-01-16 00:15:11 +0000456 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000457}
458
459static PyObject *
460Tkapp_EvalFile (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000461 PyObject *self;
462 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000463{
Barry Warsawfa701a81997-01-16 00:15:11 +0000464 char *fileName;
Guido van Rossum18468821994-06-20 07:49:28 +0000465
Barry Warsawfa701a81997-01-16 00:15:11 +0000466 if (!PyArg_Parse(args, "s", &fileName))
467 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000468
Barry Warsawfa701a81997-01-16 00:15:11 +0000469 if (Tcl_EvalFile(Tkapp_Interp(self), fileName) == TCL_ERROR)
470 return Tkinter_Error (self);
Guido van Rossum18468821994-06-20 07:49:28 +0000471
Barry Warsawfa701a81997-01-16 00:15:11 +0000472 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000473}
474
475static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000476Tkapp_Record(self, args)
477 PyObject *self;
478 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000479{
Barry Warsawfa701a81997-01-16 00:15:11 +0000480 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000481
Barry Warsawfa701a81997-01-16 00:15:11 +0000482 if (!PyArg_Parse(args, "s", &script))
483 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000484
Barry Warsawfa701a81997-01-16 00:15:11 +0000485 if (TCL_ERROR == Tcl_RecordAndEval(Tkapp_Interp(self),
486 script, TCL_NO_EVAL))
487 return Tkinter_Error (self);
Guido van Rossum18468821994-06-20 07:49:28 +0000488
Barry Warsawfa701a81997-01-16 00:15:11 +0000489 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000490}
491
492static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000493Tkapp_AddErrorInfo(self, args)
494 PyObject *self;
495 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000496{
Barry Warsawfa701a81997-01-16 00:15:11 +0000497 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000498
Barry Warsawfa701a81997-01-16 00:15:11 +0000499 if (!PyArg_Parse (args, "s", &msg))
500 return NULL;
501 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum18468821994-06-20 07:49:28 +0000502
Barry Warsawfa701a81997-01-16 00:15:11 +0000503 Py_INCREF(Py_None);
504 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000505}
506
Barry Warsawfa701a81997-01-16 00:15:11 +0000507
508
Guido van Rossum18468821994-06-20 07:49:28 +0000509/** Tcl Variable **/
510
511static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000512SetVar(self, args, flags)
513 PyObject *self;
514 PyObject *args;
515 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000516{
Barry Warsawfa701a81997-01-16 00:15:11 +0000517 char *name1, *name2, *ok;
518 PyObject *newValue;
519 PyObject *tmp = PyList_New(0);
Guido van Rossum18468821994-06-20 07:49:28 +0000520
Barry Warsawfa701a81997-01-16 00:15:11 +0000521 if (!tmp)
522 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000523
Barry Warsawfa701a81997-01-16 00:15:11 +0000524 if (PyArg_Parse(args, "(sO)", &name1, &newValue))
525 /* XXX Merge? */
526 ok = Tcl_SetVar(Tkapp_Interp (self), name1,
527 AsString (newValue, tmp), flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000528
Barry Warsawfa701a81997-01-16 00:15:11 +0000529 else if (PyArg_Parse(args, "(ssO)", &name1, &name2, &newValue))
530 ok = Tcl_SetVar2(Tkapp_Interp (self), name1, name2,
531 AsString (newValue, tmp), flags);
532 else {
533 Py_DECREF (tmp);
534 return NULL;
535 }
536 Py_DECREF (tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000537
Barry Warsawfa701a81997-01-16 00:15:11 +0000538 if (!ok)
539 return Tkinter_Error(self);
540
541 Py_INCREF(Py_None);
542 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000543}
544
545static PyObject *
546Tkapp_SetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000547 PyObject *self;
548 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000549{
Barry Warsawfa701a81997-01-16 00:15:11 +0000550 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000551}
552
553static PyObject *
554Tkapp_GlobalSetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000555 PyObject *self;
556 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000557{
Barry Warsawfa701a81997-01-16 00:15:11 +0000558 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000559}
560
Barry Warsawfa701a81997-01-16 00:15:11 +0000561
562
Guido van Rossum18468821994-06-20 07:49:28 +0000563static PyObject *
564GetVar (self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000565 PyObject *self;
566 PyObject *args;
567 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000568{
Barry Warsawfa701a81997-01-16 00:15:11 +0000569 char *name1, *name2, *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000570
Barry Warsawfa701a81997-01-16 00:15:11 +0000571 if (PyArg_Parse(args, "s", &name1))
572 s = Tcl_GetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000573
Barry Warsawfa701a81997-01-16 00:15:11 +0000574 else if (PyArg_Parse(args, "(ss)", &name1, &name2))
575 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
576 else
577 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000578
Barry Warsawfa701a81997-01-16 00:15:11 +0000579 if (s == NULL)
580 return Tkinter_Error(self);
581
582 return PyString_FromString (s);
Guido van Rossum18468821994-06-20 07:49:28 +0000583}
584
585static PyObject *
586Tkapp_GetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000587 PyObject *self;
588 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000589{
Barry Warsawfa701a81997-01-16 00:15:11 +0000590 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000591}
592
593static PyObject *
594Tkapp_GlobalGetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000595 PyObject *self;
596 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000597{
Barry Warsawfa701a81997-01-16 00:15:11 +0000598 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000599}
600
Barry Warsawfa701a81997-01-16 00:15:11 +0000601
602
Guido van Rossum18468821994-06-20 07:49:28 +0000603static PyObject *
604UnsetVar (self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000605 PyObject *self;
606 PyObject *args;
607 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000608{
Barry Warsawfa701a81997-01-16 00:15:11 +0000609 char *name1, *name2;
610 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000611
Barry Warsawfa701a81997-01-16 00:15:11 +0000612 if (PyArg_Parse(args, "s", &name1))
613 code = Tcl_UnsetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000614
Barry Warsawfa701a81997-01-16 00:15:11 +0000615 else if (PyArg_Parse(args, "(ss)", &name1, &name2))
616 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
617 else
618 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000619
Barry Warsawfa701a81997-01-16 00:15:11 +0000620 if (code == TCL_ERROR)
621 return Tkinter_Error (self);
622
623 Py_INCREF(Py_None);
624 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000625}
626
627static PyObject *
628Tkapp_UnsetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000629 PyObject *self;
630 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000631{
Barry Warsawfa701a81997-01-16 00:15:11 +0000632 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000633}
634
635static PyObject *
636Tkapp_GlobalUnsetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000637 PyObject *self;
638 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000639{
Barry Warsawfa701a81997-01-16 00:15:11 +0000640 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000641}
642
Barry Warsawfa701a81997-01-16 00:15:11 +0000643
644
Guido van Rossum18468821994-06-20 07:49:28 +0000645/** Tcl to Python **/
646
647static PyObject *
648Tkapp_GetInt (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000649 PyObject *self;
650 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000651{
Barry Warsawfa701a81997-01-16 00:15:11 +0000652 char *s;
653 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000654
Barry Warsawfa701a81997-01-16 00:15:11 +0000655 if (!PyArg_Parse(args, "s", &s))
656 return NULL;
657 if (Tcl_GetInt(Tkapp_Interp (self), s, &v) == TCL_ERROR)
658 return Tkinter_Error(self);
659 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000660}
661
662static PyObject *
663Tkapp_GetDouble (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 char *s;
668 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000669
Barry Warsawfa701a81997-01-16 00:15:11 +0000670 if (!PyArg_Parse(args, "s", &s))
671 return NULL;
672 if (Tcl_GetDouble(Tkapp_Interp (self), s, &v) == TCL_ERROR)
673 return Tkinter_Error(self);
674 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000675}
676
677static PyObject *
678Tkapp_GetBoolean (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000679 PyObject *self;
680 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000681{
Barry Warsawfa701a81997-01-16 00:15:11 +0000682 char *s;
683 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000684
Barry Warsawfa701a81997-01-16 00:15:11 +0000685 if (!PyArg_Parse(args, "s", &s))
686 return NULL;
687 if (Tcl_GetBoolean(Tkapp_Interp (self), s, &v) == TCL_ERROR)
688 return Tkinter_Error (self);
689 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000690}
691
692static PyObject *
693Tkapp_ExprString (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000694 PyObject *self;
695 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000696{
Barry Warsawfa701a81997-01-16 00:15:11 +0000697 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000698
Barry Warsawfa701a81997-01-16 00:15:11 +0000699 if (!PyArg_Parse(args, "s", &s))
700 return NULL;
701 if (Tcl_ExprString (Tkapp_Interp (self), s) == TCL_ERROR)
702 return Tkinter_Error(self);
703 return Py_BuildValue("s", Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000704}
705
706static PyObject *
707Tkapp_ExprLong (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000708 PyObject *self;
709 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000710{
Barry Warsawfa701a81997-01-16 00:15:11 +0000711 char *s;
712 long v;
Guido van Rossum18468821994-06-20 07:49:28 +0000713
Barry Warsawfa701a81997-01-16 00:15:11 +0000714 if (!PyArg_Parse(args, "s", &s))
715 return NULL;
716 if (Tcl_ExprLong(Tkapp_Interp(self), s, &v) == TCL_ERROR)
717 return Tkinter_Error(self);
718 return Py_BuildValue("l", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000719}
720
721static PyObject *
722Tkapp_ExprDouble (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000723 PyObject *self;
724 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000725{
Barry Warsawfa701a81997-01-16 00:15:11 +0000726 char *s;
727 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000728 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000729
Barry Warsawfa701a81997-01-16 00:15:11 +0000730 if (!PyArg_Parse(args, "s", &s))
731 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000732 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
733 retval = Tcl_ExprDouble (Tkapp_Interp (self), s, &v);
Guido van Rossum45b83911997-03-14 04:32:50 +0000734 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000735 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000736 return Tkinter_Error(self);
737 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000738}
739
740static PyObject *
741Tkapp_ExprBoolean (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000742 PyObject *self;
743 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000744{
Barry Warsawfa701a81997-01-16 00:15:11 +0000745 char *s;
746 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000747
Barry Warsawfa701a81997-01-16 00:15:11 +0000748 if (!PyArg_Parse(args, "s", &s))
749 return NULL;
750 if (Tcl_ExprBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
751 return Tkinter_Error(self);
752 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000753}
754
Barry Warsawfa701a81997-01-16 00:15:11 +0000755
756
Guido van Rossum18468821994-06-20 07:49:28 +0000757static PyObject *
758Tkapp_SplitList (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000759 PyObject *self;
760 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000761{
Barry Warsawfa701a81997-01-16 00:15:11 +0000762 char *list;
763 int argc;
764 char **argv;
765 PyObject *v;
766 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000767
Barry Warsawfa701a81997-01-16 00:15:11 +0000768 if (!PyArg_Parse(args, "s", &list))
769 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000770
Barry Warsawfa701a81997-01-16 00:15:11 +0000771 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
772 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000773
Barry Warsawfa701a81997-01-16 00:15:11 +0000774 if (!(v = PyTuple_New(argc)))
775 return NULL;
776
777 for (i = 0; i < argc; i++) {
778 PyObject *s = PyString_FromString(argv[i]);
779 if (!s || PyTuple_SetItem(v, i, s)) {
780 Py_DECREF(v);
781 v = NULL;
782 goto finally;
783 }
784 }
Guido van Rossum18468821994-06-20 07:49:28 +0000785
Barry Warsawfa701a81997-01-16 00:15:11 +0000786 finally:
787 ckfree(FREECAST argv);
788 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000789}
790
791static PyObject *
792Tkapp_Split (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000793 PyObject *self;
794 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000795{
Barry Warsawfa701a81997-01-16 00:15:11 +0000796 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000797
Barry Warsawfa701a81997-01-16 00:15:11 +0000798 if (!PyArg_Parse(args, "s", &list))
799 return NULL;
800 return Split(self, list);
Guido van Rossum18468821994-06-20 07:49:28 +0000801}
802
803static PyObject *
804Tkapp_Merge (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000805 PyObject *self;
806 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000807{
Barry Warsawfa701a81997-01-16 00:15:11 +0000808 char *s = Merge(args);
809 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000810
Barry Warsawfa701a81997-01-16 00:15:11 +0000811 if (s) {
812 res = PyString_FromString(s);
813 ckfree(s);
814 }
815 else
816 PyErr_SetString(Tkinter_TclError, "merge failed");
817
818 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000819}
820
Barry Warsawfa701a81997-01-16 00:15:11 +0000821
822
Guido van Rossum18468821994-06-20 07:49:28 +0000823/** Tcl Command **/
824
825/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +0000826 * function or method.
827 */
Guido van Rossum18468821994-06-20 07:49:28 +0000828static int
829PythonCmd (clientData, interp, argc, argv)
Barry Warsawfa701a81997-01-16 00:15:11 +0000830 ClientData clientData; /* Is (self, func) */
831 Tcl_Interp *interp;
832 int argc;
833 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +0000834{
Barry Warsawfa701a81997-01-16 00:15:11 +0000835 PyObject *self, *func, *arg, *res, *tmp;
836 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000837
Barry Warsawfa701a81997-01-16 00:15:11 +0000838 /* TBD: no error checking here since we know, via the
839 * Tkapp_CreateCommand() that the client data is a two-tuple
840 */
841 self = PyTuple_GetItem((PyObject *) clientData, 0);
842 func = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000843
Barry Warsawfa701a81997-01-16 00:15:11 +0000844 /* Create argument list (argv1, ..., argvN) */
845 if (!(arg = PyTuple_New(argc - 1)))
846 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000847
Barry Warsawfa701a81997-01-16 00:15:11 +0000848 for (i = 0; i < (argc - 1); i++) {
849 PyObject *s = PyString_FromString(argv[i + 1]);
850 if (!s || PyTuple_SetItem(arg, i, s)) {
851 Py_DECREF(arg);
852 PythonCmd_Error(interp);
853 }
854 }
855 res = PyEval_CallObject(func, arg);
856 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +0000857
Barry Warsawfa701a81997-01-16 00:15:11 +0000858 if (res == NULL)
859 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +0000860
Barry Warsawfa701a81997-01-16 00:15:11 +0000861 if (!(tmp = PyList_New(0))) {
862 Py_DECREF(res);
863 return PythonCmd_Error(interp);
864 }
865
866 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
867 Py_DECREF(res);
868 Py_DECREF(tmp);
869
870 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000871}
872
873static void
874PythonCmdDelete (clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +0000875 ClientData clientData; /* Is (self, func) */
Guido van Rossum18468821994-06-20 07:49:28 +0000876{
Barry Warsawfa701a81997-01-16 00:15:11 +0000877 Py_DECREF((PyObject *) clientData);
Guido van Rossum18468821994-06-20 07:49:28 +0000878}
879
Barry Warsawfa701a81997-01-16 00:15:11 +0000880
881
Guido van Rossum18468821994-06-20 07:49:28 +0000882static PyObject *
883Tkapp_CreateCommand (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000884 PyObject *self;
885 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000886{
Barry Warsawfa701a81997-01-16 00:15:11 +0000887 char *cmdName;
888 PyObject *data;
889 PyObject *func;
Guido van Rossum18468821994-06-20 07:49:28 +0000890
Barry Warsawfa701a81997-01-16 00:15:11 +0000891 /* Args is: (cmdName, func) */
892 if (!PyTuple_Check(args)
893 || !(PyTuple_Size(args) == 2)
894 || !PyString_Check(PyTuple_GetItem(args, 0))
895 || !PyCallable_Check(PyTuple_GetItem(args, 1)))
896 {
897 PyErr_SetString (PyExc_TypeError, "bad argument list");
898 return NULL;
899 }
Guido van Rossum18468821994-06-20 07:49:28 +0000900
Barry Warsawfa701a81997-01-16 00:15:11 +0000901 cmdName = PyString_AsString(PyTuple_GetItem(args, 0));
902 func = PyTuple_GetItem(args, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000903
Barry Warsawfa701a81997-01-16 00:15:11 +0000904 data = PyTuple_New(2); /* ClientData is: (self, func) */
905 if (!data)
906 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000907
Barry Warsawfa701a81997-01-16 00:15:11 +0000908 Py_INCREF(self);
909 PyTuple_SetItem(data, 0, self);
Guido van Rossum18468821994-06-20 07:49:28 +0000910
Barry Warsawfa701a81997-01-16 00:15:11 +0000911 Py_INCREF(func);
912 PyTuple_SetItem(data, 1, func);
Guido van Rossum18468821994-06-20 07:49:28 +0000913
Barry Warsawfa701a81997-01-16 00:15:11 +0000914 Tcl_CreateCommand(Tkapp_Interp (self), cmdName, PythonCmd,
915 (ClientData) data, PythonCmdDelete);
Guido van Rossum18468821994-06-20 07:49:28 +0000916
Barry Warsawfa701a81997-01-16 00:15:11 +0000917 Py_INCREF(Py_None);
918 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000919}
920
Barry Warsawfa701a81997-01-16 00:15:11 +0000921
922
Guido van Rossum18468821994-06-20 07:49:28 +0000923static PyObject *
924Tkapp_DeleteCommand (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000925 PyObject *self;
926 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000927{
Barry Warsawfa701a81997-01-16 00:15:11 +0000928 char *cmdName;
Guido van Rossum18468821994-06-20 07:49:28 +0000929
Barry Warsawfa701a81997-01-16 00:15:11 +0000930 if (!PyArg_Parse(args, "s", &cmdName))
931 return NULL;
932 if (Tcl_DeleteCommand(Tkapp_Interp(self), cmdName) == -1)
933 {
934 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
935 return NULL;
936 }
937 Py_INCREF(Py_None);
938 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000939}
940
Barry Warsawfa701a81997-01-16 00:15:11 +0000941
942
Guido van Rossum18468821994-06-20 07:49:28 +0000943/** File Handler **/
944
Guido van Rossuma597dde1995-01-10 20:56:29 +0000945static void
Guido van Rossum18468821994-06-20 07:49:28 +0000946FileHandler (clientData, mask)
Barry Warsawfa701a81997-01-16 00:15:11 +0000947 ClientData clientData; /* Is: (func, file) */
948 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +0000949{
Barry Warsawfa701a81997-01-16 00:15:11 +0000950 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +0000951
Barry Warsawfa701a81997-01-16 00:15:11 +0000952 func = PyTuple_GetItem((PyObject *) clientData, 0);
953 file = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000954
Barry Warsawfa701a81997-01-16 00:15:11 +0000955 arg = Py_BuildValue("(Oi)", file, (long) mask);
956 res = PyEval_CallObject(func, arg);
957 Py_DECREF (arg);
958
959 if (res == NULL) {
960 errorInCmd = 1;
961 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
962 }
963 Py_XDECREF(res);
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000964}
965
966static int
967GetFileNo (file)
Barry Warsawfa701a81997-01-16 00:15:11 +0000968 /* Either an int >= 0 or an object with a
969 *.fileno() method that returns an int >= 0
970 */
971 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000972{
Guido van Rossuma597dde1995-01-10 20:56:29 +0000973 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000974 int id;
975 if (PyInt_Check(file)) {
976 id = PyInt_AsLong(file);
977 if (id < 0)
978 PyErr_SetString(PyExc_ValueError, "invalid file id");
979 return id;
980 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000981 args = PyTuple_New(0);
982 if (args == NULL)
983 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000984
985 meth = PyObject_GetAttrString(file, "fileno");
986 if (meth == NULL) {
987 Py_DECREF(args);
988 return -1;
989 }
990
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000991 res = PyEval_CallObject(meth, args);
992 Py_DECREF(args);
993 Py_DECREF(meth);
994 if (res == NULL)
995 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000996
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000997 if (PyInt_Check(res))
998 id = PyInt_AsLong(res);
999 else
1000 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001001
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001002 if (id < 0)
1003 PyErr_SetString(PyExc_ValueError,
1004 "invalid fileno() return value");
1005 Py_DECREF(res);
1006 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001007}
1008
Barry Warsawfa701a81997-01-16 00:15:11 +00001009
1010static PyObject* Tkapp_ClientDataDict = NULL;
1011
Guido van Rossum18468821994-06-20 07:49:28 +00001012static PyObject *
1013Tkapp_CreateFileHandler (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001014 PyObject *self;
1015 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001016{
Barry Warsawfa701a81997-01-16 00:15:11 +00001017 PyObject *file, *func, *data;
1018 PyObject *idkey;
1019 int mask, id;
Guido van Rossum68784361996-05-16 17:17:31 +00001020#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Barry Warsawfa701a81997-01-16 00:15:11 +00001021 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001022#endif
Guido van Rossum18468821994-06-20 07:49:28 +00001023
Barry Warsawfa701a81997-01-16 00:15:11 +00001024 if (!Tkapp_ClientDataDict) {
1025 if (!(Tkapp_ClientDataDict = PyDict_New()))
1026 return NULL;
1027 }
Guido van Rossum18468821994-06-20 07:49:28 +00001028
Barry Warsawfa701a81997-01-16 00:15:11 +00001029 if (!PyArg_Parse(args, "(OiO)", &file, &mask, &func))
1030 return NULL;
1031 id = GetFileNo(file);
1032 if (id < 0)
1033 return NULL;
1034 if (!PyCallable_Check(func)) {
1035 PyErr_SetString (PyExc_TypeError, "bad argument list");
1036 return NULL;
1037 }
1038
1039 if (!(idkey = PyInt_FromLong(id)))
1040 return NULL;
1041
1042 /* ClientData is: (func, file) */
1043 data = Py_BuildValue ("(OO)", func, file);
1044 if (!data || PyDict_SetItem(Tkapp_ClientDataDict, idkey, data)) {
1045 Py_DECREF(idkey);
1046 Py_XDECREF(data);
1047 return NULL;
1048 }
1049 Py_DECREF(idkey);
Guido van Rossum76875221994-06-27 07:59:42 +00001050
Guido van Rossum68784361996-05-16 17:17:31 +00001051#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Guido van Rossum07886d01996-09-11 23:31:42 +00001052#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001053 /* We assume this is a socket... */
1054 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum845547d1996-06-26 18:26:04 +00001055#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001056 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +00001057#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001058 /* Ought to check for null Tcl_File object... */
1059 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum68784361996-05-16 17:17:31 +00001060#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001061 Tk_CreateFileHandler(id, mask, FileHandler, (ClientData) data);
Guido van Rossum68784361996-05-16 17:17:31 +00001062#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001063 /* XXX fileHandlerDict */
1064 Py_INCREF (Py_None);
1065 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001066}
1067
Barry Warsawfa701a81997-01-16 00:15:11 +00001068
Guido van Rossum18468821994-06-20 07:49:28 +00001069static PyObject *
1070Tkapp_DeleteFileHandler (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001071 PyObject *self;
1072 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001073{
Barry Warsawfa701a81997-01-16 00:15:11 +00001074 PyObject *file;
1075 PyObject *idkey;
1076 PyObject *data;
1077 int id;
Guido van Rossum68784361996-05-16 17:17:31 +00001078#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Barry Warsawfa701a81997-01-16 00:15:11 +00001079 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001080#endif
1081
Barry Warsawfa701a81997-01-16 00:15:11 +00001082 if (!PyArg_Parse(args, "O", &file))
1083 return NULL;
1084 id = GetFileNo(file);
1085 if (id < 0)
1086 return NULL;
1087
1088 if (!(idkey = PyInt_FromLong(id)))
1089 return NULL;
1090
1091 /* find and free the object created in the
1092 * Tkapp_CreateFileHandler() call
1093 */
1094 data = PyDict_GetItem(Tkapp_ClientDataDict, idkey);
1095 Py_XDECREF(data);
1096 PyDict_DelItem(Tkapp_ClientDataDict, idkey);
1097 Py_DECREF(idkey);
Guido van Rossum18468821994-06-20 07:49:28 +00001098
Guido van Rossum68784361996-05-16 17:17:31 +00001099#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Guido van Rossum07886d01996-09-11 23:31:42 +00001100#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001101 /* We assume this is a socket... */
1102 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum845547d1996-06-26 18:26:04 +00001103#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001104 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +00001105#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001106 /* Ought to check for null Tcl_File object... */
1107 Tcl_DeleteFileHandler(tfile);
Guido van Rossum68784361996-05-16 17:17:31 +00001108#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001109 Tk_DeleteFileHandler(id);
Guido van Rossum68784361996-05-16 17:17:31 +00001110#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001111 /* XXX fileHandlerDict */
1112 Py_INCREF (Py_None);
1113 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001114}
1115
Barry Warsawfa701a81997-01-16 00:15:11 +00001116
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001117/**** Tktt Object (timer token) ****/
1118
1119staticforward PyTypeObject Tktt_Type;
1120
1121typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +00001122{
1123 PyObject_HEAD
1124 Tk_TimerToken token;
1125 PyObject *func;
1126}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001127TkttObject;
1128
1129static PyObject *
1130Tktt_DeleteTimerHandler (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001131 PyObject *self;
1132 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001133{
Barry Warsawfa701a81997-01-16 00:15:11 +00001134 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001135
Barry Warsawfa701a81997-01-16 00:15:11 +00001136 if (!PyArg_Parse(args, ""))
1137 return NULL;
1138 if (v->func != NULL) {
1139 Tk_DeleteTimerHandler(v->token);
1140 PyMem_DEL(v->func);
1141 v->func = NULL;
1142 }
1143 Py_INCREF(Py_None);
1144 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001145}
1146
1147static PyMethodDef Tktt_methods[] =
1148{
Barry Warsawfa701a81997-01-16 00:15:11 +00001149 {"deletetimerhandler", Tktt_DeleteTimerHandler},
1150 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001151};
1152
1153static TkttObject *
1154Tktt_New (token, func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001155 Tk_TimerToken token;
1156 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001157{
Barry Warsawfa701a81997-01-16 00:15:11 +00001158 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001159
Barry Warsawfa701a81997-01-16 00:15:11 +00001160 v = PyObject_NEW(TkttObject, &Tktt_Type);
1161 if (v == NULL)
1162 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001163
Barry Warsawfa701a81997-01-16 00:15:11 +00001164 v->token = token;
1165 v->func = func;
1166 Py_INCREF(v->func);
1167 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001168}
1169
1170static void
1171Tktt_Dealloc (self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001172 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001173{
Barry Warsawfa701a81997-01-16 00:15:11 +00001174 PyMem_DEL (self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001175}
1176
1177static int
1178Tktt_Print (self, fp, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +00001179 PyObject *self;
1180 FILE *fp;
1181 int flags;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001182{
Barry Warsawfa701a81997-01-16 00:15:11 +00001183 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001184
Barry Warsawfa701a81997-01-16 00:15:11 +00001185 fprintf(fp, "<tktimertoken at 0x%lx%s>", (long)v,
1186 v->func == NULL ? ", handler deleted" : "");
1187 return 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001188}
1189
1190static PyObject *
1191Tktt_GetAttr (self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001192 PyObject *self;
1193 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001194{
Barry Warsawfa701a81997-01-16 00:15:11 +00001195 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001196}
1197
1198static PyTypeObject Tktt_Type =
1199{
Barry Warsawfa701a81997-01-16 00:15:11 +00001200 PyObject_HEAD_INIT (NULL)
1201 0, /*ob_size */
1202 "tktimertoken", /*tp_name */
1203 sizeof (TkttObject), /*tp_basicsize */
1204 0, /*tp_itemsize */
1205 Tktt_Dealloc, /*tp_dealloc */
1206 Tktt_Print, /*tp_print */
1207 Tktt_GetAttr, /*tp_getattr */
1208 0, /*tp_setattr */
1209 0, /*tp_compare */
1210 0, /*tp_repr */
1211 0, /*tp_as_number */
1212 0, /*tp_as_sequence */
1213 0, /*tp_as_mapping */
1214 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001215};
1216
Barry Warsawfa701a81997-01-16 00:15:11 +00001217
1218
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001219/** Timer Handler **/
1220
1221static void
1222TimerHandler (clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001223 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001224{
Barry Warsawfa701a81997-01-16 00:15:11 +00001225 PyObject *func = (PyObject *)clientData;
1226 PyObject *res = PyEval_CallObject(func, NULL);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001227
Barry Warsawfa701a81997-01-16 00:15:11 +00001228 if (res == NULL) {
1229 errorInCmd = 1;
1230 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1231 }
1232 else
1233 Py_DECREF(res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001234}
1235
1236static PyObject *
1237Tkapp_CreateTimerHandler (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001238 PyObject *self;
1239 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001240{
Barry Warsawfa701a81997-01-16 00:15:11 +00001241 int milliseconds;
1242 PyObject *func;
1243 Tk_TimerToken token;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001244
Barry Warsawfa701a81997-01-16 00:15:11 +00001245 if (!PyArg_Parse(args, "(iO)", &milliseconds, &func))
1246 return NULL;
1247 if (!PyCallable_Check(func)) {
1248 PyErr_SetString (PyExc_TypeError, "bad argument list");
1249 return NULL;
1250 }
1251 token = Tk_CreateTimerHandler(milliseconds, TimerHandler,
1252 (ClientData)func);
1253
1254 return (PyObject *) Tktt_New(token, func);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001255}
1256
Barry Warsawfa701a81997-01-16 00:15:11 +00001257
1258
Guido van Rossum18468821994-06-20 07:49:28 +00001259/** Event Loop **/
1260
Guido van Rossum18468821994-06-20 07:49:28 +00001261static PyObject *
1262Tkapp_MainLoop (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001263 PyObject *self;
1264 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001265{
Barry Warsawfa701a81997-01-16 00:15:11 +00001266 int threshold = 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001267
Barry Warsawfa701a81997-01-16 00:15:11 +00001268 if (!PyArg_ParseTuple(args, "|i", &threshold))
1269 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001270
Barry Warsawfa701a81997-01-16 00:15:11 +00001271 quitMainLoop = 0;
1272 while (Tk_GetNumMainWindows() > threshold &&
1273 !quitMainLoop &&
1274 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001275 {
Barry Warsawfa701a81997-01-16 00:15:11 +00001276 /* XXX Ought to check for other signals! */
1277 if (PyOS_InterruptOccurred()) {
1278 PyErr_SetNone(PyExc_KeyboardInterrupt);
1279 return NULL;
1280 }
1281 Tk_DoOneEvent(0);
Guido van Rossum18468821994-06-20 07:49:28 +00001282 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001283 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001284
Barry Warsawfa701a81997-01-16 00:15:11 +00001285 if (errorInCmd) {
1286 errorInCmd = 0;
1287 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1288 excInCmd = valInCmd = trbInCmd = NULL;
1289 return NULL;
1290 }
1291 Py_INCREF(Py_None);
1292 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001293}
1294
1295static PyObject *
Guido van Rossum062cfb01995-01-10 17:42:51 +00001296Tkapp_DoOneEvent (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001297 PyObject *self;
1298 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001299{
Barry Warsawfa701a81997-01-16 00:15:11 +00001300 int flags = TK_ALL_EVENTS;
1301 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001302
Barry Warsawfa701a81997-01-16 00:15:11 +00001303 if (!PyArg_ParseTuple(args, "|i", &flags))
1304 return NULL;
1305
1306 rv = Tk_DoOneEvent(flags);
1307 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001308}
1309
1310static PyObject *
Guido van Rossum18468821994-06-20 07:49:28 +00001311Tkapp_Quit (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001312 PyObject *self;
1313 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001314{
1315
Barry Warsawfa701a81997-01-16 00:15:11 +00001316 if (!PyArg_Parse(args, ""))
1317 return NULL;
1318
1319 quitMainLoop = 1;
1320 Py_INCREF(Py_None);
1321 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001322}
1323
Barry Warsawfa701a81997-01-16 00:15:11 +00001324
1325
Guido van Rossum18468821994-06-20 07:49:28 +00001326/**** Tkapp Method List ****/
1327
1328static PyMethodDef Tkapp_methods[] =
1329{
Barry Warsawfa701a81997-01-16 00:15:11 +00001330 {"call", Tkapp_Call},
1331 {"globalcall", Tkapp_GlobalCall},
1332 {"eval", Tkapp_Eval},
1333 {"globaleval", Tkapp_GlobalEval},
1334 {"evalfile", Tkapp_EvalFile},
1335 {"record", Tkapp_Record},
1336 {"adderrorinfo", Tkapp_AddErrorInfo},
1337 {"setvar", Tkapp_SetVar},
1338 {"globalsetvar", Tkapp_GlobalSetVar},
1339 {"getvar", Tkapp_GetVar},
1340 {"globalgetvar", Tkapp_GlobalGetVar},
1341 {"unsetvar", Tkapp_UnsetVar},
1342 {"globalunsetvar", Tkapp_GlobalUnsetVar},
1343 {"getint", Tkapp_GetInt},
1344 {"getdouble", Tkapp_GetDouble},
1345 {"getboolean", Tkapp_GetBoolean},
1346 {"exprstring", Tkapp_ExprString},
1347 {"exprlong", Tkapp_ExprLong},
1348 {"exprdouble", Tkapp_ExprDouble},
1349 {"exprboolean", Tkapp_ExprBoolean},
1350 {"splitlist", Tkapp_SplitList},
1351 {"split", Tkapp_Split},
1352 {"merge", Tkapp_Merge},
1353 {"createcommand", Tkapp_CreateCommand},
1354 {"deletecommand", Tkapp_DeleteCommand},
1355 {"createfilehandler", Tkapp_CreateFileHandler},
1356 {"deletefilehandler", Tkapp_DeleteFileHandler},
1357 {"createtimerhandler", Tkapp_CreateTimerHandler},
1358 {"mainloop", Tkapp_MainLoop, 1},
1359 {"dooneevent", Tkapp_DoOneEvent, 1},
1360 {"quit", Tkapp_Quit},
1361 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001362};
1363
Barry Warsawfa701a81997-01-16 00:15:11 +00001364
1365
Guido van Rossum18468821994-06-20 07:49:28 +00001366/**** Tkapp Type Methods ****/
1367
1368static void
1369Tkapp_Dealloc (self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001370 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001371{
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001372#ifdef NEED_TKCREATEMAINWINDOW
Barry Warsawfa701a81997-01-16 00:15:11 +00001373 Tk_DestroyWindow (Tkapp_Tkwin (self));
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001374#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001375 Tcl_DeleteInterp (Tkapp_Interp (self));
1376 PyMem_DEL (self);
Guido van Rossum18468821994-06-20 07:49:28 +00001377}
1378
1379static PyObject *
1380Tkapp_GetAttr (self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001381 PyObject *self;
1382 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001383{
Barry Warsawfa701a81997-01-16 00:15:11 +00001384 return Py_FindMethod (Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001385}
1386
1387static PyTypeObject Tkapp_Type =
1388{
Barry Warsawfa701a81997-01-16 00:15:11 +00001389 PyObject_HEAD_INIT (NULL)
1390 0, /*ob_size */
1391 "tkapp", /*tp_name */
1392 sizeof (TkappObject), /*tp_basicsize */
1393 0, /*tp_itemsize */
1394 Tkapp_Dealloc, /*tp_dealloc */
1395 0, /*tp_print */
1396 Tkapp_GetAttr, /*tp_getattr */
1397 0, /*tp_setattr */
1398 0, /*tp_compare */
1399 0, /*tp_repr */
1400 0, /*tp_as_number */
1401 0, /*tp_as_sequence */
1402 0, /*tp_as_mapping */
1403 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001404};
1405
Barry Warsawfa701a81997-01-16 00:15:11 +00001406
1407
Guido van Rossum18468821994-06-20 07:49:28 +00001408/**** Tkinter Module ****/
1409
1410static PyObject *
1411Tkinter_Create (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001412 PyObject *self;
1413 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001414{
Barry Warsawfa701a81997-01-16 00:15:11 +00001415 char *screenName = NULL;
1416 char *baseName = NULL;
1417 char *className = NULL;
1418 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001419
Barry Warsawfa701a81997-01-16 00:15:11 +00001420 baseName = strrchr(Py_GetProgramName (), '/');
1421 if (baseName != NULL)
1422 baseName++;
1423 else
1424 baseName = Py_GetProgramName();
1425 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001426
Barry Warsawfa701a81997-01-16 00:15:11 +00001427 if (!PyArg_ParseTuple(args, "|zssi",
1428 &screenName, &baseName, &className,
1429 &interactive))
1430 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001431
Barry Warsawfa701a81997-01-16 00:15:11 +00001432 return (PyObject *) Tkapp_New(screenName, baseName, className,
1433 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001434}
1435
1436static PyMethodDef moduleMethods[] =
1437{
Barry Warsawfa701a81997-01-16 00:15:11 +00001438 {"create", Tkinter_Create, 1},
1439 {"createfilehandler", Tkapp_CreateFileHandler, 0},
1440 {"deletefilehandler", Tkapp_DeleteFileHandler, 0},
1441 {"createtimerhandler", Tkapp_CreateTimerHandler, 0},
1442 {"mainloop", Tkapp_MainLoop, 1},
1443 {"dooneevent", Tkapp_DoOneEvent, 1},
1444 {"quit", Tkapp_Quit},
1445 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001446};
1447
1448#ifdef WITH_READLINE
1449static int
1450EventHook ()
1451{
Barry Warsawfa701a81997-01-16 00:15:11 +00001452 /* XXX Reset tty */
1453 if (errorInCmd) {
1454 errorInCmd = 0;
1455 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1456 excInCmd = valInCmd = trbInCmd = NULL;
1457 PyErr_Print();
1458 }
1459 if (Tk_GetNumMainWindows() > 0)
1460 Tk_DoOneEvent(TK_DONT_WAIT);
1461 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001462}
1463#endif /* WITH_READLINE */
1464
1465static void
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001466Tkinter_Cleanup ()
1467{
Barry Warsawfa701a81997-01-16 00:15:11 +00001468 /* This segfault with Tk 4.0 beta and seems unnecessary there as
1469 * well */
1470
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001471#if TK_MAJOR_VERSION < 4
Barry Warsawfa701a81997-01-16 00:15:11 +00001472 /* XXX rl_deprep_terminal is static, damned! */
1473 while (tkMainWindowList != 0)
1474 Tk_DestroyWindow(tkMainWindowList->win);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001475#endif
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001476}
1477
Barry Warsawfa701a81997-01-16 00:15:11 +00001478
1479/* all errors will be checked in one fell swoop in init_tkinter() */
1480static void
1481ins_long(d, name, val)
1482 PyObject *d;
1483 char *name;
1484 long val;
1485{
1486 PyObject *v = PyInt_FromLong(val);
1487 if (v) {
1488 PyDict_SetItemString(d, name, v);
1489 Py_DECREF(v);
1490 }
1491}
1492static void
1493ins_string(d, name, val)
1494 PyObject *d;
1495 char *name;
1496 char *val;
1497{
1498 PyObject *v = PyString_FromString(val);
1499 if (v) {
1500 PyDict_SetItemString(d, name, v);
1501 Py_DECREF(v);
1502 }
1503}
1504
1505
Guido van Rossum18468821994-06-20 07:49:28 +00001506void
Guido van Rossumad1f7ee1996-02-13 00:11:37 +00001507init_tkinter ()
Guido van Rossum18468821994-06-20 07:49:28 +00001508{
Barry Warsawfa701a81997-01-16 00:15:11 +00001509 static inited = 0;
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001510
Guido van Rossum18468821994-06-20 07:49:28 +00001511#ifdef WITH_READLINE
Barry Warsawfa701a81997-01-16 00:15:11 +00001512 extern int (*rl_event_hook) ();
Guido van Rossum18468821994-06-20 07:49:28 +00001513#endif /* WITH_READLINE */
Barry Warsawfa701a81997-01-16 00:15:11 +00001514 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001515
Barry Warsawfa701a81997-01-16 00:15:11 +00001516 Tkapp_Type.ob_type = &PyType_Type;
1517 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossumae92f011996-08-21 19:03:36 +00001518
Barry Warsawfa701a81997-01-16 00:15:11 +00001519 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001520
Barry Warsawfa701a81997-01-16 00:15:11 +00001521 d = PyModule_GetDict(m);
1522 Tkinter_TclError = Py_BuildValue("s", "TclError");
1523 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00001524
Barry Warsawfa701a81997-01-16 00:15:11 +00001525 ins_long(d, "READABLE", TK_READABLE);
1526 ins_long(d, "WRITABLE", TK_WRITABLE);
1527 ins_long(d, "EXCEPTION", TK_EXCEPTION);
1528 ins_long(d, "X_EVENTS", TK_X_EVENTS);
1529 ins_long(d, "FILE_EVENTS", TK_FILE_EVENTS);
1530 ins_long(d, "TIMER_EVENTS", TK_TIMER_EVENTS);
1531 ins_long(d, "IDLE_EVENTS", TK_IDLE_EVENTS);
1532 ins_long(d, "ALL_EVENTS", TK_ALL_EVENTS);
1533 ins_long(d, "DONT_WAIT", TK_DONT_WAIT);
1534 ins_string(d, "TK_VERSION", TK_VERSION);
1535 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00001536
Guido van Rossum18468821994-06-20 07:49:28 +00001537#ifdef WITH_READLINE
Barry Warsawfa701a81997-01-16 00:15:11 +00001538 rl_event_hook = EventHook;
Guido van Rossum18468821994-06-20 07:49:28 +00001539#endif /* WITH_READLINE */
1540
Barry Warsawfa701a81997-01-16 00:15:11 +00001541 if (!inited) {
1542 inited = 1;
1543 if (Py_AtExit(Tkinter_Cleanup) != 0)
1544 fprintf(stderr,
1545 "Tkinter: warning: cleanup procedure not registered\n");
1546 }
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001547
Barry Warsawfa701a81997-01-16 00:15:11 +00001548 if (PyErr_Occurred())
1549 Py_FatalError ("can't initialize module _tkinter");
Jack Jansen34cc5c31995-10-31 16:15:12 +00001550#ifdef macintosh
Barry Warsawfa701a81997-01-16 00:15:11 +00001551 TclMacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00001552#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00001553 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001554#endif /* GENERATINGCFM */
1555#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001556}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001557
Guido van Rossumec22c921996-02-25 04:50:29 +00001558
Barry Warsawfa701a81997-01-16 00:15:11 +00001559
Guido van Rossum9722ad81995-09-22 23:49:28 +00001560#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001561
1562/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001563** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001564*/
1565
Guido van Rossum9722ad81995-09-22 23:49:28 +00001566void
1567panic(char * format, ...)
1568{
Barry Warsawfa701a81997-01-16 00:15:11 +00001569 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001570
Barry Warsawfa701a81997-01-16 00:15:11 +00001571 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001572
Barry Warsawfa701a81997-01-16 00:15:11 +00001573 vfprintf(stderr, format, varg);
1574 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001575
Barry Warsawfa701a81997-01-16 00:15:11 +00001576 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001577
Barry Warsawfa701a81997-01-16 00:15:11 +00001578 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00001579}
Jack Jansen40b546d1995-11-14 10:34:45 +00001580
Guido van Rossumec22c921996-02-25 04:50:29 +00001581/*
1582** Pass events to SIOUX before passing them to Tk.
1583*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001584
Guido van Rossumec22c921996-02-25 04:50:29 +00001585static int
1586PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00001587 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001588{
Barry Warsawfa701a81997-01-16 00:15:11 +00001589 if (SIOUXHandleOneEvent(eventPtr))
1590 return 0; /* Nothing happened to the Tcl event queue */
1591 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001592}
1593
Guido van Rossum290283b1997-06-02 22:16:43 +00001594#ifdef USE_GUSI
1595/*
1596 * For Python we have to override this routine (from TclMacNotify),
1597 * since we use GUSI for our sockets, not Tcl streams. Hence, we have
1598 * to use GUSI select to see whether our socket is ready. Note that
1599 * createfilehandler (above) sets the type to TCL_UNIX_FD for our
1600 * files and sockets.
1601 *
1602 * NOTE: this code was lifted from Tcl 7.6, it may need to be modified
1603 * for other versions. */
1604
1605int
1606Tcl_FileReady(file, mask)
1607 Tcl_File file; /* File handle for a stream. */
1608 int mask; /* OR'ed combination of TCL_READABLE,
1609 * TCL_WRITABLE, and TCL_EXCEPTION:
1610 * indicates conditions caller cares about. */
1611{
1612 int type;
1613 int fd;
1614
1615 fd = (int) Tcl_GetFileInfo(file, &type);
1616
1617 if (type == TCL_MAC_SOCKET) {
1618 return TclMacSocketReady(file, mask);
1619 } else if (type == TCL_MAC_FILE) {
1620 /*
1621 * Under the Macintosh, files are always ready, so we just
1622 * return the mask that was passed in.
1623 */
1624
1625 return mask;
1626 } else if (type == TCL_UNIX_FD) {
1627 fd_set readset, writeset, excset;
1628 struct timeval tv;
1629
1630 FD_ZERO(&readset);
1631 FD_ZERO(&writeset);
1632 FD_ZERO(&excset);
1633
1634 if ( mask & TCL_READABLE ) FD_SET(fd, &readset);
1635 if ( mask & TCL_WRITABLE ) FD_SET(fd, &writeset);
1636 if ( mask & TCL_EXCEPTION ) FD_SET(fd, &excset);
1637
1638 tv.tv_sec = tv.tv_usec = 0;
1639 if ( select(fd+1, &readset, &writeset, &excset, &tv) <= 0 )
1640 return 0;
1641
1642 mask = 0;
1643 if ( FD_ISSET(fd, &readset) ) mask |= TCL_READABLE;
1644 if ( FD_ISSET(fd, &writeset) ) mask |= TCL_WRITABLE;
1645 if ( FD_ISSET(fd, &excset) ) mask |= TCL_EXCEPTION;
1646
1647 return mask;
1648 }
1649
1650 return 0;
1651}
1652#endif /* USE_GUSI */
1653
Guido van Rossumec22c921996-02-25 04:50:29 +00001654#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001655
1656/*
1657** Additional Mac specific code for dealing with shared libraries.
1658*/
1659
1660#include <Resources.h>
1661#include <CodeFragments.h>
1662
1663static int loaded_from_shlib = 0;
1664static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001665
Jack Jansen34cc5c31995-10-31 16:15:12 +00001666/*
1667** If this module is dynamically loaded the following routine should
1668** be the init routine. It takes care of adding the shared library to
1669** the resource-file chain, so that the tk routines can find their
1670** resources.
1671*/
1672OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001673init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00001674{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00001675 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00001676 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001677 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001678 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1679 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001680 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001681 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1682 loaded_from_shlib = 1;
1683 }
1684 return noErr;
1685}
1686
1687/*
1688** Insert the library resources into the search path. Put them after
1689** the resources from the application. Again, we ignore errors.
1690*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001691static
Jack Jansen34cc5c31995-10-31 16:15:12 +00001692mac_addlibresources()
1693{
1694 if ( !loaded_from_shlib )
1695 return;
1696 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1697}
1698
Guido van Rossumec22c921996-02-25 04:50:29 +00001699#endif /* GENERATINGCFM */
1700#endif /* macintosh */