blob: 6226f6b46b6ee848a76615c5f0d2fd4e2bf73d28 [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>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000065/* And this one we need to clear the menu bar */
66#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000067#endif
68
Guido van Rossum35d43371997-08-02 00:09:09 +000069#if TKMAJORMINOR < 4001
Guido van Rossum75626a31997-09-08 02:04:00 +000070 #error "Tk 4.0 or 3.x are not supported -- use 4.1 or higher"
Guido van Rossum9722ad81995-09-22 23:49:28 +000071#endif
72
Guido van Rossumb0105441997-10-08 15:25:37 +000073#if TKMAJORMINOR < 8000 || !defined(MS_WINDOWS)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000074#define HAVE_CREATEFILEHANDLER
75#endif
76
Guido van Rossum35d43371997-08-02 00:09:09 +000077extern int Tk_GetNumMainWindows();
78
Guido van Rossumec22c921996-02-25 04:50:29 +000079#ifdef macintosh
80
81/*
82** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +000083** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +000084*/
85
Guido van Rossum7ffa7611996-08-13 21:10:16 +000086/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +000087#define FREECAST (char *)
88
Guido van Rossumec22c921996-02-25 04:50:29 +000089#include <Events.h> /* For EventRecord */
90
91typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
Guido van Rossum0d2390c1997-08-14 19:57:07 +000092/* They changed the name... */
93#if TKMAJORMINOR < 8000
94#define Tcl_MacSetEventProc TclMacSetEventProc
95#endif
96void Tcl_MacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
Guido van Rossumec22c921996-02-25 04:50:29 +000097int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
98
99staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
100
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000101#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
102 #pragma import on
103#endif
104
105#include <SIOUX.h>
106extern int SIOUXIsAppWindow(WindowPtr);
107
108#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
109 #pragma import reset
110#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000111#endif /* macintosh */
112
Guido van Rossum97867b21996-08-08 19:09:53 +0000113#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000114#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000115#endif
116
Guido van Rossum18468821994-06-20 07:49:28 +0000117/**** Tkapp Object Declaration ****/
118
119staticforward PyTypeObject Tkapp_Type;
120
121typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +0000122{
123 PyObject_HEAD
124 Tcl_Interp *interp;
Barry Warsawfa701a81997-01-16 00:15:11 +0000125}
Guido van Rossum18468821994-06-20 07:49:28 +0000126TkappObject;
127
128#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000129#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
130#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
131
Guido van Rossum35d43371997-08-02 00:09:09 +0000132#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000133(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000134
Barry Warsawfa701a81997-01-16 00:15:11 +0000135
136
Guido van Rossum18468821994-06-20 07:49:28 +0000137/**** Error Handling ****/
138
139static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000140static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000141static int errorInCmd = 0;
142static PyObject *excInCmd;
143static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000144static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000145
Barry Warsawfa701a81997-01-16 00:15:11 +0000146
147
Guido van Rossum18468821994-06-20 07:49:28 +0000148static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000149Tkinter_Error(v)
150 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000151{
Barry Warsawfa701a81997-01-16 00:15:11 +0000152 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
153 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000154}
155
Barry Warsawfa701a81997-01-16 00:15:11 +0000156
Guido van Rossum18468821994-06-20 07:49:28 +0000157int
Barry Warsawfa701a81997-01-16 00:15:11 +0000158PythonCmd_Error(interp)
159 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000160{
Barry Warsawfa701a81997-01-16 00:15:11 +0000161 errorInCmd = 1;
162 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
163 return TCL_ERROR;
Guido van Rossum18468821994-06-20 07:49:28 +0000164}
165
Barry Warsawfa701a81997-01-16 00:15:11 +0000166
167
Guido van Rossum18468821994-06-20 07:49:28 +0000168/**** Utils ****/
Guido van Rossum18468821994-06-20 07:49:28 +0000169static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000170AsString(value, tmp)
171 PyObject *value;
172 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000173{
Guido van Rossum35d43371997-08-02 00:09:09 +0000174 if (PyString_Check(value))
175 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000176 else {
177 PyObject *v = PyObject_Str(value);
178 PyList_Append(tmp, v);
179 Py_DECREF(v);
180 return PyString_AsString(v);
181 }
Guido van Rossum18468821994-06-20 07:49:28 +0000182}
183
Barry Warsawfa701a81997-01-16 00:15:11 +0000184
185
Guido van Rossum18468821994-06-20 07:49:28 +0000186#define ARGSZ 64
187
188static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000189Merge(args)
190 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000191{
Barry Warsawfa701a81997-01-16 00:15:11 +0000192 PyObject *tmp = NULL;
193 char *argvStore[ARGSZ];
194 char **argv = NULL;
195 int fvStore[ARGSZ];
196 int *fv = NULL;
197 int argc = 0, i;
198 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000199
Barry Warsawfa701a81997-01-16 00:15:11 +0000200 if (!(tmp = PyList_New(0)))
201 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000202
Barry Warsawfa701a81997-01-16 00:15:11 +0000203 argv = argvStore;
204 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000205
Barry Warsawfa701a81997-01-16 00:15:11 +0000206 if (args == NULL)
207 argc = 0;
208
209 else if (!PyTuple_Check(args)) {
210 argc = 1;
211 fv[0] = 0;
212 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000213 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000214 else {
215 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000216
Barry Warsawfa701a81997-01-16 00:15:11 +0000217 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000218 argv = (char **)ckalloc(argc * sizeof(char *));
219 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000220 if (argv == NULL || fv == NULL) {
221 PyErr_NoMemory();
222 goto finally;
223 }
224 }
225
226 for (i = 0; i < argc; i++) {
227 PyObject *v = PyTuple_GetItem(args, i);
228 if (PyTuple_Check(v)) {
229 fv[i] = 1;
230 if (!(argv[i] = Merge(v)))
231 goto finally;
232 }
233 else if (v == Py_None) {
234 argc = i;
235 break;
236 }
237 else {
238 fv[i] = 0;
239 argv[i] = AsString(v, tmp);
240 }
241 }
Guido van Rossum18468821994-06-20 07:49:28 +0000242 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000243 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000244
Barry Warsawfa701a81997-01-16 00:15:11 +0000245 finally:
246 for (i = 0; i < argc; i++)
247 if (fv[i]) {
248 ckfree(argv[i]);
249 }
250 if (argv != argvStore)
251 ckfree(FREECAST argv);
252 if (fv != fvStore)
253 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000254
Barry Warsawfa701a81997-01-16 00:15:11 +0000255 Py_DECREF(tmp);
256 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000257}
258
Barry Warsawfa701a81997-01-16 00:15:11 +0000259
260
Guido van Rossum18468821994-06-20 07:49:28 +0000261static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000262Split(self, list)
263 PyObject *self;
264 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000265{
Barry Warsawfa701a81997-01-16 00:15:11 +0000266 int argc;
267 char **argv;
268 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000269
Barry Warsawfa701a81997-01-16 00:15:11 +0000270 if (list == NULL) {
271 Py_INCREF(Py_None);
272 return Py_None;
273 }
Guido van Rossum18468821994-06-20 07:49:28 +0000274
Barry Warsawfa701a81997-01-16 00:15:11 +0000275 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
276 {
277 /* Not a list.
278 * Could be a quoted string containing funnies, e.g. {"}.
279 * Return the string itself.
280 */
281 PyErr_Clear();
282 return PyString_FromString(list);
283 }
Guido van Rossum18468821994-06-20 07:49:28 +0000284
Barry Warsawfa701a81997-01-16 00:15:11 +0000285 if (argc == 0)
286 v = PyString_FromString("");
287 else if (argc == 1)
288 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000289 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000290 int i;
291 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000292
Barry Warsawfa701a81997-01-16 00:15:11 +0000293 for (i = 0; i < argc; i++) {
294 if ((w = Split(self, argv[i])) == NULL) {
295 Py_DECREF(v);
296 v = NULL;
297 break;
298 }
299 PyTuple_SetItem(v, i, w);
300 }
301 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000302 ckfree(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000303 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000304}
305
Barry Warsawfa701a81997-01-16 00:15:11 +0000306
307
Guido van Rossum18468821994-06-20 07:49:28 +0000308/**** Tkapp Object ****/
309
310#ifndef WITH_APPINIT
311int
Guido van Rossum35d43371997-08-02 00:09:09 +0000312Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000313 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000314{
Barry Warsawfa701a81997-01-16 00:15:11 +0000315 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000316
Barry Warsawfa701a81997-01-16 00:15:11 +0000317 main = Tk_MainWindow(interp);
318 if (Tcl_Init(interp) == TCL_ERROR) {
319 fprintf(stderr, "Tcl_Init error: %s\n", interp->result);
320 return TCL_ERROR;
321 }
322 if (Tk_Init(interp) == TCL_ERROR) {
323 fprintf(stderr, "Tk_Init error: %s\n", interp->result);
324 return TCL_ERROR;
325 }
326 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000327}
328#endif /* !WITH_APPINIT */
329
Guido van Rossum18468821994-06-20 07:49:28 +0000330
Barry Warsawfa701a81997-01-16 00:15:11 +0000331
332
333/* Initialize the Tk application; see the `main' function in
334 * `tkMain.c'.
335 */
336static TkappObject *
337Tkapp_New(screenName, baseName, className, interactive)
338 char *screenName;
339 char *baseName;
340 char *className;
341 int interactive;
342{
343 TkappObject *v;
344 char *argv0;
345
346 v = PyObject_NEW(TkappObject, &Tkapp_Type);
347 if (v == NULL)
348 return NULL;
349
350 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000351
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000352#if defined(macintosh) && TKMAJORMINOR >= 8000
353 /* This seems to be needed since Tk 8.0 */
354 ClearMenuBar();
355 TkMacInitMenus(v->interp);
356#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000357 /* Delete the 'exit' command, which can screw things up */
358 Tcl_DeleteCommand(v->interp, "exit");
359
Barry Warsawfa701a81997-01-16 00:15:11 +0000360 if (screenName != NULL)
361 Tcl_SetVar2(v->interp, "env", "DISPLAY",
362 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000363
Barry Warsawfa701a81997-01-16 00:15:11 +0000364 if (interactive)
365 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
366 else
367 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000368
Barry Warsawfa701a81997-01-16 00:15:11 +0000369 /* This is used to get the application class for Tk 4.1 and up */
370 argv0 = (char*)ckalloc(strlen(className) + 1);
371 if (!argv0) {
372 PyErr_NoMemory();
373 Py_DECREF(v);
374 return NULL;
375 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000376
Barry Warsawfa701a81997-01-16 00:15:11 +0000377 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000378 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000379 argv0[0] = tolower(argv0[0]);
380 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
381 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000382
Barry Warsawfa701a81997-01-16 00:15:11 +0000383 if (Tcl_AppInit(v->interp) != TCL_OK)
384 return (TkappObject *)Tkinter_Error(v);
385
386 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000387}
388
Barry Warsawfa701a81997-01-16 00:15:11 +0000389
390
Guido van Rossum18468821994-06-20 07:49:28 +0000391/** Tcl Eval **/
392
393static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000394Tkapp_Call(self, args)
395 PyObject *self;
396 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000397{
Barry Warsawfa701a81997-01-16 00:15:11 +0000398 char *cmd = Merge(args);
399 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000400
Barry Warsawfa701a81997-01-16 00:15:11 +0000401 if (!cmd)
402 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000403
Barry Warsawfa701a81997-01-16 00:15:11 +0000404 else if (Tcl_Eval(Tkapp_Interp(self), cmd) == TCL_ERROR)
405 res = Tkinter_Error(self);
406
407 else
408 res = PyString_FromString(Tkapp_Result(self));
409
410 if (cmd)
411 ckfree(cmd);
412
413 return res;
414}
415
416
417static PyObject *
418Tkapp_GlobalCall(self, args)
419 PyObject *self;
420 PyObject *args;
421{
422 char *cmd = Merge(args);
423 PyObject *res = NULL;
424
425
426 if (!cmd)
427 PyErr_SetString(Tkinter_TclError, "merge failed");
428
429 else if (Tcl_GlobalEval(Tkapp_Interp(self), cmd) == TCL_ERROR)
430 res = Tkinter_Error(self);
431 else
432 res = PyString_FromString(Tkapp_Result(self));
433
434 if (cmd)
435 ckfree(cmd);
436
437 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000438}
439
440static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000441Tkapp_Eval(self, args)
442 PyObject *self;
443 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000444{
Barry Warsawfa701a81997-01-16 00:15:11 +0000445 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000446
Guido van Rossum35d43371997-08-02 00:09:09 +0000447 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000448 return NULL;
449
450 if (Tcl_Eval(Tkapp_Interp(self), script) == TCL_ERROR)
451 return Tkinter_Error(self);
452
453 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000454}
455
456static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000457Tkapp_GlobalEval(self, args)
458 PyObject *self;
459 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000460{
Barry Warsawfa701a81997-01-16 00:15:11 +0000461 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000462
Guido van Rossum35d43371997-08-02 00:09:09 +0000463 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000464 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000465
Barry Warsawfa701a81997-01-16 00:15:11 +0000466 if (Tcl_GlobalEval(Tkapp_Interp(self), script) == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000467 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000468
Barry Warsawfa701a81997-01-16 00:15:11 +0000469 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000470}
471
472static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000473Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000474 PyObject *self;
475 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000476{
Barry Warsawfa701a81997-01-16 00:15:11 +0000477 char *fileName;
Guido van Rossum18468821994-06-20 07:49:28 +0000478
Guido van Rossum35d43371997-08-02 00:09:09 +0000479 if (!PyArg_ParseTuple(args, "s", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000480 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000481
Barry Warsawfa701a81997-01-16 00:15:11 +0000482 if (Tcl_EvalFile(Tkapp_Interp(self), fileName) == TCL_ERROR)
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_Record(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 *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000494
Guido van Rossum35d43371997-08-02 00:09:09 +0000495 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000496 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000497
Barry Warsawfa701a81997-01-16 00:15:11 +0000498 if (TCL_ERROR == Tcl_RecordAndEval(Tkapp_Interp(self),
499 script, TCL_NO_EVAL))
Guido van Rossum35d43371997-08-02 00:09:09 +0000500 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000501
Barry Warsawfa701a81997-01-16 00:15:11 +0000502 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000503}
504
505static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000506Tkapp_AddErrorInfo(self, args)
507 PyObject *self;
508 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000509{
Barry Warsawfa701a81997-01-16 00:15:11 +0000510 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000511
Guido van Rossum35d43371997-08-02 00:09:09 +0000512 if (!PyArg_ParseTuple(args, "s", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000513 return NULL;
514 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum18468821994-06-20 07:49:28 +0000515
Barry Warsawfa701a81997-01-16 00:15:11 +0000516 Py_INCREF(Py_None);
517 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000518}
519
Barry Warsawfa701a81997-01-16 00:15:11 +0000520
521
Guido van Rossum18468821994-06-20 07:49:28 +0000522/** Tcl Variable **/
523
524static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000525SetVar(self, args, flags)
526 PyObject *self;
527 PyObject *args;
528 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000529{
Barry Warsawfa701a81997-01-16 00:15:11 +0000530 char *name1, *name2, *ok;
531 PyObject *newValue;
532 PyObject *tmp = PyList_New(0);
Guido van Rossum18468821994-06-20 07:49:28 +0000533
Barry Warsawfa701a81997-01-16 00:15:11 +0000534 if (!tmp)
535 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000536
Guido van Rossum35d43371997-08-02 00:09:09 +0000537 if (PyArg_ParseTuple(args, "sO", &name1, &newValue))
Barry Warsawfa701a81997-01-16 00:15:11 +0000538 /* XXX Merge? */
Guido van Rossum35d43371997-08-02 00:09:09 +0000539 ok = Tcl_SetVar(Tkapp_Interp(self), name1,
540 AsString(newValue, tmp), flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000541
Barry Warsawfa701a81997-01-16 00:15:11 +0000542 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000543 PyErr_Clear();
544 if (PyArg_ParseTuple(args, "ssO", &name1, &name2, &newValue))
545 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
546 AsString (newValue, tmp), flags);
547 else {
548 Py_DECREF (tmp);
549 return NULL;
550 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000551 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000552 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000553
Barry Warsawfa701a81997-01-16 00:15:11 +0000554 if (!ok)
555 return Tkinter_Error(self);
556
557 Py_INCREF(Py_None);
558 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000559}
560
561static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000562Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000563 PyObject *self;
564 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000565{
Barry Warsawfa701a81997-01-16 00:15:11 +0000566 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000567}
568
569static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000570Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000571 PyObject *self;
572 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000573{
Barry Warsawfa701a81997-01-16 00:15:11 +0000574 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000575}
576
Barry Warsawfa701a81997-01-16 00:15:11 +0000577
578
Guido van Rossum18468821994-06-20 07:49:28 +0000579static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000580GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000581 PyObject *self;
582 PyObject *args;
583 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000584{
Guido van Rossum35d43371997-08-02 00:09:09 +0000585 char *name1, *name2=NULL, *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000586
Guido van Rossum35d43371997-08-02 00:09:09 +0000587 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
588 return NULL;
589 if (name2 == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +0000590 s = Tcl_GetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000591
Barry Warsawfa701a81997-01-16 00:15:11 +0000592 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000593 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000594
Barry Warsawfa701a81997-01-16 00:15:11 +0000595 if (s == NULL)
596 return Tkinter_Error(self);
597
Guido van Rossum35d43371997-08-02 00:09:09 +0000598 return PyString_FromString(s);
Guido van Rossum18468821994-06-20 07:49:28 +0000599}
600
601static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000602Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000603 PyObject *self;
604 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000605{
Barry Warsawfa701a81997-01-16 00:15:11 +0000606 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000607}
608
609static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000610Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000611 PyObject *self;
612 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000613{
Barry Warsawfa701a81997-01-16 00:15:11 +0000614 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000615}
616
Barry Warsawfa701a81997-01-16 00:15:11 +0000617
618
Guido van Rossum18468821994-06-20 07:49:28 +0000619static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000620UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000621 PyObject *self;
622 PyObject *args;
623 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000624{
Guido van Rossum35d43371997-08-02 00:09:09 +0000625 char *name1, *name2=NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000626 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000627
Guido van Rossum35d43371997-08-02 00:09:09 +0000628 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000629 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000630 if (name2 == NULL)
631 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
632
633 else
634 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000635
Barry Warsawfa701a81997-01-16 00:15:11 +0000636 if (code == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000637 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000638
639 Py_INCREF(Py_None);
640 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000641}
642
643static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000644Tkapp_UnsetVar(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 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000649}
650
651static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000652Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000653 PyObject *self;
654 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000655{
Barry Warsawfa701a81997-01-16 00:15:11 +0000656 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000657}
658
Barry Warsawfa701a81997-01-16 00:15:11 +0000659
660
Guido van Rossum18468821994-06-20 07:49:28 +0000661/** Tcl to Python **/
662
663static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000664Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000665 PyObject *self;
666 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000667{
Barry Warsawfa701a81997-01-16 00:15:11 +0000668 char *s;
669 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000670
Guido van Rossum35d43371997-08-02 00:09:09 +0000671 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000672 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000673 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000674 return Tkinter_Error(self);
675 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000676}
677
678static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000679Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000680 PyObject *self;
681 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000682{
Barry Warsawfa701a81997-01-16 00:15:11 +0000683 char *s;
684 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000685
Guido van Rossum35d43371997-08-02 00:09:09 +0000686 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000687 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000688 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000689 return Tkinter_Error(self);
690 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000691}
692
693static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000694Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000695 PyObject *self;
696 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000697{
Barry Warsawfa701a81997-01-16 00:15:11 +0000698 char *s;
699 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000700
Guido van Rossum35d43371997-08-02 00:09:09 +0000701 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000702 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000703 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
704 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000705 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000706}
707
708static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000709Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000710 PyObject *self;
711 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000712{
Barry Warsawfa701a81997-01-16 00:15:11 +0000713 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000714
Guido van Rossum35d43371997-08-02 00:09:09 +0000715 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000716 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000717 if (Tcl_ExprString(Tkapp_Interp(self), s) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000718 return Tkinter_Error(self);
719 return Py_BuildValue("s", Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000720}
721
722static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000723Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000724 PyObject *self;
725 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000726{
Barry Warsawfa701a81997-01-16 00:15:11 +0000727 char *s;
728 long v;
Guido van Rossum18468821994-06-20 07:49:28 +0000729
Guido van Rossum35d43371997-08-02 00:09:09 +0000730 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000731 return NULL;
732 if (Tcl_ExprLong(Tkapp_Interp(self), s, &v) == TCL_ERROR)
733 return Tkinter_Error(self);
734 return Py_BuildValue("l", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000735}
736
737static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000738Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000739 PyObject *self;
740 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000741{
Barry Warsawfa701a81997-01-16 00:15:11 +0000742 char *s;
743 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000744 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000745
Guido van Rossum35d43371997-08-02 00:09:09 +0000746 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000747 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000748 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum35d43371997-08-02 00:09:09 +0000749 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum45b83911997-03-14 04:32:50 +0000750 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000751 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000752 return Tkinter_Error(self);
753 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000754}
755
756static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000757Tkapp_ExprBoolean(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 *s;
762 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000763
Guido van Rossum35d43371997-08-02 00:09:09 +0000764 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000765 return NULL;
766 if (Tcl_ExprBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
767 return Tkinter_Error(self);
768 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000769}
770
Barry Warsawfa701a81997-01-16 00:15:11 +0000771
772
Guido van Rossum18468821994-06-20 07:49:28 +0000773static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000774Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000775 PyObject *self;
776 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000777{
Barry Warsawfa701a81997-01-16 00:15:11 +0000778 char *list;
779 int argc;
780 char **argv;
781 PyObject *v;
782 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000783
Guido van Rossum35d43371997-08-02 00:09:09 +0000784 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +0000785 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000786
Barry Warsawfa701a81997-01-16 00:15:11 +0000787 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
788 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000789
Barry Warsawfa701a81997-01-16 00:15:11 +0000790 if (!(v = PyTuple_New(argc)))
791 return NULL;
792
793 for (i = 0; i < argc; i++) {
794 PyObject *s = PyString_FromString(argv[i]);
795 if (!s || PyTuple_SetItem(v, i, s)) {
796 Py_DECREF(v);
797 v = NULL;
798 goto finally;
799 }
800 }
Guido van Rossum18468821994-06-20 07:49:28 +0000801
Barry Warsawfa701a81997-01-16 00:15:11 +0000802 finally:
803 ckfree(FREECAST argv);
804 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000805}
806
807static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000808Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000809 PyObject *self;
810 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000811{
Barry Warsawfa701a81997-01-16 00:15:11 +0000812 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000813
Guido van Rossum35d43371997-08-02 00:09:09 +0000814 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +0000815 return NULL;
816 return Split(self, list);
Guido van Rossum18468821994-06-20 07:49:28 +0000817}
818
819static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000820Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000821 PyObject *self;
822 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000823{
Barry Warsawfa701a81997-01-16 00:15:11 +0000824 char *s = Merge(args);
825 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000826
Barry Warsawfa701a81997-01-16 00:15:11 +0000827 if (s) {
828 res = PyString_FromString(s);
829 ckfree(s);
830 }
831 else
832 PyErr_SetString(Tkinter_TclError, "merge failed");
833
834 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000835}
836
Barry Warsawfa701a81997-01-16 00:15:11 +0000837
838
Guido van Rossum18468821994-06-20 07:49:28 +0000839/** Tcl Command **/
840
841/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +0000842 * function or method.
843 */
Guido van Rossum18468821994-06-20 07:49:28 +0000844static int
Guido van Rossum35d43371997-08-02 00:09:09 +0000845PythonCmd(clientData, interp, argc, argv)
Barry Warsawfa701a81997-01-16 00:15:11 +0000846 ClientData clientData; /* Is (self, func) */
847 Tcl_Interp *interp;
848 int argc;
849 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +0000850{
Barry Warsawfa701a81997-01-16 00:15:11 +0000851 PyObject *self, *func, *arg, *res, *tmp;
852 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000853
Barry Warsawfa701a81997-01-16 00:15:11 +0000854 /* TBD: no error checking here since we know, via the
855 * Tkapp_CreateCommand() that the client data is a two-tuple
856 */
857 self = PyTuple_GetItem((PyObject *) clientData, 0);
858 func = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000859
Barry Warsawfa701a81997-01-16 00:15:11 +0000860 /* Create argument list (argv1, ..., argvN) */
861 if (!(arg = PyTuple_New(argc - 1)))
862 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000863
Barry Warsawfa701a81997-01-16 00:15:11 +0000864 for (i = 0; i < (argc - 1); i++) {
865 PyObject *s = PyString_FromString(argv[i + 1]);
866 if (!s || PyTuple_SetItem(arg, i, s)) {
867 Py_DECREF(arg);
868 PythonCmd_Error(interp);
869 }
870 }
871 res = PyEval_CallObject(func, arg);
872 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +0000873
Barry Warsawfa701a81997-01-16 00:15:11 +0000874 if (res == NULL)
875 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +0000876
Barry Warsawfa701a81997-01-16 00:15:11 +0000877 if (!(tmp = PyList_New(0))) {
878 Py_DECREF(res);
879 return PythonCmd_Error(interp);
880 }
881
882 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
883 Py_DECREF(res);
884 Py_DECREF(tmp);
885
886 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000887}
888
889static void
Guido van Rossum35d43371997-08-02 00:09:09 +0000890PythonCmdDelete(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +0000891 ClientData clientData; /* Is (self, func) */
Guido van Rossum18468821994-06-20 07:49:28 +0000892{
Barry Warsawfa701a81997-01-16 00:15:11 +0000893 Py_DECREF((PyObject *) clientData);
Guido van Rossum18468821994-06-20 07:49:28 +0000894}
895
Barry Warsawfa701a81997-01-16 00:15:11 +0000896
897
Guido van Rossum18468821994-06-20 07:49:28 +0000898static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000899Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000900 PyObject *self;
901 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000902{
Barry Warsawfa701a81997-01-16 00:15:11 +0000903 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +0000904 PyObject *func;
Guido van Rossum35d43371997-08-02 00:09:09 +0000905 PyObject *data;
906
907 if (!PyArg_ParseTuple(args, "sO", &cmdName, &func))
908 return NULL;
909 if (!PyCallable_Check(func)) {
910 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +0000911 return NULL;
912 }
Guido van Rossum18468821994-06-20 07:49:28 +0000913
Guido van Rossum35d43371997-08-02 00:09:09 +0000914 data = Py_BuildValue("OO", self, func);
Barry Warsawfa701a81997-01-16 00:15:11 +0000915 if (!data)
916 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000917
Guido van Rossum35d43371997-08-02 00:09:09 +0000918 if (Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
919 (ClientData) data, PythonCmdDelete) == NULL)
920 {
921 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
922 Py_DECREF(data);
923 return NULL;
924 }
Guido van Rossum18468821994-06-20 07:49:28 +0000925
Barry Warsawfa701a81997-01-16 00:15:11 +0000926 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 +0000932static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000933Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000934 PyObject *self;
935 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000936{
Barry Warsawfa701a81997-01-16 00:15:11 +0000937 char *cmdName;
Guido van Rossum18468821994-06-20 07:49:28 +0000938
Guido van Rossum35d43371997-08-02 00:09:09 +0000939 if (!PyArg_ParseTuple(args, "s", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000940 return NULL;
941 if (Tcl_DeleteCommand(Tkapp_Interp(self), cmdName) == -1)
942 {
943 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
944 return NULL;
945 }
946 Py_INCREF(Py_None);
947 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000948}
949
Barry Warsawfa701a81997-01-16 00:15:11 +0000950
951
Guido van Rossum18468821994-06-20 07:49:28 +0000952/** File Handler **/
953
Guido van Rossuma597dde1995-01-10 20:56:29 +0000954static void
Guido van Rossum35d43371997-08-02 00:09:09 +0000955FileHandler(clientData, mask)
Barry Warsawfa701a81997-01-16 00:15:11 +0000956 ClientData clientData; /* Is: (func, file) */
957 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +0000958{
Barry Warsawfa701a81997-01-16 00:15:11 +0000959 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +0000960
Barry Warsawfa701a81997-01-16 00:15:11 +0000961 func = PyTuple_GetItem((PyObject *) clientData, 0);
962 file = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000963
Barry Warsawfa701a81997-01-16 00:15:11 +0000964 arg = Py_BuildValue("(Oi)", file, (long) mask);
965 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +0000966 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +0000967
968 if (res == NULL) {
969 errorInCmd = 1;
970 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
971 }
972 Py_XDECREF(res);
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000973}
974
975static int
Guido van Rossum35d43371997-08-02 00:09:09 +0000976GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +0000977 /* Either an int >= 0 or an object with a
978 *.fileno() method that returns an int >= 0
979 */
980 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000981{
Guido van Rossuma597dde1995-01-10 20:56:29 +0000982 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000983 int id;
984 if (PyInt_Check(file)) {
985 id = PyInt_AsLong(file);
986 if (id < 0)
987 PyErr_SetString(PyExc_ValueError, "invalid file id");
988 return id;
989 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000990 args = PyTuple_New(0);
991 if (args == NULL)
992 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000993
994 meth = PyObject_GetAttrString(file, "fileno");
995 if (meth == NULL) {
996 Py_DECREF(args);
997 return -1;
998 }
999
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001000 res = PyEval_CallObject(meth, args);
1001 Py_DECREF(args);
1002 Py_DECREF(meth);
1003 if (res == NULL)
1004 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001005
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001006 if (PyInt_Check(res))
1007 id = PyInt_AsLong(res);
1008 else
1009 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001010
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001011 if (id < 0)
1012 PyErr_SetString(PyExc_ValueError,
1013 "invalid fileno() return value");
1014 Py_DECREF(res);
1015 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001016}
1017
Barry Warsawfa701a81997-01-16 00:15:11 +00001018
1019static PyObject* Tkapp_ClientDataDict = NULL;
1020
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001021#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001022static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001023Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001024 PyObject *self;
1025 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001026{
Barry Warsawfa701a81997-01-16 00:15:11 +00001027 PyObject *file, *func, *data;
1028 PyObject *idkey;
1029 int mask, id;
Guido van Rossum3e819a71997-08-01 19:29:02 +00001030#if TKMAJORMINOR < 8000
Barry Warsawfa701a81997-01-16 00:15:11 +00001031 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001032#endif
Guido van Rossum18468821994-06-20 07:49:28 +00001033
Barry Warsawfa701a81997-01-16 00:15:11 +00001034 if (!Tkapp_ClientDataDict) {
1035 if (!(Tkapp_ClientDataDict = PyDict_New()))
1036 return NULL;
1037 }
Guido van Rossum18468821994-06-20 07:49:28 +00001038
Guido van Rossum35d43371997-08-02 00:09:09 +00001039 if (!PyArg_ParseTuple(args, "OiO", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001040 return NULL;
1041 id = GetFileNo(file);
1042 if (id < 0)
1043 return NULL;
1044 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001045 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001046 return NULL;
1047 }
1048
1049 if (!(idkey = PyInt_FromLong(id)))
1050 return NULL;
1051
1052 /* ClientData is: (func, file) */
Guido van Rossum35d43371997-08-02 00:09:09 +00001053 data = Py_BuildValue("(OO)", func, file);
Barry Warsawfa701a81997-01-16 00:15:11 +00001054 if (!data || PyDict_SetItem(Tkapp_ClientDataDict, idkey, data)) {
1055 Py_DECREF(idkey);
1056 Py_XDECREF(data);
1057 return NULL;
1058 }
1059 Py_DECREF(idkey);
Guido van Rossum76875221994-06-27 07:59:42 +00001060
Guido van Rossum3e819a71997-08-01 19:29:02 +00001061#if TKMAJORMINOR < 8000
Guido van Rossum07886d01996-09-11 23:31:42 +00001062#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001063 /* We assume this is a socket... */
1064 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum3e819a71997-08-01 19:29:02 +00001065#else /* !MS_WINDOWS */
Barry Warsawfa701a81997-01-16 00:15:11 +00001066 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum3e819a71997-08-01 19:29:02 +00001067#endif /* !MS_WINDOWS */
Barry Warsawfa701a81997-01-16 00:15:11 +00001068 /* Ought to check for null Tcl_File object... */
1069 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001070#else /* >= 8000 */
Guido van Rossum3e819a71997-08-01 19:29:02 +00001071 Tcl_CreateFileHandler(id, mask, FileHandler, (ClientData) data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001072#endif /* >= 8000 */
Barry Warsawfa701a81997-01-16 00:15:11 +00001073 /* XXX fileHandlerDict */
Guido van Rossum35d43371997-08-02 00:09:09 +00001074 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001075 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001076}
1077
Barry Warsawfa701a81997-01-16 00:15:11 +00001078
Guido van Rossum18468821994-06-20 07:49:28 +00001079static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001080Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001081 PyObject *self;
1082 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001083{
Barry Warsawfa701a81997-01-16 00:15:11 +00001084 PyObject *file;
1085 PyObject *idkey;
1086 PyObject *data;
1087 int id;
Guido van Rossum3e819a71997-08-01 19:29:02 +00001088#if TKMAJORMINOR < 8000
Barry Warsawfa701a81997-01-16 00:15:11 +00001089 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001090#endif
1091
Guido van Rossum35d43371997-08-02 00:09:09 +00001092 if (!PyArg_ParseTuple(args, "O", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001093 return NULL;
1094 id = GetFileNo(file);
1095 if (id < 0)
1096 return NULL;
1097
1098 if (!(idkey = PyInt_FromLong(id)))
1099 return NULL;
1100
1101 /* find and free the object created in the
1102 * Tkapp_CreateFileHandler() call
1103 */
1104 data = PyDict_GetItem(Tkapp_ClientDataDict, idkey);
1105 Py_XDECREF(data);
1106 PyDict_DelItem(Tkapp_ClientDataDict, idkey);
1107 Py_DECREF(idkey);
Guido van Rossum18468821994-06-20 07:49:28 +00001108
Guido van Rossum3e819a71997-08-01 19:29:02 +00001109#if TKMAJORMINOR < 8000
Guido van Rossum07886d01996-09-11 23:31:42 +00001110#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001111 /* We assume this is a socket... */
1112 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum845547d1996-06-26 18:26:04 +00001113#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001114 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +00001115#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001116 /* Ought to check for null Tcl_File object... */
1117 Tcl_DeleteFileHandler(tfile);
Guido van Rossum35d43371997-08-02 00:09:09 +00001118#else /* >= 8000 */
Guido van Rossum3e819a71997-08-01 19:29:02 +00001119 Tcl_DeleteFileHandler(id);
Guido van Rossum35d43371997-08-02 00:09:09 +00001120#endif /* >= 8000 */
Barry Warsawfa701a81997-01-16 00:15:11 +00001121 /* XXX fileHandlerDict */
Guido van Rossum35d43371997-08-02 00:09:09 +00001122 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001123 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001124}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001125#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001126
Barry Warsawfa701a81997-01-16 00:15:11 +00001127
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001128/**** Tktt Object (timer token) ****/
1129
1130staticforward PyTypeObject Tktt_Type;
1131
1132typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +00001133{
1134 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001135 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001136 PyObject *func;
1137}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001138TkttObject;
1139
1140static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001141Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001142 PyObject *self;
1143 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001144{
Barry Warsawfa701a81997-01-16 00:15:11 +00001145 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001146
Guido van Rossum35d43371997-08-02 00:09:09 +00001147 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001148 return NULL;
1149 if (v->func != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001150 Tcl_DeleteTimerHandler(v->token);
Barry Warsawfa701a81997-01-16 00:15:11 +00001151 PyMem_DEL(v->func);
1152 v->func = NULL;
1153 }
1154 Py_INCREF(Py_None);
1155 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001156}
1157
1158static PyMethodDef Tktt_methods[] =
1159{
Guido van Rossum35d43371997-08-02 00:09:09 +00001160 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001161 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001162};
1163
1164static TkttObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001165Tktt_New(token, func)
1166 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001167 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001168{
Barry Warsawfa701a81997-01-16 00:15:11 +00001169 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001170
Barry Warsawfa701a81997-01-16 00:15:11 +00001171 v = PyObject_NEW(TkttObject, &Tktt_Type);
1172 if (v == NULL)
1173 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001174
Barry Warsawfa701a81997-01-16 00:15:11 +00001175 v->token = token;
1176 v->func = func;
1177 Py_INCREF(v->func);
1178 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001179}
1180
1181static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001182Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001183 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001184{
Guido van Rossum35d43371997-08-02 00:09:09 +00001185 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001186}
1187
1188static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001189Tktt_Print(self, fp, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +00001190 PyObject *self;
1191 FILE *fp;
1192 int flags;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001193{
Barry Warsawfa701a81997-01-16 00:15:11 +00001194 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001195
Barry Warsawfa701a81997-01-16 00:15:11 +00001196 fprintf(fp, "<tktimertoken at 0x%lx%s>", (long)v,
1197 v->func == NULL ? ", handler deleted" : "");
1198 return 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001199}
1200
1201static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001202Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001203 PyObject *self;
1204 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001205{
Barry Warsawfa701a81997-01-16 00:15:11 +00001206 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001207}
1208
1209static PyTypeObject Tktt_Type =
1210{
Guido van Rossum35d43371997-08-02 00:09:09 +00001211 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001212 0, /*ob_size */
1213 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001214 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001215 0, /*tp_itemsize */
1216 Tktt_Dealloc, /*tp_dealloc */
1217 Tktt_Print, /*tp_print */
1218 Tktt_GetAttr, /*tp_getattr */
1219 0, /*tp_setattr */
1220 0, /*tp_compare */
1221 0, /*tp_repr */
1222 0, /*tp_as_number */
1223 0, /*tp_as_sequence */
1224 0, /*tp_as_mapping */
1225 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001226};
1227
Barry Warsawfa701a81997-01-16 00:15:11 +00001228
1229
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001230/** Timer Handler **/
1231
1232static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001233TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001234 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001235{
Barry Warsawfa701a81997-01-16 00:15:11 +00001236 PyObject *func = (PyObject *)clientData;
1237 PyObject *res = PyEval_CallObject(func, NULL);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001238
Barry Warsawfa701a81997-01-16 00:15:11 +00001239 if (res == NULL) {
1240 errorInCmd = 1;
1241 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1242 }
1243 else
1244 Py_DECREF(res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001245}
1246
1247static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001248Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001249 PyObject *self;
1250 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001251{
Barry Warsawfa701a81997-01-16 00:15:11 +00001252 int milliseconds;
1253 PyObject *func;
Guido van Rossum35d43371997-08-02 00:09:09 +00001254 Tcl_TimerToken token;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001255
Guido van Rossum35d43371997-08-02 00:09:09 +00001256 if (!PyArg_ParseTuple(args, "iO", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001257 return NULL;
1258 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001259 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001260 return NULL;
1261 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001262 token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1263 (ClientData)func);
Barry Warsawfa701a81997-01-16 00:15:11 +00001264
1265 return (PyObject *) Tktt_New(token, func);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001266}
1267
Barry Warsawfa701a81997-01-16 00:15:11 +00001268
1269
Guido van Rossum18468821994-06-20 07:49:28 +00001270/** Event Loop **/
1271
Guido van Rossum18468821994-06-20 07:49:28 +00001272static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001273Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001274 PyObject *self;
1275 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001276{
Barry Warsawfa701a81997-01-16 00:15:11 +00001277 int threshold = 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001278
Barry Warsawfa701a81997-01-16 00:15:11 +00001279 if (!PyArg_ParseTuple(args, "|i", &threshold))
1280 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001281
Barry Warsawfa701a81997-01-16 00:15:11 +00001282 quitMainLoop = 0;
1283 while (Tk_GetNumMainWindows() > threshold &&
1284 !quitMainLoop &&
1285 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001286 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001287 int result;
Guido van Rossum54e20911997-09-28 05:52:41 +00001288#ifdef HAVE_PYTCL_WAITUNTILEVENT
Guido van Rossum35d43371997-08-02 00:09:09 +00001289 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
1290 if (PyErr_CheckSignals() != 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001291 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001292 if (result)
1293 continue;
1294 /* XXX It's not *quite* certain that this is
1295 thread-safe, but it seems *rather* safe as long as
1296 no two threads call mainloop() simultaneously. */
1297 Py_BEGIN_ALLOW_THREADS
Guido van Rossum54e20911997-09-28 05:52:41 +00001298 result = PyTcl_WaitUntilEvent();
Guido van Rossum35d43371997-08-02 00:09:09 +00001299 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001300#else
1301 result = Tcl_DoOneEvent(0);
1302#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001303 if (PyErr_CheckSignals() != 0)
1304 return NULL;
1305 if (result < 0)
1306 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001307 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001308 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001309
Barry Warsawfa701a81997-01-16 00:15:11 +00001310 if (errorInCmd) {
1311 errorInCmd = 0;
1312 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1313 excInCmd = valInCmd = trbInCmd = NULL;
1314 return NULL;
1315 }
1316 Py_INCREF(Py_None);
1317 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001318}
1319
1320static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001321Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001322 PyObject *self;
1323 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001324{
Guido van Rossum35d43371997-08-02 00:09:09 +00001325 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001326 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001327
Barry Warsawfa701a81997-01-16 00:15:11 +00001328 if (!PyArg_ParseTuple(args, "|i", &flags))
1329 return NULL;
1330
Guido van Rossum35d43371997-08-02 00:09:09 +00001331 rv = Tcl_DoOneEvent(flags);
Barry Warsawfa701a81997-01-16 00:15:11 +00001332 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001333}
1334
1335static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001336Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001337 PyObject *self;
1338 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001339{
1340
Guido van Rossum35d43371997-08-02 00:09:09 +00001341 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001342 return NULL;
1343
1344 quitMainLoop = 1;
1345 Py_INCREF(Py_None);
1346 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001347}
1348
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001349static PyObject *
1350Tkapp_InterpAddr(self, args)
1351 PyObject *self;
1352 PyObject *args;
1353{
1354
1355 if (!PyArg_ParseTuple(args, ""))
1356 return NULL;
1357
1358 return PyInt_FromLong((long)Tkapp_Interp(self));
1359}
1360
Barry Warsawfa701a81997-01-16 00:15:11 +00001361
1362
Guido van Rossum18468821994-06-20 07:49:28 +00001363/**** Tkapp Method List ****/
1364
1365static PyMethodDef Tkapp_methods[] =
1366{
Guido van Rossum35d43371997-08-02 00:09:09 +00001367 {"call", Tkapp_Call, 0},
1368 {"globalcall", Tkapp_GlobalCall, 0},
1369 {"eval", Tkapp_Eval, 1},
1370 {"globaleval", Tkapp_GlobalEval, 1},
1371 {"evalfile", Tkapp_EvalFile, 1},
1372 {"record", Tkapp_Record, 1},
1373 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1374 {"setvar", Tkapp_SetVar, 1},
1375 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1376 {"getvar", Tkapp_GetVar, 1},
1377 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1378 {"unsetvar", Tkapp_UnsetVar, 1},
1379 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1380 {"getint", Tkapp_GetInt, 1},
1381 {"getdouble", Tkapp_GetDouble, 1},
1382 {"getboolean", Tkapp_GetBoolean, 1},
1383 {"exprstring", Tkapp_ExprString, 1},
1384 {"exprlong", Tkapp_ExprLong, 1},
1385 {"exprdouble", Tkapp_ExprDouble, 1},
1386 {"exprboolean", Tkapp_ExprBoolean, 1},
1387 {"splitlist", Tkapp_SplitList, 1},
1388 {"split", Tkapp_Split, 1},
1389 {"merge", Tkapp_Merge, 0},
1390 {"createcommand", Tkapp_CreateCommand, 1},
1391 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001392#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001393 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1394 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001395#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001396 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001397 {"mainloop", Tkapp_MainLoop, 1},
1398 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001399 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001400 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001401 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001402};
1403
Barry Warsawfa701a81997-01-16 00:15:11 +00001404
1405
Guido van Rossum18468821994-06-20 07:49:28 +00001406/**** Tkapp Type Methods ****/
1407
1408static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001409Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001410 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001411{
Guido van Rossum35d43371997-08-02 00:09:09 +00001412 Tcl_DeleteInterp(Tkapp_Interp(self));
1413 PyMem_DEL(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001414}
1415
1416static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001417Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001418 PyObject *self;
1419 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001420{
Guido van Rossum35d43371997-08-02 00:09:09 +00001421 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001422}
1423
1424static PyTypeObject Tkapp_Type =
1425{
Guido van Rossum35d43371997-08-02 00:09:09 +00001426 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001427 0, /*ob_size */
1428 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001429 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001430 0, /*tp_itemsize */
1431 Tkapp_Dealloc, /*tp_dealloc */
1432 0, /*tp_print */
1433 Tkapp_GetAttr, /*tp_getattr */
1434 0, /*tp_setattr */
1435 0, /*tp_compare */
1436 0, /*tp_repr */
1437 0, /*tp_as_number */
1438 0, /*tp_as_sequence */
1439 0, /*tp_as_mapping */
1440 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001441};
1442
Barry Warsawfa701a81997-01-16 00:15:11 +00001443
1444
Guido van Rossum18468821994-06-20 07:49:28 +00001445/**** Tkinter Module ****/
1446
1447static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001448Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001449 PyObject *self;
1450 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001451{
Barry Warsawfa701a81997-01-16 00:15:11 +00001452 char *screenName = NULL;
1453 char *baseName = NULL;
1454 char *className = NULL;
1455 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001456
Guido van Rossum35d43371997-08-02 00:09:09 +00001457 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001458 if (baseName != NULL)
1459 baseName++;
1460 else
1461 baseName = Py_GetProgramName();
1462 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001463
Barry Warsawfa701a81997-01-16 00:15:11 +00001464 if (!PyArg_ParseTuple(args, "|zssi",
1465 &screenName, &baseName, &className,
1466 &interactive))
1467 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001468
Barry Warsawfa701a81997-01-16 00:15:11 +00001469 return (PyObject *) Tkapp_New(screenName, baseName, className,
1470 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001471}
1472
1473static PyMethodDef moduleMethods[] =
1474{
Barry Warsawfa701a81997-01-16 00:15:11 +00001475 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001476#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001477 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1478 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001479#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001480 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001481 {"mainloop", Tkapp_MainLoop, 1},
1482 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001483 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001484 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001485};
1486
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001487static PyInterpreterState *event_interp = NULL;
1488
Guido van Rossum18468821994-06-20 07:49:28 +00001489static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001490EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00001491{
Guido van Rossuma59406a1997-10-10 17:39:19 +00001492 PyThreadState *tstate, *save_tstate;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001493
1494 if (Tk_GetNumMainWindows() == 0)
1495 return 0;
1496 if (event_interp == NULL)
1497 return 0;
1498 tstate = PyThreadState_New(event_interp);
Guido van Rossuma59406a1997-10-10 17:39:19 +00001499 save_tstate = PyThreadState_Swap(NULL);
1500 PyEval_RestoreThread(tstate);
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001501 if (!errorInCmd)
1502 Tcl_DoOneEvent(TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001503 if (errorInCmd) {
1504 errorInCmd = 0;
1505 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1506 excInCmd = valInCmd = trbInCmd = NULL;
1507 PyErr_Print();
1508 }
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001509 PyThreadState_Clear(tstate);
Guido van Rossuma59406a1997-10-10 17:39:19 +00001510 PyEval_SaveThread();
1511 PyThreadState_Swap(save_tstate);
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001512 PyThreadState_Delete(tstate);
Barry Warsawfa701a81997-01-16 00:15:11 +00001513 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001514}
Guido van Rossum18468821994-06-20 07:49:28 +00001515
Barry Warsawfa701a81997-01-16 00:15:11 +00001516
1517/* all errors will be checked in one fell swoop in init_tkinter() */
1518static void
1519ins_long(d, name, val)
1520 PyObject *d;
1521 char *name;
1522 long val;
1523{
1524 PyObject *v = PyInt_FromLong(val);
1525 if (v) {
1526 PyDict_SetItemString(d, name, v);
1527 Py_DECREF(v);
1528 }
1529}
1530static void
1531ins_string(d, name, val)
1532 PyObject *d;
1533 char *name;
1534 char *val;
1535{
1536 PyObject *v = PyString_FromString(val);
1537 if (v) {
1538 PyDict_SetItemString(d, name, v);
1539 Py_DECREF(v);
1540 }
1541}
1542
1543
Guido van Rossum18468821994-06-20 07:49:28 +00001544void
Guido van Rossum35d43371997-08-02 00:09:09 +00001545init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00001546{
Barry Warsawfa701a81997-01-16 00:15:11 +00001547 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001548
Barry Warsawfa701a81997-01-16 00:15:11 +00001549 Tkapp_Type.ob_type = &PyType_Type;
1550 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossumae92f011996-08-21 19:03:36 +00001551
Barry Warsawfa701a81997-01-16 00:15:11 +00001552 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001553
Barry Warsawfa701a81997-01-16 00:15:11 +00001554 d = PyModule_GetDict(m);
1555 Tkinter_TclError = Py_BuildValue("s", "TclError");
1556 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00001557
Guido van Rossum35d43371997-08-02 00:09:09 +00001558 ins_long(d, "READABLE", TCL_READABLE);
1559 ins_long(d, "WRITABLE", TCL_WRITABLE);
1560 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
1561 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
1562 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
1563 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
1564 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
1565 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
1566 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001567 ins_string(d, "TK_VERSION", TK_VERSION);
1568 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00001569
Guido van Rossum83551bf1997-09-13 00:44:23 +00001570 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
1571 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
1572
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001573 if (PyOS_InputHook == NULL) {
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001574 event_interp = PyThreadState_Get()->interp;
Guido van Rossum44620641997-08-11 18:57:29 +00001575 PyOS_InputHook = EventHook;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001576 }
Guido van Rossum18468821994-06-20 07:49:28 +00001577
Barry Warsawfa701a81997-01-16 00:15:11 +00001578 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001579 return;
1580
Guido van Rossum26216371998-04-20 18:47:52 +00001581#if TKMAJORMINOR >= 8000
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001582 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00001583#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001584
Jack Jansen34cc5c31995-10-31 16:15:12 +00001585#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001586 /*
1587 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
1588 ** Most of the initializations in that routine (toolbox init calls and
1589 ** such) have already been done for us, so we only need these.
1590 */
1591#if TKMAJORMINOR >= 8000
1592 tcl_macQdPtr = &qd;
1593#endif
1594
1595 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00001596#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00001597 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001598#endif /* GENERATINGCFM */
1599#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001600}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001601
Guido van Rossumec22c921996-02-25 04:50:29 +00001602
Barry Warsawfa701a81997-01-16 00:15:11 +00001603
Guido van Rossum9722ad81995-09-22 23:49:28 +00001604#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001605
1606/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001607** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001608*/
1609
Guido van Rossum9722ad81995-09-22 23:49:28 +00001610void
1611panic(char * format, ...)
1612{
Barry Warsawfa701a81997-01-16 00:15:11 +00001613 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001614
Barry Warsawfa701a81997-01-16 00:15:11 +00001615 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001616
Barry Warsawfa701a81997-01-16 00:15:11 +00001617 vfprintf(stderr, format, varg);
1618 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001619
Barry Warsawfa701a81997-01-16 00:15:11 +00001620 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001621
Barry Warsawfa701a81997-01-16 00:15:11 +00001622 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00001623}
Jack Jansen40b546d1995-11-14 10:34:45 +00001624
Guido van Rossumec22c921996-02-25 04:50:29 +00001625/*
1626** Pass events to SIOUX before passing them to Tk.
1627*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001628
Guido van Rossumec22c921996-02-25 04:50:29 +00001629static int
1630PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00001631 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001632{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00001633 WindowPtr frontwin;
1634 /*
1635 ** Sioux eats too many events, so we don't pass it everything.
1636 ** We always pass update events to Sioux, and we only pass other events if
1637 ** the Sioux window is frontmost. This means that Tk menus don't work
1638 ** in that case, but at least we can scroll the sioux window.
1639 ** Note that the SIOUXIsAppWindow() routine we use here is not really
1640 ** part of the external interface of Sioux...
1641 */
1642 frontwin = FrontWindow();
1643 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
1644 if (SIOUXHandleOneEvent(eventPtr))
1645 return 0; /* Nothing happened to the Tcl event queue */
1646 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001647 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001648}
1649
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001650#if defined(USE_GUSI) && TKMAJORMINOR < 8000
Guido van Rossum290283b1997-06-02 22:16:43 +00001651/*
1652 * For Python we have to override this routine (from TclMacNotify),
1653 * since we use GUSI for our sockets, not Tcl streams. Hence, we have
1654 * to use GUSI select to see whether our socket is ready. Note that
1655 * createfilehandler (above) sets the type to TCL_UNIX_FD for our
1656 * files and sockets.
1657 *
1658 * NOTE: this code was lifted from Tcl 7.6, it may need to be modified
1659 * for other versions. */
1660
1661int
1662Tcl_FileReady(file, mask)
1663 Tcl_File file; /* File handle for a stream. */
1664 int mask; /* OR'ed combination of TCL_READABLE,
1665 * TCL_WRITABLE, and TCL_EXCEPTION:
1666 * indicates conditions caller cares about. */
1667{
1668 int type;
1669 int fd;
1670
1671 fd = (int) Tcl_GetFileInfo(file, &type);
1672
1673 if (type == TCL_MAC_SOCKET) {
1674 return TclMacSocketReady(file, mask);
1675 } else if (type == TCL_MAC_FILE) {
1676 /*
1677 * Under the Macintosh, files are always ready, so we just
1678 * return the mask that was passed in.
1679 */
1680
1681 return mask;
1682 } else if (type == TCL_UNIX_FD) {
1683 fd_set readset, writeset, excset;
1684 struct timeval tv;
1685
1686 FD_ZERO(&readset);
1687 FD_ZERO(&writeset);
1688 FD_ZERO(&excset);
1689
1690 if ( mask & TCL_READABLE ) FD_SET(fd, &readset);
1691 if ( mask & TCL_WRITABLE ) FD_SET(fd, &writeset);
1692 if ( mask & TCL_EXCEPTION ) FD_SET(fd, &excset);
1693
1694 tv.tv_sec = tv.tv_usec = 0;
1695 if ( select(fd+1, &readset, &writeset, &excset, &tv) <= 0 )
1696 return 0;
1697
1698 mask = 0;
1699 if ( FD_ISSET(fd, &readset) ) mask |= TCL_READABLE;
1700 if ( FD_ISSET(fd, &writeset) ) mask |= TCL_WRITABLE;
1701 if ( FD_ISSET(fd, &excset) ) mask |= TCL_EXCEPTION;
1702
1703 return mask;
1704 }
1705
1706 return 0;
1707}
1708#endif /* USE_GUSI */
1709
Guido van Rossumec22c921996-02-25 04:50:29 +00001710#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001711
1712/*
1713** Additional Mac specific code for dealing with shared libraries.
1714*/
1715
1716#include <Resources.h>
1717#include <CodeFragments.h>
1718
1719static int loaded_from_shlib = 0;
1720static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001721
Jack Jansen34cc5c31995-10-31 16:15:12 +00001722/*
1723** If this module is dynamically loaded the following routine should
1724** be the init routine. It takes care of adding the shared library to
1725** the resource-file chain, so that the tk routines can find their
1726** resources.
1727*/
1728OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001729init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00001730{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00001731 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00001732 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001733 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001734 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1735 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001736 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001737 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1738 loaded_from_shlib = 1;
1739 }
1740 return noErr;
1741}
1742
1743/*
1744** Insert the library resources into the search path. Put them after
1745** the resources from the application. Again, we ignore errors.
1746*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001747static
Jack Jansen34cc5c31995-10-31 16:15:12 +00001748mac_addlibresources()
1749{
1750 if ( !loaded_from_shlib )
1751 return;
1752 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1753}
1754
Guido van Rossumec22c921996-02-25 04:50:29 +00001755#endif /* GENERATINGCFM */
1756#endif /* macintosh */