blob: 528c2296a815824a1b194be43111c1e6a0c7c76f [file] [log] [blame]
Guido van Rossum845547d1996-06-26 18:26:04 +00001/***********************************************************
2Copyright (C) 1994 Steen Lumholt.
3Copyright 1994-1995 by Stichting Mathematisch Centrum, Amsterdam,
4The Netherlands.
5
6 All Rights Reserved
7
Guido van Rossumd266eb41996-10-25 14:44:06 +00008Permission to use, copy, modify, and distribute this software and its
9documentation for any purpose and without fee is hereby granted,
Guido van Rossum845547d1996-06-26 18:26:04 +000010provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000011both that copyright notice and this permission notice appear in
Guido van Rossum845547d1996-06-26 18:26:04 +000012supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000013Centrum or CWI or Corporation for National Research Initiatives or
14CNRI not be used in advertising or publicity pertaining to
15distribution of the software without specific, written prior
16permission.
Guido van Rossum845547d1996-06-26 18:26:04 +000017
Guido van Rossumd266eb41996-10-25 14:44:06 +000018While CWI is the initial source for this software, a modified version
19is made available by the Corporation for National Research Initiatives
20(CNRI) at the Internet address ftp://ftp.python.org.
21
22STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
23REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
24MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
25CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
26DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
27PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
28TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum845547d1996-06-26 18:26:04 +000030
31******************************************************************/
32
33/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +000034
Guido van Rossum7ffa7611996-08-13 21:10:16 +000035/* TCL/TK VERSION INFO:
36
37 Unix:
Guido van Rossum496f8f61997-07-19 19:57:42 +000038 Tcl/Tk 8.0 (even alpha or beta) or 7.6/4.2 are recommended.
Guido van Rossum35d43371997-08-02 00:09:09 +000039 Versions 7.5/4.1 are the earliest versions still supported.
40 Versions 7.4/4.0 or Tk 3.x are no longer supported.
Guido van Rossum7ffa7611996-08-13 21:10:16 +000041
42 Mac and Windows:
Guido van Rossum496f8f61997-07-19 19:57:42 +000043 Use Tcl 8.0 if available (even alpha or beta).
44 The oldest usable version is 4.1p1/7.5p1.
45
Guido van Rossum7ffa7611996-08-13 21:10:16 +000046*/
47
Guido van Rossum35d43371997-08-02 00:09:09 +000048
Guido van Rossum9722ad81995-09-22 23:49:28 +000049#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000050#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000051
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000052#ifdef macintosh
53#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000054#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000055#endif
56
Guido van Rossum18468821994-06-20 07:49:28 +000057#include <tcl.h>
58#include <tk.h>
59
Guido van Rossum3e819a71997-08-01 19:29:02 +000060#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
61
Guido van Rossum35d43371997-08-02 00:09:09 +000062#if TKMAJORMINOR < 4001
63#error "Tk 4.0 or 3.x are not supported -- use 4.1 or higher"
Guido van Rossum9722ad81995-09-22 23:49:28 +000064#endif
65
Guido van Rossum35d43371997-08-02 00:09:09 +000066extern int Tk_GetNumMainWindows();
67
Guido van Rossumec22c921996-02-25 04:50:29 +000068#ifdef macintosh
69
70/*
71** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +000072** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +000073*/
74
Guido van Rossum7ffa7611996-08-13 21:10:16 +000075/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +000076#define FREECAST (char *)
77
Guido van Rossumec22c921996-02-25 04:50:29 +000078#include <Events.h> /* For EventRecord */
79
80typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
81void TclMacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
82int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
83
84staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
85
86#endif /* macintosh */
87
Guido van Rossum97867b21996-08-08 19:09:53 +000088#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +000089#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +000090#endif
91
Guido van Rossum18468821994-06-20 07:49:28 +000092/**** Tkapp Object Declaration ****/
93
94staticforward PyTypeObject Tkapp_Type;
95
96typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +000097{
98 PyObject_HEAD
99 Tcl_Interp *interp;
Barry Warsawfa701a81997-01-16 00:15:11 +0000100}
Guido van Rossum18468821994-06-20 07:49:28 +0000101TkappObject;
102
103#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000104#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
105#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
106
Guido van Rossum35d43371997-08-02 00:09:09 +0000107#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000108(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000109
Barry Warsawfa701a81997-01-16 00:15:11 +0000110
111
Guido van Rossum18468821994-06-20 07:49:28 +0000112/**** Error Handling ****/
113
114static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000115static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000116static int errorInCmd = 0;
117static PyObject *excInCmd;
118static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000119static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000120
Barry Warsawfa701a81997-01-16 00:15:11 +0000121
122
Guido van Rossum18468821994-06-20 07:49:28 +0000123static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000124Tkinter_Error(v)
125 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000126{
Barry Warsawfa701a81997-01-16 00:15:11 +0000127 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
128 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000129}
130
Barry Warsawfa701a81997-01-16 00:15:11 +0000131
Guido van Rossum18468821994-06-20 07:49:28 +0000132int
Barry Warsawfa701a81997-01-16 00:15:11 +0000133PythonCmd_Error(interp)
134 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000135{
Barry Warsawfa701a81997-01-16 00:15:11 +0000136 errorInCmd = 1;
137 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
138 return TCL_ERROR;
Guido van Rossum18468821994-06-20 07:49:28 +0000139}
140
Barry Warsawfa701a81997-01-16 00:15:11 +0000141
142
Guido van Rossum18468821994-06-20 07:49:28 +0000143/**** Utils ****/
Guido van Rossum18468821994-06-20 07:49:28 +0000144static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000145AsString(value, tmp)
146 PyObject *value;
147 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000148{
Guido van Rossum35d43371997-08-02 00:09:09 +0000149 if (PyString_Check(value))
150 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000151 else {
152 PyObject *v = PyObject_Str(value);
153 PyList_Append(tmp, v);
154 Py_DECREF(v);
155 return PyString_AsString(v);
156 }
Guido van Rossum18468821994-06-20 07:49:28 +0000157}
158
Barry Warsawfa701a81997-01-16 00:15:11 +0000159
160
Guido van Rossum18468821994-06-20 07:49:28 +0000161#define ARGSZ 64
162
163static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000164Merge(args)
165 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000166{
Barry Warsawfa701a81997-01-16 00:15:11 +0000167 PyObject *tmp = NULL;
168 char *argvStore[ARGSZ];
169 char **argv = NULL;
170 int fvStore[ARGSZ];
171 int *fv = NULL;
172 int argc = 0, i;
173 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000174
Barry Warsawfa701a81997-01-16 00:15:11 +0000175 if (!(tmp = PyList_New(0)))
176 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000177
Barry Warsawfa701a81997-01-16 00:15:11 +0000178 argv = argvStore;
179 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000180
Barry Warsawfa701a81997-01-16 00:15:11 +0000181 if (args == NULL)
182 argc = 0;
183
184 else if (!PyTuple_Check(args)) {
185 argc = 1;
186 fv[0] = 0;
187 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000188 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000189 else {
190 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000191
Barry Warsawfa701a81997-01-16 00:15:11 +0000192 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000193 argv = (char **)ckalloc(argc * sizeof(char *));
194 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000195 if (argv == NULL || fv == NULL) {
196 PyErr_NoMemory();
197 goto finally;
198 }
199 }
200
201 for (i = 0; i < argc; i++) {
202 PyObject *v = PyTuple_GetItem(args, i);
203 if (PyTuple_Check(v)) {
204 fv[i] = 1;
205 if (!(argv[i] = Merge(v)))
206 goto finally;
207 }
208 else if (v == Py_None) {
209 argc = i;
210 break;
211 }
212 else {
213 fv[i] = 0;
214 argv[i] = AsString(v, tmp);
215 }
216 }
Guido van Rossum18468821994-06-20 07:49:28 +0000217 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000218 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000219
Barry Warsawfa701a81997-01-16 00:15:11 +0000220 finally:
221 for (i = 0; i < argc; i++)
222 if (fv[i]) {
223 ckfree(argv[i]);
224 }
225 if (argv != argvStore)
226 ckfree(FREECAST argv);
227 if (fv != fvStore)
228 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000229
Barry Warsawfa701a81997-01-16 00:15:11 +0000230 Py_DECREF(tmp);
231 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000232}
233
Barry Warsawfa701a81997-01-16 00:15:11 +0000234
235
Guido van Rossum18468821994-06-20 07:49:28 +0000236static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000237Split(self, list)
238 PyObject *self;
239 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000240{
Barry Warsawfa701a81997-01-16 00:15:11 +0000241 int argc;
242 char **argv;
243 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000244
Barry Warsawfa701a81997-01-16 00:15:11 +0000245 if (list == NULL) {
246 Py_INCREF(Py_None);
247 return Py_None;
248 }
Guido van Rossum18468821994-06-20 07:49:28 +0000249
Barry Warsawfa701a81997-01-16 00:15:11 +0000250 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
251 {
252 /* Not a list.
253 * Could be a quoted string containing funnies, e.g. {"}.
254 * Return the string itself.
255 */
256 PyErr_Clear();
257 return PyString_FromString(list);
258 }
Guido van Rossum18468821994-06-20 07:49:28 +0000259
Barry Warsawfa701a81997-01-16 00:15:11 +0000260 if (argc == 0)
261 v = PyString_FromString("");
262 else if (argc == 1)
263 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000264 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000265 int i;
266 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000267
Barry Warsawfa701a81997-01-16 00:15:11 +0000268 for (i = 0; i < argc; i++) {
269 if ((w = Split(self, argv[i])) == NULL) {
270 Py_DECREF(v);
271 v = NULL;
272 break;
273 }
274 PyTuple_SetItem(v, i, w);
275 }
276 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000277 ckfree(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000278 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000279}
280
Barry Warsawfa701a81997-01-16 00:15:11 +0000281
282
Guido van Rossum18468821994-06-20 07:49:28 +0000283/**** Tkapp Object ****/
284
285#ifndef WITH_APPINIT
286int
Guido van Rossum35d43371997-08-02 00:09:09 +0000287Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000288 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000289{
Barry Warsawfa701a81997-01-16 00:15:11 +0000290 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000291
Barry Warsawfa701a81997-01-16 00:15:11 +0000292 main = Tk_MainWindow(interp);
293 if (Tcl_Init(interp) == TCL_ERROR) {
294 fprintf(stderr, "Tcl_Init error: %s\n", interp->result);
295 return TCL_ERROR;
296 }
297 if (Tk_Init(interp) == TCL_ERROR) {
298 fprintf(stderr, "Tk_Init error: %s\n", interp->result);
299 return TCL_ERROR;
300 }
301 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000302}
303#endif /* !WITH_APPINIT */
304
Guido van Rossum18468821994-06-20 07:49:28 +0000305
Barry Warsawfa701a81997-01-16 00:15:11 +0000306
307
308/* Initialize the Tk application; see the `main' function in
309 * `tkMain.c'.
310 */
311static TkappObject *
312Tkapp_New(screenName, baseName, className, interactive)
313 char *screenName;
314 char *baseName;
315 char *className;
316 int interactive;
317{
318 TkappObject *v;
319 char *argv0;
320
321 v = PyObject_NEW(TkappObject, &Tkapp_Type);
322 if (v == NULL)
323 return NULL;
324
325 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000326
Barry Warsawfa701a81997-01-16 00:15:11 +0000327 if (screenName != NULL)
328 Tcl_SetVar2(v->interp, "env", "DISPLAY",
329 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000330
Barry Warsawfa701a81997-01-16 00:15:11 +0000331 if (interactive)
332 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
333 else
334 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000335
Barry Warsawfa701a81997-01-16 00:15:11 +0000336 /* This is used to get the application class for Tk 4.1 and up */
337 argv0 = (char*)ckalloc(strlen(className) + 1);
338 if (!argv0) {
339 PyErr_NoMemory();
340 Py_DECREF(v);
341 return NULL;
342 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000343
Barry Warsawfa701a81997-01-16 00:15:11 +0000344 strcpy(argv0, className);
345 if (isupper(argv0[0]))
346 argv0[0] = tolower(argv0[0]);
347 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
348 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000349
Barry Warsawfa701a81997-01-16 00:15:11 +0000350 if (Tcl_AppInit(v->interp) != TCL_OK)
351 return (TkappObject *)Tkinter_Error(v);
352
353 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000354}
355
Barry Warsawfa701a81997-01-16 00:15:11 +0000356
357
Guido van Rossum18468821994-06-20 07:49:28 +0000358/** Tcl Eval **/
359
360static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000361Tkapp_Call(self, args)
362 PyObject *self;
363 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000364{
Barry Warsawfa701a81997-01-16 00:15:11 +0000365 char *cmd = Merge(args);
366 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000367
Barry Warsawfa701a81997-01-16 00:15:11 +0000368 if (!cmd)
369 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000370
Barry Warsawfa701a81997-01-16 00:15:11 +0000371 else if (Tcl_Eval(Tkapp_Interp(self), cmd) == TCL_ERROR)
372 res = Tkinter_Error(self);
373
374 else
375 res = PyString_FromString(Tkapp_Result(self));
376
377 if (cmd)
378 ckfree(cmd);
379
380 return res;
381}
382
383
384static PyObject *
385Tkapp_GlobalCall(self, args)
386 PyObject *self;
387 PyObject *args;
388{
389 char *cmd = Merge(args);
390 PyObject *res = NULL;
391
392
393 if (!cmd)
394 PyErr_SetString(Tkinter_TclError, "merge failed");
395
396 else if (Tcl_GlobalEval(Tkapp_Interp(self), cmd) == TCL_ERROR)
397 res = Tkinter_Error(self);
398 else
399 res = PyString_FromString(Tkapp_Result(self));
400
401 if (cmd)
402 ckfree(cmd);
403
404 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000405}
406
407static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000408Tkapp_Eval(self, args)
409 PyObject *self;
410 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000411{
Barry Warsawfa701a81997-01-16 00:15:11 +0000412 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000413
Guido van Rossum35d43371997-08-02 00:09:09 +0000414 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000415 return NULL;
416
417 if (Tcl_Eval(Tkapp_Interp(self), script) == TCL_ERROR)
418 return Tkinter_Error(self);
419
420 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000421}
422
423static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000424Tkapp_GlobalEval(self, args)
425 PyObject *self;
426 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000427{
Barry Warsawfa701a81997-01-16 00:15:11 +0000428 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000429
Guido van Rossum35d43371997-08-02 00:09:09 +0000430 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000431 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000432
Barry Warsawfa701a81997-01-16 00:15:11 +0000433 if (Tcl_GlobalEval(Tkapp_Interp(self), script) == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000434 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000435
Barry Warsawfa701a81997-01-16 00:15:11 +0000436 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000437}
438
439static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000440Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000441 PyObject *self;
442 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000443{
Barry Warsawfa701a81997-01-16 00:15:11 +0000444 char *fileName;
Guido van Rossum18468821994-06-20 07:49:28 +0000445
Guido van Rossum35d43371997-08-02 00:09:09 +0000446 if (!PyArg_ParseTuple(args, "s", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000447 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000448
Barry Warsawfa701a81997-01-16 00:15:11 +0000449 if (Tcl_EvalFile(Tkapp_Interp(self), fileName) == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000450 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000451
Barry Warsawfa701a81997-01-16 00:15:11 +0000452 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000453}
454
455static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000456Tkapp_Record(self, args)
457 PyObject *self;
458 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000459{
Barry Warsawfa701a81997-01-16 00:15:11 +0000460 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000461
Guido van Rossum35d43371997-08-02 00:09:09 +0000462 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000463 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000464
Barry Warsawfa701a81997-01-16 00:15:11 +0000465 if (TCL_ERROR == Tcl_RecordAndEval(Tkapp_Interp(self),
466 script, TCL_NO_EVAL))
Guido van Rossum35d43371997-08-02 00:09:09 +0000467 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000468
Barry Warsawfa701a81997-01-16 00:15:11 +0000469 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000470}
471
472static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000473Tkapp_AddErrorInfo(self, args)
474 PyObject *self;
475 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000476{
Barry Warsawfa701a81997-01-16 00:15:11 +0000477 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000478
Guido van Rossum35d43371997-08-02 00:09:09 +0000479 if (!PyArg_ParseTuple(args, "s", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000480 return NULL;
481 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum18468821994-06-20 07:49:28 +0000482
Barry Warsawfa701a81997-01-16 00:15:11 +0000483 Py_INCREF(Py_None);
484 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000485}
486
Barry Warsawfa701a81997-01-16 00:15:11 +0000487
488
Guido van Rossum18468821994-06-20 07:49:28 +0000489/** Tcl Variable **/
490
491static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000492SetVar(self, args, flags)
493 PyObject *self;
494 PyObject *args;
495 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000496{
Barry Warsawfa701a81997-01-16 00:15:11 +0000497 char *name1, *name2, *ok;
498 PyObject *newValue;
499 PyObject *tmp = PyList_New(0);
Guido van Rossum18468821994-06-20 07:49:28 +0000500
Barry Warsawfa701a81997-01-16 00:15:11 +0000501 if (!tmp)
502 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000503
Guido van Rossum35d43371997-08-02 00:09:09 +0000504 if (PyArg_ParseTuple(args, "sO", &name1, &newValue))
Barry Warsawfa701a81997-01-16 00:15:11 +0000505 /* XXX Merge? */
Guido van Rossum35d43371997-08-02 00:09:09 +0000506 ok = Tcl_SetVar(Tkapp_Interp(self), name1,
507 AsString(newValue, tmp), flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000508
Barry Warsawfa701a81997-01-16 00:15:11 +0000509 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000510 PyErr_Clear();
511 if (PyArg_ParseTuple(args, "ssO", &name1, &name2, &newValue))
512 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
513 AsString (newValue, tmp), flags);
514 else {
515 Py_DECREF (tmp);
516 return NULL;
517 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000518 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000519 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000520
Barry Warsawfa701a81997-01-16 00:15:11 +0000521 if (!ok)
522 return Tkinter_Error(self);
523
524 Py_INCREF(Py_None);
525 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000526}
527
528static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000529Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000530 PyObject *self;
531 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000532{
Barry Warsawfa701a81997-01-16 00:15:11 +0000533 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000534}
535
536static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000537Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000538 PyObject *self;
539 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000540{
Barry Warsawfa701a81997-01-16 00:15:11 +0000541 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000542}
543
Barry Warsawfa701a81997-01-16 00:15:11 +0000544
545
Guido van Rossum18468821994-06-20 07:49:28 +0000546static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000547GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000548 PyObject *self;
549 PyObject *args;
550 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000551{
Guido van Rossum35d43371997-08-02 00:09:09 +0000552 char *name1, *name2=NULL, *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000553
Guido van Rossum35d43371997-08-02 00:09:09 +0000554 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
555 return NULL;
556 if (name2 == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +0000557 s = Tcl_GetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000558
Barry Warsawfa701a81997-01-16 00:15:11 +0000559 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000560 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000561
Barry Warsawfa701a81997-01-16 00:15:11 +0000562 if (s == NULL)
563 return Tkinter_Error(self);
564
Guido van Rossum35d43371997-08-02 00:09:09 +0000565 return PyString_FromString(s);
Guido van Rossum18468821994-06-20 07:49:28 +0000566}
567
568static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000569Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000570 PyObject *self;
571 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000572{
Barry Warsawfa701a81997-01-16 00:15:11 +0000573 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000574}
575
576static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000577Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000578 PyObject *self;
579 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000580{
Barry Warsawfa701a81997-01-16 00:15:11 +0000581 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000582}
583
Barry Warsawfa701a81997-01-16 00:15:11 +0000584
585
Guido van Rossum18468821994-06-20 07:49:28 +0000586static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000587UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000588 PyObject *self;
589 PyObject *args;
590 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000591{
Guido van Rossum35d43371997-08-02 00:09:09 +0000592 char *name1, *name2=NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000593 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000594
Guido van Rossum35d43371997-08-02 00:09:09 +0000595 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000596 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000597 if (name2 == NULL)
598 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
599
600 else
601 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000602
Barry Warsawfa701a81997-01-16 00:15:11 +0000603 if (code == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000604 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000605
606 Py_INCREF(Py_None);
607 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000608}
609
610static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000611Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000612 PyObject *self;
613 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000614{
Barry Warsawfa701a81997-01-16 00:15:11 +0000615 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000616}
617
618static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000619Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000620 PyObject *self;
621 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000622{
Barry Warsawfa701a81997-01-16 00:15:11 +0000623 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000624}
625
Barry Warsawfa701a81997-01-16 00:15:11 +0000626
627
Guido van Rossum18468821994-06-20 07:49:28 +0000628/** Tcl to Python **/
629
630static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000631Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000632 PyObject *self;
633 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000634{
Barry Warsawfa701a81997-01-16 00:15:11 +0000635 char *s;
636 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000637
Guido van Rossum35d43371997-08-02 00:09:09 +0000638 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000639 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000640 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000641 return Tkinter_Error(self);
642 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000643}
644
645static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000646Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000647 PyObject *self;
648 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000649{
Barry Warsawfa701a81997-01-16 00:15:11 +0000650 char *s;
651 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000652
Guido van Rossum35d43371997-08-02 00:09:09 +0000653 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000654 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000655 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000656 return Tkinter_Error(self);
657 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000658}
659
660static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000661Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000662 PyObject *self;
663 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000664{
Barry Warsawfa701a81997-01-16 00:15:11 +0000665 char *s;
666 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000667
Guido van Rossum35d43371997-08-02 00:09:09 +0000668 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000669 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000670 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
671 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000672 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000673}
674
675static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000676Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000677 PyObject *self;
678 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000679{
Barry Warsawfa701a81997-01-16 00:15:11 +0000680 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000681
Guido van Rossum35d43371997-08-02 00:09:09 +0000682 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000683 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000684 if (Tcl_ExprString(Tkapp_Interp(self), s) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000685 return Tkinter_Error(self);
686 return Py_BuildValue("s", Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000687}
688
689static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000690Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000691 PyObject *self;
692 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000693{
Barry Warsawfa701a81997-01-16 00:15:11 +0000694 char *s;
695 long v;
Guido van Rossum18468821994-06-20 07:49:28 +0000696
Guido van Rossum35d43371997-08-02 00:09:09 +0000697 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000698 return NULL;
699 if (Tcl_ExprLong(Tkapp_Interp(self), s, &v) == TCL_ERROR)
700 return Tkinter_Error(self);
701 return Py_BuildValue("l", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000702}
703
704static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000705Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000706 PyObject *self;
707 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000708{
Barry Warsawfa701a81997-01-16 00:15:11 +0000709 char *s;
710 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000711 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000712
Guido van Rossum35d43371997-08-02 00:09:09 +0000713 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000714 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000715 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum35d43371997-08-02 00:09:09 +0000716 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum45b83911997-03-14 04:32:50 +0000717 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000718 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000719 return Tkinter_Error(self);
720 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000721}
722
723static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000724Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000725 PyObject *self;
726 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000727{
Barry Warsawfa701a81997-01-16 00:15:11 +0000728 char *s;
729 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000730
Guido van Rossum35d43371997-08-02 00:09:09 +0000731 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000732 return NULL;
733 if (Tcl_ExprBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
734 return Tkinter_Error(self);
735 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000736}
737
Barry Warsawfa701a81997-01-16 00:15:11 +0000738
739
Guido van Rossum18468821994-06-20 07:49:28 +0000740static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000741Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000742 PyObject *self;
743 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000744{
Barry Warsawfa701a81997-01-16 00:15:11 +0000745 char *list;
746 int argc;
747 char **argv;
748 PyObject *v;
749 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000750
Guido van Rossum35d43371997-08-02 00:09:09 +0000751 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +0000752 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000753
Barry Warsawfa701a81997-01-16 00:15:11 +0000754 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
755 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000756
Barry Warsawfa701a81997-01-16 00:15:11 +0000757 if (!(v = PyTuple_New(argc)))
758 return NULL;
759
760 for (i = 0; i < argc; i++) {
761 PyObject *s = PyString_FromString(argv[i]);
762 if (!s || PyTuple_SetItem(v, i, s)) {
763 Py_DECREF(v);
764 v = NULL;
765 goto finally;
766 }
767 }
Guido van Rossum18468821994-06-20 07:49:28 +0000768
Barry Warsawfa701a81997-01-16 00:15:11 +0000769 finally:
770 ckfree(FREECAST argv);
771 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000772}
773
774static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000775Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000776 PyObject *self;
777 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000778{
Barry Warsawfa701a81997-01-16 00:15:11 +0000779 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000780
Guido van Rossum35d43371997-08-02 00:09:09 +0000781 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +0000782 return NULL;
783 return Split(self, list);
Guido van Rossum18468821994-06-20 07:49:28 +0000784}
785
786static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000787Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000788 PyObject *self;
789 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000790{
Barry Warsawfa701a81997-01-16 00:15:11 +0000791 char *s = Merge(args);
792 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000793
Barry Warsawfa701a81997-01-16 00:15:11 +0000794 if (s) {
795 res = PyString_FromString(s);
796 ckfree(s);
797 }
798 else
799 PyErr_SetString(Tkinter_TclError, "merge failed");
800
801 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000802}
803
Barry Warsawfa701a81997-01-16 00:15:11 +0000804
805
Guido van Rossum18468821994-06-20 07:49:28 +0000806/** Tcl Command **/
807
808/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +0000809 * function or method.
810 */
Guido van Rossum18468821994-06-20 07:49:28 +0000811static int
Guido van Rossum35d43371997-08-02 00:09:09 +0000812PythonCmd(clientData, interp, argc, argv)
Barry Warsawfa701a81997-01-16 00:15:11 +0000813 ClientData clientData; /* Is (self, func) */
814 Tcl_Interp *interp;
815 int argc;
816 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +0000817{
Barry Warsawfa701a81997-01-16 00:15:11 +0000818 PyObject *self, *func, *arg, *res, *tmp;
819 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000820
Barry Warsawfa701a81997-01-16 00:15:11 +0000821 /* TBD: no error checking here since we know, via the
822 * Tkapp_CreateCommand() that the client data is a two-tuple
823 */
824 self = PyTuple_GetItem((PyObject *) clientData, 0);
825 func = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000826
Barry Warsawfa701a81997-01-16 00:15:11 +0000827 /* Create argument list (argv1, ..., argvN) */
828 if (!(arg = PyTuple_New(argc - 1)))
829 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000830
Barry Warsawfa701a81997-01-16 00:15:11 +0000831 for (i = 0; i < (argc - 1); i++) {
832 PyObject *s = PyString_FromString(argv[i + 1]);
833 if (!s || PyTuple_SetItem(arg, i, s)) {
834 Py_DECREF(arg);
835 PythonCmd_Error(interp);
836 }
837 }
838 res = PyEval_CallObject(func, arg);
839 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +0000840
Barry Warsawfa701a81997-01-16 00:15:11 +0000841 if (res == NULL)
842 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +0000843
Barry Warsawfa701a81997-01-16 00:15:11 +0000844 if (!(tmp = PyList_New(0))) {
845 Py_DECREF(res);
846 return PythonCmd_Error(interp);
847 }
848
849 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
850 Py_DECREF(res);
851 Py_DECREF(tmp);
852
853 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000854}
855
856static void
Guido van Rossum35d43371997-08-02 00:09:09 +0000857PythonCmdDelete(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +0000858 ClientData clientData; /* Is (self, func) */
Guido van Rossum18468821994-06-20 07:49:28 +0000859{
Barry Warsawfa701a81997-01-16 00:15:11 +0000860 Py_DECREF((PyObject *) clientData);
Guido van Rossum18468821994-06-20 07:49:28 +0000861}
862
Barry Warsawfa701a81997-01-16 00:15:11 +0000863
864
Guido van Rossum18468821994-06-20 07:49:28 +0000865static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000866Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000867 PyObject *self;
868 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000869{
Barry Warsawfa701a81997-01-16 00:15:11 +0000870 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +0000871 PyObject *func;
Guido van Rossum35d43371997-08-02 00:09:09 +0000872 PyObject *data;
873
874 if (!PyArg_ParseTuple(args, "sO", &cmdName, &func))
875 return NULL;
876 if (!PyCallable_Check(func)) {
877 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +0000878 return NULL;
879 }
Guido van Rossum18468821994-06-20 07:49:28 +0000880
Guido van Rossum35d43371997-08-02 00:09:09 +0000881 data = Py_BuildValue("OO", self, func);
Barry Warsawfa701a81997-01-16 00:15:11 +0000882 if (!data)
883 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000884
Guido van Rossum35d43371997-08-02 00:09:09 +0000885 if (Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
886 (ClientData) data, PythonCmdDelete) == NULL)
887 {
888 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
889 Py_DECREF(data);
890 return NULL;
891 }
Guido van Rossum18468821994-06-20 07:49:28 +0000892
Barry Warsawfa701a81997-01-16 00:15:11 +0000893 Py_INCREF(Py_None);
894 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000895}
896
Barry Warsawfa701a81997-01-16 00:15:11 +0000897
898
Guido van Rossum18468821994-06-20 07:49:28 +0000899static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000900Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000901 PyObject *self;
902 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000903{
Barry Warsawfa701a81997-01-16 00:15:11 +0000904 char *cmdName;
Guido van Rossum18468821994-06-20 07:49:28 +0000905
Guido van Rossum35d43371997-08-02 00:09:09 +0000906 if (!PyArg_ParseTuple(args, "s", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000907 return NULL;
908 if (Tcl_DeleteCommand(Tkapp_Interp(self), cmdName) == -1)
909 {
910 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
911 return NULL;
912 }
913 Py_INCREF(Py_None);
914 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000915}
916
Barry Warsawfa701a81997-01-16 00:15:11 +0000917
918
Guido van Rossum18468821994-06-20 07:49:28 +0000919/** File Handler **/
920
Guido van Rossuma597dde1995-01-10 20:56:29 +0000921static void
Guido van Rossum35d43371997-08-02 00:09:09 +0000922FileHandler(clientData, mask)
Barry Warsawfa701a81997-01-16 00:15:11 +0000923 ClientData clientData; /* Is: (func, file) */
924 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +0000925{
Barry Warsawfa701a81997-01-16 00:15:11 +0000926 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +0000927
Barry Warsawfa701a81997-01-16 00:15:11 +0000928 func = PyTuple_GetItem((PyObject *) clientData, 0);
929 file = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000930
Barry Warsawfa701a81997-01-16 00:15:11 +0000931 arg = Py_BuildValue("(Oi)", file, (long) mask);
932 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +0000933 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +0000934
935 if (res == NULL) {
936 errorInCmd = 1;
937 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
938 }
939 Py_XDECREF(res);
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000940}
941
942static int
Guido van Rossum35d43371997-08-02 00:09:09 +0000943GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +0000944 /* Either an int >= 0 or an object with a
945 *.fileno() method that returns an int >= 0
946 */
947 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000948{
Guido van Rossuma597dde1995-01-10 20:56:29 +0000949 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000950 int id;
951 if (PyInt_Check(file)) {
952 id = PyInt_AsLong(file);
953 if (id < 0)
954 PyErr_SetString(PyExc_ValueError, "invalid file id");
955 return id;
956 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000957 args = PyTuple_New(0);
958 if (args == NULL)
959 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000960
961 meth = PyObject_GetAttrString(file, "fileno");
962 if (meth == NULL) {
963 Py_DECREF(args);
964 return -1;
965 }
966
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000967 res = PyEval_CallObject(meth, args);
968 Py_DECREF(args);
969 Py_DECREF(meth);
970 if (res == NULL)
971 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000972
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000973 if (PyInt_Check(res))
974 id = PyInt_AsLong(res);
975 else
976 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000977
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000978 if (id < 0)
979 PyErr_SetString(PyExc_ValueError,
980 "invalid fileno() return value");
981 Py_DECREF(res);
982 return id;
Guido van Rossum18468821994-06-20 07:49:28 +0000983}
984
Barry Warsawfa701a81997-01-16 00:15:11 +0000985
986static PyObject* Tkapp_ClientDataDict = NULL;
987
Guido van Rossum18468821994-06-20 07:49:28 +0000988static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000989Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000990 PyObject *self;
991 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +0000992{
Barry Warsawfa701a81997-01-16 00:15:11 +0000993 PyObject *file, *func, *data;
994 PyObject *idkey;
995 int mask, id;
Guido van Rossum3e819a71997-08-01 19:29:02 +0000996#if TKMAJORMINOR < 8000
Barry Warsawfa701a81997-01-16 00:15:11 +0000997 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +0000998#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000999
Barry Warsawfa701a81997-01-16 00:15:11 +00001000 if (!Tkapp_ClientDataDict) {
1001 if (!(Tkapp_ClientDataDict = PyDict_New()))
1002 return NULL;
1003 }
Guido van Rossum18468821994-06-20 07:49:28 +00001004
Guido van Rossum35d43371997-08-02 00:09:09 +00001005 if (!PyArg_ParseTuple(args, "OiO", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001006 return NULL;
1007 id = GetFileNo(file);
1008 if (id < 0)
1009 return NULL;
1010 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001011 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001012 return NULL;
1013 }
1014
1015 if (!(idkey = PyInt_FromLong(id)))
1016 return NULL;
1017
1018 /* ClientData is: (func, file) */
Guido van Rossum35d43371997-08-02 00:09:09 +00001019 data = Py_BuildValue("(OO)", func, file);
Barry Warsawfa701a81997-01-16 00:15:11 +00001020 if (!data || PyDict_SetItem(Tkapp_ClientDataDict, idkey, data)) {
1021 Py_DECREF(idkey);
1022 Py_XDECREF(data);
1023 return NULL;
1024 }
1025 Py_DECREF(idkey);
Guido van Rossum76875221994-06-27 07:59:42 +00001026
Guido van Rossum3e819a71997-08-01 19:29:02 +00001027#if TKMAJORMINOR < 8000
Guido van Rossum07886d01996-09-11 23:31:42 +00001028#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001029 /* We assume this is a socket... */
1030 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum3e819a71997-08-01 19:29:02 +00001031#else /* !MS_WINDOWS */
Barry Warsawfa701a81997-01-16 00:15:11 +00001032 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum3e819a71997-08-01 19:29:02 +00001033#endif /* !MS_WINDOWS */
Barry Warsawfa701a81997-01-16 00:15:11 +00001034 /* Ought to check for null Tcl_File object... */
1035 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001036#else /* >= 8000 */
Guido van Rossum3e819a71997-08-01 19:29:02 +00001037 Tcl_CreateFileHandler(id, mask, FileHandler, (ClientData) data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001038#endif /* >= 8000 */
Barry Warsawfa701a81997-01-16 00:15:11 +00001039 /* XXX fileHandlerDict */
Guido van Rossum35d43371997-08-02 00:09:09 +00001040 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001041 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001042}
1043
Barry Warsawfa701a81997-01-16 00:15:11 +00001044
Guido van Rossum18468821994-06-20 07:49:28 +00001045static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001046Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001047 PyObject *self;
1048 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001049{
Barry Warsawfa701a81997-01-16 00:15:11 +00001050 PyObject *file;
1051 PyObject *idkey;
1052 PyObject *data;
1053 int id;
Guido van Rossum3e819a71997-08-01 19:29:02 +00001054#if TKMAJORMINOR < 8000
Barry Warsawfa701a81997-01-16 00:15:11 +00001055 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001056#endif
1057
Guido van Rossum35d43371997-08-02 00:09:09 +00001058 if (!PyArg_ParseTuple(args, "O", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001059 return NULL;
1060 id = GetFileNo(file);
1061 if (id < 0)
1062 return NULL;
1063
1064 if (!(idkey = PyInt_FromLong(id)))
1065 return NULL;
1066
1067 /* find and free the object created in the
1068 * Tkapp_CreateFileHandler() call
1069 */
1070 data = PyDict_GetItem(Tkapp_ClientDataDict, idkey);
1071 Py_XDECREF(data);
1072 PyDict_DelItem(Tkapp_ClientDataDict, idkey);
1073 Py_DECREF(idkey);
Guido van Rossum18468821994-06-20 07:49:28 +00001074
Guido van Rossum3e819a71997-08-01 19:29:02 +00001075#if TKMAJORMINOR < 8000
Guido van Rossum07886d01996-09-11 23:31:42 +00001076#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001077 /* We assume this is a socket... */
1078 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum845547d1996-06-26 18:26:04 +00001079#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001080 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +00001081#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001082 /* Ought to check for null Tcl_File object... */
1083 Tcl_DeleteFileHandler(tfile);
Guido van Rossum35d43371997-08-02 00:09:09 +00001084#else /* >= 8000 */
Guido van Rossum3e819a71997-08-01 19:29:02 +00001085 Tcl_DeleteFileHandler(id);
Guido van Rossum35d43371997-08-02 00:09:09 +00001086#endif /* >= 8000 */
Barry Warsawfa701a81997-01-16 00:15:11 +00001087 /* XXX fileHandlerDict */
Guido van Rossum35d43371997-08-02 00:09:09 +00001088 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001089 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001090}
1091
Barry Warsawfa701a81997-01-16 00:15:11 +00001092
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001093/**** Tktt Object (timer token) ****/
1094
1095staticforward PyTypeObject Tktt_Type;
1096
1097typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +00001098{
1099 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001100 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001101 PyObject *func;
1102}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001103TkttObject;
1104
1105static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001106Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001107 PyObject *self;
1108 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001109{
Barry Warsawfa701a81997-01-16 00:15:11 +00001110 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001111
Guido van Rossum35d43371997-08-02 00:09:09 +00001112 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001113 return NULL;
1114 if (v->func != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001115 Tcl_DeleteTimerHandler(v->token);
Barry Warsawfa701a81997-01-16 00:15:11 +00001116 PyMem_DEL(v->func);
1117 v->func = NULL;
1118 }
1119 Py_INCREF(Py_None);
1120 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001121}
1122
1123static PyMethodDef Tktt_methods[] =
1124{
Guido van Rossum35d43371997-08-02 00:09:09 +00001125 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001126 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001127};
1128
1129static TkttObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001130Tktt_New(token, func)
1131 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001132 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001133{
Barry Warsawfa701a81997-01-16 00:15:11 +00001134 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001135
Barry Warsawfa701a81997-01-16 00:15:11 +00001136 v = PyObject_NEW(TkttObject, &Tktt_Type);
1137 if (v == NULL)
1138 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001139
Barry Warsawfa701a81997-01-16 00:15:11 +00001140 v->token = token;
1141 v->func = func;
1142 Py_INCREF(v->func);
1143 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001144}
1145
1146static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001147Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001148 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001149{
Guido van Rossum35d43371997-08-02 00:09:09 +00001150 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001151}
1152
1153static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001154Tktt_Print(self, fp, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +00001155 PyObject *self;
1156 FILE *fp;
1157 int flags;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001158{
Barry Warsawfa701a81997-01-16 00:15:11 +00001159 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001160
Barry Warsawfa701a81997-01-16 00:15:11 +00001161 fprintf(fp, "<tktimertoken at 0x%lx%s>", (long)v,
1162 v->func == NULL ? ", handler deleted" : "");
1163 return 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001164}
1165
1166static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001167Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001168 PyObject *self;
1169 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001170{
Barry Warsawfa701a81997-01-16 00:15:11 +00001171 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001172}
1173
1174static PyTypeObject Tktt_Type =
1175{
Guido van Rossum35d43371997-08-02 00:09:09 +00001176 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001177 0, /*ob_size */
1178 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001179 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001180 0, /*tp_itemsize */
1181 Tktt_Dealloc, /*tp_dealloc */
1182 Tktt_Print, /*tp_print */
1183 Tktt_GetAttr, /*tp_getattr */
1184 0, /*tp_setattr */
1185 0, /*tp_compare */
1186 0, /*tp_repr */
1187 0, /*tp_as_number */
1188 0, /*tp_as_sequence */
1189 0, /*tp_as_mapping */
1190 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001191};
1192
Barry Warsawfa701a81997-01-16 00:15:11 +00001193
1194
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001195/** Timer Handler **/
1196
1197static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001198TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001199 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001200{
Barry Warsawfa701a81997-01-16 00:15:11 +00001201 PyObject *func = (PyObject *)clientData;
1202 PyObject *res = PyEval_CallObject(func, NULL);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001203
Barry Warsawfa701a81997-01-16 00:15:11 +00001204 if (res == NULL) {
1205 errorInCmd = 1;
1206 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1207 }
1208 else
1209 Py_DECREF(res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001210}
1211
1212static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001213Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001214 PyObject *self;
1215 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001216{
Barry Warsawfa701a81997-01-16 00:15:11 +00001217 int milliseconds;
1218 PyObject *func;
Guido van Rossum35d43371997-08-02 00:09:09 +00001219 Tcl_TimerToken token;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001220
Guido van Rossum35d43371997-08-02 00:09:09 +00001221 if (!PyArg_ParseTuple(args, "iO", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001222 return NULL;
1223 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001224 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001225 return NULL;
1226 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001227 token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1228 (ClientData)func);
Barry Warsawfa701a81997-01-16 00:15:11 +00001229
1230 return (PyObject *) Tktt_New(token, func);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001231}
1232
Barry Warsawfa701a81997-01-16 00:15:11 +00001233
1234
Guido van Rossum18468821994-06-20 07:49:28 +00001235/** Event Loop **/
1236
Guido van Rossum18468821994-06-20 07:49:28 +00001237static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001238Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001239 PyObject *self;
1240 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001241{
Barry Warsawfa701a81997-01-16 00:15:11 +00001242 int threshold = 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001243
Barry Warsawfa701a81997-01-16 00:15:11 +00001244 if (!PyArg_ParseTuple(args, "|i", &threshold))
1245 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001246
Barry Warsawfa701a81997-01-16 00:15:11 +00001247 quitMainLoop = 0;
1248 while (Tk_GetNumMainWindows() > threshold &&
1249 !quitMainLoop &&
1250 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001251 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001252 int result;
1253 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
1254 if (PyErr_CheckSignals() != 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001255 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001256 if (result)
1257 continue;
1258 /* XXX It's not *quite* certain that this is
1259 thread-safe, but it seems *rather* safe as long as
1260 no two threads call mainloop() simultaneously. */
1261 Py_BEGIN_ALLOW_THREADS
1262 result = Tcl_WaitForEvent((Tcl_Time *)NULL);
1263 Py_END_ALLOW_THREADS
1264 if (PyErr_CheckSignals() != 0)
1265 return NULL;
1266 if (result < 0)
1267 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001268 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001269 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001270
Barry Warsawfa701a81997-01-16 00:15:11 +00001271 if (errorInCmd) {
1272 errorInCmd = 0;
1273 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1274 excInCmd = valInCmd = trbInCmd = NULL;
1275 return NULL;
1276 }
1277 Py_INCREF(Py_None);
1278 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001279}
1280
1281static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001282Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001283 PyObject *self;
1284 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001285{
Guido van Rossum35d43371997-08-02 00:09:09 +00001286 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001287 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001288
Barry Warsawfa701a81997-01-16 00:15:11 +00001289 if (!PyArg_ParseTuple(args, "|i", &flags))
1290 return NULL;
1291
Guido van Rossum35d43371997-08-02 00:09:09 +00001292 rv = Tcl_DoOneEvent(flags);
Barry Warsawfa701a81997-01-16 00:15:11 +00001293 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001294}
1295
1296static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001297Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001298 PyObject *self;
1299 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001300{
1301
Guido van Rossum35d43371997-08-02 00:09:09 +00001302 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001303 return NULL;
1304
1305 quitMainLoop = 1;
1306 Py_INCREF(Py_None);
1307 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001308}
1309
Barry Warsawfa701a81997-01-16 00:15:11 +00001310
1311
Guido van Rossum18468821994-06-20 07:49:28 +00001312/**** Tkapp Method List ****/
1313
1314static PyMethodDef Tkapp_methods[] =
1315{
Guido van Rossum35d43371997-08-02 00:09:09 +00001316 {"call", Tkapp_Call, 0},
1317 {"globalcall", Tkapp_GlobalCall, 0},
1318 {"eval", Tkapp_Eval, 1},
1319 {"globaleval", Tkapp_GlobalEval, 1},
1320 {"evalfile", Tkapp_EvalFile, 1},
1321 {"record", Tkapp_Record, 1},
1322 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1323 {"setvar", Tkapp_SetVar, 1},
1324 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1325 {"getvar", Tkapp_GetVar, 1},
1326 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1327 {"unsetvar", Tkapp_UnsetVar, 1},
1328 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1329 {"getint", Tkapp_GetInt, 1},
1330 {"getdouble", Tkapp_GetDouble, 1},
1331 {"getboolean", Tkapp_GetBoolean, 1},
1332 {"exprstring", Tkapp_ExprString, 1},
1333 {"exprlong", Tkapp_ExprLong, 1},
1334 {"exprdouble", Tkapp_ExprDouble, 1},
1335 {"exprboolean", Tkapp_ExprBoolean, 1},
1336 {"splitlist", Tkapp_SplitList, 1},
1337 {"split", Tkapp_Split, 1},
1338 {"merge", Tkapp_Merge, 0},
1339 {"createcommand", Tkapp_CreateCommand, 1},
1340 {"deletecommand", Tkapp_DeleteCommand, 1},
1341 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1342 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
1343 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001344 {"mainloop", Tkapp_MainLoop, 1},
1345 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001346 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001347 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001348};
1349
Barry Warsawfa701a81997-01-16 00:15:11 +00001350
1351
Guido van Rossum18468821994-06-20 07:49:28 +00001352/**** Tkapp Type Methods ****/
1353
1354static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001355Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001356 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001357{
Guido van Rossum35d43371997-08-02 00:09:09 +00001358 Tcl_DeleteInterp(Tkapp_Interp(self));
1359 PyMem_DEL(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001360}
1361
1362static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001363Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001364 PyObject *self;
1365 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001366{
Guido van Rossum35d43371997-08-02 00:09:09 +00001367 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001368}
1369
1370static PyTypeObject Tkapp_Type =
1371{
Guido van Rossum35d43371997-08-02 00:09:09 +00001372 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001373 0, /*ob_size */
1374 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001375 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001376 0, /*tp_itemsize */
1377 Tkapp_Dealloc, /*tp_dealloc */
1378 0, /*tp_print */
1379 Tkapp_GetAttr, /*tp_getattr */
1380 0, /*tp_setattr */
1381 0, /*tp_compare */
1382 0, /*tp_repr */
1383 0, /*tp_as_number */
1384 0, /*tp_as_sequence */
1385 0, /*tp_as_mapping */
1386 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001387};
1388
Barry Warsawfa701a81997-01-16 00:15:11 +00001389
1390
Guido van Rossum18468821994-06-20 07:49:28 +00001391/**** Tkinter Module ****/
1392
1393static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001394Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001395 PyObject *self;
1396 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001397{
Barry Warsawfa701a81997-01-16 00:15:11 +00001398 char *screenName = NULL;
1399 char *baseName = NULL;
1400 char *className = NULL;
1401 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001402
Guido van Rossum35d43371997-08-02 00:09:09 +00001403 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001404 if (baseName != NULL)
1405 baseName++;
1406 else
1407 baseName = Py_GetProgramName();
1408 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001409
Barry Warsawfa701a81997-01-16 00:15:11 +00001410 if (!PyArg_ParseTuple(args, "|zssi",
1411 &screenName, &baseName, &className,
1412 &interactive))
1413 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001414
Barry Warsawfa701a81997-01-16 00:15:11 +00001415 return (PyObject *) Tkapp_New(screenName, baseName, className,
1416 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001417}
1418
1419static PyMethodDef moduleMethods[] =
1420{
Barry Warsawfa701a81997-01-16 00:15:11 +00001421 {"create", Tkinter_Create, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001422 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1423 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
1424 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001425 {"mainloop", Tkapp_MainLoop, 1},
1426 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001427 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001428 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001429};
1430
1431#ifdef WITH_READLINE
1432static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001433EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00001434{
Barry Warsawfa701a81997-01-16 00:15:11 +00001435 /* XXX Reset tty */
1436 if (errorInCmd) {
1437 errorInCmd = 0;
1438 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1439 excInCmd = valInCmd = trbInCmd = NULL;
1440 PyErr_Print();
1441 }
1442 if (Tk_GetNumMainWindows() > 0)
Guido van Rossum35d43371997-08-02 00:09:09 +00001443 Tcl_DoOneEvent(TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001444 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001445}
1446#endif /* WITH_READLINE */
1447
Barry Warsawfa701a81997-01-16 00:15:11 +00001448
1449/* all errors will be checked in one fell swoop in init_tkinter() */
1450static void
1451ins_long(d, name, val)
1452 PyObject *d;
1453 char *name;
1454 long val;
1455{
1456 PyObject *v = PyInt_FromLong(val);
1457 if (v) {
1458 PyDict_SetItemString(d, name, v);
1459 Py_DECREF(v);
1460 }
1461}
1462static void
1463ins_string(d, name, val)
1464 PyObject *d;
1465 char *name;
1466 char *val;
1467{
1468 PyObject *v = PyString_FromString(val);
1469 if (v) {
1470 PyDict_SetItemString(d, name, v);
1471 Py_DECREF(v);
1472 }
1473}
1474
1475
Guido van Rossum18468821994-06-20 07:49:28 +00001476void
Guido van Rossum35d43371997-08-02 00:09:09 +00001477init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00001478{
1479#ifdef WITH_READLINE
Barry Warsawfa701a81997-01-16 00:15:11 +00001480 extern int (*rl_event_hook) ();
Guido van Rossum18468821994-06-20 07:49:28 +00001481#endif /* WITH_READLINE */
Barry Warsawfa701a81997-01-16 00:15:11 +00001482 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001483
Barry Warsawfa701a81997-01-16 00:15:11 +00001484 Tkapp_Type.ob_type = &PyType_Type;
1485 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossumae92f011996-08-21 19:03:36 +00001486
Barry Warsawfa701a81997-01-16 00:15:11 +00001487 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001488
Barry Warsawfa701a81997-01-16 00:15:11 +00001489 d = PyModule_GetDict(m);
1490 Tkinter_TclError = Py_BuildValue("s", "TclError");
1491 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00001492
Guido van Rossum35d43371997-08-02 00:09:09 +00001493 ins_long(d, "READABLE", TCL_READABLE);
1494 ins_long(d, "WRITABLE", TCL_WRITABLE);
1495 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
1496 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
1497 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
1498 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
1499 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
1500 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
1501 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001502 ins_string(d, "TK_VERSION", TK_VERSION);
1503 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00001504
Guido van Rossum18468821994-06-20 07:49:28 +00001505#ifdef WITH_READLINE
Barry Warsawfa701a81997-01-16 00:15:11 +00001506 rl_event_hook = EventHook;
Guido van Rossum18468821994-06-20 07:49:28 +00001507#endif /* WITH_READLINE */
1508
Barry Warsawfa701a81997-01-16 00:15:11 +00001509 if (PyErr_Occurred())
Guido van Rossum35d43371997-08-02 00:09:09 +00001510 Py_FatalError("can't initialize module _tkinter");
Jack Jansen34cc5c31995-10-31 16:15:12 +00001511#ifdef macintosh
Barry Warsawfa701a81997-01-16 00:15:11 +00001512 TclMacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00001513#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00001514 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001515#endif /* GENERATINGCFM */
1516#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001517}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001518
Guido van Rossumec22c921996-02-25 04:50:29 +00001519
Barry Warsawfa701a81997-01-16 00:15:11 +00001520
Guido van Rossum9722ad81995-09-22 23:49:28 +00001521#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001522
1523/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001524** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001525*/
1526
Guido van Rossum9722ad81995-09-22 23:49:28 +00001527void
1528panic(char * format, ...)
1529{
Barry Warsawfa701a81997-01-16 00:15:11 +00001530 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001531
Barry Warsawfa701a81997-01-16 00:15:11 +00001532 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001533
Barry Warsawfa701a81997-01-16 00:15:11 +00001534 vfprintf(stderr, format, varg);
1535 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001536
Barry Warsawfa701a81997-01-16 00:15:11 +00001537 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001538
Barry Warsawfa701a81997-01-16 00:15:11 +00001539 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00001540}
Jack Jansen40b546d1995-11-14 10:34:45 +00001541
Guido van Rossumec22c921996-02-25 04:50:29 +00001542/*
1543** Pass events to SIOUX before passing them to Tk.
1544*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001545
Guido van Rossumec22c921996-02-25 04:50:29 +00001546static int
1547PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00001548 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001549{
Barry Warsawfa701a81997-01-16 00:15:11 +00001550 if (SIOUXHandleOneEvent(eventPtr))
1551 return 0; /* Nothing happened to the Tcl event queue */
1552 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001553}
1554
Guido van Rossum290283b1997-06-02 22:16:43 +00001555#ifdef USE_GUSI
1556/*
1557 * For Python we have to override this routine (from TclMacNotify),
1558 * since we use GUSI for our sockets, not Tcl streams. Hence, we have
1559 * to use GUSI select to see whether our socket is ready. Note that
1560 * createfilehandler (above) sets the type to TCL_UNIX_FD for our
1561 * files and sockets.
1562 *
1563 * NOTE: this code was lifted from Tcl 7.6, it may need to be modified
1564 * for other versions. */
1565
1566int
1567Tcl_FileReady(file, mask)
1568 Tcl_File file; /* File handle for a stream. */
1569 int mask; /* OR'ed combination of TCL_READABLE,
1570 * TCL_WRITABLE, and TCL_EXCEPTION:
1571 * indicates conditions caller cares about. */
1572{
1573 int type;
1574 int fd;
1575
1576 fd = (int) Tcl_GetFileInfo(file, &type);
1577
1578 if (type == TCL_MAC_SOCKET) {
1579 return TclMacSocketReady(file, mask);
1580 } else if (type == TCL_MAC_FILE) {
1581 /*
1582 * Under the Macintosh, files are always ready, so we just
1583 * return the mask that was passed in.
1584 */
1585
1586 return mask;
1587 } else if (type == TCL_UNIX_FD) {
1588 fd_set readset, writeset, excset;
1589 struct timeval tv;
1590
1591 FD_ZERO(&readset);
1592 FD_ZERO(&writeset);
1593 FD_ZERO(&excset);
1594
1595 if ( mask & TCL_READABLE ) FD_SET(fd, &readset);
1596 if ( mask & TCL_WRITABLE ) FD_SET(fd, &writeset);
1597 if ( mask & TCL_EXCEPTION ) FD_SET(fd, &excset);
1598
1599 tv.tv_sec = tv.tv_usec = 0;
1600 if ( select(fd+1, &readset, &writeset, &excset, &tv) <= 0 )
1601 return 0;
1602
1603 mask = 0;
1604 if ( FD_ISSET(fd, &readset) ) mask |= TCL_READABLE;
1605 if ( FD_ISSET(fd, &writeset) ) mask |= TCL_WRITABLE;
1606 if ( FD_ISSET(fd, &excset) ) mask |= TCL_EXCEPTION;
1607
1608 return mask;
1609 }
1610
1611 return 0;
1612}
1613#endif /* USE_GUSI */
1614
Guido van Rossumec22c921996-02-25 04:50:29 +00001615#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001616
1617/*
1618** Additional Mac specific code for dealing with shared libraries.
1619*/
1620
1621#include <Resources.h>
1622#include <CodeFragments.h>
1623
1624static int loaded_from_shlib = 0;
1625static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001626
Jack Jansen34cc5c31995-10-31 16:15:12 +00001627/*
1628** If this module is dynamically loaded the following routine should
1629** be the init routine. It takes care of adding the shared library to
1630** the resource-file chain, so that the tk routines can find their
1631** resources.
1632*/
1633OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001634init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00001635{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00001636 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00001637 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001638 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001639 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1640 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001641 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001642 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1643 loaded_from_shlib = 1;
1644 }
1645 return noErr;
1646}
1647
1648/*
1649** Insert the library resources into the search path. Put them after
1650** the resources from the application. Again, we ignore errors.
1651*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001652static
Jack Jansen34cc5c31995-10-31 16:15:12 +00001653mac_addlibresources()
1654{
1655 if ( !loaded_from_shlib )
1656 return;
1657 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1658}
1659
Guido van Rossumec22c921996-02-25 04:50:29 +00001660#endif /* GENERATINGCFM */
1661#endif /* macintosh */