blob: 8def1efe0eeba73c4e848068abf41bbfdc519ab1 [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 Rossumb0105441997-10-08 15:25:37 +000071#if TKMAJORMINOR < 8000 || !defined(MS_WINDOWS)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000072#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
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000340 /* Delete the 'exit' command, which can screw things up */
341 Tcl_DeleteCommand(v->interp, "exit");
342
Barry Warsawfa701a81997-01-16 00:15:11 +0000343 if (screenName != NULL)
344 Tcl_SetVar2(v->interp, "env", "DISPLAY",
345 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000346
Barry Warsawfa701a81997-01-16 00:15:11 +0000347 if (interactive)
348 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
349 else
350 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000351
Barry Warsawfa701a81997-01-16 00:15:11 +0000352 /* This is used to get the application class for Tk 4.1 and up */
353 argv0 = (char*)ckalloc(strlen(className) + 1);
354 if (!argv0) {
355 PyErr_NoMemory();
356 Py_DECREF(v);
357 return NULL;
358 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000359
Barry Warsawfa701a81997-01-16 00:15:11 +0000360 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000361 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000362 argv0[0] = tolower(argv0[0]);
363 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
364 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000365
Barry Warsawfa701a81997-01-16 00:15:11 +0000366 if (Tcl_AppInit(v->interp) != TCL_OK)
367 return (TkappObject *)Tkinter_Error(v);
368
369 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000370}
371
Barry Warsawfa701a81997-01-16 00:15:11 +0000372
373
Guido van Rossum18468821994-06-20 07:49:28 +0000374/** Tcl Eval **/
375
376static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000377Tkapp_Call(self, args)
378 PyObject *self;
379 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000380{
Barry Warsawfa701a81997-01-16 00:15:11 +0000381 char *cmd = Merge(args);
382 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000383
Barry Warsawfa701a81997-01-16 00:15:11 +0000384 if (!cmd)
385 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000386
Barry Warsawfa701a81997-01-16 00:15:11 +0000387 else if (Tcl_Eval(Tkapp_Interp(self), cmd) == TCL_ERROR)
388 res = Tkinter_Error(self);
389
390 else
391 res = PyString_FromString(Tkapp_Result(self));
392
393 if (cmd)
394 ckfree(cmd);
395
396 return res;
397}
398
399
400static PyObject *
401Tkapp_GlobalCall(self, args)
402 PyObject *self;
403 PyObject *args;
404{
405 char *cmd = Merge(args);
406 PyObject *res = NULL;
407
408
409 if (!cmd)
410 PyErr_SetString(Tkinter_TclError, "merge failed");
411
412 else if (Tcl_GlobalEval(Tkapp_Interp(self), cmd) == TCL_ERROR)
413 res = Tkinter_Error(self);
414 else
415 res = PyString_FromString(Tkapp_Result(self));
416
417 if (cmd)
418 ckfree(cmd);
419
420 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000421}
422
423static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000424Tkapp_Eval(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;
432
433 if (Tcl_Eval(Tkapp_Interp(self), script) == TCL_ERROR)
434 return Tkinter_Error(self);
435
436 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000437}
438
439static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000440Tkapp_GlobalEval(self, args)
441 PyObject *self;
442 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000443{
Barry Warsawfa701a81997-01-16 00:15:11 +0000444 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000445
Guido van Rossum35d43371997-08-02 00:09:09 +0000446 if (!PyArg_ParseTuple(args, "s", &script))
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_GlobalEval(Tkapp_Interp(self), script) == 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 *
Guido van Rossum35d43371997-08-02 00:09:09 +0000456Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000457 PyObject *self;
458 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000459{
Barry Warsawfa701a81997-01-16 00:15:11 +0000460 char *fileName;
Guido van Rossum18468821994-06-20 07:49:28 +0000461
Guido van Rossum35d43371997-08-02 00:09:09 +0000462 if (!PyArg_ParseTuple(args, "s", &fileName))
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_EvalFile(Tkapp_Interp(self), fileName) == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000466 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000467
Barry Warsawfa701a81997-01-16 00:15:11 +0000468 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000469}
470
471static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000472Tkapp_Record(self, args)
473 PyObject *self;
474 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000475{
Barry Warsawfa701a81997-01-16 00:15:11 +0000476 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000477
Guido van Rossum35d43371997-08-02 00:09:09 +0000478 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000479 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000480
Barry Warsawfa701a81997-01-16 00:15:11 +0000481 if (TCL_ERROR == Tcl_RecordAndEval(Tkapp_Interp(self),
482 script, TCL_NO_EVAL))
Guido van Rossum35d43371997-08-02 00:09:09 +0000483 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000484
Barry Warsawfa701a81997-01-16 00:15:11 +0000485 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000486}
487
488static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000489Tkapp_AddErrorInfo(self, args)
490 PyObject *self;
491 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000492{
Barry Warsawfa701a81997-01-16 00:15:11 +0000493 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000494
Guido van Rossum35d43371997-08-02 00:09:09 +0000495 if (!PyArg_ParseTuple(args, "s", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000496 return NULL;
497 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum18468821994-06-20 07:49:28 +0000498
Barry Warsawfa701a81997-01-16 00:15:11 +0000499 Py_INCREF(Py_None);
500 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000501}
502
Barry Warsawfa701a81997-01-16 00:15:11 +0000503
504
Guido van Rossum18468821994-06-20 07:49:28 +0000505/** Tcl Variable **/
506
507static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000508SetVar(self, args, flags)
509 PyObject *self;
510 PyObject *args;
511 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000512{
Barry Warsawfa701a81997-01-16 00:15:11 +0000513 char *name1, *name2, *ok;
514 PyObject *newValue;
515 PyObject *tmp = PyList_New(0);
Guido van Rossum18468821994-06-20 07:49:28 +0000516
Barry Warsawfa701a81997-01-16 00:15:11 +0000517 if (!tmp)
518 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000519
Guido van Rossum35d43371997-08-02 00:09:09 +0000520 if (PyArg_ParseTuple(args, "sO", &name1, &newValue))
Barry Warsawfa701a81997-01-16 00:15:11 +0000521 /* XXX Merge? */
Guido van Rossum35d43371997-08-02 00:09:09 +0000522 ok = Tcl_SetVar(Tkapp_Interp(self), name1,
523 AsString(newValue, tmp), flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000524
Barry Warsawfa701a81997-01-16 00:15:11 +0000525 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000526 PyErr_Clear();
527 if (PyArg_ParseTuple(args, "ssO", &name1, &name2, &newValue))
528 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
529 AsString (newValue, tmp), flags);
530 else {
531 Py_DECREF (tmp);
532 return NULL;
533 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000534 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000535 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000536
Barry Warsawfa701a81997-01-16 00:15:11 +0000537 if (!ok)
538 return Tkinter_Error(self);
539
540 Py_INCREF(Py_None);
541 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000542}
543
544static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000545Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000546 PyObject *self;
547 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000548{
Barry Warsawfa701a81997-01-16 00:15:11 +0000549 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000550}
551
552static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000553Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000554 PyObject *self;
555 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000556{
Barry Warsawfa701a81997-01-16 00:15:11 +0000557 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000558}
559
Barry Warsawfa701a81997-01-16 00:15:11 +0000560
561
Guido van Rossum18468821994-06-20 07:49:28 +0000562static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000563GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000564 PyObject *self;
565 PyObject *args;
566 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000567{
Guido van Rossum35d43371997-08-02 00:09:09 +0000568 char *name1, *name2=NULL, *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000569
Guido van Rossum35d43371997-08-02 00:09:09 +0000570 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
571 return NULL;
572 if (name2 == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +0000573 s = Tcl_GetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000574
Barry Warsawfa701a81997-01-16 00:15:11 +0000575 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000576 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000577
Barry Warsawfa701a81997-01-16 00:15:11 +0000578 if (s == NULL)
579 return Tkinter_Error(self);
580
Guido van Rossum35d43371997-08-02 00:09:09 +0000581 return PyString_FromString(s);
Guido van Rossum18468821994-06-20 07:49:28 +0000582}
583
584static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000585Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000586 PyObject *self;
587 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000588{
Barry Warsawfa701a81997-01-16 00:15:11 +0000589 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000590}
591
592static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000593Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000594 PyObject *self;
595 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000596{
Barry Warsawfa701a81997-01-16 00:15:11 +0000597 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000598}
599
Barry Warsawfa701a81997-01-16 00:15:11 +0000600
601
Guido van Rossum18468821994-06-20 07:49:28 +0000602static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000603UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000604 PyObject *self;
605 PyObject *args;
606 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000607{
Guido van Rossum35d43371997-08-02 00:09:09 +0000608 char *name1, *name2=NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000609 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000610
Guido van Rossum35d43371997-08-02 00:09:09 +0000611 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000612 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000613 if (name2 == NULL)
614 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
615
616 else
617 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000618
Barry Warsawfa701a81997-01-16 00:15:11 +0000619 if (code == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000620 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000621
622 Py_INCREF(Py_None);
623 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000624}
625
626static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000627Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000628 PyObject *self;
629 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000630{
Barry Warsawfa701a81997-01-16 00:15:11 +0000631 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000632}
633
634static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000635Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000636 PyObject *self;
637 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000638{
Barry Warsawfa701a81997-01-16 00:15:11 +0000639 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000640}
641
Barry Warsawfa701a81997-01-16 00:15:11 +0000642
643
Guido van Rossum18468821994-06-20 07:49:28 +0000644/** Tcl to Python **/
645
646static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000647Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000648 PyObject *self;
649 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000650{
Barry Warsawfa701a81997-01-16 00:15:11 +0000651 char *s;
652 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000653
Guido van Rossum35d43371997-08-02 00:09:09 +0000654 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000655 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000656 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000657 return Tkinter_Error(self);
658 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000659}
660
661static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000662Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000663 PyObject *self;
664 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000665{
Barry Warsawfa701a81997-01-16 00:15:11 +0000666 char *s;
667 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000668
Guido van Rossum35d43371997-08-02 00:09:09 +0000669 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000670 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000671 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000672 return Tkinter_Error(self);
673 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000674}
675
676static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000677Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000678 PyObject *self;
679 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000680{
Barry Warsawfa701a81997-01-16 00:15:11 +0000681 char *s;
682 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000683
Guido van Rossum35d43371997-08-02 00:09:09 +0000684 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000685 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000686 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
687 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000688 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000689}
690
691static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000692Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000693 PyObject *self;
694 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000695{
Barry Warsawfa701a81997-01-16 00:15:11 +0000696 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000697
Guido van Rossum35d43371997-08-02 00:09:09 +0000698 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000699 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000700 if (Tcl_ExprString(Tkapp_Interp(self), s) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000701 return Tkinter_Error(self);
702 return Py_BuildValue("s", Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000703}
704
705static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000706Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000707 PyObject *self;
708 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000709{
Barry Warsawfa701a81997-01-16 00:15:11 +0000710 char *s;
711 long v;
Guido van Rossum18468821994-06-20 07:49:28 +0000712
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;
715 if (Tcl_ExprLong(Tkapp_Interp(self), s, &v) == TCL_ERROR)
716 return Tkinter_Error(self);
717 return Py_BuildValue("l", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000718}
719
720static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000721Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000722 PyObject *self;
723 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000724{
Barry Warsawfa701a81997-01-16 00:15:11 +0000725 char *s;
726 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000727 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000728
Guido van Rossum35d43371997-08-02 00:09:09 +0000729 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000730 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000731 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum35d43371997-08-02 00:09:09 +0000732 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum45b83911997-03-14 04:32:50 +0000733 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000734 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000735 return Tkinter_Error(self);
736 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000737}
738
739static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000740Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000741 PyObject *self;
742 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000743{
Barry Warsawfa701a81997-01-16 00:15:11 +0000744 char *s;
745 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000746
Guido van Rossum35d43371997-08-02 00:09:09 +0000747 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000748 return NULL;
749 if (Tcl_ExprBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
750 return Tkinter_Error(self);
751 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000752}
753
Barry Warsawfa701a81997-01-16 00:15:11 +0000754
755
Guido van Rossum18468821994-06-20 07:49:28 +0000756static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000757Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000758 PyObject *self;
759 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000760{
Barry Warsawfa701a81997-01-16 00:15:11 +0000761 char *list;
762 int argc;
763 char **argv;
764 PyObject *v;
765 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000766
Guido van Rossum35d43371997-08-02 00:09:09 +0000767 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +0000768 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000769
Barry Warsawfa701a81997-01-16 00:15:11 +0000770 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
771 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000772
Barry Warsawfa701a81997-01-16 00:15:11 +0000773 if (!(v = PyTuple_New(argc)))
774 return NULL;
775
776 for (i = 0; i < argc; i++) {
777 PyObject *s = PyString_FromString(argv[i]);
778 if (!s || PyTuple_SetItem(v, i, s)) {
779 Py_DECREF(v);
780 v = NULL;
781 goto finally;
782 }
783 }
Guido van Rossum18468821994-06-20 07:49:28 +0000784
Barry Warsawfa701a81997-01-16 00:15:11 +0000785 finally:
786 ckfree(FREECAST argv);
787 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000788}
789
790static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000791Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000792 PyObject *self;
793 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000794{
Barry Warsawfa701a81997-01-16 00:15:11 +0000795 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000796
Guido van Rossum35d43371997-08-02 00:09:09 +0000797 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +0000798 return NULL;
799 return Split(self, list);
Guido van Rossum18468821994-06-20 07:49:28 +0000800}
801
802static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000803Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000804 PyObject *self;
805 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000806{
Barry Warsawfa701a81997-01-16 00:15:11 +0000807 char *s = Merge(args);
808 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000809
Barry Warsawfa701a81997-01-16 00:15:11 +0000810 if (s) {
811 res = PyString_FromString(s);
812 ckfree(s);
813 }
814 else
815 PyErr_SetString(Tkinter_TclError, "merge failed");
816
817 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000818}
819
Barry Warsawfa701a81997-01-16 00:15:11 +0000820
821
Guido van Rossum18468821994-06-20 07:49:28 +0000822/** Tcl Command **/
823
824/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +0000825 * function or method.
826 */
Guido van Rossum18468821994-06-20 07:49:28 +0000827static int
Guido van Rossum35d43371997-08-02 00:09:09 +0000828PythonCmd(clientData, interp, argc, argv)
Barry Warsawfa701a81997-01-16 00:15:11 +0000829 ClientData clientData; /* Is (self, func) */
830 Tcl_Interp *interp;
831 int argc;
832 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +0000833{
Barry Warsawfa701a81997-01-16 00:15:11 +0000834 PyObject *self, *func, *arg, *res, *tmp;
835 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000836
Barry Warsawfa701a81997-01-16 00:15:11 +0000837 /* TBD: no error checking here since we know, via the
838 * Tkapp_CreateCommand() that the client data is a two-tuple
839 */
840 self = PyTuple_GetItem((PyObject *) clientData, 0);
841 func = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000842
Barry Warsawfa701a81997-01-16 00:15:11 +0000843 /* Create argument list (argv1, ..., argvN) */
844 if (!(arg = PyTuple_New(argc - 1)))
845 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000846
Barry Warsawfa701a81997-01-16 00:15:11 +0000847 for (i = 0; i < (argc - 1); i++) {
848 PyObject *s = PyString_FromString(argv[i + 1]);
849 if (!s || PyTuple_SetItem(arg, i, s)) {
850 Py_DECREF(arg);
851 PythonCmd_Error(interp);
852 }
853 }
854 res = PyEval_CallObject(func, arg);
855 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +0000856
Barry Warsawfa701a81997-01-16 00:15:11 +0000857 if (res == NULL)
858 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +0000859
Barry Warsawfa701a81997-01-16 00:15:11 +0000860 if (!(tmp = PyList_New(0))) {
861 Py_DECREF(res);
862 return PythonCmd_Error(interp);
863 }
864
865 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
866 Py_DECREF(res);
867 Py_DECREF(tmp);
868
869 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000870}
871
872static void
Guido van Rossum35d43371997-08-02 00:09:09 +0000873PythonCmdDelete(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +0000874 ClientData clientData; /* Is (self, func) */
Guido van Rossum18468821994-06-20 07:49:28 +0000875{
Barry Warsawfa701a81997-01-16 00:15:11 +0000876 Py_DECREF((PyObject *) clientData);
Guido van Rossum18468821994-06-20 07:49:28 +0000877}
878
Barry Warsawfa701a81997-01-16 00:15:11 +0000879
880
Guido van Rossum18468821994-06-20 07:49:28 +0000881static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000882Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000883 PyObject *self;
884 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000885{
Barry Warsawfa701a81997-01-16 00:15:11 +0000886 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +0000887 PyObject *func;
Guido van Rossum35d43371997-08-02 00:09:09 +0000888 PyObject *data;
889
890 if (!PyArg_ParseTuple(args, "sO", &cmdName, &func))
891 return NULL;
892 if (!PyCallable_Check(func)) {
893 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +0000894 return NULL;
895 }
Guido van Rossum18468821994-06-20 07:49:28 +0000896
Guido van Rossum35d43371997-08-02 00:09:09 +0000897 data = Py_BuildValue("OO", self, func);
Barry Warsawfa701a81997-01-16 00:15:11 +0000898 if (!data)
899 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000900
Guido van Rossum35d43371997-08-02 00:09:09 +0000901 if (Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
902 (ClientData) data, PythonCmdDelete) == NULL)
903 {
904 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
905 Py_DECREF(data);
906 return NULL;
907 }
Guido van Rossum18468821994-06-20 07:49:28 +0000908
Barry Warsawfa701a81997-01-16 00:15:11 +0000909 Py_INCREF(Py_None);
910 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000911}
912
Barry Warsawfa701a81997-01-16 00:15:11 +0000913
914
Guido van Rossum18468821994-06-20 07:49:28 +0000915static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000916Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000917 PyObject *self;
918 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000919{
Barry Warsawfa701a81997-01-16 00:15:11 +0000920 char *cmdName;
Guido van Rossum18468821994-06-20 07:49:28 +0000921
Guido van Rossum35d43371997-08-02 00:09:09 +0000922 if (!PyArg_ParseTuple(args, "s", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000923 return NULL;
924 if (Tcl_DeleteCommand(Tkapp_Interp(self), cmdName) == -1)
925 {
926 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
927 return NULL;
928 }
929 Py_INCREF(Py_None);
930 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000931}
932
Barry Warsawfa701a81997-01-16 00:15:11 +0000933
934
Guido van Rossum18468821994-06-20 07:49:28 +0000935/** File Handler **/
936
Guido van Rossuma597dde1995-01-10 20:56:29 +0000937static void
Guido van Rossum35d43371997-08-02 00:09:09 +0000938FileHandler(clientData, mask)
Barry Warsawfa701a81997-01-16 00:15:11 +0000939 ClientData clientData; /* Is: (func, file) */
940 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +0000941{
Barry Warsawfa701a81997-01-16 00:15:11 +0000942 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +0000943
Barry Warsawfa701a81997-01-16 00:15:11 +0000944 func = PyTuple_GetItem((PyObject *) clientData, 0);
945 file = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000946
Barry Warsawfa701a81997-01-16 00:15:11 +0000947 arg = Py_BuildValue("(Oi)", file, (long) mask);
948 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +0000949 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +0000950
951 if (res == NULL) {
952 errorInCmd = 1;
953 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
954 }
955 Py_XDECREF(res);
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000956}
957
958static int
Guido van Rossum35d43371997-08-02 00:09:09 +0000959GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +0000960 /* Either an int >= 0 or an object with a
961 *.fileno() method that returns an int >= 0
962 */
963 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000964{
Guido van Rossuma597dde1995-01-10 20:56:29 +0000965 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000966 int id;
967 if (PyInt_Check(file)) {
968 id = PyInt_AsLong(file);
969 if (id < 0)
970 PyErr_SetString(PyExc_ValueError, "invalid file id");
971 return id;
972 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000973 args = PyTuple_New(0);
974 if (args == NULL)
975 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000976
977 meth = PyObject_GetAttrString(file, "fileno");
978 if (meth == NULL) {
979 Py_DECREF(args);
980 return -1;
981 }
982
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000983 res = PyEval_CallObject(meth, args);
984 Py_DECREF(args);
985 Py_DECREF(meth);
986 if (res == NULL)
987 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000988
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000989 if (PyInt_Check(res))
990 id = PyInt_AsLong(res);
991 else
992 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000993
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000994 if (id < 0)
995 PyErr_SetString(PyExc_ValueError,
996 "invalid fileno() return value");
997 Py_DECREF(res);
998 return id;
Guido van Rossum18468821994-06-20 07:49:28 +0000999}
1000
Barry Warsawfa701a81997-01-16 00:15:11 +00001001
1002static PyObject* Tkapp_ClientDataDict = NULL;
1003
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001004#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001005static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001006Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001007 PyObject *self;
1008 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001009{
Barry Warsawfa701a81997-01-16 00:15:11 +00001010 PyObject *file, *func, *data;
1011 PyObject *idkey;
1012 int mask, id;
Guido van Rossum3e819a71997-08-01 19:29:02 +00001013#if TKMAJORMINOR < 8000
Barry Warsawfa701a81997-01-16 00:15:11 +00001014 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001015#endif
Guido van Rossum18468821994-06-20 07:49:28 +00001016
Barry Warsawfa701a81997-01-16 00:15:11 +00001017 if (!Tkapp_ClientDataDict) {
1018 if (!(Tkapp_ClientDataDict = PyDict_New()))
1019 return NULL;
1020 }
Guido van Rossum18468821994-06-20 07:49:28 +00001021
Guido van Rossum35d43371997-08-02 00:09:09 +00001022 if (!PyArg_ParseTuple(args, "OiO", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001023 return NULL;
1024 id = GetFileNo(file);
1025 if (id < 0)
1026 return NULL;
1027 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001028 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001029 return NULL;
1030 }
1031
1032 if (!(idkey = PyInt_FromLong(id)))
1033 return NULL;
1034
1035 /* ClientData is: (func, file) */
Guido van Rossum35d43371997-08-02 00:09:09 +00001036 data = Py_BuildValue("(OO)", func, file);
Barry Warsawfa701a81997-01-16 00:15:11 +00001037 if (!data || PyDict_SetItem(Tkapp_ClientDataDict, idkey, data)) {
1038 Py_DECREF(idkey);
1039 Py_XDECREF(data);
1040 return NULL;
1041 }
1042 Py_DECREF(idkey);
Guido van Rossum76875221994-06-27 07:59:42 +00001043
Guido van Rossum3e819a71997-08-01 19:29:02 +00001044#if TKMAJORMINOR < 8000
Guido van Rossum07886d01996-09-11 23:31:42 +00001045#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001046 /* We assume this is a socket... */
1047 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum3e819a71997-08-01 19:29:02 +00001048#else /* !MS_WINDOWS */
Barry Warsawfa701a81997-01-16 00:15:11 +00001049 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum3e819a71997-08-01 19:29:02 +00001050#endif /* !MS_WINDOWS */
Barry Warsawfa701a81997-01-16 00:15:11 +00001051 /* Ought to check for null Tcl_File object... */
1052 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001053#else /* >= 8000 */
Guido van Rossum3e819a71997-08-01 19:29:02 +00001054 Tcl_CreateFileHandler(id, mask, FileHandler, (ClientData) data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001055#endif /* >= 8000 */
Barry Warsawfa701a81997-01-16 00:15:11 +00001056 /* XXX fileHandlerDict */
Guido van Rossum35d43371997-08-02 00:09:09 +00001057 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001058 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001059}
1060
Barry Warsawfa701a81997-01-16 00:15:11 +00001061
Guido van Rossum18468821994-06-20 07:49:28 +00001062static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001063Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001064 PyObject *self;
1065 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001066{
Barry Warsawfa701a81997-01-16 00:15:11 +00001067 PyObject *file;
1068 PyObject *idkey;
1069 PyObject *data;
1070 int id;
Guido van Rossum3e819a71997-08-01 19:29:02 +00001071#if TKMAJORMINOR < 8000
Barry Warsawfa701a81997-01-16 00:15:11 +00001072 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001073#endif
1074
Guido van Rossum35d43371997-08-02 00:09:09 +00001075 if (!PyArg_ParseTuple(args, "O", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001076 return NULL;
1077 id = GetFileNo(file);
1078 if (id < 0)
1079 return NULL;
1080
1081 if (!(idkey = PyInt_FromLong(id)))
1082 return NULL;
1083
1084 /* find and free the object created in the
1085 * Tkapp_CreateFileHandler() call
1086 */
1087 data = PyDict_GetItem(Tkapp_ClientDataDict, idkey);
1088 Py_XDECREF(data);
1089 PyDict_DelItem(Tkapp_ClientDataDict, idkey);
1090 Py_DECREF(idkey);
Guido van Rossum18468821994-06-20 07:49:28 +00001091
Guido van Rossum3e819a71997-08-01 19:29:02 +00001092#if TKMAJORMINOR < 8000
Guido van Rossum07886d01996-09-11 23:31:42 +00001093#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001094 /* We assume this is a socket... */
1095 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum845547d1996-06-26 18:26:04 +00001096#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001097 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +00001098#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001099 /* Ought to check for null Tcl_File object... */
1100 Tcl_DeleteFileHandler(tfile);
Guido van Rossum35d43371997-08-02 00:09:09 +00001101#else /* >= 8000 */
Guido van Rossum3e819a71997-08-01 19:29:02 +00001102 Tcl_DeleteFileHandler(id);
Guido van Rossum35d43371997-08-02 00:09:09 +00001103#endif /* >= 8000 */
Barry Warsawfa701a81997-01-16 00:15:11 +00001104 /* XXX fileHandlerDict */
Guido van Rossum35d43371997-08-02 00:09:09 +00001105 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001106 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001107}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001108#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001109
Barry Warsawfa701a81997-01-16 00:15:11 +00001110
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001111/**** Tktt Object (timer token) ****/
1112
1113staticforward PyTypeObject Tktt_Type;
1114
1115typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +00001116{
1117 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001118 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001119 PyObject *func;
1120}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001121TkttObject;
1122
1123static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001124Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001125 PyObject *self;
1126 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001127{
Barry Warsawfa701a81997-01-16 00:15:11 +00001128 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001129
Guido van Rossum35d43371997-08-02 00:09:09 +00001130 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001131 return NULL;
1132 if (v->func != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001133 Tcl_DeleteTimerHandler(v->token);
Barry Warsawfa701a81997-01-16 00:15:11 +00001134 PyMem_DEL(v->func);
1135 v->func = NULL;
1136 }
1137 Py_INCREF(Py_None);
1138 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001139}
1140
1141static PyMethodDef Tktt_methods[] =
1142{
Guido van Rossum35d43371997-08-02 00:09:09 +00001143 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001144 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001145};
1146
1147static TkttObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001148Tktt_New(token, func)
1149 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001150 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001151{
Barry Warsawfa701a81997-01-16 00:15:11 +00001152 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001153
Barry Warsawfa701a81997-01-16 00:15:11 +00001154 v = PyObject_NEW(TkttObject, &Tktt_Type);
1155 if (v == NULL)
1156 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001157
Barry Warsawfa701a81997-01-16 00:15:11 +00001158 v->token = token;
1159 v->func = func;
1160 Py_INCREF(v->func);
1161 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001162}
1163
1164static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001165Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001166 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001167{
Guido van Rossum35d43371997-08-02 00:09:09 +00001168 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001169}
1170
1171static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001172Tktt_Print(self, fp, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +00001173 PyObject *self;
1174 FILE *fp;
1175 int flags;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001176{
Barry Warsawfa701a81997-01-16 00:15:11 +00001177 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001178
Barry Warsawfa701a81997-01-16 00:15:11 +00001179 fprintf(fp, "<tktimertoken at 0x%lx%s>", (long)v,
1180 v->func == NULL ? ", handler deleted" : "");
1181 return 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001182}
1183
1184static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001185Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001186 PyObject *self;
1187 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001188{
Barry Warsawfa701a81997-01-16 00:15:11 +00001189 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001190}
1191
1192static PyTypeObject Tktt_Type =
1193{
Guido van Rossum35d43371997-08-02 00:09:09 +00001194 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001195 0, /*ob_size */
1196 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001197 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001198 0, /*tp_itemsize */
1199 Tktt_Dealloc, /*tp_dealloc */
1200 Tktt_Print, /*tp_print */
1201 Tktt_GetAttr, /*tp_getattr */
1202 0, /*tp_setattr */
1203 0, /*tp_compare */
1204 0, /*tp_repr */
1205 0, /*tp_as_number */
1206 0, /*tp_as_sequence */
1207 0, /*tp_as_mapping */
1208 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001209};
1210
Barry Warsawfa701a81997-01-16 00:15:11 +00001211
1212
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001213/** Timer Handler **/
1214
1215static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001216TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001217 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001218{
Barry Warsawfa701a81997-01-16 00:15:11 +00001219 PyObject *func = (PyObject *)clientData;
1220 PyObject *res = PyEval_CallObject(func, NULL);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001221
Barry Warsawfa701a81997-01-16 00:15:11 +00001222 if (res == NULL) {
1223 errorInCmd = 1;
1224 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1225 }
1226 else
1227 Py_DECREF(res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001228}
1229
1230static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001231Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001232 PyObject *self;
1233 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001234{
Barry Warsawfa701a81997-01-16 00:15:11 +00001235 int milliseconds;
1236 PyObject *func;
Guido van Rossum35d43371997-08-02 00:09:09 +00001237 Tcl_TimerToken token;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001238
Guido van Rossum35d43371997-08-02 00:09:09 +00001239 if (!PyArg_ParseTuple(args, "iO", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001240 return NULL;
1241 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001242 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001243 return NULL;
1244 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001245 token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1246 (ClientData)func);
Barry Warsawfa701a81997-01-16 00:15:11 +00001247
1248 return (PyObject *) Tktt_New(token, func);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001249}
1250
Barry Warsawfa701a81997-01-16 00:15:11 +00001251
1252
Guido van Rossum18468821994-06-20 07:49:28 +00001253/** Event Loop **/
1254
Guido van Rossum18468821994-06-20 07:49:28 +00001255static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001256Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001257 PyObject *self;
1258 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001259{
Barry Warsawfa701a81997-01-16 00:15:11 +00001260 int threshold = 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001261
Barry Warsawfa701a81997-01-16 00:15:11 +00001262 if (!PyArg_ParseTuple(args, "|i", &threshold))
1263 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001264
Barry Warsawfa701a81997-01-16 00:15:11 +00001265 quitMainLoop = 0;
1266 while (Tk_GetNumMainWindows() > threshold &&
1267 !quitMainLoop &&
1268 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001269 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001270 int result;
Guido van Rossum54e20911997-09-28 05:52:41 +00001271#ifdef HAVE_PYTCL_WAITUNTILEVENT
Guido van Rossum35d43371997-08-02 00:09:09 +00001272 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
1273 if (PyErr_CheckSignals() != 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001274 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001275 if (result)
1276 continue;
1277 /* XXX It's not *quite* certain that this is
1278 thread-safe, but it seems *rather* safe as long as
1279 no two threads call mainloop() simultaneously. */
1280 Py_BEGIN_ALLOW_THREADS
Guido van Rossum54e20911997-09-28 05:52:41 +00001281 result = PyTcl_WaitUntilEvent();
Guido van Rossum35d43371997-08-02 00:09:09 +00001282 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001283#else
1284 result = Tcl_DoOneEvent(0);
1285#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001286 if (PyErr_CheckSignals() != 0)
1287 return NULL;
1288 if (result < 0)
1289 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001290 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001291 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001292
Barry Warsawfa701a81997-01-16 00:15:11 +00001293 if (errorInCmd) {
1294 errorInCmd = 0;
1295 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1296 excInCmd = valInCmd = trbInCmd = NULL;
1297 return NULL;
1298 }
1299 Py_INCREF(Py_None);
1300 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001301}
1302
1303static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001304Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001305 PyObject *self;
1306 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001307{
Guido van Rossum35d43371997-08-02 00:09:09 +00001308 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001309 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001310
Barry Warsawfa701a81997-01-16 00:15:11 +00001311 if (!PyArg_ParseTuple(args, "|i", &flags))
1312 return NULL;
1313
Guido van Rossum35d43371997-08-02 00:09:09 +00001314 rv = Tcl_DoOneEvent(flags);
Barry Warsawfa701a81997-01-16 00:15:11 +00001315 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001316}
1317
1318static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001319Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001320 PyObject *self;
1321 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001322{
1323
Guido van Rossum35d43371997-08-02 00:09:09 +00001324 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001325 return NULL;
1326
1327 quitMainLoop = 1;
1328 Py_INCREF(Py_None);
1329 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001330}
1331
Barry Warsawfa701a81997-01-16 00:15:11 +00001332
1333
Guido van Rossum18468821994-06-20 07:49:28 +00001334/**** Tkapp Method List ****/
1335
1336static PyMethodDef Tkapp_methods[] =
1337{
Guido van Rossum35d43371997-08-02 00:09:09 +00001338 {"call", Tkapp_Call, 0},
1339 {"globalcall", Tkapp_GlobalCall, 0},
1340 {"eval", Tkapp_Eval, 1},
1341 {"globaleval", Tkapp_GlobalEval, 1},
1342 {"evalfile", Tkapp_EvalFile, 1},
1343 {"record", Tkapp_Record, 1},
1344 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1345 {"setvar", Tkapp_SetVar, 1},
1346 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1347 {"getvar", Tkapp_GetVar, 1},
1348 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1349 {"unsetvar", Tkapp_UnsetVar, 1},
1350 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1351 {"getint", Tkapp_GetInt, 1},
1352 {"getdouble", Tkapp_GetDouble, 1},
1353 {"getboolean", Tkapp_GetBoolean, 1},
1354 {"exprstring", Tkapp_ExprString, 1},
1355 {"exprlong", Tkapp_ExprLong, 1},
1356 {"exprdouble", Tkapp_ExprDouble, 1},
1357 {"exprboolean", Tkapp_ExprBoolean, 1},
1358 {"splitlist", Tkapp_SplitList, 1},
1359 {"split", Tkapp_Split, 1},
1360 {"merge", Tkapp_Merge, 0},
1361 {"createcommand", Tkapp_CreateCommand, 1},
1362 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001363#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001364 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1365 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001366#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001367 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001368 {"mainloop", Tkapp_MainLoop, 1},
1369 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001370 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001371 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001372};
1373
Barry Warsawfa701a81997-01-16 00:15:11 +00001374
1375
Guido van Rossum18468821994-06-20 07:49:28 +00001376/**** Tkapp Type Methods ****/
1377
1378static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001379Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001380 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001381{
Guido van Rossum35d43371997-08-02 00:09:09 +00001382 Tcl_DeleteInterp(Tkapp_Interp(self));
1383 PyMem_DEL(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001384}
1385
1386static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001387Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001388 PyObject *self;
1389 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001390{
Guido van Rossum35d43371997-08-02 00:09:09 +00001391 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001392}
1393
1394static PyTypeObject Tkapp_Type =
1395{
Guido van Rossum35d43371997-08-02 00:09:09 +00001396 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001397 0, /*ob_size */
1398 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001399 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001400 0, /*tp_itemsize */
1401 Tkapp_Dealloc, /*tp_dealloc */
1402 0, /*tp_print */
1403 Tkapp_GetAttr, /*tp_getattr */
1404 0, /*tp_setattr */
1405 0, /*tp_compare */
1406 0, /*tp_repr */
1407 0, /*tp_as_number */
1408 0, /*tp_as_sequence */
1409 0, /*tp_as_mapping */
1410 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001411};
1412
Barry Warsawfa701a81997-01-16 00:15:11 +00001413
1414
Guido van Rossum18468821994-06-20 07:49:28 +00001415/**** Tkinter Module ****/
1416
1417static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001418Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001419 PyObject *self;
1420 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001421{
Barry Warsawfa701a81997-01-16 00:15:11 +00001422 char *screenName = NULL;
1423 char *baseName = NULL;
1424 char *className = NULL;
1425 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001426
Guido van Rossum35d43371997-08-02 00:09:09 +00001427 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001428 if (baseName != NULL)
1429 baseName++;
1430 else
1431 baseName = Py_GetProgramName();
1432 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001433
Barry Warsawfa701a81997-01-16 00:15:11 +00001434 if (!PyArg_ParseTuple(args, "|zssi",
1435 &screenName, &baseName, &className,
1436 &interactive))
1437 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001438
Barry Warsawfa701a81997-01-16 00:15:11 +00001439 return (PyObject *) Tkapp_New(screenName, baseName, className,
1440 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001441}
1442
1443static PyMethodDef moduleMethods[] =
1444{
Barry Warsawfa701a81997-01-16 00:15:11 +00001445 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001446#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001447 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1448 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001449#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001450 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001451 {"mainloop", Tkapp_MainLoop, 1},
1452 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001453 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001454 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001455};
1456
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001457static PyInterpreterState *event_interp = NULL;
1458
Guido van Rossum18468821994-06-20 07:49:28 +00001459static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001460EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00001461{
Guido van Rossuma59406a1997-10-10 17:39:19 +00001462 PyThreadState *tstate, *save_tstate;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001463
1464 if (Tk_GetNumMainWindows() == 0)
1465 return 0;
1466 if (event_interp == NULL)
1467 return 0;
1468 tstate = PyThreadState_New(event_interp);
Guido van Rossuma59406a1997-10-10 17:39:19 +00001469 save_tstate = PyThreadState_Swap(NULL);
1470 PyEval_RestoreThread(tstate);
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001471 if (!errorInCmd)
1472 Tcl_DoOneEvent(TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001473 if (errorInCmd) {
1474 errorInCmd = 0;
1475 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1476 excInCmd = valInCmd = trbInCmd = NULL;
1477 PyErr_Print();
1478 }
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001479 PyThreadState_Clear(tstate);
Guido van Rossuma59406a1997-10-10 17:39:19 +00001480 PyEval_SaveThread();
1481 PyThreadState_Swap(save_tstate);
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001482 PyThreadState_Delete(tstate);
Barry Warsawfa701a81997-01-16 00:15:11 +00001483 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001484}
Guido van Rossum18468821994-06-20 07:49:28 +00001485
Barry Warsawfa701a81997-01-16 00:15:11 +00001486
1487/* all errors will be checked in one fell swoop in init_tkinter() */
1488static void
1489ins_long(d, name, val)
1490 PyObject *d;
1491 char *name;
1492 long val;
1493{
1494 PyObject *v = PyInt_FromLong(val);
1495 if (v) {
1496 PyDict_SetItemString(d, name, v);
1497 Py_DECREF(v);
1498 }
1499}
1500static void
1501ins_string(d, name, val)
1502 PyObject *d;
1503 char *name;
1504 char *val;
1505{
1506 PyObject *v = PyString_FromString(val);
1507 if (v) {
1508 PyDict_SetItemString(d, name, v);
1509 Py_DECREF(v);
1510 }
1511}
1512
1513
Guido van Rossum18468821994-06-20 07:49:28 +00001514void
Guido van Rossum35d43371997-08-02 00:09:09 +00001515init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00001516{
Barry Warsawfa701a81997-01-16 00:15:11 +00001517 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001518
Barry Warsawfa701a81997-01-16 00:15:11 +00001519 Tkapp_Type.ob_type = &PyType_Type;
1520 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossumae92f011996-08-21 19:03:36 +00001521
Barry Warsawfa701a81997-01-16 00:15:11 +00001522 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001523
Barry Warsawfa701a81997-01-16 00:15:11 +00001524 d = PyModule_GetDict(m);
1525 Tkinter_TclError = Py_BuildValue("s", "TclError");
1526 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00001527
Guido van Rossum35d43371997-08-02 00:09:09 +00001528 ins_long(d, "READABLE", TCL_READABLE);
1529 ins_long(d, "WRITABLE", TCL_WRITABLE);
1530 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
1531 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
1532 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
1533 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
1534 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
1535 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
1536 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001537 ins_string(d, "TK_VERSION", TK_VERSION);
1538 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00001539
Guido van Rossum83551bf1997-09-13 00:44:23 +00001540 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
1541 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
1542
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001543 if (PyOS_InputHook == NULL) {
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001544 event_interp = PyThreadState_Get()->interp;
Guido van Rossum44620641997-08-11 18:57:29 +00001545 PyOS_InputHook = EventHook;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001546 }
Guido van Rossum18468821994-06-20 07:49:28 +00001547
Barry Warsawfa701a81997-01-16 00:15:11 +00001548 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001549 return;
1550
Guido van Rossum26216371998-04-20 18:47:52 +00001551#if TKMAJORMINOR >= 8000
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001552 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00001553#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001554
Jack Jansen34cc5c31995-10-31 16:15:12 +00001555#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001556 /*
1557 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
1558 ** Most of the initializations in that routine (toolbox init calls and
1559 ** such) have already been done for us, so we only need these.
1560 */
1561#if TKMAJORMINOR >= 8000
1562 tcl_macQdPtr = &qd;
1563#endif
1564
1565 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00001566#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00001567 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001568#endif /* GENERATINGCFM */
1569#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001570}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001571
Guido van Rossumec22c921996-02-25 04:50:29 +00001572
Barry Warsawfa701a81997-01-16 00:15:11 +00001573
Guido van Rossum9722ad81995-09-22 23:49:28 +00001574#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001575
1576/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001577** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001578*/
1579
Guido van Rossum9722ad81995-09-22 23:49:28 +00001580void
1581panic(char * format, ...)
1582{
Barry Warsawfa701a81997-01-16 00:15:11 +00001583 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001584
Barry Warsawfa701a81997-01-16 00:15:11 +00001585 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001586
Barry Warsawfa701a81997-01-16 00:15:11 +00001587 vfprintf(stderr, format, varg);
1588 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001589
Barry Warsawfa701a81997-01-16 00:15:11 +00001590 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001591
Barry Warsawfa701a81997-01-16 00:15:11 +00001592 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00001593}
Jack Jansen40b546d1995-11-14 10:34:45 +00001594
Guido van Rossumec22c921996-02-25 04:50:29 +00001595/*
1596** Pass events to SIOUX before passing them to Tk.
1597*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001598
Guido van Rossumec22c921996-02-25 04:50:29 +00001599static int
1600PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00001601 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001602{
Barry Warsawfa701a81997-01-16 00:15:11 +00001603 if (SIOUXHandleOneEvent(eventPtr))
1604 return 0; /* Nothing happened to the Tcl event queue */
1605 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001606}
1607
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001608#if defined(USE_GUSI) && TKMAJORMINOR < 8000
Guido van Rossum290283b1997-06-02 22:16:43 +00001609/*
1610 * For Python we have to override this routine (from TclMacNotify),
1611 * since we use GUSI for our sockets, not Tcl streams. Hence, we have
1612 * to use GUSI select to see whether our socket is ready. Note that
1613 * createfilehandler (above) sets the type to TCL_UNIX_FD for our
1614 * files and sockets.
1615 *
1616 * NOTE: this code was lifted from Tcl 7.6, it may need to be modified
1617 * for other versions. */
1618
1619int
1620Tcl_FileReady(file, mask)
1621 Tcl_File file; /* File handle for a stream. */
1622 int mask; /* OR'ed combination of TCL_READABLE,
1623 * TCL_WRITABLE, and TCL_EXCEPTION:
1624 * indicates conditions caller cares about. */
1625{
1626 int type;
1627 int fd;
1628
1629 fd = (int) Tcl_GetFileInfo(file, &type);
1630
1631 if (type == TCL_MAC_SOCKET) {
1632 return TclMacSocketReady(file, mask);
1633 } else if (type == TCL_MAC_FILE) {
1634 /*
1635 * Under the Macintosh, files are always ready, so we just
1636 * return the mask that was passed in.
1637 */
1638
1639 return mask;
1640 } else if (type == TCL_UNIX_FD) {
1641 fd_set readset, writeset, excset;
1642 struct timeval tv;
1643
1644 FD_ZERO(&readset);
1645 FD_ZERO(&writeset);
1646 FD_ZERO(&excset);
1647
1648 if ( mask & TCL_READABLE ) FD_SET(fd, &readset);
1649 if ( mask & TCL_WRITABLE ) FD_SET(fd, &writeset);
1650 if ( mask & TCL_EXCEPTION ) FD_SET(fd, &excset);
1651
1652 tv.tv_sec = tv.tv_usec = 0;
1653 if ( select(fd+1, &readset, &writeset, &excset, &tv) <= 0 )
1654 return 0;
1655
1656 mask = 0;
1657 if ( FD_ISSET(fd, &readset) ) mask |= TCL_READABLE;
1658 if ( FD_ISSET(fd, &writeset) ) mask |= TCL_WRITABLE;
1659 if ( FD_ISSET(fd, &excset) ) mask |= TCL_EXCEPTION;
1660
1661 return mask;
1662 }
1663
1664 return 0;
1665}
1666#endif /* USE_GUSI */
1667
Guido van Rossumec22c921996-02-25 04:50:29 +00001668#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001669
1670/*
1671** Additional Mac specific code for dealing with shared libraries.
1672*/
1673
1674#include <Resources.h>
1675#include <CodeFragments.h>
1676
1677static int loaded_from_shlib = 0;
1678static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001679
Jack Jansen34cc5c31995-10-31 16:15:12 +00001680/*
1681** If this module is dynamically loaded the following routine should
1682** be the init routine. It takes care of adding the shared library to
1683** the resource-file chain, so that the tk routines can find their
1684** resources.
1685*/
1686OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001687init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00001688{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00001689 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00001690 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001691 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001692 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1693 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001694 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001695 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1696 loaded_from_shlib = 1;
1697 }
1698 return noErr;
1699}
1700
1701/*
1702** Insert the library resources into the search path. Put them after
1703** the resources from the application. Again, we ignore errors.
1704*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001705static
Jack Jansen34cc5c31995-10-31 16:15:12 +00001706mac_addlibresources()
1707{
1708 if ( !loaded_from_shlib )
1709 return;
1710 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1711}
1712
Guido van Rossumec22c921996-02-25 04:50:29 +00001713#endif /* GENERATINGCFM */
1714#endif /* macintosh */