blob: fccfb30dda5597dee0361d551eba9a37f97b412b [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
52#endif
53
Guido van Rossum18468821994-06-20 07:49:28 +000054#include <tcl.h>
55#include <tk.h>
56
Guido van Rossum32aa1a71996-07-31 19:51:15 +000057extern char *Py_GetProgramName ();
Guido van Rossumd308e2b1994-07-07 09:25:12 +000058
Guido van Rossum9722ad81995-09-22 23:49:28 +000059/* Internal declarations from tkInt.h. */
60#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
61extern int Tk_GetNumMainWindows();
62#else
Guido van Rossum18468821994-06-20 07:49:28 +000063extern int tk_NumMainWindows;
Guido van Rossum9722ad81995-09-22 23:49:28 +000064#define Tk_GetNumMainWindows() (tk_NumMainWindows)
Guido van Rossumdfd428d1996-02-25 04:46:40 +000065#define NEED_TKCREATEMAINWINDOW 1
Guido van Rossum9722ad81995-09-22 23:49:28 +000066#endif
67
68#if TK_MAJOR_VERSION < 4
Guido van Rossumd308e2b1994-07-07 09:25:12 +000069extern struct { Tk_Window win; } *tkMainWindowList;
Guido van Rossum9722ad81995-09-22 23:49:28 +000070#endif
Guido van Rossum18468821994-06-20 07:49:28 +000071
Guido van Rossumec22c921996-02-25 04:50:29 +000072#ifdef macintosh
73
74/*
75** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +000076** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +000077*/
78
Guido van Rossum7ffa7611996-08-13 21:10:16 +000079/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +000080#define FREECAST (char *)
81
Guido van Rossumec22c921996-02-25 04:50:29 +000082#include <Events.h> /* For EventRecord */
83
84typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
85void TclMacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
86int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
87
88staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
89
90#endif /* macintosh */
91
Guido van Rossum97867b21996-08-08 19:09:53 +000092#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +000093#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +000094#endif
95
Guido van Rossum18468821994-06-20 07:49:28 +000096/**** Tkapp Object Declaration ****/
97
98staticforward PyTypeObject Tkapp_Type;
99
100typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +0000101{
102 PyObject_HEAD
103 Tcl_Interp *interp;
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000104#ifdef NEED_TKCREATEMAINWINDOW
Barry Warsawfa701a81997-01-16 00:15:11 +0000105 Tk_Window tkwin;
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000106#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000107}
Guido van Rossum18468821994-06-20 07:49:28 +0000108TkappObject;
109
110#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000111#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +0000112#define Tkapp_Tkwin(v) (((TkappObject *) (v))->tkwin)
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000113#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000114#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
115#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
116
117#define DEBUG_REFCNT(v) (printf ("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000118(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000119
Barry Warsawfa701a81997-01-16 00:15:11 +0000120
121
Guido van Rossum18468821994-06-20 07:49:28 +0000122/**** Error Handling ****/
123
124static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000125static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000126static int errorInCmd = 0;
127static PyObject *excInCmd;
128static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000129static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000130
Barry Warsawfa701a81997-01-16 00:15:11 +0000131
132
Guido van Rossum18468821994-06-20 07:49:28 +0000133static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000134Tkinter_Error(v)
135 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000136{
Barry Warsawfa701a81997-01-16 00:15:11 +0000137 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
138 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000139}
140
Barry Warsawfa701a81997-01-16 00:15:11 +0000141
Guido van Rossum18468821994-06-20 07:49:28 +0000142int
Barry Warsawfa701a81997-01-16 00:15:11 +0000143PythonCmd_Error(interp)
144 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000145{
Barry Warsawfa701a81997-01-16 00:15:11 +0000146 errorInCmd = 1;
147 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
148 return TCL_ERROR;
Guido van Rossum18468821994-06-20 07:49:28 +0000149}
150
Barry Warsawfa701a81997-01-16 00:15:11 +0000151
152
Guido van Rossum18468821994-06-20 07:49:28 +0000153/**** Utils ****/
Guido van Rossum18468821994-06-20 07:49:28 +0000154static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000155AsString(value, tmp)
156 PyObject *value;
157 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000158{
Barry Warsawfa701a81997-01-16 00:15:11 +0000159 if (PyString_Check (value))
160 return PyString_AsString (value);
161 else {
162 PyObject *v = PyObject_Str(value);
163 PyList_Append(tmp, v);
164 Py_DECREF(v);
165 return PyString_AsString(v);
166 }
Guido van Rossum18468821994-06-20 07:49:28 +0000167}
168
Barry Warsawfa701a81997-01-16 00:15:11 +0000169
170
Guido van Rossum18468821994-06-20 07:49:28 +0000171#define ARGSZ 64
172
173static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000174Merge(args)
175 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000176{
Barry Warsawfa701a81997-01-16 00:15:11 +0000177 PyObject *tmp = NULL;
178 char *argvStore[ARGSZ];
179 char **argv = NULL;
180 int fvStore[ARGSZ];
181 int *fv = NULL;
182 int argc = 0, i;
183 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000184
Barry Warsawfa701a81997-01-16 00:15:11 +0000185 if (!(tmp = PyList_New(0)))
186 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000187
Barry Warsawfa701a81997-01-16 00:15:11 +0000188 argv = argvStore;
189 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000190
Barry Warsawfa701a81997-01-16 00:15:11 +0000191 if (args == NULL)
192 argc = 0;
193
194 else if (!PyTuple_Check(args)) {
195 argc = 1;
196 fv[0] = 0;
197 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000198 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000199 else {
200 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000201
Barry Warsawfa701a81997-01-16 00:15:11 +0000202 if (argc > ARGSZ) {
203 argv = (char **)ckalloc(argc * sizeof (char *));
204 fv = (int *)ckalloc(argc * sizeof (int));
205 if (argv == NULL || fv == NULL) {
206 PyErr_NoMemory();
207 goto finally;
208 }
209 }
210
211 for (i = 0; i < argc; i++) {
212 PyObject *v = PyTuple_GetItem(args, i);
213 if (PyTuple_Check(v)) {
214 fv[i] = 1;
215 if (!(argv[i] = Merge(v)))
216 goto finally;
217 }
218 else if (v == Py_None) {
219 argc = i;
220 break;
221 }
222 else {
223 fv[i] = 0;
224 argv[i] = AsString(v, tmp);
225 }
226 }
Guido van Rossum18468821994-06-20 07:49:28 +0000227 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000228 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000229
Barry Warsawfa701a81997-01-16 00:15:11 +0000230 finally:
231 for (i = 0; i < argc; i++)
232 if (fv[i]) {
233 ckfree(argv[i]);
234 }
235 if (argv != argvStore)
236 ckfree(FREECAST argv);
237 if (fv != fvStore)
238 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000239
Barry Warsawfa701a81997-01-16 00:15:11 +0000240 Py_DECREF(tmp);
241 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000242}
243
Barry Warsawfa701a81997-01-16 00:15:11 +0000244
245
Guido van Rossum18468821994-06-20 07:49:28 +0000246static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000247Split(self, list)
248 PyObject *self;
249 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000250{
Barry Warsawfa701a81997-01-16 00:15:11 +0000251 int argc;
252 char **argv;
253 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000254
Barry Warsawfa701a81997-01-16 00:15:11 +0000255 if (list == NULL) {
256 Py_INCREF(Py_None);
257 return Py_None;
258 }
Guido van Rossum18468821994-06-20 07:49:28 +0000259
Barry Warsawfa701a81997-01-16 00:15:11 +0000260 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
261 {
262 /* Not a list.
263 * Could be a quoted string containing funnies, e.g. {"}.
264 * Return the string itself.
265 */
266 PyErr_Clear();
267 return PyString_FromString(list);
268 }
Guido van Rossum18468821994-06-20 07:49:28 +0000269
Barry Warsawfa701a81997-01-16 00:15:11 +0000270 if (argc == 0)
271 v = PyString_FromString("");
272 else if (argc == 1)
273 v = PyString_FromString(argv[0]);
274 else if ((v = PyTuple_New (argc)) != NULL) {
275 int i;
276 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000277
Barry Warsawfa701a81997-01-16 00:15:11 +0000278 for (i = 0; i < argc; i++) {
279 if ((w = Split(self, argv[i])) == NULL) {
280 Py_DECREF(v);
281 v = NULL;
282 break;
283 }
284 PyTuple_SetItem(v, i, w);
285 }
286 }
287 ckfree (FREECAST argv);
288 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000289}
290
Barry Warsawfa701a81997-01-16 00:15:11 +0000291
292
Guido van Rossum18468821994-06-20 07:49:28 +0000293/**** Tkapp Object ****/
294
295#ifndef WITH_APPINIT
296int
297Tcl_AppInit (interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000298 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000299{
Barry Warsawfa701a81997-01-16 00:15:11 +0000300 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000301
Barry Warsawfa701a81997-01-16 00:15:11 +0000302 main = Tk_MainWindow(interp);
303 if (Tcl_Init(interp) == TCL_ERROR) {
304 fprintf(stderr, "Tcl_Init error: %s\n", interp->result);
305 return TCL_ERROR;
306 }
307 if (Tk_Init(interp) == TCL_ERROR) {
308 fprintf(stderr, "Tk_Init error: %s\n", interp->result);
309 return TCL_ERROR;
310 }
311 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000312}
313#endif /* !WITH_APPINIT */
314
Guido van Rossum18468821994-06-20 07:49:28 +0000315
Barry Warsawfa701a81997-01-16 00:15:11 +0000316
317
318/* Initialize the Tk application; see the `main' function in
319 * `tkMain.c'.
320 */
321static TkappObject *
322Tkapp_New(screenName, baseName, className, interactive)
323 char *screenName;
324 char *baseName;
325 char *className;
326 int interactive;
327{
328 TkappObject *v;
329 char *argv0;
330
331 v = PyObject_NEW(TkappObject, &Tkapp_Type);
332 if (v == NULL)
333 return NULL;
334
335 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000336
337#ifdef NEED_TKCREATEMAINWINDOW
Barry Warsawfa701a81997-01-16 00:15:11 +0000338 v->tkwin = Tk_CreateMainWindow(v->interp, screenName,
339 baseName, className);
340 if (v->tkwin == NULL)
341 return (TkappObject *)Tkinter_Error((PyObject *) v);
Guido van Rossum18468821994-06-20 07:49:28 +0000342
Barry Warsawfa701a81997-01-16 00:15:11 +0000343 Tk_GeometryRequest(v->tkwin, 200, 200);
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000344#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000345
Barry Warsawfa701a81997-01-16 00:15:11 +0000346 if (screenName != NULL)
347 Tcl_SetVar2(v->interp, "env", "DISPLAY",
348 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000349
Barry Warsawfa701a81997-01-16 00:15:11 +0000350 if (interactive)
351 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
352 else
353 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000354
Barry Warsawfa701a81997-01-16 00:15:11 +0000355 /* This is used to get the application class for Tk 4.1 and up */
356 argv0 = (char*)ckalloc(strlen(className) + 1);
357 if (!argv0) {
358 PyErr_NoMemory();
359 Py_DECREF(v);
360 return NULL;
361 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000362
Barry Warsawfa701a81997-01-16 00:15:11 +0000363 strcpy(argv0, className);
364 if (isupper(argv0[0]))
365 argv0[0] = tolower(argv0[0]);
366 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
367 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000368
Barry Warsawfa701a81997-01-16 00:15:11 +0000369 if (Tcl_AppInit(v->interp) != TCL_OK)
370 return (TkappObject *)Tkinter_Error(v);
371
372 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000373}
374
Barry Warsawfa701a81997-01-16 00:15:11 +0000375
376
Guido van Rossum18468821994-06-20 07:49:28 +0000377/** Tcl Eval **/
378
379static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000380Tkapp_Call(self, args)
381 PyObject *self;
382 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000383{
Barry Warsawfa701a81997-01-16 00:15:11 +0000384 char *cmd = Merge(args);
385 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000386
Barry Warsawfa701a81997-01-16 00:15:11 +0000387 if (!cmd)
388 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000389
Barry Warsawfa701a81997-01-16 00:15:11 +0000390 else if (Tcl_Eval(Tkapp_Interp(self), cmd) == TCL_ERROR)
391 res = Tkinter_Error(self);
392
393 else
394 res = PyString_FromString(Tkapp_Result(self));
395
396 if (cmd)
397 ckfree(cmd);
398
399 return res;
400}
401
402
403static PyObject *
404Tkapp_GlobalCall(self, args)
405 PyObject *self;
406 PyObject *args;
407{
408 char *cmd = Merge(args);
409 PyObject *res = NULL;
410
411
412 if (!cmd)
413 PyErr_SetString(Tkinter_TclError, "merge failed");
414
415 else if (Tcl_GlobalEval(Tkapp_Interp(self), cmd) == TCL_ERROR)
416 res = Tkinter_Error(self);
417 else
418 res = PyString_FromString(Tkapp_Result(self));
419
420 if (cmd)
421 ckfree(cmd);
422
423 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000424}
425
426static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000427Tkapp_Eval(self, args)
428 PyObject *self;
429 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000430{
Barry Warsawfa701a81997-01-16 00:15:11 +0000431 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000432
Barry Warsawfa701a81997-01-16 00:15:11 +0000433 if (!PyArg_Parse (args, "s", &script))
434 return NULL;
435
436 if (Tcl_Eval(Tkapp_Interp(self), script) == TCL_ERROR)
437 return Tkinter_Error(self);
438
439 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000440}
441
442static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000443Tkapp_GlobalEval(self, args)
444 PyObject *self;
445 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000446{
Barry Warsawfa701a81997-01-16 00:15:11 +0000447 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000448
Barry Warsawfa701a81997-01-16 00:15:11 +0000449 if (!PyArg_Parse(args, "s", &script))
450 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000451
Barry Warsawfa701a81997-01-16 00:15:11 +0000452 if (Tcl_GlobalEval(Tkapp_Interp(self), script) == TCL_ERROR)
453 return Tkinter_Error (self);
Guido van Rossum18468821994-06-20 07:49:28 +0000454
Barry Warsawfa701a81997-01-16 00:15:11 +0000455 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000456}
457
458static PyObject *
459Tkapp_EvalFile (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000460 PyObject *self;
461 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000462{
Barry Warsawfa701a81997-01-16 00:15:11 +0000463 char *fileName;
Guido van Rossum18468821994-06-20 07:49:28 +0000464
Barry Warsawfa701a81997-01-16 00:15:11 +0000465 if (!PyArg_Parse(args, "s", &fileName))
466 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000467
Barry Warsawfa701a81997-01-16 00:15:11 +0000468 if (Tcl_EvalFile(Tkapp_Interp(self), fileName) == TCL_ERROR)
469 return Tkinter_Error (self);
Guido van Rossum18468821994-06-20 07:49:28 +0000470
Barry Warsawfa701a81997-01-16 00:15:11 +0000471 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000472}
473
474static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000475Tkapp_Record(self, args)
476 PyObject *self;
477 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000478{
Barry Warsawfa701a81997-01-16 00:15:11 +0000479 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000480
Barry Warsawfa701a81997-01-16 00:15:11 +0000481 if (!PyArg_Parse(args, "s", &script))
482 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000483
Barry Warsawfa701a81997-01-16 00:15:11 +0000484 if (TCL_ERROR == Tcl_RecordAndEval(Tkapp_Interp(self),
485 script, TCL_NO_EVAL))
486 return Tkinter_Error (self);
Guido van Rossum18468821994-06-20 07:49:28 +0000487
Barry Warsawfa701a81997-01-16 00:15:11 +0000488 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000489}
490
491static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000492Tkapp_AddErrorInfo(self, args)
493 PyObject *self;
494 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000495{
Barry Warsawfa701a81997-01-16 00:15:11 +0000496 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000497
Barry Warsawfa701a81997-01-16 00:15:11 +0000498 if (!PyArg_Parse (args, "s", &msg))
499 return NULL;
500 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum18468821994-06-20 07:49:28 +0000501
Barry Warsawfa701a81997-01-16 00:15:11 +0000502 Py_INCREF(Py_None);
503 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000504}
505
Barry Warsawfa701a81997-01-16 00:15:11 +0000506
507
Guido van Rossum18468821994-06-20 07:49:28 +0000508/** Tcl Variable **/
509
510static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000511SetVar(self, args, flags)
512 PyObject *self;
513 PyObject *args;
514 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000515{
Barry Warsawfa701a81997-01-16 00:15:11 +0000516 char *name1, *name2, *ok;
517 PyObject *newValue;
518 PyObject *tmp = PyList_New(0);
Guido van Rossum18468821994-06-20 07:49:28 +0000519
Barry Warsawfa701a81997-01-16 00:15:11 +0000520 if (!tmp)
521 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000522
Barry Warsawfa701a81997-01-16 00:15:11 +0000523 if (PyArg_Parse(args, "(sO)", &name1, &newValue))
524 /* XXX Merge? */
525 ok = Tcl_SetVar(Tkapp_Interp (self), name1,
526 AsString (newValue, tmp), flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000527
Barry Warsawfa701a81997-01-16 00:15:11 +0000528 else if (PyArg_Parse(args, "(ssO)", &name1, &name2, &newValue))
529 ok = Tcl_SetVar2(Tkapp_Interp (self), name1, name2,
530 AsString (newValue, tmp), flags);
531 else {
532 Py_DECREF (tmp);
533 return NULL;
534 }
535 Py_DECREF (tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000536
Barry Warsawfa701a81997-01-16 00:15:11 +0000537 if (!ok)
538 return Tkinter_Error(self);
539
540 Py_INCREF(Py_None);
541 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000542}
543
544static PyObject *
545Tkapp_SetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000546 PyObject *self;
547 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000548{
Barry Warsawfa701a81997-01-16 00:15:11 +0000549 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000550}
551
552static PyObject *
553Tkapp_GlobalSetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000554 PyObject *self;
555 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000556{
Barry Warsawfa701a81997-01-16 00:15:11 +0000557 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000558}
559
Barry Warsawfa701a81997-01-16 00:15:11 +0000560
561
Guido van Rossum18468821994-06-20 07:49:28 +0000562static PyObject *
563GetVar (self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000564 PyObject *self;
565 PyObject *args;
566 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000567{
Barry Warsawfa701a81997-01-16 00:15:11 +0000568 char *name1, *name2, *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000569
Barry Warsawfa701a81997-01-16 00:15:11 +0000570 if (PyArg_Parse(args, "s", &name1))
571 s = Tcl_GetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000572
Barry Warsawfa701a81997-01-16 00:15:11 +0000573 else if (PyArg_Parse(args, "(ss)", &name1, &name2))
574 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
575 else
576 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000577
Barry Warsawfa701a81997-01-16 00:15:11 +0000578 if (s == NULL)
579 return Tkinter_Error(self);
580
581 return PyString_FromString (s);
Guido van Rossum18468821994-06-20 07:49:28 +0000582}
583
584static PyObject *
585Tkapp_GetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000586 PyObject *self;
587 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000588{
Barry Warsawfa701a81997-01-16 00:15:11 +0000589 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000590}
591
592static PyObject *
593Tkapp_GlobalGetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000594 PyObject *self;
595 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000596{
Barry Warsawfa701a81997-01-16 00:15:11 +0000597 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000598}
599
Barry Warsawfa701a81997-01-16 00:15:11 +0000600
601
Guido van Rossum18468821994-06-20 07:49:28 +0000602static PyObject *
603UnsetVar (self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000604 PyObject *self;
605 PyObject *args;
606 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000607{
Barry Warsawfa701a81997-01-16 00:15:11 +0000608 char *name1, *name2;
609 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000610
Barry Warsawfa701a81997-01-16 00:15:11 +0000611 if (PyArg_Parse(args, "s", &name1))
612 code = Tcl_UnsetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000613
Barry Warsawfa701a81997-01-16 00:15:11 +0000614 else if (PyArg_Parse(args, "(ss)", &name1, &name2))
615 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
616 else
617 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000618
Barry Warsawfa701a81997-01-16 00:15:11 +0000619 if (code == TCL_ERROR)
620 return Tkinter_Error (self);
621
622 Py_INCREF(Py_None);
623 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000624}
625
626static PyObject *
627Tkapp_UnsetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000628 PyObject *self;
629 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000630{
Barry Warsawfa701a81997-01-16 00:15:11 +0000631 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000632}
633
634static PyObject *
635Tkapp_GlobalUnsetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000636 PyObject *self;
637 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000638{
Barry Warsawfa701a81997-01-16 00:15:11 +0000639 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000640}
641
Barry Warsawfa701a81997-01-16 00:15:11 +0000642
643
Guido van Rossum18468821994-06-20 07:49:28 +0000644/** Tcl to Python **/
645
646static PyObject *
647Tkapp_GetInt (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000648 PyObject *self;
649 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000650{
Barry Warsawfa701a81997-01-16 00:15:11 +0000651 char *s;
652 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000653
Barry Warsawfa701a81997-01-16 00:15:11 +0000654 if (!PyArg_Parse(args, "s", &s))
655 return NULL;
656 if (Tcl_GetInt(Tkapp_Interp (self), s, &v) == TCL_ERROR)
657 return Tkinter_Error(self);
658 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000659}
660
661static PyObject *
662Tkapp_GetDouble (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000663 PyObject *self;
664 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000665{
Barry Warsawfa701a81997-01-16 00:15:11 +0000666 char *s;
667 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000668
Barry Warsawfa701a81997-01-16 00:15:11 +0000669 if (!PyArg_Parse(args, "s", &s))
670 return NULL;
671 if (Tcl_GetDouble(Tkapp_Interp (self), s, &v) == TCL_ERROR)
672 return Tkinter_Error(self);
673 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000674}
675
676static PyObject *
677Tkapp_GetBoolean (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000678 PyObject *self;
679 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000680{
Barry Warsawfa701a81997-01-16 00:15:11 +0000681 char *s;
682 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000683
Barry Warsawfa701a81997-01-16 00:15:11 +0000684 if (!PyArg_Parse(args, "s", &s))
685 return NULL;
686 if (Tcl_GetBoolean(Tkapp_Interp (self), s, &v) == TCL_ERROR)
687 return Tkinter_Error (self);
688 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000689}
690
691static PyObject *
692Tkapp_ExprString (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000693 PyObject *self;
694 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000695{
Barry Warsawfa701a81997-01-16 00:15:11 +0000696 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000697
Barry Warsawfa701a81997-01-16 00:15:11 +0000698 if (!PyArg_Parse(args, "s", &s))
699 return NULL;
700 if (Tcl_ExprString (Tkapp_Interp (self), s) == TCL_ERROR)
701 return Tkinter_Error(self);
702 return Py_BuildValue("s", Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000703}
704
705static PyObject *
706Tkapp_ExprLong (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000707 PyObject *self;
708 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000709{
Barry Warsawfa701a81997-01-16 00:15:11 +0000710 char *s;
711 long v;
Guido van Rossum18468821994-06-20 07:49:28 +0000712
Barry Warsawfa701a81997-01-16 00:15:11 +0000713 if (!PyArg_Parse(args, "s", &s))
714 return NULL;
715 if (Tcl_ExprLong(Tkapp_Interp(self), s, &v) == TCL_ERROR)
716 return Tkinter_Error(self);
717 return Py_BuildValue("l", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000718}
719
720static PyObject *
721Tkapp_ExprDouble (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000722 PyObject *self;
723 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000724{
Barry Warsawfa701a81997-01-16 00:15:11 +0000725 char *s;
726 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000727 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000728
Barry Warsawfa701a81997-01-16 00:15:11 +0000729 if (!PyArg_Parse(args, "s", &s))
730 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000731 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
732 retval = Tcl_ExprDouble (Tkapp_Interp (self), s, &v);
Guido van Rossum45b83911997-03-14 04:32:50 +0000733 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000734 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000735 return Tkinter_Error(self);
736 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000737}
738
739static PyObject *
740Tkapp_ExprBoolean (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000741 PyObject *self;
742 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000743{
Barry Warsawfa701a81997-01-16 00:15:11 +0000744 char *s;
745 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000746
Barry Warsawfa701a81997-01-16 00:15:11 +0000747 if (!PyArg_Parse(args, "s", &s))
748 return NULL;
749 if (Tcl_ExprBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
750 return Tkinter_Error(self);
751 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000752}
753
Barry Warsawfa701a81997-01-16 00:15:11 +0000754
755
Guido van Rossum18468821994-06-20 07:49:28 +0000756static PyObject *
757Tkapp_SplitList (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000758 PyObject *self;
759 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000760{
Barry Warsawfa701a81997-01-16 00:15:11 +0000761 char *list;
762 int argc;
763 char **argv;
764 PyObject *v;
765 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000766
Barry Warsawfa701a81997-01-16 00:15:11 +0000767 if (!PyArg_Parse(args, "s", &list))
768 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000769
Barry Warsawfa701a81997-01-16 00:15:11 +0000770 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
771 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000772
Barry Warsawfa701a81997-01-16 00:15:11 +0000773 if (!(v = PyTuple_New(argc)))
774 return NULL;
775
776 for (i = 0; i < argc; i++) {
777 PyObject *s = PyString_FromString(argv[i]);
778 if (!s || PyTuple_SetItem(v, i, s)) {
779 Py_DECREF(v);
780 v = NULL;
781 goto finally;
782 }
783 }
Guido van Rossum18468821994-06-20 07:49:28 +0000784
Barry Warsawfa701a81997-01-16 00:15:11 +0000785 finally:
786 ckfree(FREECAST argv);
787 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000788}
789
790static PyObject *
791Tkapp_Split (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000792 PyObject *self;
793 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000794{
Barry Warsawfa701a81997-01-16 00:15:11 +0000795 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000796
Barry Warsawfa701a81997-01-16 00:15:11 +0000797 if (!PyArg_Parse(args, "s", &list))
798 return NULL;
799 return Split(self, list);
Guido van Rossum18468821994-06-20 07:49:28 +0000800}
801
802static PyObject *
803Tkapp_Merge (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000804 PyObject *self;
805 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000806{
Barry Warsawfa701a81997-01-16 00:15:11 +0000807 char *s = Merge(args);
808 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000809
Barry Warsawfa701a81997-01-16 00:15:11 +0000810 if (s) {
811 res = PyString_FromString(s);
812 ckfree(s);
813 }
814 else
815 PyErr_SetString(Tkinter_TclError, "merge failed");
816
817 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000818}
819
Barry Warsawfa701a81997-01-16 00:15:11 +0000820
821
Guido van Rossum18468821994-06-20 07:49:28 +0000822/** Tcl Command **/
823
824/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +0000825 * function or method.
826 */
Guido van Rossum18468821994-06-20 07:49:28 +0000827static int
828PythonCmd (clientData, interp, argc, argv)
Barry Warsawfa701a81997-01-16 00:15:11 +0000829 ClientData clientData; /* Is (self, func) */
830 Tcl_Interp *interp;
831 int argc;
832 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +0000833{
Barry Warsawfa701a81997-01-16 00:15:11 +0000834 PyObject *self, *func, *arg, *res, *tmp;
835 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000836
Barry Warsawfa701a81997-01-16 00:15:11 +0000837 /* TBD: no error checking here since we know, via the
838 * Tkapp_CreateCommand() that the client data is a two-tuple
839 */
840 self = PyTuple_GetItem((PyObject *) clientData, 0);
841 func = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000842
Barry Warsawfa701a81997-01-16 00:15:11 +0000843 /* Create argument list (argv1, ..., argvN) */
844 if (!(arg = PyTuple_New(argc - 1)))
845 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000846
Barry Warsawfa701a81997-01-16 00:15:11 +0000847 for (i = 0; i < (argc - 1); i++) {
848 PyObject *s = PyString_FromString(argv[i + 1]);
849 if (!s || PyTuple_SetItem(arg, i, s)) {
850 Py_DECREF(arg);
851 PythonCmd_Error(interp);
852 }
853 }
854 res = PyEval_CallObject(func, arg);
855 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +0000856
Barry Warsawfa701a81997-01-16 00:15:11 +0000857 if (res == NULL)
858 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +0000859
Barry Warsawfa701a81997-01-16 00:15:11 +0000860 if (!(tmp = PyList_New(0))) {
861 Py_DECREF(res);
862 return PythonCmd_Error(interp);
863 }
864
865 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
866 Py_DECREF(res);
867 Py_DECREF(tmp);
868
869 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000870}
871
872static void
873PythonCmdDelete (clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +0000874 ClientData clientData; /* Is (self, func) */
Guido van Rossum18468821994-06-20 07:49:28 +0000875{
Barry Warsawfa701a81997-01-16 00:15:11 +0000876 Py_DECREF((PyObject *) clientData);
Guido van Rossum18468821994-06-20 07:49:28 +0000877}
878
Barry Warsawfa701a81997-01-16 00:15:11 +0000879
880
Guido van Rossum18468821994-06-20 07:49:28 +0000881static PyObject *
882Tkapp_CreateCommand (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000883 PyObject *self;
884 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000885{
Barry Warsawfa701a81997-01-16 00:15:11 +0000886 char *cmdName;
887 PyObject *data;
888 PyObject *func;
Guido van Rossum18468821994-06-20 07:49:28 +0000889
Barry Warsawfa701a81997-01-16 00:15:11 +0000890 /* Args is: (cmdName, func) */
891 if (!PyTuple_Check(args)
892 || !(PyTuple_Size(args) == 2)
893 || !PyString_Check(PyTuple_GetItem(args, 0))
894 || !PyCallable_Check(PyTuple_GetItem(args, 1)))
895 {
896 PyErr_SetString (PyExc_TypeError, "bad argument list");
897 return NULL;
898 }
Guido van Rossum18468821994-06-20 07:49:28 +0000899
Barry Warsawfa701a81997-01-16 00:15:11 +0000900 cmdName = PyString_AsString(PyTuple_GetItem(args, 0));
901 func = PyTuple_GetItem(args, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000902
Barry Warsawfa701a81997-01-16 00:15:11 +0000903 data = PyTuple_New(2); /* ClientData is: (self, func) */
904 if (!data)
905 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000906
Barry Warsawfa701a81997-01-16 00:15:11 +0000907 Py_INCREF(self);
908 PyTuple_SetItem(data, 0, self);
Guido van Rossum18468821994-06-20 07:49:28 +0000909
Barry Warsawfa701a81997-01-16 00:15:11 +0000910 Py_INCREF(func);
911 PyTuple_SetItem(data, 1, func);
Guido van Rossum18468821994-06-20 07:49:28 +0000912
Barry Warsawfa701a81997-01-16 00:15:11 +0000913 Tcl_CreateCommand(Tkapp_Interp (self), cmdName, PythonCmd,
914 (ClientData) data, PythonCmdDelete);
Guido van Rossum18468821994-06-20 07:49:28 +0000915
Barry Warsawfa701a81997-01-16 00:15:11 +0000916 Py_INCREF(Py_None);
917 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000918}
919
Barry Warsawfa701a81997-01-16 00:15:11 +0000920
921
Guido van Rossum18468821994-06-20 07:49:28 +0000922static PyObject *
923Tkapp_DeleteCommand (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000924 PyObject *self;
925 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000926{
Barry Warsawfa701a81997-01-16 00:15:11 +0000927 char *cmdName;
Guido van Rossum18468821994-06-20 07:49:28 +0000928
Barry Warsawfa701a81997-01-16 00:15:11 +0000929 if (!PyArg_Parse(args, "s", &cmdName))
930 return NULL;
931 if (Tcl_DeleteCommand(Tkapp_Interp(self), cmdName) == -1)
932 {
933 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
934 return NULL;
935 }
936 Py_INCREF(Py_None);
937 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000938}
939
Barry Warsawfa701a81997-01-16 00:15:11 +0000940
941
Guido van Rossum18468821994-06-20 07:49:28 +0000942/** File Handler **/
943
Guido van Rossuma597dde1995-01-10 20:56:29 +0000944static void
Guido van Rossum18468821994-06-20 07:49:28 +0000945FileHandler (clientData, mask)
Barry Warsawfa701a81997-01-16 00:15:11 +0000946 ClientData clientData; /* Is: (func, file) */
947 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +0000948{
Barry Warsawfa701a81997-01-16 00:15:11 +0000949 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +0000950
Barry Warsawfa701a81997-01-16 00:15:11 +0000951 func = PyTuple_GetItem((PyObject *) clientData, 0);
952 file = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000953
Barry Warsawfa701a81997-01-16 00:15:11 +0000954 arg = Py_BuildValue("(Oi)", file, (long) mask);
955 res = PyEval_CallObject(func, arg);
956 Py_DECREF (arg);
957
958 if (res == NULL) {
959 errorInCmd = 1;
960 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
961 }
962 Py_XDECREF(res);
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000963}
964
965static int
966GetFileNo (file)
Barry Warsawfa701a81997-01-16 00:15:11 +0000967 /* Either an int >= 0 or an object with a
968 *.fileno() method that returns an int >= 0
969 */
970 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000971{
Guido van Rossuma597dde1995-01-10 20:56:29 +0000972 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000973 int id;
974 if (PyInt_Check(file)) {
975 id = PyInt_AsLong(file);
976 if (id < 0)
977 PyErr_SetString(PyExc_ValueError, "invalid file id");
978 return id;
979 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000980 args = PyTuple_New(0);
981 if (args == NULL)
982 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000983
984 meth = PyObject_GetAttrString(file, "fileno");
985 if (meth == NULL) {
986 Py_DECREF(args);
987 return -1;
988 }
989
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000990 res = PyEval_CallObject(meth, args);
991 Py_DECREF(args);
992 Py_DECREF(meth);
993 if (res == NULL)
994 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000995
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000996 if (PyInt_Check(res))
997 id = PyInt_AsLong(res);
998 else
999 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001000
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001001 if (id < 0)
1002 PyErr_SetString(PyExc_ValueError,
1003 "invalid fileno() return value");
1004 Py_DECREF(res);
1005 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001006}
1007
Barry Warsawfa701a81997-01-16 00:15:11 +00001008
1009static PyObject* Tkapp_ClientDataDict = NULL;
1010
Guido van Rossum18468821994-06-20 07:49:28 +00001011static PyObject *
1012Tkapp_CreateFileHandler (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001013 PyObject *self;
1014 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001015{
Barry Warsawfa701a81997-01-16 00:15:11 +00001016 PyObject *file, *func, *data;
1017 PyObject *idkey;
1018 int mask, id;
Guido van Rossum68784361996-05-16 17:17:31 +00001019#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Barry Warsawfa701a81997-01-16 00:15:11 +00001020 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001021#endif
Guido van Rossum18468821994-06-20 07:49:28 +00001022
Barry Warsawfa701a81997-01-16 00:15:11 +00001023 if (!Tkapp_ClientDataDict) {
1024 if (!(Tkapp_ClientDataDict = PyDict_New()))
1025 return NULL;
1026 }
Guido van Rossum18468821994-06-20 07:49:28 +00001027
Barry Warsawfa701a81997-01-16 00:15:11 +00001028 if (!PyArg_Parse(args, "(OiO)", &file, &mask, &func))
1029 return NULL;
1030 id = GetFileNo(file);
1031 if (id < 0)
1032 return NULL;
1033 if (!PyCallable_Check(func)) {
1034 PyErr_SetString (PyExc_TypeError, "bad argument list");
1035 return NULL;
1036 }
1037
1038 if (!(idkey = PyInt_FromLong(id)))
1039 return NULL;
1040
1041 /* ClientData is: (func, file) */
1042 data = Py_BuildValue ("(OO)", func, file);
1043 if (!data || PyDict_SetItem(Tkapp_ClientDataDict, idkey, data)) {
1044 Py_DECREF(idkey);
1045 Py_XDECREF(data);
1046 return NULL;
1047 }
1048 Py_DECREF(idkey);
Guido van Rossum76875221994-06-27 07:59:42 +00001049
Guido van Rossum68784361996-05-16 17:17:31 +00001050#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Guido van Rossum07886d01996-09-11 23:31:42 +00001051#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001052 /* We assume this is a socket... */
1053 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum845547d1996-06-26 18:26:04 +00001054#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001055 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +00001056#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001057 /* Ought to check for null Tcl_File object... */
1058 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum68784361996-05-16 17:17:31 +00001059#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001060 Tk_CreateFileHandler(id, mask, FileHandler, (ClientData) data);
Guido van Rossum68784361996-05-16 17:17:31 +00001061#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001062 /* XXX fileHandlerDict */
1063 Py_INCREF (Py_None);
1064 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001065}
1066
Barry Warsawfa701a81997-01-16 00:15:11 +00001067
Guido van Rossum18468821994-06-20 07:49:28 +00001068static PyObject *
1069Tkapp_DeleteFileHandler (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001070 PyObject *self;
1071 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001072{
Barry Warsawfa701a81997-01-16 00:15:11 +00001073 PyObject *file;
1074 PyObject *idkey;
1075 PyObject *data;
1076 int id;
Guido van Rossum68784361996-05-16 17:17:31 +00001077#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Barry Warsawfa701a81997-01-16 00:15:11 +00001078 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001079#endif
1080
Barry Warsawfa701a81997-01-16 00:15:11 +00001081 if (!PyArg_Parse(args, "O", &file))
1082 return NULL;
1083 id = GetFileNo(file);
1084 if (id < 0)
1085 return NULL;
1086
1087 if (!(idkey = PyInt_FromLong(id)))
1088 return NULL;
1089
1090 /* find and free the object created in the
1091 * Tkapp_CreateFileHandler() call
1092 */
1093 data = PyDict_GetItem(Tkapp_ClientDataDict, idkey);
1094 Py_XDECREF(data);
1095 PyDict_DelItem(Tkapp_ClientDataDict, idkey);
1096 Py_DECREF(idkey);
Guido van Rossum18468821994-06-20 07:49:28 +00001097
Guido van Rossum68784361996-05-16 17:17:31 +00001098#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Guido van Rossum07886d01996-09-11 23:31:42 +00001099#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001100 /* We assume this is a socket... */
1101 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum845547d1996-06-26 18:26:04 +00001102#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001103 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +00001104#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001105 /* Ought to check for null Tcl_File object... */
1106 Tcl_DeleteFileHandler(tfile);
Guido van Rossum68784361996-05-16 17:17:31 +00001107#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001108 Tk_DeleteFileHandler(id);
Guido van Rossum68784361996-05-16 17:17:31 +00001109#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001110 /* XXX fileHandlerDict */
1111 Py_INCREF (Py_None);
1112 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001113}
1114
Barry Warsawfa701a81997-01-16 00:15:11 +00001115
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001116/**** Tktt Object (timer token) ****/
1117
1118staticforward PyTypeObject Tktt_Type;
1119
1120typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +00001121{
1122 PyObject_HEAD
1123 Tk_TimerToken token;
1124 PyObject *func;
1125}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001126TkttObject;
1127
1128static PyObject *
1129Tktt_DeleteTimerHandler (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001130 PyObject *self;
1131 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001132{
Barry Warsawfa701a81997-01-16 00:15:11 +00001133 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001134
Barry Warsawfa701a81997-01-16 00:15:11 +00001135 if (!PyArg_Parse(args, ""))
1136 return NULL;
1137 if (v->func != NULL) {
1138 Tk_DeleteTimerHandler(v->token);
1139 PyMem_DEL(v->func);
1140 v->func = NULL;
1141 }
1142 Py_INCREF(Py_None);
1143 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001144}
1145
1146static PyMethodDef Tktt_methods[] =
1147{
Barry Warsawfa701a81997-01-16 00:15:11 +00001148 {"deletetimerhandler", Tktt_DeleteTimerHandler},
1149 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001150};
1151
1152static TkttObject *
1153Tktt_New (token, func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001154 Tk_TimerToken token;
1155 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001156{
Barry Warsawfa701a81997-01-16 00:15:11 +00001157 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001158
Barry Warsawfa701a81997-01-16 00:15:11 +00001159 v = PyObject_NEW(TkttObject, &Tktt_Type);
1160 if (v == NULL)
1161 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001162
Barry Warsawfa701a81997-01-16 00:15:11 +00001163 v->token = token;
1164 v->func = func;
1165 Py_INCREF(v->func);
1166 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001167}
1168
1169static void
1170Tktt_Dealloc (self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001171 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001172{
Barry Warsawfa701a81997-01-16 00:15:11 +00001173 PyMem_DEL (self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001174}
1175
1176static int
1177Tktt_Print (self, fp, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +00001178 PyObject *self;
1179 FILE *fp;
1180 int flags;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001181{
Barry Warsawfa701a81997-01-16 00:15:11 +00001182 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001183
Barry Warsawfa701a81997-01-16 00:15:11 +00001184 fprintf(fp, "<tktimertoken at 0x%lx%s>", (long)v,
1185 v->func == NULL ? ", handler deleted" : "");
1186 return 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001187}
1188
1189static PyObject *
1190Tktt_GetAttr (self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001191 PyObject *self;
1192 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001193{
Barry Warsawfa701a81997-01-16 00:15:11 +00001194 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001195}
1196
1197static PyTypeObject Tktt_Type =
1198{
Barry Warsawfa701a81997-01-16 00:15:11 +00001199 PyObject_HEAD_INIT (NULL)
1200 0, /*ob_size */
1201 "tktimertoken", /*tp_name */
1202 sizeof (TkttObject), /*tp_basicsize */
1203 0, /*tp_itemsize */
1204 Tktt_Dealloc, /*tp_dealloc */
1205 Tktt_Print, /*tp_print */
1206 Tktt_GetAttr, /*tp_getattr */
1207 0, /*tp_setattr */
1208 0, /*tp_compare */
1209 0, /*tp_repr */
1210 0, /*tp_as_number */
1211 0, /*tp_as_sequence */
1212 0, /*tp_as_mapping */
1213 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001214};
1215
Barry Warsawfa701a81997-01-16 00:15:11 +00001216
1217
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001218/** Timer Handler **/
1219
1220static void
1221TimerHandler (clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001222 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001223{
Barry Warsawfa701a81997-01-16 00:15:11 +00001224 PyObject *func = (PyObject *)clientData;
1225 PyObject *res = PyEval_CallObject(func, NULL);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001226
Barry Warsawfa701a81997-01-16 00:15:11 +00001227 if (res == NULL) {
1228 errorInCmd = 1;
1229 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1230 }
1231 else
1232 Py_DECREF(res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001233}
1234
1235static PyObject *
1236Tkapp_CreateTimerHandler (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001237 PyObject *self;
1238 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001239{
Barry Warsawfa701a81997-01-16 00:15:11 +00001240 int milliseconds;
1241 PyObject *func;
1242 Tk_TimerToken token;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001243
Barry Warsawfa701a81997-01-16 00:15:11 +00001244 if (!PyArg_Parse(args, "(iO)", &milliseconds, &func))
1245 return NULL;
1246 if (!PyCallable_Check(func)) {
1247 PyErr_SetString (PyExc_TypeError, "bad argument list");
1248 return NULL;
1249 }
1250 token = Tk_CreateTimerHandler(milliseconds, TimerHandler,
1251 (ClientData)func);
1252
1253 return (PyObject *) Tktt_New(token, func);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001254}
1255
Barry Warsawfa701a81997-01-16 00:15:11 +00001256
1257
Guido van Rossum18468821994-06-20 07:49:28 +00001258/** Event Loop **/
1259
Guido van Rossum18468821994-06-20 07:49:28 +00001260static PyObject *
1261Tkapp_MainLoop (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001262 PyObject *self;
1263 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001264{
Barry Warsawfa701a81997-01-16 00:15:11 +00001265 int threshold = 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001266
Barry Warsawfa701a81997-01-16 00:15:11 +00001267 if (!PyArg_ParseTuple(args, "|i", &threshold))
1268 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001269
Barry Warsawfa701a81997-01-16 00:15:11 +00001270 quitMainLoop = 0;
1271 while (Tk_GetNumMainWindows() > threshold &&
1272 !quitMainLoop &&
1273 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001274 {
Barry Warsawfa701a81997-01-16 00:15:11 +00001275 /* XXX Ought to check for other signals! */
1276 if (PyOS_InterruptOccurred()) {
1277 PyErr_SetNone(PyExc_KeyboardInterrupt);
1278 return NULL;
1279 }
1280 Tk_DoOneEvent(0);
Guido van Rossum18468821994-06-20 07:49:28 +00001281 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001282 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001283
Barry Warsawfa701a81997-01-16 00:15:11 +00001284 if (errorInCmd) {
1285 errorInCmd = 0;
1286 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1287 excInCmd = valInCmd = trbInCmd = NULL;
1288 return NULL;
1289 }
1290 Py_INCREF(Py_None);
1291 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001292}
1293
1294static PyObject *
Guido van Rossum062cfb01995-01-10 17:42:51 +00001295Tkapp_DoOneEvent (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001296 PyObject *self;
1297 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001298{
Barry Warsawfa701a81997-01-16 00:15:11 +00001299 int flags = TK_ALL_EVENTS;
1300 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001301
Barry Warsawfa701a81997-01-16 00:15:11 +00001302 if (!PyArg_ParseTuple(args, "|i", &flags))
1303 return NULL;
1304
1305 rv = Tk_DoOneEvent(flags);
1306 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001307}
1308
1309static PyObject *
Guido van Rossum18468821994-06-20 07:49:28 +00001310Tkapp_Quit (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001311 PyObject *self;
1312 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001313{
1314
Barry Warsawfa701a81997-01-16 00:15:11 +00001315 if (!PyArg_Parse(args, ""))
1316 return NULL;
1317
1318 quitMainLoop = 1;
1319 Py_INCREF(Py_None);
1320 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001321}
1322
Barry Warsawfa701a81997-01-16 00:15:11 +00001323
1324
Guido van Rossum18468821994-06-20 07:49:28 +00001325/**** Tkapp Method List ****/
1326
1327static PyMethodDef Tkapp_methods[] =
1328{
Barry Warsawfa701a81997-01-16 00:15:11 +00001329 {"call", Tkapp_Call},
1330 {"globalcall", Tkapp_GlobalCall},
1331 {"eval", Tkapp_Eval},
1332 {"globaleval", Tkapp_GlobalEval},
1333 {"evalfile", Tkapp_EvalFile},
1334 {"record", Tkapp_Record},
1335 {"adderrorinfo", Tkapp_AddErrorInfo},
1336 {"setvar", Tkapp_SetVar},
1337 {"globalsetvar", Tkapp_GlobalSetVar},
1338 {"getvar", Tkapp_GetVar},
1339 {"globalgetvar", Tkapp_GlobalGetVar},
1340 {"unsetvar", Tkapp_UnsetVar},
1341 {"globalunsetvar", Tkapp_GlobalUnsetVar},
1342 {"getint", Tkapp_GetInt},
1343 {"getdouble", Tkapp_GetDouble},
1344 {"getboolean", Tkapp_GetBoolean},
1345 {"exprstring", Tkapp_ExprString},
1346 {"exprlong", Tkapp_ExprLong},
1347 {"exprdouble", Tkapp_ExprDouble},
1348 {"exprboolean", Tkapp_ExprBoolean},
1349 {"splitlist", Tkapp_SplitList},
1350 {"split", Tkapp_Split},
1351 {"merge", Tkapp_Merge},
1352 {"createcommand", Tkapp_CreateCommand},
1353 {"deletecommand", Tkapp_DeleteCommand},
1354 {"createfilehandler", Tkapp_CreateFileHandler},
1355 {"deletefilehandler", Tkapp_DeleteFileHandler},
1356 {"createtimerhandler", Tkapp_CreateTimerHandler},
1357 {"mainloop", Tkapp_MainLoop, 1},
1358 {"dooneevent", Tkapp_DoOneEvent, 1},
1359 {"quit", Tkapp_Quit},
1360 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001361};
1362
Barry Warsawfa701a81997-01-16 00:15:11 +00001363
1364
Guido van Rossum18468821994-06-20 07:49:28 +00001365/**** Tkapp Type Methods ****/
1366
1367static void
1368Tkapp_Dealloc (self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001369 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001370{
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001371#ifdef NEED_TKCREATEMAINWINDOW
Barry Warsawfa701a81997-01-16 00:15:11 +00001372 Tk_DestroyWindow (Tkapp_Tkwin (self));
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001373#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001374 Tcl_DeleteInterp (Tkapp_Interp (self));
1375 PyMem_DEL (self);
Guido van Rossum18468821994-06-20 07:49:28 +00001376}
1377
1378static PyObject *
1379Tkapp_GetAttr (self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001380 PyObject *self;
1381 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001382{
Barry Warsawfa701a81997-01-16 00:15:11 +00001383 return Py_FindMethod (Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001384}
1385
1386static PyTypeObject Tkapp_Type =
1387{
Barry Warsawfa701a81997-01-16 00:15:11 +00001388 PyObject_HEAD_INIT (NULL)
1389 0, /*ob_size */
1390 "tkapp", /*tp_name */
1391 sizeof (TkappObject), /*tp_basicsize */
1392 0, /*tp_itemsize */
1393 Tkapp_Dealloc, /*tp_dealloc */
1394 0, /*tp_print */
1395 Tkapp_GetAttr, /*tp_getattr */
1396 0, /*tp_setattr */
1397 0, /*tp_compare */
1398 0, /*tp_repr */
1399 0, /*tp_as_number */
1400 0, /*tp_as_sequence */
1401 0, /*tp_as_mapping */
1402 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001403};
1404
Barry Warsawfa701a81997-01-16 00:15:11 +00001405
1406
Guido van Rossum18468821994-06-20 07:49:28 +00001407/**** Tkinter Module ****/
1408
1409static PyObject *
1410Tkinter_Create (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001411 PyObject *self;
1412 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001413{
Barry Warsawfa701a81997-01-16 00:15:11 +00001414 char *screenName = NULL;
1415 char *baseName = NULL;
1416 char *className = NULL;
1417 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001418
Barry Warsawfa701a81997-01-16 00:15:11 +00001419 baseName = strrchr(Py_GetProgramName (), '/');
1420 if (baseName != NULL)
1421 baseName++;
1422 else
1423 baseName = Py_GetProgramName();
1424 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001425
Barry Warsawfa701a81997-01-16 00:15:11 +00001426 if (!PyArg_ParseTuple(args, "|zssi",
1427 &screenName, &baseName, &className,
1428 &interactive))
1429 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001430
Barry Warsawfa701a81997-01-16 00:15:11 +00001431 return (PyObject *) Tkapp_New(screenName, baseName, className,
1432 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001433}
1434
1435static PyMethodDef moduleMethods[] =
1436{
Barry Warsawfa701a81997-01-16 00:15:11 +00001437 {"create", Tkinter_Create, 1},
1438 {"createfilehandler", Tkapp_CreateFileHandler, 0},
1439 {"deletefilehandler", Tkapp_DeleteFileHandler, 0},
1440 {"createtimerhandler", Tkapp_CreateTimerHandler, 0},
1441 {"mainloop", Tkapp_MainLoop, 1},
1442 {"dooneevent", Tkapp_DoOneEvent, 1},
1443 {"quit", Tkapp_Quit},
1444 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001445};
1446
1447#ifdef WITH_READLINE
1448static int
1449EventHook ()
1450{
Barry Warsawfa701a81997-01-16 00:15:11 +00001451 /* XXX Reset tty */
1452 if (errorInCmd) {
1453 errorInCmd = 0;
1454 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1455 excInCmd = valInCmd = trbInCmd = NULL;
1456 PyErr_Print();
1457 }
1458 if (Tk_GetNumMainWindows() > 0)
1459 Tk_DoOneEvent(TK_DONT_WAIT);
1460 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001461}
1462#endif /* WITH_READLINE */
1463
1464static void
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001465Tkinter_Cleanup ()
1466{
Barry Warsawfa701a81997-01-16 00:15:11 +00001467 /* This segfault with Tk 4.0 beta and seems unnecessary there as
1468 * well */
1469
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001470#if TK_MAJOR_VERSION < 4
Barry Warsawfa701a81997-01-16 00:15:11 +00001471 /* XXX rl_deprep_terminal is static, damned! */
1472 while (tkMainWindowList != 0)
1473 Tk_DestroyWindow(tkMainWindowList->win);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001474#endif
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001475}
1476
Barry Warsawfa701a81997-01-16 00:15:11 +00001477
1478/* all errors will be checked in one fell swoop in init_tkinter() */
1479static void
1480ins_long(d, name, val)
1481 PyObject *d;
1482 char *name;
1483 long val;
1484{
1485 PyObject *v = PyInt_FromLong(val);
1486 if (v) {
1487 PyDict_SetItemString(d, name, v);
1488 Py_DECREF(v);
1489 }
1490}
1491static void
1492ins_string(d, name, val)
1493 PyObject *d;
1494 char *name;
1495 char *val;
1496{
1497 PyObject *v = PyString_FromString(val);
1498 if (v) {
1499 PyDict_SetItemString(d, name, v);
1500 Py_DECREF(v);
1501 }
1502}
1503
1504
Guido van Rossum18468821994-06-20 07:49:28 +00001505void
Guido van Rossumad1f7ee1996-02-13 00:11:37 +00001506init_tkinter ()
Guido van Rossum18468821994-06-20 07:49:28 +00001507{
Barry Warsawfa701a81997-01-16 00:15:11 +00001508 static inited = 0;
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001509
Guido van Rossum18468821994-06-20 07:49:28 +00001510#ifdef WITH_READLINE
Barry Warsawfa701a81997-01-16 00:15:11 +00001511 extern int (*rl_event_hook) ();
Guido van Rossum18468821994-06-20 07:49:28 +00001512#endif /* WITH_READLINE */
Barry Warsawfa701a81997-01-16 00:15:11 +00001513 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001514
Barry Warsawfa701a81997-01-16 00:15:11 +00001515 Tkapp_Type.ob_type = &PyType_Type;
1516 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossumae92f011996-08-21 19:03:36 +00001517
Barry Warsawfa701a81997-01-16 00:15:11 +00001518 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001519
Barry Warsawfa701a81997-01-16 00:15:11 +00001520 d = PyModule_GetDict(m);
1521 Tkinter_TclError = Py_BuildValue("s", "TclError");
1522 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00001523
Barry Warsawfa701a81997-01-16 00:15:11 +00001524 ins_long(d, "READABLE", TK_READABLE);
1525 ins_long(d, "WRITABLE", TK_WRITABLE);
1526 ins_long(d, "EXCEPTION", TK_EXCEPTION);
1527 ins_long(d, "X_EVENTS", TK_X_EVENTS);
1528 ins_long(d, "FILE_EVENTS", TK_FILE_EVENTS);
1529 ins_long(d, "TIMER_EVENTS", TK_TIMER_EVENTS);
1530 ins_long(d, "IDLE_EVENTS", TK_IDLE_EVENTS);
1531 ins_long(d, "ALL_EVENTS", TK_ALL_EVENTS);
1532 ins_long(d, "DONT_WAIT", TK_DONT_WAIT);
1533 ins_string(d, "TK_VERSION", TK_VERSION);
1534 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00001535
Guido van Rossum18468821994-06-20 07:49:28 +00001536#ifdef WITH_READLINE
Barry Warsawfa701a81997-01-16 00:15:11 +00001537 rl_event_hook = EventHook;
Guido van Rossum18468821994-06-20 07:49:28 +00001538#endif /* WITH_READLINE */
1539
Barry Warsawfa701a81997-01-16 00:15:11 +00001540 if (!inited) {
1541 inited = 1;
1542 if (Py_AtExit(Tkinter_Cleanup) != 0)
1543 fprintf(stderr,
1544 "Tkinter: warning: cleanup procedure not registered\n");
1545 }
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001546
Barry Warsawfa701a81997-01-16 00:15:11 +00001547 if (PyErr_Occurred())
1548 Py_FatalError ("can't initialize module _tkinter");
Jack Jansen34cc5c31995-10-31 16:15:12 +00001549#ifdef macintosh
Barry Warsawfa701a81997-01-16 00:15:11 +00001550 TclMacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00001551#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00001552 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001553#endif /* GENERATINGCFM */
1554#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001555}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001556
Guido van Rossumec22c921996-02-25 04:50:29 +00001557
Barry Warsawfa701a81997-01-16 00:15:11 +00001558
Guido van Rossum9722ad81995-09-22 23:49:28 +00001559#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001560
1561/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001562** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001563*/
1564
Guido van Rossum9722ad81995-09-22 23:49:28 +00001565void
1566panic(char * format, ...)
1567{
Barry Warsawfa701a81997-01-16 00:15:11 +00001568 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001569
Barry Warsawfa701a81997-01-16 00:15:11 +00001570 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001571
Barry Warsawfa701a81997-01-16 00:15:11 +00001572 vfprintf(stderr, format, varg);
1573 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001574
Barry Warsawfa701a81997-01-16 00:15:11 +00001575 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001576
Barry Warsawfa701a81997-01-16 00:15:11 +00001577 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00001578}
Jack Jansen40b546d1995-11-14 10:34:45 +00001579
Guido van Rossumec22c921996-02-25 04:50:29 +00001580/*
1581** Pass events to SIOUX before passing them to Tk.
1582*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001583
Guido van Rossumec22c921996-02-25 04:50:29 +00001584static int
1585PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00001586 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001587{
Barry Warsawfa701a81997-01-16 00:15:11 +00001588 if (SIOUXHandleOneEvent(eventPtr))
1589 return 0; /* Nothing happened to the Tcl event queue */
1590 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001591}
1592
Guido van Rossumec22c921996-02-25 04:50:29 +00001593#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001594
1595/*
1596** Additional Mac specific code for dealing with shared libraries.
1597*/
1598
1599#include <Resources.h>
1600#include <CodeFragments.h>
1601
1602static int loaded_from_shlib = 0;
1603static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001604
Jack Jansen34cc5c31995-10-31 16:15:12 +00001605/*
1606** If this module is dynamically loaded the following routine should
1607** be the init routine. It takes care of adding the shared library to
1608** the resource-file chain, so that the tk routines can find their
1609** resources.
1610*/
1611OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001612init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00001613{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00001614 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00001615 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001616 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001617 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1618 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001619 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001620 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1621 loaded_from_shlib = 1;
1622 }
1623 return noErr;
1624}
1625
1626/*
1627** Insert the library resources into the search path. Put them after
1628** the resources from the application. Again, we ignore errors.
1629*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001630static
Jack Jansen34cc5c31995-10-31 16:15:12 +00001631mac_addlibresources()
1632{
1633 if ( !loaded_from_shlib )
1634 return;
1635 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1636}
1637
Guido van Rossumec22c921996-02-25 04:50:29 +00001638#endif /* GENERATINGCFM */
1639#endif /* macintosh */