blob: 1de3372aec9fba4f157c664a1c402819f332481e [file] [log] [blame]
Guido van Rossum845547d1996-06-26 18:26:04 +00001/***********************************************************
2Copyright (C) 1994 Steen Lumholt.
3Copyright 1994-1995 by Stichting Mathematisch Centrum, Amsterdam,
4The Netherlands.
5
6 All Rights Reserved
7
Guido van Rossumd266eb41996-10-25 14:44:06 +00008Permission to use, copy, modify, and distribute this software and its
9documentation for any purpose and without fee is hereby granted,
Guido van Rossum845547d1996-06-26 18:26:04 +000010provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000011both that copyright notice and this permission notice appear in
Guido van Rossum845547d1996-06-26 18:26:04 +000012supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000013Centrum or CWI or Corporation for National Research Initiatives or
14CNRI not be used in advertising or publicity pertaining to
15distribution of the software without specific, written prior
16permission.
Guido van Rossum845547d1996-06-26 18:26:04 +000017
Guido van Rossumd266eb41996-10-25 14:44:06 +000018While CWI is the initial source for this software, a modified version
19is made available by the Corporation for National Research Initiatives
20(CNRI) at the Internet address ftp://ftp.python.org.
21
22STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
23REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
24MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
25CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
26DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
27PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
28TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum845547d1996-06-26 18:26:04 +000030
31******************************************************************/
32
33/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +000034
Guido van Rossum7ffa7611996-08-13 21:10:16 +000035/* TCL/TK VERSION INFO:
36
37 Unix:
Guido van Rossum496f8f61997-07-19 19:57:42 +000038 Tcl/Tk 8.0 (even alpha or beta) or 7.6/4.2 are recommended.
39 This should work with any version from 7.4/4.0 upwards.
40 Tk 3.x is no longer supported.
Guido van Rossum7ffa7611996-08-13 21:10:16 +000041
42 Mac and Windows:
Guido van Rossum496f8f61997-07-19 19:57:42 +000043 Use Tcl 8.0 if available (even alpha or beta).
44 The oldest usable version is 4.1p1/7.5p1.
45
Guido van Rossum7ffa7611996-08-13 21:10:16 +000046*/
47
Guido van Rossum9722ad81995-09-22 23:49:28 +000048#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000049#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000050
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000051#ifdef macintosh
52#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000053#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000054#endif
55
Guido van Rossum18468821994-06-20 07:49:28 +000056#include <tcl.h>
57#include <tk.h>
58
Guido van Rossum32aa1a71996-07-31 19:51:15 +000059extern char *Py_GetProgramName ();
Guido van Rossumd308e2b1994-07-07 09:25:12 +000060
Guido van Rossum9722ad81995-09-22 23:49:28 +000061/* Internal declarations from tkInt.h. */
62#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
63extern int Tk_GetNumMainWindows();
64#else
Guido van Rossum18468821994-06-20 07:49:28 +000065extern int tk_NumMainWindows;
Guido van Rossum9722ad81995-09-22 23:49:28 +000066#define Tk_GetNumMainWindows() (tk_NumMainWindows)
Guido van Rossumdfd428d1996-02-25 04:46:40 +000067#define NEED_TKCREATEMAINWINDOW 1
Guido van Rossum9722ad81995-09-22 23:49:28 +000068#endif
69
70#if TK_MAJOR_VERSION < 4
Guido van Rossum496f8f61997-07-19 19:57:42 +000071#error "Tk 3.x is not supported"
Guido van Rossum9722ad81995-09-22 23:49:28 +000072#endif
Guido van Rossum18468821994-06-20 07:49:28 +000073
Guido van Rossumec22c921996-02-25 04:50:29 +000074#ifdef macintosh
75
76/*
77** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +000078** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +000079*/
80
Guido van Rossum7ffa7611996-08-13 21:10:16 +000081/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +000082#define FREECAST (char *)
83
Guido van Rossumec22c921996-02-25 04:50:29 +000084#include <Events.h> /* For EventRecord */
85
86typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
87void TclMacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
88int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
89
90staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
91
92#endif /* macintosh */
93
Guido van Rossum97867b21996-08-08 19:09:53 +000094#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +000095#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +000096#endif
97
Guido van Rossum18468821994-06-20 07:49:28 +000098/**** Tkapp Object Declaration ****/
99
100staticforward PyTypeObject Tkapp_Type;
101
102typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +0000103{
104 PyObject_HEAD
105 Tcl_Interp *interp;
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000106#ifdef NEED_TKCREATEMAINWINDOW
Barry Warsawfa701a81997-01-16 00:15:11 +0000107 Tk_Window tkwin;
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000108#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000109}
Guido van Rossum18468821994-06-20 07:49:28 +0000110TkappObject;
111
112#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000113#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +0000114#define Tkapp_Tkwin(v) (((TkappObject *) (v))->tkwin)
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000115#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000116#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
117#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
118
119#define DEBUG_REFCNT(v) (printf ("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000120(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000121
Barry Warsawfa701a81997-01-16 00:15:11 +0000122
123
Guido van Rossum18468821994-06-20 07:49:28 +0000124/**** Error Handling ****/
125
126static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000127static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000128static int errorInCmd = 0;
129static PyObject *excInCmd;
130static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000131static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000132
Barry Warsawfa701a81997-01-16 00:15:11 +0000133
134
Guido van Rossum18468821994-06-20 07:49:28 +0000135static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000136Tkinter_Error(v)
137 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000138{
Barry Warsawfa701a81997-01-16 00:15:11 +0000139 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
140 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000141}
142
Barry Warsawfa701a81997-01-16 00:15:11 +0000143
Guido van Rossum18468821994-06-20 07:49:28 +0000144int
Barry Warsawfa701a81997-01-16 00:15:11 +0000145PythonCmd_Error(interp)
146 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000147{
Barry Warsawfa701a81997-01-16 00:15:11 +0000148 errorInCmd = 1;
149 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
150 return TCL_ERROR;
Guido van Rossum18468821994-06-20 07:49:28 +0000151}
152
Barry Warsawfa701a81997-01-16 00:15:11 +0000153
154
Guido van Rossum18468821994-06-20 07:49:28 +0000155/**** Utils ****/
Guido van Rossum18468821994-06-20 07:49:28 +0000156static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000157AsString(value, tmp)
158 PyObject *value;
159 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000160{
Barry Warsawfa701a81997-01-16 00:15:11 +0000161 if (PyString_Check (value))
162 return PyString_AsString (value);
163 else {
164 PyObject *v = PyObject_Str(value);
165 PyList_Append(tmp, v);
166 Py_DECREF(v);
167 return PyString_AsString(v);
168 }
Guido van Rossum18468821994-06-20 07:49:28 +0000169}
170
Barry Warsawfa701a81997-01-16 00:15:11 +0000171
172
Guido van Rossum18468821994-06-20 07:49:28 +0000173#define ARGSZ 64
174
175static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000176Merge(args)
177 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000178{
Barry Warsawfa701a81997-01-16 00:15:11 +0000179 PyObject *tmp = NULL;
180 char *argvStore[ARGSZ];
181 char **argv = NULL;
182 int fvStore[ARGSZ];
183 int *fv = NULL;
184 int argc = 0, i;
185 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000186
Barry Warsawfa701a81997-01-16 00:15:11 +0000187 if (!(tmp = PyList_New(0)))
188 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000189
Barry Warsawfa701a81997-01-16 00:15:11 +0000190 argv = argvStore;
191 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000192
Barry Warsawfa701a81997-01-16 00:15:11 +0000193 if (args == NULL)
194 argc = 0;
195
196 else if (!PyTuple_Check(args)) {
197 argc = 1;
198 fv[0] = 0;
199 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000200 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000201 else {
202 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000203
Barry Warsawfa701a81997-01-16 00:15:11 +0000204 if (argc > ARGSZ) {
205 argv = (char **)ckalloc(argc * sizeof (char *));
206 fv = (int *)ckalloc(argc * sizeof (int));
207 if (argv == NULL || fv == NULL) {
208 PyErr_NoMemory();
209 goto finally;
210 }
211 }
212
213 for (i = 0; i < argc; i++) {
214 PyObject *v = PyTuple_GetItem(args, i);
215 if (PyTuple_Check(v)) {
216 fv[i] = 1;
217 if (!(argv[i] = Merge(v)))
218 goto finally;
219 }
220 else if (v == Py_None) {
221 argc = i;
222 break;
223 }
224 else {
225 fv[i] = 0;
226 argv[i] = AsString(v, tmp);
227 }
228 }
Guido van Rossum18468821994-06-20 07:49:28 +0000229 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000230 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000231
Barry Warsawfa701a81997-01-16 00:15:11 +0000232 finally:
233 for (i = 0; i < argc; i++)
234 if (fv[i]) {
235 ckfree(argv[i]);
236 }
237 if (argv != argvStore)
238 ckfree(FREECAST argv);
239 if (fv != fvStore)
240 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000241
Barry Warsawfa701a81997-01-16 00:15:11 +0000242 Py_DECREF(tmp);
243 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000244}
245
Barry Warsawfa701a81997-01-16 00:15:11 +0000246
247
Guido van Rossum18468821994-06-20 07:49:28 +0000248static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000249Split(self, list)
250 PyObject *self;
251 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000252{
Barry Warsawfa701a81997-01-16 00:15:11 +0000253 int argc;
254 char **argv;
255 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000256
Barry Warsawfa701a81997-01-16 00:15:11 +0000257 if (list == NULL) {
258 Py_INCREF(Py_None);
259 return Py_None;
260 }
Guido van Rossum18468821994-06-20 07:49:28 +0000261
Barry Warsawfa701a81997-01-16 00:15:11 +0000262 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
263 {
264 /* Not a list.
265 * Could be a quoted string containing funnies, e.g. {"}.
266 * Return the string itself.
267 */
268 PyErr_Clear();
269 return PyString_FromString(list);
270 }
Guido van Rossum18468821994-06-20 07:49:28 +0000271
Barry Warsawfa701a81997-01-16 00:15:11 +0000272 if (argc == 0)
273 v = PyString_FromString("");
274 else if (argc == 1)
275 v = PyString_FromString(argv[0]);
276 else if ((v = PyTuple_New (argc)) != NULL) {
277 int i;
278 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000279
Barry Warsawfa701a81997-01-16 00:15:11 +0000280 for (i = 0; i < argc; i++) {
281 if ((w = Split(self, argv[i])) == NULL) {
282 Py_DECREF(v);
283 v = NULL;
284 break;
285 }
286 PyTuple_SetItem(v, i, w);
287 }
288 }
289 ckfree (FREECAST argv);
290 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000291}
292
Barry Warsawfa701a81997-01-16 00:15:11 +0000293
294
Guido van Rossum18468821994-06-20 07:49:28 +0000295/**** Tkapp Object ****/
296
297#ifndef WITH_APPINIT
298int
299Tcl_AppInit (interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000300 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000301{
Barry Warsawfa701a81997-01-16 00:15:11 +0000302 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000303
Barry Warsawfa701a81997-01-16 00:15:11 +0000304 main = Tk_MainWindow(interp);
305 if (Tcl_Init(interp) == TCL_ERROR) {
306 fprintf(stderr, "Tcl_Init error: %s\n", interp->result);
307 return TCL_ERROR;
308 }
309 if (Tk_Init(interp) == TCL_ERROR) {
310 fprintf(stderr, "Tk_Init error: %s\n", interp->result);
311 return TCL_ERROR;
312 }
313 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000314}
315#endif /* !WITH_APPINIT */
316
Guido van Rossum18468821994-06-20 07:49:28 +0000317
Barry Warsawfa701a81997-01-16 00:15:11 +0000318
319
320/* Initialize the Tk application; see the `main' function in
321 * `tkMain.c'.
322 */
323static TkappObject *
324Tkapp_New(screenName, baseName, className, interactive)
325 char *screenName;
326 char *baseName;
327 char *className;
328 int interactive;
329{
330 TkappObject *v;
331 char *argv0;
332
333 v = PyObject_NEW(TkappObject, &Tkapp_Type);
334 if (v == NULL)
335 return NULL;
336
337 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000338
339#ifdef NEED_TKCREATEMAINWINDOW
Barry Warsawfa701a81997-01-16 00:15:11 +0000340 v->tkwin = Tk_CreateMainWindow(v->interp, screenName,
341 baseName, className);
342 if (v->tkwin == NULL)
343 return (TkappObject *)Tkinter_Error((PyObject *) v);
Guido van Rossum18468821994-06-20 07:49:28 +0000344
Barry Warsawfa701a81997-01-16 00:15:11 +0000345 Tk_GeometryRequest(v->tkwin, 200, 200);
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000346#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000347
Barry Warsawfa701a81997-01-16 00:15:11 +0000348 if (screenName != NULL)
349 Tcl_SetVar2(v->interp, "env", "DISPLAY",
350 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000351
Barry Warsawfa701a81997-01-16 00:15:11 +0000352 if (interactive)
353 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
354 else
355 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000356
Barry Warsawfa701a81997-01-16 00:15:11 +0000357 /* This is used to get the application class for Tk 4.1 and up */
358 argv0 = (char*)ckalloc(strlen(className) + 1);
359 if (!argv0) {
360 PyErr_NoMemory();
361 Py_DECREF(v);
362 return NULL;
363 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000364
Barry Warsawfa701a81997-01-16 00:15:11 +0000365 strcpy(argv0, className);
366 if (isupper(argv0[0]))
367 argv0[0] = tolower(argv0[0]);
368 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
369 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000370
Barry Warsawfa701a81997-01-16 00:15:11 +0000371 if (Tcl_AppInit(v->interp) != TCL_OK)
372 return (TkappObject *)Tkinter_Error(v);
373
374 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000375}
376
Barry Warsawfa701a81997-01-16 00:15:11 +0000377
378
Guido van Rossum18468821994-06-20 07:49:28 +0000379/** Tcl Eval **/
380
381static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000382Tkapp_Call(self, args)
383 PyObject *self;
384 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000385{
Barry Warsawfa701a81997-01-16 00:15:11 +0000386 char *cmd = Merge(args);
387 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000388
Barry Warsawfa701a81997-01-16 00:15:11 +0000389 if (!cmd)
390 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000391
Barry Warsawfa701a81997-01-16 00:15:11 +0000392 else if (Tcl_Eval(Tkapp_Interp(self), cmd) == TCL_ERROR)
393 res = Tkinter_Error(self);
394
395 else
396 res = PyString_FromString(Tkapp_Result(self));
397
398 if (cmd)
399 ckfree(cmd);
400
401 return res;
402}
403
404
405static PyObject *
406Tkapp_GlobalCall(self, args)
407 PyObject *self;
408 PyObject *args;
409{
410 char *cmd = Merge(args);
411 PyObject *res = NULL;
412
413
414 if (!cmd)
415 PyErr_SetString(Tkinter_TclError, "merge failed");
416
417 else if (Tcl_GlobalEval(Tkapp_Interp(self), cmd) == TCL_ERROR)
418 res = Tkinter_Error(self);
419 else
420 res = PyString_FromString(Tkapp_Result(self));
421
422 if (cmd)
423 ckfree(cmd);
424
425 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000426}
427
428static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000429Tkapp_Eval(self, args)
430 PyObject *self;
431 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000432{
Barry Warsawfa701a81997-01-16 00:15:11 +0000433 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000434
Barry Warsawfa701a81997-01-16 00:15:11 +0000435 if (!PyArg_Parse (args, "s", &script))
436 return NULL;
437
438 if (Tcl_Eval(Tkapp_Interp(self), script) == TCL_ERROR)
439 return Tkinter_Error(self);
440
441 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000442}
443
444static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000445Tkapp_GlobalEval(self, args)
446 PyObject *self;
447 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000448{
Barry Warsawfa701a81997-01-16 00:15:11 +0000449 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000450
Barry Warsawfa701a81997-01-16 00:15:11 +0000451 if (!PyArg_Parse(args, "s", &script))
452 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000453
Barry Warsawfa701a81997-01-16 00:15:11 +0000454 if (Tcl_GlobalEval(Tkapp_Interp(self), script) == TCL_ERROR)
455 return Tkinter_Error (self);
Guido van Rossum18468821994-06-20 07:49:28 +0000456
Barry Warsawfa701a81997-01-16 00:15:11 +0000457 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000458}
459
460static PyObject *
461Tkapp_EvalFile (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000462 PyObject *self;
463 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000464{
Barry Warsawfa701a81997-01-16 00:15:11 +0000465 char *fileName;
Guido van Rossum18468821994-06-20 07:49:28 +0000466
Barry Warsawfa701a81997-01-16 00:15:11 +0000467 if (!PyArg_Parse(args, "s", &fileName))
468 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000469
Barry Warsawfa701a81997-01-16 00:15:11 +0000470 if (Tcl_EvalFile(Tkapp_Interp(self), fileName) == TCL_ERROR)
471 return Tkinter_Error (self);
Guido van Rossum18468821994-06-20 07:49:28 +0000472
Barry Warsawfa701a81997-01-16 00:15:11 +0000473 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000474}
475
476static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000477Tkapp_Record(self, args)
478 PyObject *self;
479 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000480{
Barry Warsawfa701a81997-01-16 00:15:11 +0000481 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000482
Barry Warsawfa701a81997-01-16 00:15:11 +0000483 if (!PyArg_Parse(args, "s", &script))
484 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000485
Barry Warsawfa701a81997-01-16 00:15:11 +0000486 if (TCL_ERROR == Tcl_RecordAndEval(Tkapp_Interp(self),
487 script, TCL_NO_EVAL))
488 return Tkinter_Error (self);
Guido van Rossum18468821994-06-20 07:49:28 +0000489
Barry Warsawfa701a81997-01-16 00:15:11 +0000490 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000491}
492
493static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000494Tkapp_AddErrorInfo(self, args)
495 PyObject *self;
496 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000497{
Barry Warsawfa701a81997-01-16 00:15:11 +0000498 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000499
Barry Warsawfa701a81997-01-16 00:15:11 +0000500 if (!PyArg_Parse (args, "s", &msg))
501 return NULL;
502 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum18468821994-06-20 07:49:28 +0000503
Barry Warsawfa701a81997-01-16 00:15:11 +0000504 Py_INCREF(Py_None);
505 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000506}
507
Barry Warsawfa701a81997-01-16 00:15:11 +0000508
509
Guido van Rossum18468821994-06-20 07:49:28 +0000510/** Tcl Variable **/
511
512static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000513SetVar(self, args, flags)
514 PyObject *self;
515 PyObject *args;
516 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000517{
Barry Warsawfa701a81997-01-16 00:15:11 +0000518 char *name1, *name2, *ok;
519 PyObject *newValue;
520 PyObject *tmp = PyList_New(0);
Guido van Rossum18468821994-06-20 07:49:28 +0000521
Barry Warsawfa701a81997-01-16 00:15:11 +0000522 if (!tmp)
523 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000524
Barry Warsawfa701a81997-01-16 00:15:11 +0000525 if (PyArg_Parse(args, "(sO)", &name1, &newValue))
526 /* XXX Merge? */
527 ok = Tcl_SetVar(Tkapp_Interp (self), name1,
528 AsString (newValue, tmp), flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000529
Barry Warsawfa701a81997-01-16 00:15:11 +0000530 else if (PyArg_Parse(args, "(ssO)", &name1, &name2, &newValue))
531 ok = Tcl_SetVar2(Tkapp_Interp (self), name1, name2,
532 AsString (newValue, tmp), flags);
533 else {
534 Py_DECREF (tmp);
535 return NULL;
536 }
537 Py_DECREF (tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000538
Barry Warsawfa701a81997-01-16 00:15:11 +0000539 if (!ok)
540 return Tkinter_Error(self);
541
542 Py_INCREF(Py_None);
543 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000544}
545
546static PyObject *
547Tkapp_SetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000548 PyObject *self;
549 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000550{
Barry Warsawfa701a81997-01-16 00:15:11 +0000551 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000552}
553
554static PyObject *
555Tkapp_GlobalSetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000556 PyObject *self;
557 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000558{
Barry Warsawfa701a81997-01-16 00:15:11 +0000559 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000560}
561
Barry Warsawfa701a81997-01-16 00:15:11 +0000562
563
Guido van Rossum18468821994-06-20 07:49:28 +0000564static PyObject *
565GetVar (self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000566 PyObject *self;
567 PyObject *args;
568 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000569{
Barry Warsawfa701a81997-01-16 00:15:11 +0000570 char *name1, *name2, *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000571
Barry Warsawfa701a81997-01-16 00:15:11 +0000572 if (PyArg_Parse(args, "s", &name1))
573 s = Tcl_GetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000574
Barry Warsawfa701a81997-01-16 00:15:11 +0000575 else if (PyArg_Parse(args, "(ss)", &name1, &name2))
576 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
577 else
578 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000579
Barry Warsawfa701a81997-01-16 00:15:11 +0000580 if (s == NULL)
581 return Tkinter_Error(self);
582
583 return PyString_FromString (s);
Guido van Rossum18468821994-06-20 07:49:28 +0000584}
585
586static PyObject *
587Tkapp_GetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000588 PyObject *self;
589 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000590{
Barry Warsawfa701a81997-01-16 00:15:11 +0000591 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000592}
593
594static PyObject *
595Tkapp_GlobalGetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000596 PyObject *self;
597 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000598{
Barry Warsawfa701a81997-01-16 00:15:11 +0000599 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000600}
601
Barry Warsawfa701a81997-01-16 00:15:11 +0000602
603
Guido van Rossum18468821994-06-20 07:49:28 +0000604static PyObject *
605UnsetVar (self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000606 PyObject *self;
607 PyObject *args;
608 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000609{
Barry Warsawfa701a81997-01-16 00:15:11 +0000610 char *name1, *name2;
611 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000612
Barry Warsawfa701a81997-01-16 00:15:11 +0000613 if (PyArg_Parse(args, "s", &name1))
614 code = Tcl_UnsetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000615
Barry Warsawfa701a81997-01-16 00:15:11 +0000616 else if (PyArg_Parse(args, "(ss)", &name1, &name2))
617 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
618 else
619 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000620
Barry Warsawfa701a81997-01-16 00:15:11 +0000621 if (code == TCL_ERROR)
622 return Tkinter_Error (self);
623
624 Py_INCREF(Py_None);
625 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000626}
627
628static PyObject *
629Tkapp_UnsetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000630 PyObject *self;
631 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000632{
Barry Warsawfa701a81997-01-16 00:15:11 +0000633 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000634}
635
636static PyObject *
637Tkapp_GlobalUnsetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000638 PyObject *self;
639 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000640{
Barry Warsawfa701a81997-01-16 00:15:11 +0000641 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000642}
643
Barry Warsawfa701a81997-01-16 00:15:11 +0000644
645
Guido van Rossum18468821994-06-20 07:49:28 +0000646/** Tcl to Python **/
647
648static PyObject *
649Tkapp_GetInt (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000650 PyObject *self;
651 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000652{
Barry Warsawfa701a81997-01-16 00:15:11 +0000653 char *s;
654 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000655
Barry Warsawfa701a81997-01-16 00:15:11 +0000656 if (!PyArg_Parse(args, "s", &s))
657 return NULL;
658 if (Tcl_GetInt(Tkapp_Interp (self), s, &v) == TCL_ERROR)
659 return Tkinter_Error(self);
660 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000661}
662
663static PyObject *
664Tkapp_GetDouble (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000665 PyObject *self;
666 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000667{
Barry Warsawfa701a81997-01-16 00:15:11 +0000668 char *s;
669 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000670
Barry Warsawfa701a81997-01-16 00:15:11 +0000671 if (!PyArg_Parse(args, "s", &s))
672 return NULL;
673 if (Tcl_GetDouble(Tkapp_Interp (self), s, &v) == TCL_ERROR)
674 return Tkinter_Error(self);
675 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000676}
677
678static PyObject *
679Tkapp_GetBoolean (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000680 PyObject *self;
681 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000682{
Barry Warsawfa701a81997-01-16 00:15:11 +0000683 char *s;
684 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000685
Barry Warsawfa701a81997-01-16 00:15:11 +0000686 if (!PyArg_Parse(args, "s", &s))
687 return NULL;
688 if (Tcl_GetBoolean(Tkapp_Interp (self), s, &v) == TCL_ERROR)
689 return Tkinter_Error (self);
690 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000691}
692
693static PyObject *
694Tkapp_ExprString (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000695 PyObject *self;
696 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000697{
Barry Warsawfa701a81997-01-16 00:15:11 +0000698 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000699
Barry Warsawfa701a81997-01-16 00:15:11 +0000700 if (!PyArg_Parse(args, "s", &s))
701 return NULL;
702 if (Tcl_ExprString (Tkapp_Interp (self), s) == TCL_ERROR)
703 return Tkinter_Error(self);
704 return Py_BuildValue("s", Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000705}
706
707static PyObject *
708Tkapp_ExprLong (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000709 PyObject *self;
710 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000711{
Barry Warsawfa701a81997-01-16 00:15:11 +0000712 char *s;
713 long v;
Guido van Rossum18468821994-06-20 07:49:28 +0000714
Barry Warsawfa701a81997-01-16 00:15:11 +0000715 if (!PyArg_Parse(args, "s", &s))
716 return NULL;
717 if (Tcl_ExprLong(Tkapp_Interp(self), s, &v) == TCL_ERROR)
718 return Tkinter_Error(self);
719 return Py_BuildValue("l", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000720}
721
722static PyObject *
723Tkapp_ExprDouble (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000724 PyObject *self;
725 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000726{
Barry Warsawfa701a81997-01-16 00:15:11 +0000727 char *s;
728 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000729 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000730
Barry Warsawfa701a81997-01-16 00:15:11 +0000731 if (!PyArg_Parse(args, "s", &s))
732 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000733 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
734 retval = Tcl_ExprDouble (Tkapp_Interp (self), s, &v);
Guido van Rossum45b83911997-03-14 04:32:50 +0000735 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000736 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000737 return Tkinter_Error(self);
738 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000739}
740
741static PyObject *
742Tkapp_ExprBoolean (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000743 PyObject *self;
744 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000745{
Barry Warsawfa701a81997-01-16 00:15:11 +0000746 char *s;
747 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000748
Barry Warsawfa701a81997-01-16 00:15:11 +0000749 if (!PyArg_Parse(args, "s", &s))
750 return NULL;
751 if (Tcl_ExprBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
752 return Tkinter_Error(self);
753 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000754}
755
Barry Warsawfa701a81997-01-16 00:15:11 +0000756
757
Guido van Rossum18468821994-06-20 07:49:28 +0000758static PyObject *
759Tkapp_SplitList (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000760 PyObject *self;
761 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000762{
Barry Warsawfa701a81997-01-16 00:15:11 +0000763 char *list;
764 int argc;
765 char **argv;
766 PyObject *v;
767 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000768
Barry Warsawfa701a81997-01-16 00:15:11 +0000769 if (!PyArg_Parse(args, "s", &list))
770 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000771
Barry Warsawfa701a81997-01-16 00:15:11 +0000772 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
773 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000774
Barry Warsawfa701a81997-01-16 00:15:11 +0000775 if (!(v = PyTuple_New(argc)))
776 return NULL;
777
778 for (i = 0; i < argc; i++) {
779 PyObject *s = PyString_FromString(argv[i]);
780 if (!s || PyTuple_SetItem(v, i, s)) {
781 Py_DECREF(v);
782 v = NULL;
783 goto finally;
784 }
785 }
Guido van Rossum18468821994-06-20 07:49:28 +0000786
Barry Warsawfa701a81997-01-16 00:15:11 +0000787 finally:
788 ckfree(FREECAST argv);
789 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000790}
791
792static PyObject *
793Tkapp_Split (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000794 PyObject *self;
795 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000796{
Barry Warsawfa701a81997-01-16 00:15:11 +0000797 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000798
Barry Warsawfa701a81997-01-16 00:15:11 +0000799 if (!PyArg_Parse(args, "s", &list))
800 return NULL;
801 return Split(self, list);
Guido van Rossum18468821994-06-20 07:49:28 +0000802}
803
804static PyObject *
805Tkapp_Merge (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000806 PyObject *self;
807 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000808{
Barry Warsawfa701a81997-01-16 00:15:11 +0000809 char *s = Merge(args);
810 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000811
Barry Warsawfa701a81997-01-16 00:15:11 +0000812 if (s) {
813 res = PyString_FromString(s);
814 ckfree(s);
815 }
816 else
817 PyErr_SetString(Tkinter_TclError, "merge failed");
818
819 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000820}
821
Barry Warsawfa701a81997-01-16 00:15:11 +0000822
823
Guido van Rossum18468821994-06-20 07:49:28 +0000824/** Tcl Command **/
825
826/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +0000827 * function or method.
828 */
Guido van Rossum18468821994-06-20 07:49:28 +0000829static int
830PythonCmd (clientData, interp, argc, argv)
Barry Warsawfa701a81997-01-16 00:15:11 +0000831 ClientData clientData; /* Is (self, func) */
832 Tcl_Interp *interp;
833 int argc;
834 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +0000835{
Barry Warsawfa701a81997-01-16 00:15:11 +0000836 PyObject *self, *func, *arg, *res, *tmp;
837 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000838
Barry Warsawfa701a81997-01-16 00:15:11 +0000839 /* TBD: no error checking here since we know, via the
840 * Tkapp_CreateCommand() that the client data is a two-tuple
841 */
842 self = PyTuple_GetItem((PyObject *) clientData, 0);
843 func = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000844
Barry Warsawfa701a81997-01-16 00:15:11 +0000845 /* Create argument list (argv1, ..., argvN) */
846 if (!(arg = PyTuple_New(argc - 1)))
847 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000848
Barry Warsawfa701a81997-01-16 00:15:11 +0000849 for (i = 0; i < (argc - 1); i++) {
850 PyObject *s = PyString_FromString(argv[i + 1]);
851 if (!s || PyTuple_SetItem(arg, i, s)) {
852 Py_DECREF(arg);
853 PythonCmd_Error(interp);
854 }
855 }
856 res = PyEval_CallObject(func, arg);
857 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +0000858
Barry Warsawfa701a81997-01-16 00:15:11 +0000859 if (res == NULL)
860 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +0000861
Barry Warsawfa701a81997-01-16 00:15:11 +0000862 if (!(tmp = PyList_New(0))) {
863 Py_DECREF(res);
864 return PythonCmd_Error(interp);
865 }
866
867 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
868 Py_DECREF(res);
869 Py_DECREF(tmp);
870
871 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000872}
873
874static void
875PythonCmdDelete (clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +0000876 ClientData clientData; /* Is (self, func) */
Guido van Rossum18468821994-06-20 07:49:28 +0000877{
Barry Warsawfa701a81997-01-16 00:15:11 +0000878 Py_DECREF((PyObject *) clientData);
Guido van Rossum18468821994-06-20 07:49:28 +0000879}
880
Barry Warsawfa701a81997-01-16 00:15:11 +0000881
882
Guido van Rossum18468821994-06-20 07:49:28 +0000883static PyObject *
884Tkapp_CreateCommand (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000885 PyObject *self;
886 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000887{
Barry Warsawfa701a81997-01-16 00:15:11 +0000888 char *cmdName;
889 PyObject *data;
890 PyObject *func;
Guido van Rossum18468821994-06-20 07:49:28 +0000891
Barry Warsawfa701a81997-01-16 00:15:11 +0000892 /* Args is: (cmdName, func) */
893 if (!PyTuple_Check(args)
894 || !(PyTuple_Size(args) == 2)
895 || !PyString_Check(PyTuple_GetItem(args, 0))
896 || !PyCallable_Check(PyTuple_GetItem(args, 1)))
897 {
898 PyErr_SetString (PyExc_TypeError, "bad argument list");
899 return NULL;
900 }
Guido van Rossum18468821994-06-20 07:49:28 +0000901
Barry Warsawfa701a81997-01-16 00:15:11 +0000902 cmdName = PyString_AsString(PyTuple_GetItem(args, 0));
903 func = PyTuple_GetItem(args, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000904
Barry Warsawfa701a81997-01-16 00:15:11 +0000905 data = PyTuple_New(2); /* ClientData is: (self, func) */
906 if (!data)
907 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000908
Barry Warsawfa701a81997-01-16 00:15:11 +0000909 Py_INCREF(self);
910 PyTuple_SetItem(data, 0, self);
Guido van Rossum18468821994-06-20 07:49:28 +0000911
Barry Warsawfa701a81997-01-16 00:15:11 +0000912 Py_INCREF(func);
913 PyTuple_SetItem(data, 1, func);
Guido van Rossum18468821994-06-20 07:49:28 +0000914
Barry Warsawfa701a81997-01-16 00:15:11 +0000915 Tcl_CreateCommand(Tkapp_Interp (self), cmdName, PythonCmd,
916 (ClientData) data, PythonCmdDelete);
Guido van Rossum18468821994-06-20 07:49:28 +0000917
Barry Warsawfa701a81997-01-16 00:15:11 +0000918 Py_INCREF(Py_None);
919 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000920}
921
Barry Warsawfa701a81997-01-16 00:15:11 +0000922
923
Guido van Rossum18468821994-06-20 07:49:28 +0000924static PyObject *
925Tkapp_DeleteCommand (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000926 PyObject *self;
927 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000928{
Barry Warsawfa701a81997-01-16 00:15:11 +0000929 char *cmdName;
Guido van Rossum18468821994-06-20 07:49:28 +0000930
Barry Warsawfa701a81997-01-16 00:15:11 +0000931 if (!PyArg_Parse(args, "s", &cmdName))
932 return NULL;
933 if (Tcl_DeleteCommand(Tkapp_Interp(self), cmdName) == -1)
934 {
935 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
936 return NULL;
937 }
938 Py_INCREF(Py_None);
939 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000940}
941
Barry Warsawfa701a81997-01-16 00:15:11 +0000942
943
Guido van Rossum18468821994-06-20 07:49:28 +0000944/** File Handler **/
945
Guido van Rossuma597dde1995-01-10 20:56:29 +0000946static void
Guido van Rossum18468821994-06-20 07:49:28 +0000947FileHandler (clientData, mask)
Barry Warsawfa701a81997-01-16 00:15:11 +0000948 ClientData clientData; /* Is: (func, file) */
949 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +0000950{
Barry Warsawfa701a81997-01-16 00:15:11 +0000951 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +0000952
Barry Warsawfa701a81997-01-16 00:15:11 +0000953 func = PyTuple_GetItem((PyObject *) clientData, 0);
954 file = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000955
Barry Warsawfa701a81997-01-16 00:15:11 +0000956 arg = Py_BuildValue("(Oi)", file, (long) mask);
957 res = PyEval_CallObject(func, arg);
958 Py_DECREF (arg);
959
960 if (res == NULL) {
961 errorInCmd = 1;
962 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
963 }
964 Py_XDECREF(res);
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000965}
966
967static int
968GetFileNo (file)
Barry Warsawfa701a81997-01-16 00:15:11 +0000969 /* Either an int >= 0 or an object with a
970 *.fileno() method that returns an int >= 0
971 */
972 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000973{
Guido van Rossuma597dde1995-01-10 20:56:29 +0000974 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000975 int id;
976 if (PyInt_Check(file)) {
977 id = PyInt_AsLong(file);
978 if (id < 0)
979 PyErr_SetString(PyExc_ValueError, "invalid file id");
980 return id;
981 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000982 args = PyTuple_New(0);
983 if (args == NULL)
984 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000985
986 meth = PyObject_GetAttrString(file, "fileno");
987 if (meth == NULL) {
988 Py_DECREF(args);
989 return -1;
990 }
991
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000992 res = PyEval_CallObject(meth, args);
993 Py_DECREF(args);
994 Py_DECREF(meth);
995 if (res == NULL)
996 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000997
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000998 if (PyInt_Check(res))
999 id = PyInt_AsLong(res);
1000 else
1001 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001002
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001003 if (id < 0)
1004 PyErr_SetString(PyExc_ValueError,
1005 "invalid fileno() return value");
1006 Py_DECREF(res);
1007 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001008}
1009
Barry Warsawfa701a81997-01-16 00:15:11 +00001010
1011static PyObject* Tkapp_ClientDataDict = NULL;
1012
Guido van Rossum18468821994-06-20 07:49:28 +00001013static PyObject *
1014Tkapp_CreateFileHandler (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001015 PyObject *self;
1016 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001017{
Barry Warsawfa701a81997-01-16 00:15:11 +00001018 PyObject *file, *func, *data;
1019 PyObject *idkey;
1020 int mask, id;
Guido van Rossum68784361996-05-16 17:17:31 +00001021#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Barry Warsawfa701a81997-01-16 00:15:11 +00001022 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001023#endif
Guido van Rossum18468821994-06-20 07:49:28 +00001024
Barry Warsawfa701a81997-01-16 00:15:11 +00001025 if (!Tkapp_ClientDataDict) {
1026 if (!(Tkapp_ClientDataDict = PyDict_New()))
1027 return NULL;
1028 }
Guido van Rossum18468821994-06-20 07:49:28 +00001029
Barry Warsawfa701a81997-01-16 00:15:11 +00001030 if (!PyArg_Parse(args, "(OiO)", &file, &mask, &func))
1031 return NULL;
1032 id = GetFileNo(file);
1033 if (id < 0)
1034 return NULL;
1035 if (!PyCallable_Check(func)) {
1036 PyErr_SetString (PyExc_TypeError, "bad argument list");
1037 return NULL;
1038 }
1039
1040 if (!(idkey = PyInt_FromLong(id)))
1041 return NULL;
1042
1043 /* ClientData is: (func, file) */
1044 data = Py_BuildValue ("(OO)", func, file);
1045 if (!data || PyDict_SetItem(Tkapp_ClientDataDict, idkey, data)) {
1046 Py_DECREF(idkey);
1047 Py_XDECREF(data);
1048 return NULL;
1049 }
1050 Py_DECREF(idkey);
Guido van Rossum76875221994-06-27 07:59:42 +00001051
Guido van Rossum68784361996-05-16 17:17:31 +00001052#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Guido van Rossum07886d01996-09-11 23:31:42 +00001053#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001054 /* We assume this is a socket... */
1055 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum845547d1996-06-26 18:26:04 +00001056#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001057 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +00001058#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001059 /* Ought to check for null Tcl_File object... */
1060 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum68784361996-05-16 17:17:31 +00001061#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001062 Tk_CreateFileHandler(id, mask, FileHandler, (ClientData) data);
Guido van Rossum68784361996-05-16 17:17:31 +00001063#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001064 /* XXX fileHandlerDict */
1065 Py_INCREF (Py_None);
1066 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001067}
1068
Barry Warsawfa701a81997-01-16 00:15:11 +00001069
Guido van Rossum18468821994-06-20 07:49:28 +00001070static PyObject *
1071Tkapp_DeleteFileHandler (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001072 PyObject *self;
1073 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001074{
Barry Warsawfa701a81997-01-16 00:15:11 +00001075 PyObject *file;
1076 PyObject *idkey;
1077 PyObject *data;
1078 int id;
Guido van Rossum68784361996-05-16 17:17:31 +00001079#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Barry Warsawfa701a81997-01-16 00:15:11 +00001080 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001081#endif
1082
Barry Warsawfa701a81997-01-16 00:15:11 +00001083 if (!PyArg_Parse(args, "O", &file))
1084 return NULL;
1085 id = GetFileNo(file);
1086 if (id < 0)
1087 return NULL;
1088
1089 if (!(idkey = PyInt_FromLong(id)))
1090 return NULL;
1091
1092 /* find and free the object created in the
1093 * Tkapp_CreateFileHandler() call
1094 */
1095 data = PyDict_GetItem(Tkapp_ClientDataDict, idkey);
1096 Py_XDECREF(data);
1097 PyDict_DelItem(Tkapp_ClientDataDict, idkey);
1098 Py_DECREF(idkey);
Guido van Rossum18468821994-06-20 07:49:28 +00001099
Guido van Rossum68784361996-05-16 17:17:31 +00001100#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Guido van Rossum07886d01996-09-11 23:31:42 +00001101#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001102 /* We assume this is a socket... */
1103 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum845547d1996-06-26 18:26:04 +00001104#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001105 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +00001106#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001107 /* Ought to check for null Tcl_File object... */
1108 Tcl_DeleteFileHandler(tfile);
Guido van Rossum68784361996-05-16 17:17:31 +00001109#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001110 Tk_DeleteFileHandler(id);
Guido van Rossum68784361996-05-16 17:17:31 +00001111#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001112 /* XXX fileHandlerDict */
1113 Py_INCREF (Py_None);
1114 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001115}
1116
Barry Warsawfa701a81997-01-16 00:15:11 +00001117
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001118/**** Tktt Object (timer token) ****/
1119
1120staticforward PyTypeObject Tktt_Type;
1121
1122typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +00001123{
1124 PyObject_HEAD
1125 Tk_TimerToken token;
1126 PyObject *func;
1127}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001128TkttObject;
1129
1130static PyObject *
1131Tktt_DeleteTimerHandler (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001132 PyObject *self;
1133 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001134{
Barry Warsawfa701a81997-01-16 00:15:11 +00001135 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001136
Barry Warsawfa701a81997-01-16 00:15:11 +00001137 if (!PyArg_Parse(args, ""))
1138 return NULL;
1139 if (v->func != NULL) {
1140 Tk_DeleteTimerHandler(v->token);
1141 PyMem_DEL(v->func);
1142 v->func = NULL;
1143 }
1144 Py_INCREF(Py_None);
1145 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001146}
1147
1148static PyMethodDef Tktt_methods[] =
1149{
Barry Warsawfa701a81997-01-16 00:15:11 +00001150 {"deletetimerhandler", Tktt_DeleteTimerHandler},
1151 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001152};
1153
1154static TkttObject *
1155Tktt_New (token, func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001156 Tk_TimerToken token;
1157 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001158{
Barry Warsawfa701a81997-01-16 00:15:11 +00001159 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001160
Barry Warsawfa701a81997-01-16 00:15:11 +00001161 v = PyObject_NEW(TkttObject, &Tktt_Type);
1162 if (v == NULL)
1163 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001164
Barry Warsawfa701a81997-01-16 00:15:11 +00001165 v->token = token;
1166 v->func = func;
1167 Py_INCREF(v->func);
1168 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001169}
1170
1171static void
1172Tktt_Dealloc (self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001173 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001174{
Barry Warsawfa701a81997-01-16 00:15:11 +00001175 PyMem_DEL (self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001176}
1177
1178static int
1179Tktt_Print (self, fp, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +00001180 PyObject *self;
1181 FILE *fp;
1182 int flags;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001183{
Barry Warsawfa701a81997-01-16 00:15:11 +00001184 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001185
Barry Warsawfa701a81997-01-16 00:15:11 +00001186 fprintf(fp, "<tktimertoken at 0x%lx%s>", (long)v,
1187 v->func == NULL ? ", handler deleted" : "");
1188 return 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001189}
1190
1191static PyObject *
1192Tktt_GetAttr (self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001193 PyObject *self;
1194 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001195{
Barry Warsawfa701a81997-01-16 00:15:11 +00001196 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001197}
1198
1199static PyTypeObject Tktt_Type =
1200{
Barry Warsawfa701a81997-01-16 00:15:11 +00001201 PyObject_HEAD_INIT (NULL)
1202 0, /*ob_size */
1203 "tktimertoken", /*tp_name */
1204 sizeof (TkttObject), /*tp_basicsize */
1205 0, /*tp_itemsize */
1206 Tktt_Dealloc, /*tp_dealloc */
1207 Tktt_Print, /*tp_print */
1208 Tktt_GetAttr, /*tp_getattr */
1209 0, /*tp_setattr */
1210 0, /*tp_compare */
1211 0, /*tp_repr */
1212 0, /*tp_as_number */
1213 0, /*tp_as_sequence */
1214 0, /*tp_as_mapping */
1215 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001216};
1217
Barry Warsawfa701a81997-01-16 00:15:11 +00001218
1219
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001220/** Timer Handler **/
1221
1222static void
1223TimerHandler (clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001224 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001225{
Barry Warsawfa701a81997-01-16 00:15:11 +00001226 PyObject *func = (PyObject *)clientData;
1227 PyObject *res = PyEval_CallObject(func, NULL);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001228
Barry Warsawfa701a81997-01-16 00:15:11 +00001229 if (res == NULL) {
1230 errorInCmd = 1;
1231 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1232 }
1233 else
1234 Py_DECREF(res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001235}
1236
1237static PyObject *
1238Tkapp_CreateTimerHandler (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001239 PyObject *self;
1240 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001241{
Barry Warsawfa701a81997-01-16 00:15:11 +00001242 int milliseconds;
1243 PyObject *func;
1244 Tk_TimerToken token;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001245
Barry Warsawfa701a81997-01-16 00:15:11 +00001246 if (!PyArg_Parse(args, "(iO)", &milliseconds, &func))
1247 return NULL;
1248 if (!PyCallable_Check(func)) {
1249 PyErr_SetString (PyExc_TypeError, "bad argument list");
1250 return NULL;
1251 }
1252 token = Tk_CreateTimerHandler(milliseconds, TimerHandler,
1253 (ClientData)func);
1254
1255 return (PyObject *) Tktt_New(token, func);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001256}
1257
Barry Warsawfa701a81997-01-16 00:15:11 +00001258
1259
Guido van Rossum18468821994-06-20 07:49:28 +00001260/** Event Loop **/
1261
Guido van Rossum18468821994-06-20 07:49:28 +00001262static PyObject *
1263Tkapp_MainLoop (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001264 PyObject *self;
1265 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001266{
Barry Warsawfa701a81997-01-16 00:15:11 +00001267 int threshold = 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001268
Barry Warsawfa701a81997-01-16 00:15:11 +00001269 if (!PyArg_ParseTuple(args, "|i", &threshold))
1270 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001271
Barry Warsawfa701a81997-01-16 00:15:11 +00001272 quitMainLoop = 0;
1273 while (Tk_GetNumMainWindows() > threshold &&
1274 !quitMainLoop &&
1275 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001276 {
Barry Warsawfa701a81997-01-16 00:15:11 +00001277 /* XXX Ought to check for other signals! */
1278 if (PyOS_InterruptOccurred()) {
1279 PyErr_SetNone(PyExc_KeyboardInterrupt);
1280 return NULL;
1281 }
1282 Tk_DoOneEvent(0);
Guido van Rossum18468821994-06-20 07:49:28 +00001283 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001284 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001285
Barry Warsawfa701a81997-01-16 00:15:11 +00001286 if (errorInCmd) {
1287 errorInCmd = 0;
1288 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1289 excInCmd = valInCmd = trbInCmd = NULL;
1290 return NULL;
1291 }
1292 Py_INCREF(Py_None);
1293 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001294}
1295
1296static PyObject *
Guido van Rossum062cfb01995-01-10 17:42:51 +00001297Tkapp_DoOneEvent (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001298 PyObject *self;
1299 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001300{
Barry Warsawfa701a81997-01-16 00:15:11 +00001301 int flags = TK_ALL_EVENTS;
1302 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001303
Barry Warsawfa701a81997-01-16 00:15:11 +00001304 if (!PyArg_ParseTuple(args, "|i", &flags))
1305 return NULL;
1306
1307 rv = Tk_DoOneEvent(flags);
1308 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001309}
1310
1311static PyObject *
Guido van Rossum18468821994-06-20 07:49:28 +00001312Tkapp_Quit (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001313 PyObject *self;
1314 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001315{
1316
Barry Warsawfa701a81997-01-16 00:15:11 +00001317 if (!PyArg_Parse(args, ""))
1318 return NULL;
1319
1320 quitMainLoop = 1;
1321 Py_INCREF(Py_None);
1322 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001323}
1324
Barry Warsawfa701a81997-01-16 00:15:11 +00001325
1326
Guido van Rossum18468821994-06-20 07:49:28 +00001327/**** Tkapp Method List ****/
1328
1329static PyMethodDef Tkapp_methods[] =
1330{
Barry Warsawfa701a81997-01-16 00:15:11 +00001331 {"call", Tkapp_Call},
1332 {"globalcall", Tkapp_GlobalCall},
1333 {"eval", Tkapp_Eval},
1334 {"globaleval", Tkapp_GlobalEval},
1335 {"evalfile", Tkapp_EvalFile},
1336 {"record", Tkapp_Record},
1337 {"adderrorinfo", Tkapp_AddErrorInfo},
1338 {"setvar", Tkapp_SetVar},
1339 {"globalsetvar", Tkapp_GlobalSetVar},
1340 {"getvar", Tkapp_GetVar},
1341 {"globalgetvar", Tkapp_GlobalGetVar},
1342 {"unsetvar", Tkapp_UnsetVar},
1343 {"globalunsetvar", Tkapp_GlobalUnsetVar},
1344 {"getint", Tkapp_GetInt},
1345 {"getdouble", Tkapp_GetDouble},
1346 {"getboolean", Tkapp_GetBoolean},
1347 {"exprstring", Tkapp_ExprString},
1348 {"exprlong", Tkapp_ExprLong},
1349 {"exprdouble", Tkapp_ExprDouble},
1350 {"exprboolean", Tkapp_ExprBoolean},
1351 {"splitlist", Tkapp_SplitList},
1352 {"split", Tkapp_Split},
1353 {"merge", Tkapp_Merge},
1354 {"createcommand", Tkapp_CreateCommand},
1355 {"deletecommand", Tkapp_DeleteCommand},
1356 {"createfilehandler", Tkapp_CreateFileHandler},
1357 {"deletefilehandler", Tkapp_DeleteFileHandler},
1358 {"createtimerhandler", Tkapp_CreateTimerHandler},
1359 {"mainloop", Tkapp_MainLoop, 1},
1360 {"dooneevent", Tkapp_DoOneEvent, 1},
1361 {"quit", Tkapp_Quit},
1362 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001363};
1364
Barry Warsawfa701a81997-01-16 00:15:11 +00001365
1366
Guido van Rossum18468821994-06-20 07:49:28 +00001367/**** Tkapp Type Methods ****/
1368
1369static void
1370Tkapp_Dealloc (self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001371 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001372{
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001373#ifdef NEED_TKCREATEMAINWINDOW
Barry Warsawfa701a81997-01-16 00:15:11 +00001374 Tk_DestroyWindow (Tkapp_Tkwin (self));
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001375#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001376 Tcl_DeleteInterp (Tkapp_Interp (self));
1377 PyMem_DEL (self);
Guido van Rossum18468821994-06-20 07:49:28 +00001378}
1379
1380static PyObject *
1381Tkapp_GetAttr (self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001382 PyObject *self;
1383 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001384{
Barry Warsawfa701a81997-01-16 00:15:11 +00001385 return Py_FindMethod (Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001386}
1387
1388static PyTypeObject Tkapp_Type =
1389{
Barry Warsawfa701a81997-01-16 00:15:11 +00001390 PyObject_HEAD_INIT (NULL)
1391 0, /*ob_size */
1392 "tkapp", /*tp_name */
1393 sizeof (TkappObject), /*tp_basicsize */
1394 0, /*tp_itemsize */
1395 Tkapp_Dealloc, /*tp_dealloc */
1396 0, /*tp_print */
1397 Tkapp_GetAttr, /*tp_getattr */
1398 0, /*tp_setattr */
1399 0, /*tp_compare */
1400 0, /*tp_repr */
1401 0, /*tp_as_number */
1402 0, /*tp_as_sequence */
1403 0, /*tp_as_mapping */
1404 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001405};
1406
Barry Warsawfa701a81997-01-16 00:15:11 +00001407
1408
Guido van Rossum18468821994-06-20 07:49:28 +00001409/**** Tkinter Module ****/
1410
1411static PyObject *
1412Tkinter_Create (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001413 PyObject *self;
1414 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001415{
Barry Warsawfa701a81997-01-16 00:15:11 +00001416 char *screenName = NULL;
1417 char *baseName = NULL;
1418 char *className = NULL;
1419 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001420
Barry Warsawfa701a81997-01-16 00:15:11 +00001421 baseName = strrchr(Py_GetProgramName (), '/');
1422 if (baseName != NULL)
1423 baseName++;
1424 else
1425 baseName = Py_GetProgramName();
1426 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001427
Barry Warsawfa701a81997-01-16 00:15:11 +00001428 if (!PyArg_ParseTuple(args, "|zssi",
1429 &screenName, &baseName, &className,
1430 &interactive))
1431 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001432
Barry Warsawfa701a81997-01-16 00:15:11 +00001433 return (PyObject *) Tkapp_New(screenName, baseName, className,
1434 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001435}
1436
1437static PyMethodDef moduleMethods[] =
1438{
Barry Warsawfa701a81997-01-16 00:15:11 +00001439 {"create", Tkinter_Create, 1},
1440 {"createfilehandler", Tkapp_CreateFileHandler, 0},
1441 {"deletefilehandler", Tkapp_DeleteFileHandler, 0},
1442 {"createtimerhandler", Tkapp_CreateTimerHandler, 0},
1443 {"mainloop", Tkapp_MainLoop, 1},
1444 {"dooneevent", Tkapp_DoOneEvent, 1},
1445 {"quit", Tkapp_Quit},
1446 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001447};
1448
1449#ifdef WITH_READLINE
1450static int
1451EventHook ()
1452{
Barry Warsawfa701a81997-01-16 00:15:11 +00001453 /* XXX Reset tty */
1454 if (errorInCmd) {
1455 errorInCmd = 0;
1456 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1457 excInCmd = valInCmd = trbInCmd = NULL;
1458 PyErr_Print();
1459 }
1460 if (Tk_GetNumMainWindows() > 0)
1461 Tk_DoOneEvent(TK_DONT_WAIT);
1462 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001463}
1464#endif /* WITH_READLINE */
1465
Barry Warsawfa701a81997-01-16 00:15:11 +00001466
1467/* all errors will be checked in one fell swoop in init_tkinter() */
1468static void
1469ins_long(d, name, val)
1470 PyObject *d;
1471 char *name;
1472 long val;
1473{
1474 PyObject *v = PyInt_FromLong(val);
1475 if (v) {
1476 PyDict_SetItemString(d, name, v);
1477 Py_DECREF(v);
1478 }
1479}
1480static void
1481ins_string(d, name, val)
1482 PyObject *d;
1483 char *name;
1484 char *val;
1485{
1486 PyObject *v = PyString_FromString(val);
1487 if (v) {
1488 PyDict_SetItemString(d, name, v);
1489 Py_DECREF(v);
1490 }
1491}
1492
1493
Guido van Rossum18468821994-06-20 07:49:28 +00001494void
Guido van Rossumad1f7ee1996-02-13 00:11:37 +00001495init_tkinter ()
Guido van Rossum18468821994-06-20 07:49:28 +00001496{
1497#ifdef WITH_READLINE
Barry Warsawfa701a81997-01-16 00:15:11 +00001498 extern int (*rl_event_hook) ();
Guido van Rossum18468821994-06-20 07:49:28 +00001499#endif /* WITH_READLINE */
Barry Warsawfa701a81997-01-16 00:15:11 +00001500 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001501
Barry Warsawfa701a81997-01-16 00:15:11 +00001502 Tkapp_Type.ob_type = &PyType_Type;
1503 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossumae92f011996-08-21 19:03:36 +00001504
Barry Warsawfa701a81997-01-16 00:15:11 +00001505 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001506
Barry Warsawfa701a81997-01-16 00:15:11 +00001507 d = PyModule_GetDict(m);
1508 Tkinter_TclError = Py_BuildValue("s", "TclError");
1509 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00001510
Barry Warsawfa701a81997-01-16 00:15:11 +00001511 ins_long(d, "READABLE", TK_READABLE);
1512 ins_long(d, "WRITABLE", TK_WRITABLE);
1513 ins_long(d, "EXCEPTION", TK_EXCEPTION);
1514 ins_long(d, "X_EVENTS", TK_X_EVENTS);
1515 ins_long(d, "FILE_EVENTS", TK_FILE_EVENTS);
1516 ins_long(d, "TIMER_EVENTS", TK_TIMER_EVENTS);
1517 ins_long(d, "IDLE_EVENTS", TK_IDLE_EVENTS);
1518 ins_long(d, "ALL_EVENTS", TK_ALL_EVENTS);
1519 ins_long(d, "DONT_WAIT", TK_DONT_WAIT);
1520 ins_string(d, "TK_VERSION", TK_VERSION);
1521 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00001522
Guido van Rossum18468821994-06-20 07:49:28 +00001523#ifdef WITH_READLINE
Barry Warsawfa701a81997-01-16 00:15:11 +00001524 rl_event_hook = EventHook;
Guido van Rossum18468821994-06-20 07:49:28 +00001525#endif /* WITH_READLINE */
1526
Barry Warsawfa701a81997-01-16 00:15:11 +00001527 if (PyErr_Occurred())
1528 Py_FatalError ("can't initialize module _tkinter");
Jack Jansen34cc5c31995-10-31 16:15:12 +00001529#ifdef macintosh
Barry Warsawfa701a81997-01-16 00:15:11 +00001530 TclMacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00001531#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00001532 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001533#endif /* GENERATINGCFM */
1534#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001535}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001536
Guido van Rossumec22c921996-02-25 04:50:29 +00001537
Barry Warsawfa701a81997-01-16 00:15:11 +00001538
Guido van Rossum9722ad81995-09-22 23:49:28 +00001539#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001540
1541/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001542** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001543*/
1544
Guido van Rossum9722ad81995-09-22 23:49:28 +00001545void
1546panic(char * format, ...)
1547{
Barry Warsawfa701a81997-01-16 00:15:11 +00001548 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001549
Barry Warsawfa701a81997-01-16 00:15:11 +00001550 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001551
Barry Warsawfa701a81997-01-16 00:15:11 +00001552 vfprintf(stderr, format, varg);
1553 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001554
Barry Warsawfa701a81997-01-16 00:15:11 +00001555 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001556
Barry Warsawfa701a81997-01-16 00:15:11 +00001557 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00001558}
Jack Jansen40b546d1995-11-14 10:34:45 +00001559
Guido van Rossumec22c921996-02-25 04:50:29 +00001560/*
1561** Pass events to SIOUX before passing them to Tk.
1562*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001563
Guido van Rossumec22c921996-02-25 04:50:29 +00001564static int
1565PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00001566 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001567{
Barry Warsawfa701a81997-01-16 00:15:11 +00001568 if (SIOUXHandleOneEvent(eventPtr))
1569 return 0; /* Nothing happened to the Tcl event queue */
1570 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001571}
1572
Guido van Rossum290283b1997-06-02 22:16:43 +00001573#ifdef USE_GUSI
1574/*
1575 * For Python we have to override this routine (from TclMacNotify),
1576 * since we use GUSI for our sockets, not Tcl streams. Hence, we have
1577 * to use GUSI select to see whether our socket is ready. Note that
1578 * createfilehandler (above) sets the type to TCL_UNIX_FD for our
1579 * files and sockets.
1580 *
1581 * NOTE: this code was lifted from Tcl 7.6, it may need to be modified
1582 * for other versions. */
1583
1584int
1585Tcl_FileReady(file, mask)
1586 Tcl_File file; /* File handle for a stream. */
1587 int mask; /* OR'ed combination of TCL_READABLE,
1588 * TCL_WRITABLE, and TCL_EXCEPTION:
1589 * indicates conditions caller cares about. */
1590{
1591 int type;
1592 int fd;
1593
1594 fd = (int) Tcl_GetFileInfo(file, &type);
1595
1596 if (type == TCL_MAC_SOCKET) {
1597 return TclMacSocketReady(file, mask);
1598 } else if (type == TCL_MAC_FILE) {
1599 /*
1600 * Under the Macintosh, files are always ready, so we just
1601 * return the mask that was passed in.
1602 */
1603
1604 return mask;
1605 } else if (type == TCL_UNIX_FD) {
1606 fd_set readset, writeset, excset;
1607 struct timeval tv;
1608
1609 FD_ZERO(&readset);
1610 FD_ZERO(&writeset);
1611 FD_ZERO(&excset);
1612
1613 if ( mask & TCL_READABLE ) FD_SET(fd, &readset);
1614 if ( mask & TCL_WRITABLE ) FD_SET(fd, &writeset);
1615 if ( mask & TCL_EXCEPTION ) FD_SET(fd, &excset);
1616
1617 tv.tv_sec = tv.tv_usec = 0;
1618 if ( select(fd+1, &readset, &writeset, &excset, &tv) <= 0 )
1619 return 0;
1620
1621 mask = 0;
1622 if ( FD_ISSET(fd, &readset) ) mask |= TCL_READABLE;
1623 if ( FD_ISSET(fd, &writeset) ) mask |= TCL_WRITABLE;
1624 if ( FD_ISSET(fd, &excset) ) mask |= TCL_EXCEPTION;
1625
1626 return mask;
1627 }
1628
1629 return 0;
1630}
1631#endif /* USE_GUSI */
1632
Guido van Rossumec22c921996-02-25 04:50:29 +00001633#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001634
1635/*
1636** Additional Mac specific code for dealing with shared libraries.
1637*/
1638
1639#include <Resources.h>
1640#include <CodeFragments.h>
1641
1642static int loaded_from_shlib = 0;
1643static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001644
Jack Jansen34cc5c31995-10-31 16:15:12 +00001645/*
1646** If this module is dynamically loaded the following routine should
1647** be the init routine. It takes care of adding the shared library to
1648** the resource-file chain, so that the tk routines can find their
1649** resources.
1650*/
1651OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001652init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00001653{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00001654 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00001655 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001656 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001657 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1658 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001659 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001660 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1661 loaded_from_shlib = 1;
1662 }
1663 return noErr;
1664}
1665
1666/*
1667** Insert the library resources into the search path. Put them after
1668** the resources from the application. Again, we ignore errors.
1669*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001670static
Jack Jansen34cc5c31995-10-31 16:15:12 +00001671mac_addlibresources()
1672{
1673 if ( !loaded_from_shlib )
1674 return;
1675 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1676}
1677
Guido van Rossumec22c921996-02-25 04:50:29 +00001678#endif /* GENERATINGCFM */
1679#endif /* macintosh */