blob: 19ed4f8fb3ca9ccc7961358bbeebd132591d7c6f [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 Rossum0d2390c1997-08-14 19:57:07 +000062#if TKMAJORMINOR >= 8000 && defined(macintosh)
63/* Sigh, we have to include this to get at the tcl qd pointer */
64#include <tkMac.h>
65#endif
66
Guido van Rossum35d43371997-08-02 00:09:09 +000067#if TKMAJORMINOR < 4001
Guido van Rossum75626a31997-09-08 02:04:00 +000068 #error "Tk 4.0 or 3.x are not supported -- use 4.1 or higher"
Guido van Rossum9722ad81995-09-22 23:49:28 +000069#endif
70
Guido van Rossum0d2390c1997-08-14 19:57:07 +000071#if TKMAJORMINOR < 8000 || !defined(MS_WINDOWS) && !defined(macintosh)
72#define HAVE_CREATEFILEHANDLER
73#endif
74
Guido van Rossum35d43371997-08-02 00:09:09 +000075extern int Tk_GetNumMainWindows();
76
Guido van Rossumec22c921996-02-25 04:50:29 +000077#ifdef macintosh
78
79/*
80** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +000081** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +000082*/
83
Guido van Rossum7ffa7611996-08-13 21:10:16 +000084/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +000085#define FREECAST (char *)
86
Guido van Rossumec22c921996-02-25 04:50:29 +000087#include <Events.h> /* For EventRecord */
88
89typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
Guido van Rossum0d2390c1997-08-14 19:57:07 +000090/* They changed the name... */
91#if TKMAJORMINOR < 8000
92#define Tcl_MacSetEventProc TclMacSetEventProc
93#endif
94void Tcl_MacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
Guido van Rossumec22c921996-02-25 04:50:29 +000095int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
96
97staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
98
99#endif /* macintosh */
100
Guido van Rossum97867b21996-08-08 19:09:53 +0000101#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000102#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000103#endif
104
Guido van Rossum18468821994-06-20 07:49:28 +0000105/**** Tkapp Object Declaration ****/
106
107staticforward PyTypeObject Tkapp_Type;
108
109typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +0000110{
111 PyObject_HEAD
112 Tcl_Interp *interp;
Barry Warsawfa701a81997-01-16 00:15:11 +0000113}
Guido van Rossum18468821994-06-20 07:49:28 +0000114TkappObject;
115
116#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000117#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
118#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
119
Guido van Rossum35d43371997-08-02 00:09:09 +0000120#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000121(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000122
Barry Warsawfa701a81997-01-16 00:15:11 +0000123
124
Guido van Rossum18468821994-06-20 07:49:28 +0000125/**** Error Handling ****/
126
127static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000128static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000129static int errorInCmd = 0;
130static PyObject *excInCmd;
131static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000132static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000133
Barry Warsawfa701a81997-01-16 00:15:11 +0000134
135
Guido van Rossum18468821994-06-20 07:49:28 +0000136static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000137Tkinter_Error(v)
138 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000139{
Barry Warsawfa701a81997-01-16 00:15:11 +0000140 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
141 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000142}
143
Barry Warsawfa701a81997-01-16 00:15:11 +0000144
Guido van Rossum18468821994-06-20 07:49:28 +0000145int
Barry Warsawfa701a81997-01-16 00:15:11 +0000146PythonCmd_Error(interp)
147 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000148{
Barry Warsawfa701a81997-01-16 00:15:11 +0000149 errorInCmd = 1;
150 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
151 return TCL_ERROR;
Guido van Rossum18468821994-06-20 07:49:28 +0000152}
153
Barry Warsawfa701a81997-01-16 00:15:11 +0000154
155
Guido van Rossum18468821994-06-20 07:49:28 +0000156/**** Utils ****/
Guido van Rossum18468821994-06-20 07:49:28 +0000157static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000158AsString(value, tmp)
159 PyObject *value;
160 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000161{
Guido van Rossum35d43371997-08-02 00:09:09 +0000162 if (PyString_Check(value))
163 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000164 else {
165 PyObject *v = PyObject_Str(value);
166 PyList_Append(tmp, v);
167 Py_DECREF(v);
168 return PyString_AsString(v);
169 }
Guido van Rossum18468821994-06-20 07:49:28 +0000170}
171
Barry Warsawfa701a81997-01-16 00:15:11 +0000172
173
Guido van Rossum18468821994-06-20 07:49:28 +0000174#define ARGSZ 64
175
176static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000177Merge(args)
178 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000179{
Barry Warsawfa701a81997-01-16 00:15:11 +0000180 PyObject *tmp = NULL;
181 char *argvStore[ARGSZ];
182 char **argv = NULL;
183 int fvStore[ARGSZ];
184 int *fv = NULL;
185 int argc = 0, i;
186 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000187
Barry Warsawfa701a81997-01-16 00:15:11 +0000188 if (!(tmp = PyList_New(0)))
189 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000190
Barry Warsawfa701a81997-01-16 00:15:11 +0000191 argv = argvStore;
192 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000193
Barry Warsawfa701a81997-01-16 00:15:11 +0000194 if (args == NULL)
195 argc = 0;
196
197 else if (!PyTuple_Check(args)) {
198 argc = 1;
199 fv[0] = 0;
200 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000201 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000202 else {
203 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000204
Barry Warsawfa701a81997-01-16 00:15:11 +0000205 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000206 argv = (char **)ckalloc(argc * sizeof(char *));
207 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000208 if (argv == NULL || fv == NULL) {
209 PyErr_NoMemory();
210 goto finally;
211 }
212 }
213
214 for (i = 0; i < argc; i++) {
215 PyObject *v = PyTuple_GetItem(args, i);
216 if (PyTuple_Check(v)) {
217 fv[i] = 1;
218 if (!(argv[i] = Merge(v)))
219 goto finally;
220 }
221 else if (v == Py_None) {
222 argc = i;
223 break;
224 }
225 else {
226 fv[i] = 0;
227 argv[i] = AsString(v, tmp);
228 }
229 }
Guido van Rossum18468821994-06-20 07:49:28 +0000230 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000231 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000232
Barry Warsawfa701a81997-01-16 00:15:11 +0000233 finally:
234 for (i = 0; i < argc; i++)
235 if (fv[i]) {
236 ckfree(argv[i]);
237 }
238 if (argv != argvStore)
239 ckfree(FREECAST argv);
240 if (fv != fvStore)
241 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000242
Barry Warsawfa701a81997-01-16 00:15:11 +0000243 Py_DECREF(tmp);
244 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000245}
246
Barry Warsawfa701a81997-01-16 00:15:11 +0000247
248
Guido van Rossum18468821994-06-20 07:49:28 +0000249static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000250Split(self, list)
251 PyObject *self;
252 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000253{
Barry Warsawfa701a81997-01-16 00:15:11 +0000254 int argc;
255 char **argv;
256 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000257
Barry Warsawfa701a81997-01-16 00:15:11 +0000258 if (list == NULL) {
259 Py_INCREF(Py_None);
260 return Py_None;
261 }
Guido van Rossum18468821994-06-20 07:49:28 +0000262
Barry Warsawfa701a81997-01-16 00:15:11 +0000263 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
264 {
265 /* Not a list.
266 * Could be a quoted string containing funnies, e.g. {"}.
267 * Return the string itself.
268 */
269 PyErr_Clear();
270 return PyString_FromString(list);
271 }
Guido van Rossum18468821994-06-20 07:49:28 +0000272
Barry Warsawfa701a81997-01-16 00:15:11 +0000273 if (argc == 0)
274 v = PyString_FromString("");
275 else if (argc == 1)
276 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000277 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000278 int i;
279 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000280
Barry Warsawfa701a81997-01-16 00:15:11 +0000281 for (i = 0; i < argc; i++) {
282 if ((w = Split(self, argv[i])) == NULL) {
283 Py_DECREF(v);
284 v = NULL;
285 break;
286 }
287 PyTuple_SetItem(v, i, w);
288 }
289 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000290 ckfree(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000291 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000292}
293
Barry Warsawfa701a81997-01-16 00:15:11 +0000294
295
Guido van Rossum18468821994-06-20 07:49:28 +0000296/**** Tkapp Object ****/
297
298#ifndef WITH_APPINIT
299int
Guido van Rossum35d43371997-08-02 00:09:09 +0000300Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000301 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000302{
Barry Warsawfa701a81997-01-16 00:15:11 +0000303 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000304
Barry Warsawfa701a81997-01-16 00:15:11 +0000305 main = Tk_MainWindow(interp);
306 if (Tcl_Init(interp) == TCL_ERROR) {
307 fprintf(stderr, "Tcl_Init error: %s\n", interp->result);
308 return TCL_ERROR;
309 }
310 if (Tk_Init(interp) == TCL_ERROR) {
311 fprintf(stderr, "Tk_Init error: %s\n", interp->result);
312 return TCL_ERROR;
313 }
314 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000315}
316#endif /* !WITH_APPINIT */
317
Guido van Rossum18468821994-06-20 07:49:28 +0000318
Barry Warsawfa701a81997-01-16 00:15:11 +0000319
320
321/* Initialize the Tk application; see the `main' function in
322 * `tkMain.c'.
323 */
324static TkappObject *
325Tkapp_New(screenName, baseName, className, interactive)
326 char *screenName;
327 char *baseName;
328 char *className;
329 int interactive;
330{
331 TkappObject *v;
332 char *argv0;
333
334 v = PyObject_NEW(TkappObject, &Tkapp_Type);
335 if (v == NULL)
336 return NULL;
337
338 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000339
Barry Warsawfa701a81997-01-16 00:15:11 +0000340 if (screenName != NULL)
341 Tcl_SetVar2(v->interp, "env", "DISPLAY",
342 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000343
Barry Warsawfa701a81997-01-16 00:15:11 +0000344 if (interactive)
345 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
346 else
347 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000348
Barry Warsawfa701a81997-01-16 00:15:11 +0000349 /* This is used to get the application class for Tk 4.1 and up */
350 argv0 = (char*)ckalloc(strlen(className) + 1);
351 if (!argv0) {
352 PyErr_NoMemory();
353 Py_DECREF(v);
354 return NULL;
355 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000356
Barry Warsawfa701a81997-01-16 00:15:11 +0000357 strcpy(argv0, className);
358 if (isupper(argv0[0]))
359 argv0[0] = tolower(argv0[0]);
360 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
361 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000362
Barry Warsawfa701a81997-01-16 00:15:11 +0000363 if (Tcl_AppInit(v->interp) != TCL_OK)
364 return (TkappObject *)Tkinter_Error(v);
365
366 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000367}
368
Barry Warsawfa701a81997-01-16 00:15:11 +0000369
370
Guido van Rossum18468821994-06-20 07:49:28 +0000371/** Tcl Eval **/
372
373static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000374Tkapp_Call(self, args)
375 PyObject *self;
376 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000377{
Barry Warsawfa701a81997-01-16 00:15:11 +0000378 char *cmd = Merge(args);
379 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000380
Barry Warsawfa701a81997-01-16 00:15:11 +0000381 if (!cmd)
382 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000383
Barry Warsawfa701a81997-01-16 00:15:11 +0000384 else if (Tcl_Eval(Tkapp_Interp(self), cmd) == TCL_ERROR)
385 res = Tkinter_Error(self);
386
387 else
388 res = PyString_FromString(Tkapp_Result(self));
389
390 if (cmd)
391 ckfree(cmd);
392
393 return res;
394}
395
396
397static PyObject *
398Tkapp_GlobalCall(self, args)
399 PyObject *self;
400 PyObject *args;
401{
402 char *cmd = Merge(args);
403 PyObject *res = NULL;
404
405
406 if (!cmd)
407 PyErr_SetString(Tkinter_TclError, "merge failed");
408
409 else if (Tcl_GlobalEval(Tkapp_Interp(self), cmd) == TCL_ERROR)
410 res = Tkinter_Error(self);
411 else
412 res = PyString_FromString(Tkapp_Result(self));
413
414 if (cmd)
415 ckfree(cmd);
416
417 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000418}
419
420static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000421Tkapp_Eval(self, args)
422 PyObject *self;
423 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000424{
Barry Warsawfa701a81997-01-16 00:15:11 +0000425 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000426
Guido van Rossum35d43371997-08-02 00:09:09 +0000427 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000428 return NULL;
429
430 if (Tcl_Eval(Tkapp_Interp(self), script) == TCL_ERROR)
431 return Tkinter_Error(self);
432
433 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000434}
435
436static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000437Tkapp_GlobalEval(self, args)
438 PyObject *self;
439 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000440{
Barry Warsawfa701a81997-01-16 00:15:11 +0000441 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000442
Guido van Rossum35d43371997-08-02 00:09:09 +0000443 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000444 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000445
Barry Warsawfa701a81997-01-16 00:15:11 +0000446 if (Tcl_GlobalEval(Tkapp_Interp(self), script) == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000447 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000448
Barry Warsawfa701a81997-01-16 00:15:11 +0000449 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000450}
451
452static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000453Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000454 PyObject *self;
455 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000456{
Barry Warsawfa701a81997-01-16 00:15:11 +0000457 char *fileName;
Guido van Rossum18468821994-06-20 07:49:28 +0000458
Guido van Rossum35d43371997-08-02 00:09:09 +0000459 if (!PyArg_ParseTuple(args, "s", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000460 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000461
Barry Warsawfa701a81997-01-16 00:15:11 +0000462 if (Tcl_EvalFile(Tkapp_Interp(self), fileName) == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000463 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000464
Barry Warsawfa701a81997-01-16 00:15:11 +0000465 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000466}
467
468static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000469Tkapp_Record(self, args)
470 PyObject *self;
471 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000472{
Barry Warsawfa701a81997-01-16 00:15:11 +0000473 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000474
Guido van Rossum35d43371997-08-02 00:09:09 +0000475 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000476 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000477
Barry Warsawfa701a81997-01-16 00:15:11 +0000478 if (TCL_ERROR == Tcl_RecordAndEval(Tkapp_Interp(self),
479 script, TCL_NO_EVAL))
Guido van Rossum35d43371997-08-02 00:09:09 +0000480 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000481
Barry Warsawfa701a81997-01-16 00:15:11 +0000482 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000483}
484
485static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000486Tkapp_AddErrorInfo(self, args)
487 PyObject *self;
488 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000489{
Barry Warsawfa701a81997-01-16 00:15:11 +0000490 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000491
Guido van Rossum35d43371997-08-02 00:09:09 +0000492 if (!PyArg_ParseTuple(args, "s", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000493 return NULL;
494 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum18468821994-06-20 07:49:28 +0000495
Barry Warsawfa701a81997-01-16 00:15:11 +0000496 Py_INCREF(Py_None);
497 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000498}
499
Barry Warsawfa701a81997-01-16 00:15:11 +0000500
501
Guido van Rossum18468821994-06-20 07:49:28 +0000502/** Tcl Variable **/
503
504static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000505SetVar(self, args, flags)
506 PyObject *self;
507 PyObject *args;
508 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000509{
Barry Warsawfa701a81997-01-16 00:15:11 +0000510 char *name1, *name2, *ok;
511 PyObject *newValue;
512 PyObject *tmp = PyList_New(0);
Guido van Rossum18468821994-06-20 07:49:28 +0000513
Barry Warsawfa701a81997-01-16 00:15:11 +0000514 if (!tmp)
515 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000516
Guido van Rossum35d43371997-08-02 00:09:09 +0000517 if (PyArg_ParseTuple(args, "sO", &name1, &newValue))
Barry Warsawfa701a81997-01-16 00:15:11 +0000518 /* XXX Merge? */
Guido van Rossum35d43371997-08-02 00:09:09 +0000519 ok = Tcl_SetVar(Tkapp_Interp(self), name1,
520 AsString(newValue, tmp), flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000521
Barry Warsawfa701a81997-01-16 00:15:11 +0000522 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000523 PyErr_Clear();
524 if (PyArg_ParseTuple(args, "ssO", &name1, &name2, &newValue))
525 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
526 AsString (newValue, tmp), flags);
527 else {
528 Py_DECREF (tmp);
529 return NULL;
530 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000531 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000532 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000533
Barry Warsawfa701a81997-01-16 00:15:11 +0000534 if (!ok)
535 return Tkinter_Error(self);
536
537 Py_INCREF(Py_None);
538 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000539}
540
541static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000542Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000543 PyObject *self;
544 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000545{
Barry Warsawfa701a81997-01-16 00:15:11 +0000546 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000547}
548
549static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000550Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000551 PyObject *self;
552 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000553{
Barry Warsawfa701a81997-01-16 00:15:11 +0000554 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000555}
556
Barry Warsawfa701a81997-01-16 00:15:11 +0000557
558
Guido van Rossum18468821994-06-20 07:49:28 +0000559static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000560GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000561 PyObject *self;
562 PyObject *args;
563 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000564{
Guido van Rossum35d43371997-08-02 00:09:09 +0000565 char *name1, *name2=NULL, *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000566
Guido van Rossum35d43371997-08-02 00:09:09 +0000567 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
568 return NULL;
569 if (name2 == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +0000570 s = Tcl_GetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000571
Barry Warsawfa701a81997-01-16 00:15:11 +0000572 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000573 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000574
Barry Warsawfa701a81997-01-16 00:15:11 +0000575 if (s == NULL)
576 return Tkinter_Error(self);
577
Guido van Rossum35d43371997-08-02 00:09:09 +0000578 return PyString_FromString(s);
Guido van Rossum18468821994-06-20 07:49:28 +0000579}
580
581static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000582Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000583 PyObject *self;
584 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000585{
Barry Warsawfa701a81997-01-16 00:15:11 +0000586 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000587}
588
589static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000590Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000591 PyObject *self;
592 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000593{
Barry Warsawfa701a81997-01-16 00:15:11 +0000594 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000595}
596
Barry Warsawfa701a81997-01-16 00:15:11 +0000597
598
Guido van Rossum18468821994-06-20 07:49:28 +0000599static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000600UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000601 PyObject *self;
602 PyObject *args;
603 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000604{
Guido van Rossum35d43371997-08-02 00:09:09 +0000605 char *name1, *name2=NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000606 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000607
Guido van Rossum35d43371997-08-02 00:09:09 +0000608 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000609 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000610 if (name2 == NULL)
611 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
612
613 else
614 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000615
Barry Warsawfa701a81997-01-16 00:15:11 +0000616 if (code == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000617 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000618
619 Py_INCREF(Py_None);
620 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000621}
622
623static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000624Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000625 PyObject *self;
626 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000627{
Barry Warsawfa701a81997-01-16 00:15:11 +0000628 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000629}
630
631static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000632Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000633 PyObject *self;
634 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000635{
Barry Warsawfa701a81997-01-16 00:15:11 +0000636 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000637}
638
Barry Warsawfa701a81997-01-16 00:15:11 +0000639
640
Guido van Rossum18468821994-06-20 07:49:28 +0000641/** Tcl to Python **/
642
643static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000644Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000645 PyObject *self;
646 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000647{
Barry Warsawfa701a81997-01-16 00:15:11 +0000648 char *s;
649 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000650
Guido van Rossum35d43371997-08-02 00:09:09 +0000651 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000652 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000653 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000654 return Tkinter_Error(self);
655 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000656}
657
658static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000659Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000660 PyObject *self;
661 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000662{
Barry Warsawfa701a81997-01-16 00:15:11 +0000663 char *s;
664 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000665
Guido van Rossum35d43371997-08-02 00:09:09 +0000666 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000667 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000668 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000669 return Tkinter_Error(self);
670 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000671}
672
673static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000674Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000675 PyObject *self;
676 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000677{
Barry Warsawfa701a81997-01-16 00:15:11 +0000678 char *s;
679 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000680
Guido van Rossum35d43371997-08-02 00:09:09 +0000681 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000682 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000683 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
684 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000685 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000686}
687
688static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000689Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000690 PyObject *self;
691 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000692{
Barry Warsawfa701a81997-01-16 00:15:11 +0000693 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000694
Guido van Rossum35d43371997-08-02 00:09:09 +0000695 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000696 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000697 if (Tcl_ExprString(Tkapp_Interp(self), s) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000698 return Tkinter_Error(self);
699 return Py_BuildValue("s", Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000700}
701
702static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000703Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000704 PyObject *self;
705 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000706{
Barry Warsawfa701a81997-01-16 00:15:11 +0000707 char *s;
708 long v;
Guido van Rossum18468821994-06-20 07:49:28 +0000709
Guido van Rossum35d43371997-08-02 00:09:09 +0000710 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000711 return NULL;
712 if (Tcl_ExprLong(Tkapp_Interp(self), s, &v) == TCL_ERROR)
713 return Tkinter_Error(self);
714 return Py_BuildValue("l", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000715}
716
717static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000718Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000719 PyObject *self;
720 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000721{
Barry Warsawfa701a81997-01-16 00:15:11 +0000722 char *s;
723 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000724 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000725
Guido van Rossum35d43371997-08-02 00:09:09 +0000726 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000727 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000728 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum35d43371997-08-02 00:09:09 +0000729 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum45b83911997-03-14 04:32:50 +0000730 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000731 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000732 return Tkinter_Error(self);
733 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000734}
735
736static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000737Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000738 PyObject *self;
739 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000740{
Barry Warsawfa701a81997-01-16 00:15:11 +0000741 char *s;
742 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000743
Guido van Rossum35d43371997-08-02 00:09:09 +0000744 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000745 return NULL;
746 if (Tcl_ExprBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
747 return Tkinter_Error(self);
748 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000749}
750
Barry Warsawfa701a81997-01-16 00:15:11 +0000751
752
Guido van Rossum18468821994-06-20 07:49:28 +0000753static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000754Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000755 PyObject *self;
756 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000757{
Barry Warsawfa701a81997-01-16 00:15:11 +0000758 char *list;
759 int argc;
760 char **argv;
761 PyObject *v;
762 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000763
Guido van Rossum35d43371997-08-02 00:09:09 +0000764 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +0000765 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000766
Barry Warsawfa701a81997-01-16 00:15:11 +0000767 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
768 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000769
Barry Warsawfa701a81997-01-16 00:15:11 +0000770 if (!(v = PyTuple_New(argc)))
771 return NULL;
772
773 for (i = 0; i < argc; i++) {
774 PyObject *s = PyString_FromString(argv[i]);
775 if (!s || PyTuple_SetItem(v, i, s)) {
776 Py_DECREF(v);
777 v = NULL;
778 goto finally;
779 }
780 }
Guido van Rossum18468821994-06-20 07:49:28 +0000781
Barry Warsawfa701a81997-01-16 00:15:11 +0000782 finally:
783 ckfree(FREECAST argv);
784 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000785}
786
787static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000788Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000789 PyObject *self;
790 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000791{
Barry Warsawfa701a81997-01-16 00:15:11 +0000792 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000793
Guido van Rossum35d43371997-08-02 00:09:09 +0000794 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +0000795 return NULL;
796 return Split(self, list);
Guido van Rossum18468821994-06-20 07:49:28 +0000797}
798
799static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000800Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000801 PyObject *self;
802 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000803{
Barry Warsawfa701a81997-01-16 00:15:11 +0000804 char *s = Merge(args);
805 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000806
Barry Warsawfa701a81997-01-16 00:15:11 +0000807 if (s) {
808 res = PyString_FromString(s);
809 ckfree(s);
810 }
811 else
812 PyErr_SetString(Tkinter_TclError, "merge failed");
813
814 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000815}
816
Barry Warsawfa701a81997-01-16 00:15:11 +0000817
818
Guido van Rossum18468821994-06-20 07:49:28 +0000819/** Tcl Command **/
820
821/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +0000822 * function or method.
823 */
Guido van Rossum18468821994-06-20 07:49:28 +0000824static int
Guido van Rossum35d43371997-08-02 00:09:09 +0000825PythonCmd(clientData, interp, argc, argv)
Barry Warsawfa701a81997-01-16 00:15:11 +0000826 ClientData clientData; /* Is (self, func) */
827 Tcl_Interp *interp;
828 int argc;
829 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +0000830{
Barry Warsawfa701a81997-01-16 00:15:11 +0000831 PyObject *self, *func, *arg, *res, *tmp;
832 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000833
Barry Warsawfa701a81997-01-16 00:15:11 +0000834 /* TBD: no error checking here since we know, via the
835 * Tkapp_CreateCommand() that the client data is a two-tuple
836 */
837 self = PyTuple_GetItem((PyObject *) clientData, 0);
838 func = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000839
Barry Warsawfa701a81997-01-16 00:15:11 +0000840 /* Create argument list (argv1, ..., argvN) */
841 if (!(arg = PyTuple_New(argc - 1)))
842 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000843
Barry Warsawfa701a81997-01-16 00:15:11 +0000844 for (i = 0; i < (argc - 1); i++) {
845 PyObject *s = PyString_FromString(argv[i + 1]);
846 if (!s || PyTuple_SetItem(arg, i, s)) {
847 Py_DECREF(arg);
848 PythonCmd_Error(interp);
849 }
850 }
851 res = PyEval_CallObject(func, arg);
852 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +0000853
Barry Warsawfa701a81997-01-16 00:15:11 +0000854 if (res == NULL)
855 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +0000856
Barry Warsawfa701a81997-01-16 00:15:11 +0000857 if (!(tmp = PyList_New(0))) {
858 Py_DECREF(res);
859 return PythonCmd_Error(interp);
860 }
861
862 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
863 Py_DECREF(res);
864 Py_DECREF(tmp);
865
866 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000867}
868
869static void
Guido van Rossum35d43371997-08-02 00:09:09 +0000870PythonCmdDelete(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +0000871 ClientData clientData; /* Is (self, func) */
Guido van Rossum18468821994-06-20 07:49:28 +0000872{
Barry Warsawfa701a81997-01-16 00:15:11 +0000873 Py_DECREF((PyObject *) clientData);
Guido van Rossum18468821994-06-20 07:49:28 +0000874}
875
Barry Warsawfa701a81997-01-16 00:15:11 +0000876
877
Guido van Rossum18468821994-06-20 07:49:28 +0000878static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000879Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000880 PyObject *self;
881 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000882{
Barry Warsawfa701a81997-01-16 00:15:11 +0000883 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +0000884 PyObject *func;
Guido van Rossum35d43371997-08-02 00:09:09 +0000885 PyObject *data;
886
887 if (!PyArg_ParseTuple(args, "sO", &cmdName, &func))
888 return NULL;
889 if (!PyCallable_Check(func)) {
890 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +0000891 return NULL;
892 }
Guido van Rossum18468821994-06-20 07:49:28 +0000893
Guido van Rossum35d43371997-08-02 00:09:09 +0000894 data = Py_BuildValue("OO", self, func);
Barry Warsawfa701a81997-01-16 00:15:11 +0000895 if (!data)
896 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000897
Guido van Rossum35d43371997-08-02 00:09:09 +0000898 if (Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
899 (ClientData) data, PythonCmdDelete) == NULL)
900 {
901 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
902 Py_DECREF(data);
903 return NULL;
904 }
Guido van Rossum18468821994-06-20 07:49:28 +0000905
Barry Warsawfa701a81997-01-16 00:15:11 +0000906 Py_INCREF(Py_None);
907 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000908}
909
Barry Warsawfa701a81997-01-16 00:15:11 +0000910
911
Guido van Rossum18468821994-06-20 07:49:28 +0000912static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000913Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000914 PyObject *self;
915 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000916{
Barry Warsawfa701a81997-01-16 00:15:11 +0000917 char *cmdName;
Guido van Rossum18468821994-06-20 07:49:28 +0000918
Guido van Rossum35d43371997-08-02 00:09:09 +0000919 if (!PyArg_ParseTuple(args, "s", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000920 return NULL;
921 if (Tcl_DeleteCommand(Tkapp_Interp(self), cmdName) == -1)
922 {
923 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
924 return NULL;
925 }
926 Py_INCREF(Py_None);
927 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000928}
929
Barry Warsawfa701a81997-01-16 00:15:11 +0000930
931
Guido van Rossum18468821994-06-20 07:49:28 +0000932/** File Handler **/
933
Guido van Rossuma597dde1995-01-10 20:56:29 +0000934static void
Guido van Rossum35d43371997-08-02 00:09:09 +0000935FileHandler(clientData, mask)
Barry Warsawfa701a81997-01-16 00:15:11 +0000936 ClientData clientData; /* Is: (func, file) */
937 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +0000938{
Barry Warsawfa701a81997-01-16 00:15:11 +0000939 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +0000940
Barry Warsawfa701a81997-01-16 00:15:11 +0000941 func = PyTuple_GetItem((PyObject *) clientData, 0);
942 file = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000943
Barry Warsawfa701a81997-01-16 00:15:11 +0000944 arg = Py_BuildValue("(Oi)", file, (long) mask);
945 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +0000946 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +0000947
948 if (res == NULL) {
949 errorInCmd = 1;
950 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
951 }
952 Py_XDECREF(res);
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000953}
954
955static int
Guido van Rossum35d43371997-08-02 00:09:09 +0000956GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +0000957 /* Either an int >= 0 or an object with a
958 *.fileno() method that returns an int >= 0
959 */
960 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000961{
Guido van Rossuma597dde1995-01-10 20:56:29 +0000962 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000963 int id;
964 if (PyInt_Check(file)) {
965 id = PyInt_AsLong(file);
966 if (id < 0)
967 PyErr_SetString(PyExc_ValueError, "invalid file id");
968 return id;
969 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000970 args = PyTuple_New(0);
971 if (args == NULL)
972 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000973
974 meth = PyObject_GetAttrString(file, "fileno");
975 if (meth == NULL) {
976 Py_DECREF(args);
977 return -1;
978 }
979
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000980 res = PyEval_CallObject(meth, args);
981 Py_DECREF(args);
982 Py_DECREF(meth);
983 if (res == NULL)
984 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000985
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000986 if (PyInt_Check(res))
987 id = PyInt_AsLong(res);
988 else
989 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000990
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000991 if (id < 0)
992 PyErr_SetString(PyExc_ValueError,
993 "invalid fileno() return value");
994 Py_DECREF(res);
995 return id;
Guido van Rossum18468821994-06-20 07:49:28 +0000996}
997
Barry Warsawfa701a81997-01-16 00:15:11 +0000998
999static PyObject* Tkapp_ClientDataDict = NULL;
1000
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001001#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001002static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001003Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001004 PyObject *self;
1005 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001006{
Barry Warsawfa701a81997-01-16 00:15:11 +00001007 PyObject *file, *func, *data;
1008 PyObject *idkey;
1009 int mask, id;
Guido van Rossum3e819a71997-08-01 19:29:02 +00001010#if TKMAJORMINOR < 8000
Barry Warsawfa701a81997-01-16 00:15:11 +00001011 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001012#endif
Guido van Rossum18468821994-06-20 07:49:28 +00001013
Barry Warsawfa701a81997-01-16 00:15:11 +00001014 if (!Tkapp_ClientDataDict) {
1015 if (!(Tkapp_ClientDataDict = PyDict_New()))
1016 return NULL;
1017 }
Guido van Rossum18468821994-06-20 07:49:28 +00001018
Guido van Rossum35d43371997-08-02 00:09:09 +00001019 if (!PyArg_ParseTuple(args, "OiO", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001020 return NULL;
1021 id = GetFileNo(file);
1022 if (id < 0)
1023 return NULL;
1024 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001025 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001026 return NULL;
1027 }
1028
1029 if (!(idkey = PyInt_FromLong(id)))
1030 return NULL;
1031
1032 /* ClientData is: (func, file) */
Guido van Rossum35d43371997-08-02 00:09:09 +00001033 data = Py_BuildValue("(OO)", func, file);
Barry Warsawfa701a81997-01-16 00:15:11 +00001034 if (!data || PyDict_SetItem(Tkapp_ClientDataDict, idkey, data)) {
1035 Py_DECREF(idkey);
1036 Py_XDECREF(data);
1037 return NULL;
1038 }
1039 Py_DECREF(idkey);
Guido van Rossum76875221994-06-27 07:59:42 +00001040
Guido van Rossum3e819a71997-08-01 19:29:02 +00001041#if TKMAJORMINOR < 8000
Guido van Rossum07886d01996-09-11 23:31:42 +00001042#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001043 /* We assume this is a socket... */
1044 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum3e819a71997-08-01 19:29:02 +00001045#else /* !MS_WINDOWS */
Barry Warsawfa701a81997-01-16 00:15:11 +00001046 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum3e819a71997-08-01 19:29:02 +00001047#endif /* !MS_WINDOWS */
Barry Warsawfa701a81997-01-16 00:15:11 +00001048 /* Ought to check for null Tcl_File object... */
1049 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001050#else /* >= 8000 */
Guido van Rossum3e819a71997-08-01 19:29:02 +00001051 Tcl_CreateFileHandler(id, mask, FileHandler, (ClientData) data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001052#endif /* >= 8000 */
Barry Warsawfa701a81997-01-16 00:15:11 +00001053 /* XXX fileHandlerDict */
Guido van Rossum35d43371997-08-02 00:09:09 +00001054 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001055 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001056}
1057
Barry Warsawfa701a81997-01-16 00:15:11 +00001058
Guido van Rossum18468821994-06-20 07:49:28 +00001059static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001060Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001061 PyObject *self;
1062 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001063{
Barry Warsawfa701a81997-01-16 00:15:11 +00001064 PyObject *file;
1065 PyObject *idkey;
1066 PyObject *data;
1067 int id;
Guido van Rossum3e819a71997-08-01 19:29:02 +00001068#if TKMAJORMINOR < 8000
Barry Warsawfa701a81997-01-16 00:15:11 +00001069 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001070#endif
1071
Guido van Rossum35d43371997-08-02 00:09:09 +00001072 if (!PyArg_ParseTuple(args, "O", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001073 return NULL;
1074 id = GetFileNo(file);
1075 if (id < 0)
1076 return NULL;
1077
1078 if (!(idkey = PyInt_FromLong(id)))
1079 return NULL;
1080
1081 /* find and free the object created in the
1082 * Tkapp_CreateFileHandler() call
1083 */
1084 data = PyDict_GetItem(Tkapp_ClientDataDict, idkey);
1085 Py_XDECREF(data);
1086 PyDict_DelItem(Tkapp_ClientDataDict, idkey);
1087 Py_DECREF(idkey);
Guido van Rossum18468821994-06-20 07:49:28 +00001088
Guido van Rossum3e819a71997-08-01 19:29:02 +00001089#if TKMAJORMINOR < 8000
Guido van Rossum07886d01996-09-11 23:31:42 +00001090#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001091 /* We assume this is a socket... */
1092 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum845547d1996-06-26 18:26:04 +00001093#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001094 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +00001095#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001096 /* Ought to check for null Tcl_File object... */
1097 Tcl_DeleteFileHandler(tfile);
Guido van Rossum35d43371997-08-02 00:09:09 +00001098#else /* >= 8000 */
Guido van Rossum3e819a71997-08-01 19:29:02 +00001099 Tcl_DeleteFileHandler(id);
Guido van Rossum35d43371997-08-02 00:09:09 +00001100#endif /* >= 8000 */
Barry Warsawfa701a81997-01-16 00:15:11 +00001101 /* XXX fileHandlerDict */
Guido van Rossum35d43371997-08-02 00:09:09 +00001102 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001103 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001104}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001105#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001106
Barry Warsawfa701a81997-01-16 00:15:11 +00001107
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001108/**** Tktt Object (timer token) ****/
1109
1110staticforward PyTypeObject Tktt_Type;
1111
1112typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +00001113{
1114 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001115 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001116 PyObject *func;
1117}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001118TkttObject;
1119
1120static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001121Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001122 PyObject *self;
1123 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001124{
Barry Warsawfa701a81997-01-16 00:15:11 +00001125 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001126
Guido van Rossum35d43371997-08-02 00:09:09 +00001127 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001128 return NULL;
1129 if (v->func != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001130 Tcl_DeleteTimerHandler(v->token);
Barry Warsawfa701a81997-01-16 00:15:11 +00001131 PyMem_DEL(v->func);
1132 v->func = NULL;
1133 }
1134 Py_INCREF(Py_None);
1135 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001136}
1137
1138static PyMethodDef Tktt_methods[] =
1139{
Guido van Rossum35d43371997-08-02 00:09:09 +00001140 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001141 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001142};
1143
1144static TkttObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001145Tktt_New(token, func)
1146 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001147 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001148{
Barry Warsawfa701a81997-01-16 00:15:11 +00001149 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001150
Barry Warsawfa701a81997-01-16 00:15:11 +00001151 v = PyObject_NEW(TkttObject, &Tktt_Type);
1152 if (v == NULL)
1153 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001154
Barry Warsawfa701a81997-01-16 00:15:11 +00001155 v->token = token;
1156 v->func = func;
1157 Py_INCREF(v->func);
1158 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001159}
1160
1161static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001162Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001163 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001164{
Guido van Rossum35d43371997-08-02 00:09:09 +00001165 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001166}
1167
1168static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001169Tktt_Print(self, fp, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +00001170 PyObject *self;
1171 FILE *fp;
1172 int flags;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001173{
Barry Warsawfa701a81997-01-16 00:15:11 +00001174 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001175
Barry Warsawfa701a81997-01-16 00:15:11 +00001176 fprintf(fp, "<tktimertoken at 0x%lx%s>", (long)v,
1177 v->func == NULL ? ", handler deleted" : "");
1178 return 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001179}
1180
1181static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001182Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001183 PyObject *self;
1184 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001185{
Barry Warsawfa701a81997-01-16 00:15:11 +00001186 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001187}
1188
1189static PyTypeObject Tktt_Type =
1190{
Guido van Rossum35d43371997-08-02 00:09:09 +00001191 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001192 0, /*ob_size */
1193 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001194 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001195 0, /*tp_itemsize */
1196 Tktt_Dealloc, /*tp_dealloc */
1197 Tktt_Print, /*tp_print */
1198 Tktt_GetAttr, /*tp_getattr */
1199 0, /*tp_setattr */
1200 0, /*tp_compare */
1201 0, /*tp_repr */
1202 0, /*tp_as_number */
1203 0, /*tp_as_sequence */
1204 0, /*tp_as_mapping */
1205 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001206};
1207
Barry Warsawfa701a81997-01-16 00:15:11 +00001208
1209
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001210/** Timer Handler **/
1211
1212static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001213TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001214 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001215{
Barry Warsawfa701a81997-01-16 00:15:11 +00001216 PyObject *func = (PyObject *)clientData;
1217 PyObject *res = PyEval_CallObject(func, NULL);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001218
Barry Warsawfa701a81997-01-16 00:15:11 +00001219 if (res == NULL) {
1220 errorInCmd = 1;
1221 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1222 }
1223 else
1224 Py_DECREF(res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001225}
1226
1227static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001228Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001229 PyObject *self;
1230 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001231{
Barry Warsawfa701a81997-01-16 00:15:11 +00001232 int milliseconds;
1233 PyObject *func;
Guido van Rossum35d43371997-08-02 00:09:09 +00001234 Tcl_TimerToken token;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001235
Guido van Rossum35d43371997-08-02 00:09:09 +00001236 if (!PyArg_ParseTuple(args, "iO", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001237 return NULL;
1238 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001239 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001240 return NULL;
1241 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001242 token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1243 (ClientData)func);
Barry Warsawfa701a81997-01-16 00:15:11 +00001244
1245 return (PyObject *) Tktt_New(token, func);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001246}
1247
Barry Warsawfa701a81997-01-16 00:15:11 +00001248
1249
Guido van Rossum18468821994-06-20 07:49:28 +00001250/** Event Loop **/
1251
Guido van Rossum18468821994-06-20 07:49:28 +00001252static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001253Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001254 PyObject *self;
1255 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001256{
Barry Warsawfa701a81997-01-16 00:15:11 +00001257 int threshold = 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001258
Barry Warsawfa701a81997-01-16 00:15:11 +00001259 if (!PyArg_ParseTuple(args, "|i", &threshold))
1260 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001261
Barry Warsawfa701a81997-01-16 00:15:11 +00001262 quitMainLoop = 0;
1263 while (Tk_GetNumMainWindows() > threshold &&
1264 !quitMainLoop &&
1265 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001266 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001267 int result;
Guido van Rossum54e20911997-09-28 05:52:41 +00001268#ifdef HAVE_PYTCL_WAITUNTILEVENT
Guido van Rossum35d43371997-08-02 00:09:09 +00001269 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
1270 if (PyErr_CheckSignals() != 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001271 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001272 if (result)
1273 continue;
1274 /* XXX It's not *quite* certain that this is
1275 thread-safe, but it seems *rather* safe as long as
1276 no two threads call mainloop() simultaneously. */
1277 Py_BEGIN_ALLOW_THREADS
Guido van Rossum54e20911997-09-28 05:52:41 +00001278 result = PyTcl_WaitUntilEvent();
Guido van Rossum35d43371997-08-02 00:09:09 +00001279 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001280#else
1281 result = Tcl_DoOneEvent(0);
1282#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001283 if (PyErr_CheckSignals() != 0)
1284 return NULL;
1285 if (result < 0)
1286 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001287 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001288 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001289
Barry Warsawfa701a81997-01-16 00:15:11 +00001290 if (errorInCmd) {
1291 errorInCmd = 0;
1292 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1293 excInCmd = valInCmd = trbInCmd = NULL;
1294 return NULL;
1295 }
1296 Py_INCREF(Py_None);
1297 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001298}
1299
1300static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001301Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001302 PyObject *self;
1303 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001304{
Guido van Rossum35d43371997-08-02 00:09:09 +00001305 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001306 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001307
Barry Warsawfa701a81997-01-16 00:15:11 +00001308 if (!PyArg_ParseTuple(args, "|i", &flags))
1309 return NULL;
1310
Guido van Rossum35d43371997-08-02 00:09:09 +00001311 rv = Tcl_DoOneEvent(flags);
Barry Warsawfa701a81997-01-16 00:15:11 +00001312 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001313}
1314
1315static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001316Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001317 PyObject *self;
1318 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001319{
1320
Guido van Rossum35d43371997-08-02 00:09:09 +00001321 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001322 return NULL;
1323
1324 quitMainLoop = 1;
1325 Py_INCREF(Py_None);
1326 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001327}
1328
Barry Warsawfa701a81997-01-16 00:15:11 +00001329
1330
Guido van Rossum18468821994-06-20 07:49:28 +00001331/**** Tkapp Method List ****/
1332
1333static PyMethodDef Tkapp_methods[] =
1334{
Guido van Rossum35d43371997-08-02 00:09:09 +00001335 {"call", Tkapp_Call, 0},
1336 {"globalcall", Tkapp_GlobalCall, 0},
1337 {"eval", Tkapp_Eval, 1},
1338 {"globaleval", Tkapp_GlobalEval, 1},
1339 {"evalfile", Tkapp_EvalFile, 1},
1340 {"record", Tkapp_Record, 1},
1341 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1342 {"setvar", Tkapp_SetVar, 1},
1343 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1344 {"getvar", Tkapp_GetVar, 1},
1345 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1346 {"unsetvar", Tkapp_UnsetVar, 1},
1347 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1348 {"getint", Tkapp_GetInt, 1},
1349 {"getdouble", Tkapp_GetDouble, 1},
1350 {"getboolean", Tkapp_GetBoolean, 1},
1351 {"exprstring", Tkapp_ExprString, 1},
1352 {"exprlong", Tkapp_ExprLong, 1},
1353 {"exprdouble", Tkapp_ExprDouble, 1},
1354 {"exprboolean", Tkapp_ExprBoolean, 1},
1355 {"splitlist", Tkapp_SplitList, 1},
1356 {"split", Tkapp_Split, 1},
1357 {"merge", Tkapp_Merge, 0},
1358 {"createcommand", Tkapp_CreateCommand, 1},
1359 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001360#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001361 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1362 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001363#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001364 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001365 {"mainloop", Tkapp_MainLoop, 1},
1366 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001367 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001368 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001369};
1370
Barry Warsawfa701a81997-01-16 00:15:11 +00001371
1372
Guido van Rossum18468821994-06-20 07:49:28 +00001373/**** Tkapp Type Methods ****/
1374
1375static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001376Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001377 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001378{
Guido van Rossum35d43371997-08-02 00:09:09 +00001379 Tcl_DeleteInterp(Tkapp_Interp(self));
1380 PyMem_DEL(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001381}
1382
1383static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001384Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001385 PyObject *self;
1386 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001387{
Guido van Rossum35d43371997-08-02 00:09:09 +00001388 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001389}
1390
1391static PyTypeObject Tkapp_Type =
1392{
Guido van Rossum35d43371997-08-02 00:09:09 +00001393 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001394 0, /*ob_size */
1395 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001396 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001397 0, /*tp_itemsize */
1398 Tkapp_Dealloc, /*tp_dealloc */
1399 0, /*tp_print */
1400 Tkapp_GetAttr, /*tp_getattr */
1401 0, /*tp_setattr */
1402 0, /*tp_compare */
1403 0, /*tp_repr */
1404 0, /*tp_as_number */
1405 0, /*tp_as_sequence */
1406 0, /*tp_as_mapping */
1407 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001408};
1409
Barry Warsawfa701a81997-01-16 00:15:11 +00001410
1411
Guido van Rossum18468821994-06-20 07:49:28 +00001412/**** Tkinter Module ****/
1413
1414static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001415Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001416 PyObject *self;
1417 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001418{
Barry Warsawfa701a81997-01-16 00:15:11 +00001419 char *screenName = NULL;
1420 char *baseName = NULL;
1421 char *className = NULL;
1422 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001423
Guido van Rossum35d43371997-08-02 00:09:09 +00001424 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001425 if (baseName != NULL)
1426 baseName++;
1427 else
1428 baseName = Py_GetProgramName();
1429 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001430
Barry Warsawfa701a81997-01-16 00:15:11 +00001431 if (!PyArg_ParseTuple(args, "|zssi",
1432 &screenName, &baseName, &className,
1433 &interactive))
1434 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001435
Barry Warsawfa701a81997-01-16 00:15:11 +00001436 return (PyObject *) Tkapp_New(screenName, baseName, className,
1437 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001438}
1439
1440static PyMethodDef moduleMethods[] =
1441{
Barry Warsawfa701a81997-01-16 00:15:11 +00001442 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001443#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001444 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1445 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001446#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001447 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001448 {"mainloop", Tkapp_MainLoop, 1},
1449 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001450 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001451 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001452};
1453
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001454static PyInterpreterState *event_interp = NULL;
1455
Guido van Rossum18468821994-06-20 07:49:28 +00001456static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001457EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00001458{
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001459 PyThreadState *tstate;
1460
1461 if (Tk_GetNumMainWindows() == 0)
1462 return 0;
1463 if (event_interp == NULL)
1464 return 0;
1465 tstate = PyThreadState_New(event_interp);
1466 PyEval_AcquireThread(tstate);
1467 if (!errorInCmd)
1468 Tcl_DoOneEvent(TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001469 if (errorInCmd) {
1470 errorInCmd = 0;
1471 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1472 excInCmd = valInCmd = trbInCmd = NULL;
1473 PyErr_Print();
1474 }
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001475 PyThreadState_Clear(tstate);
1476 PyEval_ReleaseThread(tstate);
1477 PyThreadState_Delete(tstate);
Barry Warsawfa701a81997-01-16 00:15:11 +00001478 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001479}
Guido van Rossum18468821994-06-20 07:49:28 +00001480
Barry Warsawfa701a81997-01-16 00:15:11 +00001481
1482/* all errors will be checked in one fell swoop in init_tkinter() */
1483static void
1484ins_long(d, name, val)
1485 PyObject *d;
1486 char *name;
1487 long val;
1488{
1489 PyObject *v = PyInt_FromLong(val);
1490 if (v) {
1491 PyDict_SetItemString(d, name, v);
1492 Py_DECREF(v);
1493 }
1494}
1495static void
1496ins_string(d, name, val)
1497 PyObject *d;
1498 char *name;
1499 char *val;
1500{
1501 PyObject *v = PyString_FromString(val);
1502 if (v) {
1503 PyDict_SetItemString(d, name, v);
1504 Py_DECREF(v);
1505 }
1506}
1507
1508
Guido van Rossum18468821994-06-20 07:49:28 +00001509void
Guido van Rossum35d43371997-08-02 00:09:09 +00001510init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00001511{
Barry Warsawfa701a81997-01-16 00:15:11 +00001512 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001513
Barry Warsawfa701a81997-01-16 00:15:11 +00001514 Tkapp_Type.ob_type = &PyType_Type;
1515 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossumae92f011996-08-21 19:03:36 +00001516
Barry Warsawfa701a81997-01-16 00:15:11 +00001517 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001518
Barry Warsawfa701a81997-01-16 00:15:11 +00001519 d = PyModule_GetDict(m);
1520 Tkinter_TclError = Py_BuildValue("s", "TclError");
1521 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00001522
Guido van Rossum35d43371997-08-02 00:09:09 +00001523 ins_long(d, "READABLE", TCL_READABLE);
1524 ins_long(d, "WRITABLE", TCL_WRITABLE);
1525 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
1526 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
1527 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
1528 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
1529 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
1530 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
1531 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001532 ins_string(d, "TK_VERSION", TK_VERSION);
1533 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00001534
Guido van Rossum83551bf1997-09-13 00:44:23 +00001535 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
1536 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
1537
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001538 if (PyOS_InputHook == NULL) {
1539 PyEval_InitThreads();
1540 event_interp = PyThreadState_Get()->interp;
Guido van Rossum44620641997-08-11 18:57:29 +00001541 PyOS_InputHook = EventHook;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001542 }
Guido van Rossum18468821994-06-20 07:49:28 +00001543
Barry Warsawfa701a81997-01-16 00:15:11 +00001544 if (PyErr_Occurred())
Guido van Rossum35d43371997-08-02 00:09:09 +00001545 Py_FatalError("can't initialize module _tkinter");
Jack Jansen34cc5c31995-10-31 16:15:12 +00001546#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001547 /*
1548 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
1549 ** Most of the initializations in that routine (toolbox init calls and
1550 ** such) have already been done for us, so we only need these.
1551 */
1552#if TKMAJORMINOR >= 8000
1553 tcl_macQdPtr = &qd;
1554#endif
1555
1556 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00001557#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00001558 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001559#endif /* GENERATINGCFM */
1560#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001561}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001562
Guido van Rossumec22c921996-02-25 04:50:29 +00001563
Barry Warsawfa701a81997-01-16 00:15:11 +00001564
Guido van Rossum9722ad81995-09-22 23:49:28 +00001565#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001566
1567/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001568** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001569*/
1570
Guido van Rossum9722ad81995-09-22 23:49:28 +00001571void
1572panic(char * format, ...)
1573{
Barry Warsawfa701a81997-01-16 00:15:11 +00001574 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001575
Barry Warsawfa701a81997-01-16 00:15:11 +00001576 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001577
Barry Warsawfa701a81997-01-16 00:15:11 +00001578 vfprintf(stderr, format, varg);
1579 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001580
Barry Warsawfa701a81997-01-16 00:15:11 +00001581 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001582
Barry Warsawfa701a81997-01-16 00:15:11 +00001583 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00001584}
Jack Jansen40b546d1995-11-14 10:34:45 +00001585
Guido van Rossumec22c921996-02-25 04:50:29 +00001586/*
1587** Pass events to SIOUX before passing them to Tk.
1588*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001589
Guido van Rossumec22c921996-02-25 04:50:29 +00001590static int
1591PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00001592 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001593{
Barry Warsawfa701a81997-01-16 00:15:11 +00001594 if (SIOUXHandleOneEvent(eventPtr))
1595 return 0; /* Nothing happened to the Tcl event queue */
1596 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001597}
1598
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001599#if defined(USE_GUSI) && TKMAJORMINOR < 8000
Guido van Rossum290283b1997-06-02 22:16:43 +00001600/*
1601 * For Python we have to override this routine (from TclMacNotify),
1602 * since we use GUSI for our sockets, not Tcl streams. Hence, we have
1603 * to use GUSI select to see whether our socket is ready. Note that
1604 * createfilehandler (above) sets the type to TCL_UNIX_FD for our
1605 * files and sockets.
1606 *
1607 * NOTE: this code was lifted from Tcl 7.6, it may need to be modified
1608 * for other versions. */
1609
1610int
1611Tcl_FileReady(file, mask)
1612 Tcl_File file; /* File handle for a stream. */
1613 int mask; /* OR'ed combination of TCL_READABLE,
1614 * TCL_WRITABLE, and TCL_EXCEPTION:
1615 * indicates conditions caller cares about. */
1616{
1617 int type;
1618 int fd;
1619
1620 fd = (int) Tcl_GetFileInfo(file, &type);
1621
1622 if (type == TCL_MAC_SOCKET) {
1623 return TclMacSocketReady(file, mask);
1624 } else if (type == TCL_MAC_FILE) {
1625 /*
1626 * Under the Macintosh, files are always ready, so we just
1627 * return the mask that was passed in.
1628 */
1629
1630 return mask;
1631 } else if (type == TCL_UNIX_FD) {
1632 fd_set readset, writeset, excset;
1633 struct timeval tv;
1634
1635 FD_ZERO(&readset);
1636 FD_ZERO(&writeset);
1637 FD_ZERO(&excset);
1638
1639 if ( mask & TCL_READABLE ) FD_SET(fd, &readset);
1640 if ( mask & TCL_WRITABLE ) FD_SET(fd, &writeset);
1641 if ( mask & TCL_EXCEPTION ) FD_SET(fd, &excset);
1642
1643 tv.tv_sec = tv.tv_usec = 0;
1644 if ( select(fd+1, &readset, &writeset, &excset, &tv) <= 0 )
1645 return 0;
1646
1647 mask = 0;
1648 if ( FD_ISSET(fd, &readset) ) mask |= TCL_READABLE;
1649 if ( FD_ISSET(fd, &writeset) ) mask |= TCL_WRITABLE;
1650 if ( FD_ISSET(fd, &excset) ) mask |= TCL_EXCEPTION;
1651
1652 return mask;
1653 }
1654
1655 return 0;
1656}
1657#endif /* USE_GUSI */
1658
Guido van Rossumec22c921996-02-25 04:50:29 +00001659#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001660
1661/*
1662** Additional Mac specific code for dealing with shared libraries.
1663*/
1664
1665#include <Resources.h>
1666#include <CodeFragments.h>
1667
1668static int loaded_from_shlib = 0;
1669static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001670
Jack Jansen34cc5c31995-10-31 16:15:12 +00001671/*
1672** If this module is dynamically loaded the following routine should
1673** be the init routine. It takes care of adding the shared library to
1674** the resource-file chain, so that the tk routines can find their
1675** resources.
1676*/
1677OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001678init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00001679{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00001680 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00001681 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001682 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001683 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1684 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001685 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001686 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1687 loaded_from_shlib = 1;
1688 }
1689 return noErr;
1690}
1691
1692/*
1693** Insert the library resources into the search path. Put them after
1694** the resources from the application. Again, we ignore errors.
1695*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001696static
Jack Jansen34cc5c31995-10-31 16:15:12 +00001697mac_addlibresources()
1698{
1699 if ( !loaded_from_shlib )
1700 return;
1701 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1702}
1703
Guido van Rossumec22c921996-02-25 04:50:29 +00001704#endif /* GENERATINGCFM */
1705#endif /* macintosh */