blob: f63bd3805c278dd499390fdc95ab824a9c5d8780 [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 Rossum212643f1998-04-29 16:22:14 +000046 XXX Further speed-up ideas, involving Tcl 8.0 features:
47
48 - In Tcl_Call(), create Tcl objects from the arguments, possibly using
49 intelligent mappings between Python objects and Tcl objects (e.g. ints,
50 floats and Tcl window pointers could be handled specially).
51
52 - Register a new Tcl type, "Python callable", which can be called more
53 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
54
Guido van Rossum7ffa7611996-08-13 21:10:16 +000055*/
56
Guido van Rossum35d43371997-08-02 00:09:09 +000057
Guido van Rossum9722ad81995-09-22 23:49:28 +000058#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000059#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000060
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000061#ifdef macintosh
62#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000063#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000064#endif
65
Guido van Rossum18468821994-06-20 07:49:28 +000066#include <tcl.h>
67#include <tk.h>
68
Guido van Rossum3e819a71997-08-01 19:29:02 +000069#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
70
Guido van Rossum0d2390c1997-08-14 19:57:07 +000071#if TKMAJORMINOR >= 8000 && defined(macintosh)
72/* Sigh, we have to include this to get at the tcl qd pointer */
73#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000074/* And this one we need to clear the menu bar */
75#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000076#endif
77
Guido van Rossum35d43371997-08-02 00:09:09 +000078#if TKMAJORMINOR < 4001
Guido van Rossum75626a31997-09-08 02:04:00 +000079 #error "Tk 4.0 or 3.x are not supported -- use 4.1 or higher"
Guido van Rossum9722ad81995-09-22 23:49:28 +000080#endif
81
Guido van Rossumb0105441997-10-08 15:25:37 +000082#if TKMAJORMINOR < 8000 || !defined(MS_WINDOWS)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000083#define HAVE_CREATEFILEHANDLER
84#endif
85
Guido van Rossum7bf15641998-05-22 18:28:17 +000086#ifdef MS_WINDOWS
87#define FHANDLETYPE TCL_WIN_SOCKET
88#else
89#define FHANDLETYPE TCL_UNIX_FD
90#endif
91
92#if TKMAJORMINOR < 8000
93#define FHANDLE Tcl_File
94#define MAKEFHANDLE(fd) Tcl_GetFile((ClientData)(fd), FHANDLETYPE)
95#else
96#define FHANDLE int
97#define MAKEFHANDLE(fd) (fd)
98#endif
99
100#if defined(HAVE_CREATEFILEHANDLER) && !defined(MS_WINDOWS)
101#define WAIT_FOR_STDIN
102#endif
103
Guido van Rossum35d43371997-08-02 00:09:09 +0000104extern int Tk_GetNumMainWindows();
105
Guido van Rossumec22c921996-02-25 04:50:29 +0000106#ifdef macintosh
107
108/*
109** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000110** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000111*/
112
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000113/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000114#define FREECAST (char *)
115
Guido van Rossumec22c921996-02-25 04:50:29 +0000116#include <Events.h> /* For EventRecord */
117
118typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
Guido van Rossum0d2390c1997-08-14 19:57:07 +0000119/* They changed the name... */
120#if TKMAJORMINOR < 8000
121#define Tcl_MacSetEventProc TclMacSetEventProc
122#endif
123void Tcl_MacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
Guido van Rossumec22c921996-02-25 04:50:29 +0000124int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
125
126staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
127
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000128#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
129 #pragma import on
130#endif
131
132#include <SIOUX.h>
133extern int SIOUXIsAppWindow(WindowPtr);
134
135#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
136 #pragma import reset
137#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000138#endif /* macintosh */
139
Guido van Rossum97867b21996-08-08 19:09:53 +0000140#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000141#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000142#endif
143
Guido van Rossum18468821994-06-20 07:49:28 +0000144/**** Tkapp Object Declaration ****/
145
146staticforward PyTypeObject Tkapp_Type;
147
148typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +0000149{
150 PyObject_HEAD
151 Tcl_Interp *interp;
Barry Warsawfa701a81997-01-16 00:15:11 +0000152}
Guido van Rossum18468821994-06-20 07:49:28 +0000153TkappObject;
154
155#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000156#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
157#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
158
Guido van Rossum35d43371997-08-02 00:09:09 +0000159#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000160(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000161
Barry Warsawfa701a81997-01-16 00:15:11 +0000162
163
Guido van Rossum18468821994-06-20 07:49:28 +0000164/**** Error Handling ****/
165
166static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000167static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000168static int errorInCmd = 0;
169static PyObject *excInCmd;
170static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000171static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000172
Barry Warsawfa701a81997-01-16 00:15:11 +0000173
174
Guido van Rossum18468821994-06-20 07:49:28 +0000175static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000176Tkinter_Error(v)
177 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000178{
Barry Warsawfa701a81997-01-16 00:15:11 +0000179 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
180 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000181}
182
Barry Warsawfa701a81997-01-16 00:15:11 +0000183
Guido van Rossum18468821994-06-20 07:49:28 +0000184int
Barry Warsawfa701a81997-01-16 00:15:11 +0000185PythonCmd_Error(interp)
186 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000187{
Barry Warsawfa701a81997-01-16 00:15:11 +0000188 errorInCmd = 1;
189 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
190 return TCL_ERROR;
Guido van Rossum18468821994-06-20 07:49:28 +0000191}
192
Barry Warsawfa701a81997-01-16 00:15:11 +0000193
194
Guido van Rossum18468821994-06-20 07:49:28 +0000195/**** Utils ****/
Guido van Rossum18468821994-06-20 07:49:28 +0000196static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000197AsString(value, tmp)
198 PyObject *value;
199 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000200{
Guido van Rossum35d43371997-08-02 00:09:09 +0000201 if (PyString_Check(value))
202 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000203 else {
204 PyObject *v = PyObject_Str(value);
205 PyList_Append(tmp, v);
206 Py_DECREF(v);
207 return PyString_AsString(v);
208 }
Guido van Rossum18468821994-06-20 07:49:28 +0000209}
210
Barry Warsawfa701a81997-01-16 00:15:11 +0000211
212
Guido van Rossum18468821994-06-20 07:49:28 +0000213#define ARGSZ 64
214
215static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000216Merge(args)
217 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000218{
Barry Warsawfa701a81997-01-16 00:15:11 +0000219 PyObject *tmp = NULL;
220 char *argvStore[ARGSZ];
221 char **argv = NULL;
222 int fvStore[ARGSZ];
223 int *fv = NULL;
224 int argc = 0, i;
225 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000226
Barry Warsawfa701a81997-01-16 00:15:11 +0000227 if (!(tmp = PyList_New(0)))
228 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000229
Barry Warsawfa701a81997-01-16 00:15:11 +0000230 argv = argvStore;
231 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000232
Barry Warsawfa701a81997-01-16 00:15:11 +0000233 if (args == NULL)
234 argc = 0;
235
236 else if (!PyTuple_Check(args)) {
237 argc = 1;
238 fv[0] = 0;
239 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000240 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000241 else {
242 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000243
Barry Warsawfa701a81997-01-16 00:15:11 +0000244 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000245 argv = (char **)ckalloc(argc * sizeof(char *));
246 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000247 if (argv == NULL || fv == NULL) {
248 PyErr_NoMemory();
249 goto finally;
250 }
251 }
252
253 for (i = 0; i < argc; i++) {
254 PyObject *v = PyTuple_GetItem(args, i);
255 if (PyTuple_Check(v)) {
256 fv[i] = 1;
257 if (!(argv[i] = Merge(v)))
258 goto finally;
259 }
260 else if (v == Py_None) {
261 argc = i;
262 break;
263 }
264 else {
265 fv[i] = 0;
266 argv[i] = AsString(v, tmp);
267 }
268 }
Guido van Rossum18468821994-06-20 07:49:28 +0000269 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000270 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000271
Barry Warsawfa701a81997-01-16 00:15:11 +0000272 finally:
273 for (i = 0; i < argc; i++)
274 if (fv[i]) {
275 ckfree(argv[i]);
276 }
277 if (argv != argvStore)
278 ckfree(FREECAST argv);
279 if (fv != fvStore)
280 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000281
Barry Warsawfa701a81997-01-16 00:15:11 +0000282 Py_DECREF(tmp);
283 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000284}
285
Barry Warsawfa701a81997-01-16 00:15:11 +0000286
287
Guido van Rossum18468821994-06-20 07:49:28 +0000288static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000289Split(self, list)
290 PyObject *self;
291 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000292{
Barry Warsawfa701a81997-01-16 00:15:11 +0000293 int argc;
294 char **argv;
295 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000296
Barry Warsawfa701a81997-01-16 00:15:11 +0000297 if (list == NULL) {
298 Py_INCREF(Py_None);
299 return Py_None;
300 }
Guido van Rossum18468821994-06-20 07:49:28 +0000301
Barry Warsawfa701a81997-01-16 00:15:11 +0000302 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
303 {
304 /* Not a list.
305 * Could be a quoted string containing funnies, e.g. {"}.
306 * Return the string itself.
307 */
308 PyErr_Clear();
309 return PyString_FromString(list);
310 }
Guido van Rossum18468821994-06-20 07:49:28 +0000311
Barry Warsawfa701a81997-01-16 00:15:11 +0000312 if (argc == 0)
313 v = PyString_FromString("");
314 else if (argc == 1)
315 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000316 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000317 int i;
318 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000319
Barry Warsawfa701a81997-01-16 00:15:11 +0000320 for (i = 0; i < argc; i++) {
321 if ((w = Split(self, argv[i])) == NULL) {
322 Py_DECREF(v);
323 v = NULL;
324 break;
325 }
326 PyTuple_SetItem(v, i, w);
327 }
328 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000329 ckfree(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000330 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000331}
332
Barry Warsawfa701a81997-01-16 00:15:11 +0000333
334
Guido van Rossum18468821994-06-20 07:49:28 +0000335/**** Tkapp Object ****/
336
337#ifndef WITH_APPINIT
338int
Guido van Rossum35d43371997-08-02 00:09:09 +0000339Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000340 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000341{
Barry Warsawfa701a81997-01-16 00:15:11 +0000342 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000343
Barry Warsawfa701a81997-01-16 00:15:11 +0000344 main = Tk_MainWindow(interp);
345 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000346 PySys_WriteStderr("Tcl_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000347 return TCL_ERROR;
348 }
349 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000350 PySys_WriteStderr("Tk_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000351 return TCL_ERROR;
352 }
353 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000354}
355#endif /* !WITH_APPINIT */
356
Guido van Rossum18468821994-06-20 07:49:28 +0000357
Barry Warsawfa701a81997-01-16 00:15:11 +0000358
359
360/* Initialize the Tk application; see the `main' function in
361 * `tkMain.c'.
362 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000363
364static void EnableEventHook(); /* Forward */
365static void DisableEventHook(); /* Forward */
366
Barry Warsawfa701a81997-01-16 00:15:11 +0000367static TkappObject *
368Tkapp_New(screenName, baseName, className, interactive)
369 char *screenName;
370 char *baseName;
371 char *className;
372 int interactive;
373{
374 TkappObject *v;
375 char *argv0;
376
377 v = PyObject_NEW(TkappObject, &Tkapp_Type);
378 if (v == NULL)
379 return NULL;
380
381 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000382
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000383#if defined(macintosh) && TKMAJORMINOR >= 8000
384 /* This seems to be needed since Tk 8.0 */
385 ClearMenuBar();
386 TkMacInitMenus(v->interp);
387#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000388 /* Delete the 'exit' command, which can screw things up */
389 Tcl_DeleteCommand(v->interp, "exit");
390
Barry Warsawfa701a81997-01-16 00:15:11 +0000391 if (screenName != NULL)
392 Tcl_SetVar2(v->interp, "env", "DISPLAY",
393 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000394
Barry Warsawfa701a81997-01-16 00:15:11 +0000395 if (interactive)
396 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
397 else
398 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000399
Barry Warsawfa701a81997-01-16 00:15:11 +0000400 /* This is used to get the application class for Tk 4.1 and up */
401 argv0 = (char*)ckalloc(strlen(className) + 1);
402 if (!argv0) {
403 PyErr_NoMemory();
404 Py_DECREF(v);
405 return NULL;
406 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000407
Barry Warsawfa701a81997-01-16 00:15:11 +0000408 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000409 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000410 argv0[0] = tolower(argv0[0]);
411 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
412 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000413
Barry Warsawfa701a81997-01-16 00:15:11 +0000414 if (Tcl_AppInit(v->interp) != TCL_OK)
415 return (TkappObject *)Tkinter_Error(v);
416
Guido van Rossum7bf15641998-05-22 18:28:17 +0000417 EnableEventHook();
418
Barry Warsawfa701a81997-01-16 00:15:11 +0000419 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000420}
421
Barry Warsawfa701a81997-01-16 00:15:11 +0000422
423
Guido van Rossum18468821994-06-20 07:49:28 +0000424/** Tcl Eval **/
425
426static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000427Tkapp_Call(self, args)
428 PyObject *self;
429 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000430{
Guido van Rossum212643f1998-04-29 16:22:14 +0000431 /* This is copied from Merge() */
432 PyObject *tmp = NULL;
433 char *argvStore[ARGSZ];
434 char **argv = NULL;
435 int fvStore[ARGSZ];
436 int *fv = NULL;
437 int argc = 0, i;
438 PyObject *res = NULL; /* except this has a different type */
439 Tcl_CmdInfo info; /* and this is added */
440 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
Guido van Rossum18468821994-06-20 07:49:28 +0000441
Guido van Rossum212643f1998-04-29 16:22:14 +0000442 if (!(tmp = PyList_New(0)))
443 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000444
Guido van Rossum212643f1998-04-29 16:22:14 +0000445 argv = argvStore;
446 fv = fvStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000447
Guido van Rossum212643f1998-04-29 16:22:14 +0000448 if (args == NULL)
449 argc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000450
Guido van Rossum212643f1998-04-29 16:22:14 +0000451 else if (!PyTuple_Check(args)) {
452 argc = 1;
453 fv[0] = 0;
454 argv[0] = AsString(args, tmp);
455 }
456 else {
457 argc = PyTuple_Size(args);
458
459 if (argc > ARGSZ) {
460 argv = (char **)ckalloc(argc * sizeof(char *));
461 fv = (int *)ckalloc(argc * sizeof(int));
462 if (argv == NULL || fv == NULL) {
463 PyErr_NoMemory();
464 goto finally;
465 }
466 }
467
468 for (i = 0; i < argc; i++) {
469 PyObject *v = PyTuple_GetItem(args, i);
470 if (PyTuple_Check(v)) {
471 fv[i] = 1;
472 if (!(argv[i] = Merge(v)))
473 goto finally;
474 }
475 else if (v == Py_None) {
476 argc = i;
477 break;
478 }
479 else {
480 fv[i] = 0;
481 argv[i] = AsString(v, tmp);
482 }
483 }
484 }
485 /* End code copied from Merge() */
486
487 /* All this to avoid a call to Tcl_Merge() and the corresponding call
488 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
489 if (Py_VerboseFlag >= 2) {
490 for (i = 0; i < argc; i++)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000491 PySys_WriteStderr("%s ", argv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000492 }
493 if (argc < 1 ||
494 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
495 info.proc == NULL)
496 {
497 char *cmd;
498 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000499 PySys_WriteStderr("... use TclEval ");
Guido van Rossum212643f1998-04-29 16:22:14 +0000500 cmd = Tcl_Merge(argc, argv);
501 i = Tcl_Eval(interp, cmd);
Barry Warsawfa701a81997-01-16 00:15:11 +0000502 ckfree(cmd);
Guido van Rossum212643f1998-04-29 16:22:14 +0000503 }
504 else {
505 Tcl_ResetResult(interp);
506 i = (*info.proc)(info.clientData, interp, argc, argv);
507 }
508 if (i == TCL_ERROR) {
509 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000510 PySys_WriteStderr("... error: '%s'\n",
Guido van Rossum212643f1998-04-29 16:22:14 +0000511 interp->result);
512 Tkinter_Error(self);
513 }
514 else {
515 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000516 PySys_WriteStderr("-> '%s'\n", interp->result);
Guido van Rossum212643f1998-04-29 16:22:14 +0000517 res = PyString_FromString(interp->result);
518 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000519
Guido van Rossum212643f1998-04-29 16:22:14 +0000520 /* Copied from Merge() again */
521 finally:
522 for (i = 0; i < argc; i++)
523 if (fv[i]) {
524 ckfree(argv[i]);
525 }
526 if (argv != argvStore)
527 ckfree(FREECAST argv);
528 if (fv != fvStore)
529 ckfree(FREECAST fv);
530
531 Py_DECREF(tmp);
Barry Warsawfa701a81997-01-16 00:15:11 +0000532 return res;
533}
534
535
536static PyObject *
537Tkapp_GlobalCall(self, args)
538 PyObject *self;
539 PyObject *args;
540{
Guido van Rossum212643f1998-04-29 16:22:14 +0000541 /* Could do the same here as for Tkapp_Call(), but this is not used
542 much, so I can't be bothered. Unfortunately Tcl doesn't export a
543 way for the user to do what all its Global* variants do (save and
544 reset the scope pointer, call the local version, restore the saved
545 scope pointer). */
546
Barry Warsawfa701a81997-01-16 00:15:11 +0000547 char *cmd = Merge(args);
548 PyObject *res = NULL;
549
550
551 if (!cmd)
552 PyErr_SetString(Tkinter_TclError, "merge failed");
553
554 else if (Tcl_GlobalEval(Tkapp_Interp(self), cmd) == TCL_ERROR)
555 res = Tkinter_Error(self);
556 else
557 res = PyString_FromString(Tkapp_Result(self));
558
559 if (cmd)
560 ckfree(cmd);
561
562 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000563}
564
565static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000566Tkapp_Eval(self, args)
567 PyObject *self;
568 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000569{
Barry Warsawfa701a81997-01-16 00:15:11 +0000570 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000571
Guido van Rossum35d43371997-08-02 00:09:09 +0000572 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000573 return NULL;
574
575 if (Tcl_Eval(Tkapp_Interp(self), script) == TCL_ERROR)
576 return Tkinter_Error(self);
577
578 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000579}
580
581static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000582Tkapp_GlobalEval(self, args)
583 PyObject *self;
584 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000585{
Barry Warsawfa701a81997-01-16 00:15:11 +0000586 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000587
Guido van Rossum35d43371997-08-02 00:09:09 +0000588 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000589 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000590
Barry Warsawfa701a81997-01-16 00:15:11 +0000591 if (Tcl_GlobalEval(Tkapp_Interp(self), script) == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000592 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000593
Barry Warsawfa701a81997-01-16 00:15:11 +0000594 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000595}
596
597static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000598Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000599 PyObject *self;
600 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000601{
Barry Warsawfa701a81997-01-16 00:15:11 +0000602 char *fileName;
Guido van Rossum18468821994-06-20 07:49:28 +0000603
Guido van Rossum35d43371997-08-02 00:09:09 +0000604 if (!PyArg_ParseTuple(args, "s", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000605 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000606
Barry Warsawfa701a81997-01-16 00:15:11 +0000607 if (Tcl_EvalFile(Tkapp_Interp(self), fileName) == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000608 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000609
Barry Warsawfa701a81997-01-16 00:15:11 +0000610 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000611}
612
613static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000614Tkapp_Record(self, args)
615 PyObject *self;
616 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000617{
Barry Warsawfa701a81997-01-16 00:15:11 +0000618 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000619
Guido van Rossum35d43371997-08-02 00:09:09 +0000620 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000621 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000622
Barry Warsawfa701a81997-01-16 00:15:11 +0000623 if (TCL_ERROR == Tcl_RecordAndEval(Tkapp_Interp(self),
624 script, TCL_NO_EVAL))
Guido van Rossum35d43371997-08-02 00:09:09 +0000625 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000626
Barry Warsawfa701a81997-01-16 00:15:11 +0000627 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000628}
629
630static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000631Tkapp_AddErrorInfo(self, args)
632 PyObject *self;
633 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000634{
Barry Warsawfa701a81997-01-16 00:15:11 +0000635 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000636
Guido van Rossum35d43371997-08-02 00:09:09 +0000637 if (!PyArg_ParseTuple(args, "s", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000638 return NULL;
639 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum18468821994-06-20 07:49:28 +0000640
Barry Warsawfa701a81997-01-16 00:15:11 +0000641 Py_INCREF(Py_None);
642 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000643}
644
Barry Warsawfa701a81997-01-16 00:15:11 +0000645
646
Guido van Rossum18468821994-06-20 07:49:28 +0000647/** Tcl Variable **/
648
649static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000650SetVar(self, args, flags)
651 PyObject *self;
652 PyObject *args;
653 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000654{
Barry Warsawfa701a81997-01-16 00:15:11 +0000655 char *name1, *name2, *ok;
656 PyObject *newValue;
657 PyObject *tmp = PyList_New(0);
Guido van Rossum18468821994-06-20 07:49:28 +0000658
Barry Warsawfa701a81997-01-16 00:15:11 +0000659 if (!tmp)
660 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000661
Guido van Rossum35d43371997-08-02 00:09:09 +0000662 if (PyArg_ParseTuple(args, "sO", &name1, &newValue))
Barry Warsawfa701a81997-01-16 00:15:11 +0000663 /* XXX Merge? */
Guido van Rossum35d43371997-08-02 00:09:09 +0000664 ok = Tcl_SetVar(Tkapp_Interp(self), name1,
665 AsString(newValue, tmp), flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000666
Barry Warsawfa701a81997-01-16 00:15:11 +0000667 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000668 PyErr_Clear();
669 if (PyArg_ParseTuple(args, "ssO", &name1, &name2, &newValue))
670 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
671 AsString (newValue, tmp), flags);
672 else {
673 Py_DECREF (tmp);
674 return NULL;
675 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000676 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000677 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000678
Barry Warsawfa701a81997-01-16 00:15:11 +0000679 if (!ok)
680 return Tkinter_Error(self);
681
682 Py_INCREF(Py_None);
683 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000684}
685
686static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000687Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000688 PyObject *self;
689 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000690{
Barry Warsawfa701a81997-01-16 00:15:11 +0000691 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000692}
693
694static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000695Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000696 PyObject *self;
697 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000698{
Barry Warsawfa701a81997-01-16 00:15:11 +0000699 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000700}
701
Barry Warsawfa701a81997-01-16 00:15:11 +0000702
703
Guido van Rossum18468821994-06-20 07:49:28 +0000704static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000705GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000706 PyObject *self;
707 PyObject *args;
708 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000709{
Guido van Rossum35d43371997-08-02 00:09:09 +0000710 char *name1, *name2=NULL, *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000711
Guido van Rossum35d43371997-08-02 00:09:09 +0000712 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
713 return NULL;
714 if (name2 == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +0000715 s = Tcl_GetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000716
Barry Warsawfa701a81997-01-16 00:15:11 +0000717 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000718 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000719
Barry Warsawfa701a81997-01-16 00:15:11 +0000720 if (s == NULL)
721 return Tkinter_Error(self);
722
Guido van Rossum35d43371997-08-02 00:09:09 +0000723 return PyString_FromString(s);
Guido van Rossum18468821994-06-20 07:49:28 +0000724}
725
726static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000727Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000728 PyObject *self;
729 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000730{
Barry Warsawfa701a81997-01-16 00:15:11 +0000731 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000732}
733
734static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000735Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000736 PyObject *self;
737 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000738{
Barry Warsawfa701a81997-01-16 00:15:11 +0000739 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000740}
741
Barry Warsawfa701a81997-01-16 00:15:11 +0000742
743
Guido van Rossum18468821994-06-20 07:49:28 +0000744static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000745UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000746 PyObject *self;
747 PyObject *args;
748 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000749{
Guido van Rossum35d43371997-08-02 00:09:09 +0000750 char *name1, *name2=NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000751 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000752
Guido van Rossum35d43371997-08-02 00:09:09 +0000753 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000754 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000755 if (name2 == NULL)
756 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
757
758 else
759 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000760
Barry Warsawfa701a81997-01-16 00:15:11 +0000761 if (code == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000762 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000763
764 Py_INCREF(Py_None);
765 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000766}
767
768static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000769Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000770 PyObject *self;
771 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000772{
Barry Warsawfa701a81997-01-16 00:15:11 +0000773 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000774}
775
776static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000777Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000778 PyObject *self;
779 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000780{
Barry Warsawfa701a81997-01-16 00:15:11 +0000781 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000782}
783
Barry Warsawfa701a81997-01-16 00:15:11 +0000784
785
Guido van Rossum18468821994-06-20 07:49:28 +0000786/** Tcl to Python **/
787
788static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000789Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000790 PyObject *self;
791 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000792{
Barry Warsawfa701a81997-01-16 00:15:11 +0000793 char *s;
794 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000795
Guido van Rossum35d43371997-08-02 00:09:09 +0000796 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000797 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000798 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000799 return Tkinter_Error(self);
800 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000801}
802
803static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000804Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000805 PyObject *self;
806 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000807{
Barry Warsawfa701a81997-01-16 00:15:11 +0000808 char *s;
809 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000810
Guido van Rossum35d43371997-08-02 00:09:09 +0000811 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000812 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000813 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000814 return Tkinter_Error(self);
815 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000816}
817
818static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000819Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000820 PyObject *self;
821 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000822{
Barry Warsawfa701a81997-01-16 00:15:11 +0000823 char *s;
824 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000825
Guido van Rossum35d43371997-08-02 00:09:09 +0000826 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000827 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000828 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
829 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000830 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000831}
832
833static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000834Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000835 PyObject *self;
836 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000837{
Barry Warsawfa701a81997-01-16 00:15:11 +0000838 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000839
Guido van Rossum35d43371997-08-02 00:09:09 +0000840 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000841 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000842 if (Tcl_ExprString(Tkapp_Interp(self), s) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000843 return Tkinter_Error(self);
844 return Py_BuildValue("s", Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000845}
846
847static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000848Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000849 PyObject *self;
850 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000851{
Barry Warsawfa701a81997-01-16 00:15:11 +0000852 char *s;
853 long v;
Guido van Rossum18468821994-06-20 07:49:28 +0000854
Guido van Rossum35d43371997-08-02 00:09:09 +0000855 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000856 return NULL;
857 if (Tcl_ExprLong(Tkapp_Interp(self), s, &v) == TCL_ERROR)
858 return Tkinter_Error(self);
859 return Py_BuildValue("l", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000860}
861
862static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000863Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000864 PyObject *self;
865 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000866{
Barry Warsawfa701a81997-01-16 00:15:11 +0000867 char *s;
868 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000869 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000870
Guido van Rossum35d43371997-08-02 00:09:09 +0000871 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000872 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000873 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum35d43371997-08-02 00:09:09 +0000874 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum45b83911997-03-14 04:32:50 +0000875 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000876 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000877 return Tkinter_Error(self);
878 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000879}
880
881static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000882Tkapp_ExprBoolean(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 *s;
887 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000888
Guido van Rossum35d43371997-08-02 00:09:09 +0000889 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000890 return NULL;
891 if (Tcl_ExprBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
892 return Tkinter_Error(self);
893 return Py_BuildValue("i", v);
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_SplitList(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 *list;
904 int argc;
905 char **argv;
906 PyObject *v;
907 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000908
Guido van Rossum35d43371997-08-02 00:09:09 +0000909 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +0000910 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000911
Barry Warsawfa701a81997-01-16 00:15:11 +0000912 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
913 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000914
Barry Warsawfa701a81997-01-16 00:15:11 +0000915 if (!(v = PyTuple_New(argc)))
916 return NULL;
917
918 for (i = 0; i < argc; i++) {
919 PyObject *s = PyString_FromString(argv[i]);
920 if (!s || PyTuple_SetItem(v, i, s)) {
921 Py_DECREF(v);
922 v = NULL;
923 goto finally;
924 }
925 }
Guido van Rossum18468821994-06-20 07:49:28 +0000926
Barry Warsawfa701a81997-01-16 00:15:11 +0000927 finally:
928 ckfree(FREECAST argv);
929 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000930}
931
932static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000933Tkapp_Split(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 *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000938
Guido van Rossum35d43371997-08-02 00:09:09 +0000939 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +0000940 return NULL;
941 return Split(self, list);
Guido van Rossum18468821994-06-20 07:49:28 +0000942}
943
944static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000945Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000946 PyObject *self;
947 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000948{
Barry Warsawfa701a81997-01-16 00:15:11 +0000949 char *s = Merge(args);
950 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000951
Barry Warsawfa701a81997-01-16 00:15:11 +0000952 if (s) {
953 res = PyString_FromString(s);
954 ckfree(s);
955 }
956 else
957 PyErr_SetString(Tkinter_TclError, "merge failed");
958
959 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000960}
961
Barry Warsawfa701a81997-01-16 00:15:11 +0000962
963
Guido van Rossum18468821994-06-20 07:49:28 +0000964/** Tcl Command **/
965
966/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +0000967 * function or method.
968 */
Guido van Rossum18468821994-06-20 07:49:28 +0000969static int
Guido van Rossum35d43371997-08-02 00:09:09 +0000970PythonCmd(clientData, interp, argc, argv)
Barry Warsawfa701a81997-01-16 00:15:11 +0000971 ClientData clientData; /* Is (self, func) */
972 Tcl_Interp *interp;
973 int argc;
974 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +0000975{
Barry Warsawfa701a81997-01-16 00:15:11 +0000976 PyObject *self, *func, *arg, *res, *tmp;
977 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000978
Barry Warsawfa701a81997-01-16 00:15:11 +0000979 /* TBD: no error checking here since we know, via the
980 * Tkapp_CreateCommand() that the client data is a two-tuple
981 */
982 self = PyTuple_GetItem((PyObject *) clientData, 0);
983 func = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000984
Barry Warsawfa701a81997-01-16 00:15:11 +0000985 /* Create argument list (argv1, ..., argvN) */
986 if (!(arg = PyTuple_New(argc - 1)))
987 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000988
Barry Warsawfa701a81997-01-16 00:15:11 +0000989 for (i = 0; i < (argc - 1); i++) {
990 PyObject *s = PyString_FromString(argv[i + 1]);
991 if (!s || PyTuple_SetItem(arg, i, s)) {
992 Py_DECREF(arg);
993 PythonCmd_Error(interp);
994 }
995 }
996 res = PyEval_CallObject(func, arg);
997 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +0000998
Barry Warsawfa701a81997-01-16 00:15:11 +0000999 if (res == NULL)
1000 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001001
Barry Warsawfa701a81997-01-16 00:15:11 +00001002 if (!(tmp = PyList_New(0))) {
1003 Py_DECREF(res);
1004 return PythonCmd_Error(interp);
1005 }
1006
1007 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
1008 Py_DECREF(res);
1009 Py_DECREF(tmp);
1010
1011 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +00001012}
1013
1014static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001015PythonCmdDelete(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001016 ClientData clientData; /* Is (self, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001017{
Barry Warsawfa701a81997-01-16 00:15:11 +00001018 Py_DECREF((PyObject *) clientData);
Guido van Rossum18468821994-06-20 07:49:28 +00001019}
1020
Barry Warsawfa701a81997-01-16 00:15:11 +00001021
1022
Guido van Rossum18468821994-06-20 07:49:28 +00001023static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001024Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001025 PyObject *self;
1026 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001027{
Barry Warsawfa701a81997-01-16 00:15:11 +00001028 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001029 PyObject *func;
Guido van Rossum35d43371997-08-02 00:09:09 +00001030 PyObject *data;
1031
1032 if (!PyArg_ParseTuple(args, "sO", &cmdName, &func))
1033 return NULL;
1034 if (!PyCallable_Check(func)) {
1035 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001036 return NULL;
1037 }
Guido van Rossum18468821994-06-20 07:49:28 +00001038
Guido van Rossum35d43371997-08-02 00:09:09 +00001039 data = Py_BuildValue("OO", self, func);
Barry Warsawfa701a81997-01-16 00:15:11 +00001040 if (!data)
1041 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001042
Guido van Rossum35d43371997-08-02 00:09:09 +00001043 if (Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1044 (ClientData) data, PythonCmdDelete) == NULL)
1045 {
1046 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
1047 Py_DECREF(data);
1048 return NULL;
1049 }
Guido van Rossum18468821994-06-20 07:49:28 +00001050
Barry Warsawfa701a81997-01-16 00:15:11 +00001051 Py_INCREF(Py_None);
1052 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001053}
1054
Barry Warsawfa701a81997-01-16 00:15:11 +00001055
1056
Guido van Rossum18468821994-06-20 07:49:28 +00001057static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001058Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001059 PyObject *self;
1060 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001061{
Barry Warsawfa701a81997-01-16 00:15:11 +00001062 char *cmdName;
Guido van Rossum18468821994-06-20 07:49:28 +00001063
Guido van Rossum35d43371997-08-02 00:09:09 +00001064 if (!PyArg_ParseTuple(args, "s", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001065 return NULL;
1066 if (Tcl_DeleteCommand(Tkapp_Interp(self), cmdName) == -1)
1067 {
1068 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1069 return NULL;
1070 }
1071 Py_INCREF(Py_None);
1072 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001073}
1074
Barry Warsawfa701a81997-01-16 00:15:11 +00001075
1076
Guido van Rossum18468821994-06-20 07:49:28 +00001077/** File Handler **/
1078
Guido van Rossuma597dde1995-01-10 20:56:29 +00001079static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001080FileHandler(clientData, mask)
Barry Warsawfa701a81997-01-16 00:15:11 +00001081 ClientData clientData; /* Is: (func, file) */
1082 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +00001083{
Barry Warsawfa701a81997-01-16 00:15:11 +00001084 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001085
Barry Warsawfa701a81997-01-16 00:15:11 +00001086 func = PyTuple_GetItem((PyObject *) clientData, 0);
1087 file = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +00001088
Barry Warsawfa701a81997-01-16 00:15:11 +00001089 arg = Py_BuildValue("(Oi)", file, (long) mask);
1090 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001091 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001092
1093 if (res == NULL) {
1094 errorInCmd = 1;
1095 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1096 }
1097 Py_XDECREF(res);
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001098}
1099
1100static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001101GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +00001102 /* Either an int >= 0 or an object with a
1103 *.fileno() method that returns an int >= 0
1104 */
1105 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001106{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001107 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001108 int id;
1109 if (PyInt_Check(file)) {
1110 id = PyInt_AsLong(file);
1111 if (id < 0)
1112 PyErr_SetString(PyExc_ValueError, "invalid file id");
1113 return id;
1114 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001115 args = PyTuple_New(0);
1116 if (args == NULL)
1117 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001118
1119 meth = PyObject_GetAttrString(file, "fileno");
1120 if (meth == NULL) {
1121 Py_DECREF(args);
1122 return -1;
1123 }
1124
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001125 res = PyEval_CallObject(meth, args);
1126 Py_DECREF(args);
1127 Py_DECREF(meth);
1128 if (res == NULL)
1129 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001130
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001131 if (PyInt_Check(res))
1132 id = PyInt_AsLong(res);
1133 else
1134 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001135
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001136 if (id < 0)
1137 PyErr_SetString(PyExc_ValueError,
1138 "invalid fileno() return value");
1139 Py_DECREF(res);
1140 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001141}
1142
Barry Warsawfa701a81997-01-16 00:15:11 +00001143
1144static PyObject* Tkapp_ClientDataDict = NULL;
1145
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001146#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001147static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001148Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001149 PyObject *self;
1150 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001151{
Barry Warsawfa701a81997-01-16 00:15:11 +00001152 PyObject *file, *func, *data;
1153 PyObject *idkey;
1154 int mask, id;
Guido van Rossum7bf15641998-05-22 18:28:17 +00001155 FHANDLE tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001156
Barry Warsawfa701a81997-01-16 00:15:11 +00001157 if (!Tkapp_ClientDataDict) {
1158 if (!(Tkapp_ClientDataDict = PyDict_New()))
1159 return NULL;
1160 }
Guido van Rossum18468821994-06-20 07:49:28 +00001161
Guido van Rossum35d43371997-08-02 00:09:09 +00001162 if (!PyArg_ParseTuple(args, "OiO", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001163 return NULL;
1164 id = GetFileNo(file);
1165 if (id < 0)
1166 return NULL;
1167 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001168 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001169 return NULL;
1170 }
1171
1172 if (!(idkey = PyInt_FromLong(id)))
1173 return NULL;
1174
1175 /* ClientData is: (func, file) */
Guido van Rossum35d43371997-08-02 00:09:09 +00001176 data = Py_BuildValue("(OO)", func, file);
Barry Warsawfa701a81997-01-16 00:15:11 +00001177 if (!data || PyDict_SetItem(Tkapp_ClientDataDict, idkey, data)) {
1178 Py_DECREF(idkey);
1179 Py_XDECREF(data);
1180 return NULL;
1181 }
1182 Py_DECREF(idkey);
Guido van Rossum76875221994-06-27 07:59:42 +00001183
Guido van Rossum7bf15641998-05-22 18:28:17 +00001184 tfile = MAKEFHANDLE(id);
Barry Warsawfa701a81997-01-16 00:15:11 +00001185 /* Ought to check for null Tcl_File object... */
1186 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Barry Warsawfa701a81997-01-16 00:15:11 +00001187 /* XXX fileHandlerDict */
Guido van Rossum35d43371997-08-02 00:09:09 +00001188 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001189 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001190}
1191
Barry Warsawfa701a81997-01-16 00:15:11 +00001192
Guido van Rossum18468821994-06-20 07:49:28 +00001193static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001194Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001195 PyObject *self;
1196 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001197{
Barry Warsawfa701a81997-01-16 00:15:11 +00001198 PyObject *file;
1199 PyObject *idkey;
1200 PyObject *data;
1201 int id;
Guido van Rossum7bf15641998-05-22 18:28:17 +00001202 FHANDLE tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001203
Guido van Rossum35d43371997-08-02 00:09:09 +00001204 if (!PyArg_ParseTuple(args, "O", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001205 return NULL;
1206 id = GetFileNo(file);
1207 if (id < 0)
1208 return NULL;
1209
1210 if (!(idkey = PyInt_FromLong(id)))
1211 return NULL;
1212
1213 /* find and free the object created in the
1214 * Tkapp_CreateFileHandler() call
1215 */
1216 data = PyDict_GetItem(Tkapp_ClientDataDict, idkey);
1217 Py_XDECREF(data);
1218 PyDict_DelItem(Tkapp_ClientDataDict, idkey);
1219 Py_DECREF(idkey);
Guido van Rossum18468821994-06-20 07:49:28 +00001220
Guido van Rossum7bf15641998-05-22 18:28:17 +00001221 tfile = MAKEFHANDLE(id);
Barry Warsawfa701a81997-01-16 00:15:11 +00001222 /* Ought to check for null Tcl_File object... */
1223 Tcl_DeleteFileHandler(tfile);
Barry Warsawfa701a81997-01-16 00:15:11 +00001224 /* XXX fileHandlerDict */
Guido van Rossum35d43371997-08-02 00:09:09 +00001225 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001226 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001227}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001228#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001229
Barry Warsawfa701a81997-01-16 00:15:11 +00001230
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001231/**** Tktt Object (timer token) ****/
1232
1233staticforward PyTypeObject Tktt_Type;
1234
1235typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +00001236{
1237 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001238 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001239 PyObject *func;
1240}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001241TkttObject;
1242
1243static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001244Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001245 PyObject *self;
1246 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001247{
Barry Warsawfa701a81997-01-16 00:15:11 +00001248 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001249
Guido van Rossum35d43371997-08-02 00:09:09 +00001250 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001251 return NULL;
1252 if (v->func != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001253 Tcl_DeleteTimerHandler(v->token);
Barry Warsawfa701a81997-01-16 00:15:11 +00001254 PyMem_DEL(v->func);
1255 v->func = NULL;
1256 }
1257 Py_INCREF(Py_None);
1258 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001259}
1260
1261static PyMethodDef Tktt_methods[] =
1262{
Guido van Rossum35d43371997-08-02 00:09:09 +00001263 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001264 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001265};
1266
1267static TkttObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001268Tktt_New(token, func)
1269 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001270 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001271{
Barry Warsawfa701a81997-01-16 00:15:11 +00001272 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001273
Barry Warsawfa701a81997-01-16 00:15:11 +00001274 v = PyObject_NEW(TkttObject, &Tktt_Type);
1275 if (v == NULL)
1276 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001277
Barry Warsawfa701a81997-01-16 00:15:11 +00001278 v->token = token;
1279 v->func = func;
1280 Py_INCREF(v->func);
1281 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001282}
1283
1284static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001285Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001286 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001287{
Guido van Rossum35d43371997-08-02 00:09:09 +00001288 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001289}
1290
Guido van Rossum597ac201998-05-12 14:36:19 +00001291static PyObject *
1292Tktt_Repr(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001293 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001294{
Barry Warsawfa701a81997-01-16 00:15:11 +00001295 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001296 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001297
Guido van Rossum597ac201998-05-12 14:36:19 +00001298 sprintf(buf, "<tktimertoken at 0x%lx%s>", (long)v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001299 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001300 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001301}
1302
1303static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001304Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001305 PyObject *self;
1306 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001307{
Barry Warsawfa701a81997-01-16 00:15:11 +00001308 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001309}
1310
1311static PyTypeObject Tktt_Type =
1312{
Guido van Rossum35d43371997-08-02 00:09:09 +00001313 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001314 0, /*ob_size */
1315 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001316 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001317 0, /*tp_itemsize */
1318 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001319 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001320 Tktt_GetAttr, /*tp_getattr */
1321 0, /*tp_setattr */
1322 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001323 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001324 0, /*tp_as_number */
1325 0, /*tp_as_sequence */
1326 0, /*tp_as_mapping */
1327 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001328};
1329
Barry Warsawfa701a81997-01-16 00:15:11 +00001330
1331
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001332/** Timer Handler **/
1333
1334static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001335TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001336 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001337{
Barry Warsawfa701a81997-01-16 00:15:11 +00001338 PyObject *func = (PyObject *)clientData;
1339 PyObject *res = PyEval_CallObject(func, NULL);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001340
Barry Warsawfa701a81997-01-16 00:15:11 +00001341 if (res == NULL) {
1342 errorInCmd = 1;
1343 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1344 }
1345 else
1346 Py_DECREF(res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001347}
1348
1349static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001350Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001351 PyObject *self;
1352 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001353{
Barry Warsawfa701a81997-01-16 00:15:11 +00001354 int milliseconds;
1355 PyObject *func;
Guido van Rossum35d43371997-08-02 00:09:09 +00001356 Tcl_TimerToken token;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001357
Guido van Rossum35d43371997-08-02 00:09:09 +00001358 if (!PyArg_ParseTuple(args, "iO", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001359 return NULL;
1360 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001361 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001362 return NULL;
1363 }
Guido van Rossum35d43371997-08-02 00:09:09 +00001364 token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1365 (ClientData)func);
Barry Warsawfa701a81997-01-16 00:15:11 +00001366
1367 return (PyObject *) Tktt_New(token, func);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001368}
1369
Barry Warsawfa701a81997-01-16 00:15:11 +00001370
1371
Guido van Rossum18468821994-06-20 07:49:28 +00001372/** Event Loop **/
1373
Guido van Rossum18468821994-06-20 07:49:28 +00001374static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001375Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001376 PyObject *self;
1377 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001378{
Barry Warsawfa701a81997-01-16 00:15:11 +00001379 int threshold = 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001380
Barry Warsawfa701a81997-01-16 00:15:11 +00001381 if (!PyArg_ParseTuple(args, "|i", &threshold))
1382 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001383
Barry Warsawfa701a81997-01-16 00:15:11 +00001384 quitMainLoop = 0;
1385 while (Tk_GetNumMainWindows() > threshold &&
1386 !quitMainLoop &&
1387 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001388 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001389 int result;
Guido van Rossum54e20911997-09-28 05:52:41 +00001390#ifdef HAVE_PYTCL_WAITUNTILEVENT
Guido van Rossum35d43371997-08-02 00:09:09 +00001391 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
1392 if (PyErr_CheckSignals() != 0)
Barry Warsawfa701a81997-01-16 00:15:11 +00001393 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +00001394 if (result)
1395 continue;
1396 /* XXX It's not *quite* certain that this is
1397 thread-safe, but it seems *rather* safe as long as
1398 no two threads call mainloop() simultaneously. */
1399 Py_BEGIN_ALLOW_THREADS
Guido van Rossum54e20911997-09-28 05:52:41 +00001400 result = PyTcl_WaitUntilEvent();
Guido van Rossum35d43371997-08-02 00:09:09 +00001401 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001402#else
1403 result = Tcl_DoOneEvent(0);
1404#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001405 if (PyErr_CheckSignals() != 0)
1406 return NULL;
1407 if (result < 0)
1408 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001409 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001410 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001411
Barry Warsawfa701a81997-01-16 00:15:11 +00001412 if (errorInCmd) {
1413 errorInCmd = 0;
1414 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1415 excInCmd = valInCmd = trbInCmd = NULL;
1416 return NULL;
1417 }
1418 Py_INCREF(Py_None);
1419 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001420}
1421
1422static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001423Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001424 PyObject *self;
1425 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001426{
Guido van Rossum35d43371997-08-02 00:09:09 +00001427 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001428 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001429
Barry Warsawfa701a81997-01-16 00:15:11 +00001430 if (!PyArg_ParseTuple(args, "|i", &flags))
1431 return NULL;
1432
Guido van Rossum35d43371997-08-02 00:09:09 +00001433 rv = Tcl_DoOneEvent(flags);
Barry Warsawfa701a81997-01-16 00:15:11 +00001434 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001435}
1436
1437static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001438Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001439 PyObject *self;
1440 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001441{
1442
Guido van Rossum35d43371997-08-02 00:09:09 +00001443 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001444 return NULL;
1445
1446 quitMainLoop = 1;
1447 Py_INCREF(Py_None);
1448 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001449}
1450
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001451static PyObject *
1452Tkapp_InterpAddr(self, args)
1453 PyObject *self;
1454 PyObject *args;
1455{
1456
1457 if (!PyArg_ParseTuple(args, ""))
1458 return NULL;
1459
1460 return PyInt_FromLong((long)Tkapp_Interp(self));
1461}
1462
Barry Warsawfa701a81997-01-16 00:15:11 +00001463
1464
Guido van Rossum18468821994-06-20 07:49:28 +00001465/**** Tkapp Method List ****/
1466
1467static PyMethodDef Tkapp_methods[] =
1468{
Guido van Rossum35d43371997-08-02 00:09:09 +00001469 {"call", Tkapp_Call, 0},
1470 {"globalcall", Tkapp_GlobalCall, 0},
1471 {"eval", Tkapp_Eval, 1},
1472 {"globaleval", Tkapp_GlobalEval, 1},
1473 {"evalfile", Tkapp_EvalFile, 1},
1474 {"record", Tkapp_Record, 1},
1475 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1476 {"setvar", Tkapp_SetVar, 1},
1477 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1478 {"getvar", Tkapp_GetVar, 1},
1479 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1480 {"unsetvar", Tkapp_UnsetVar, 1},
1481 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1482 {"getint", Tkapp_GetInt, 1},
1483 {"getdouble", Tkapp_GetDouble, 1},
1484 {"getboolean", Tkapp_GetBoolean, 1},
1485 {"exprstring", Tkapp_ExprString, 1},
1486 {"exprlong", Tkapp_ExprLong, 1},
1487 {"exprdouble", Tkapp_ExprDouble, 1},
1488 {"exprboolean", Tkapp_ExprBoolean, 1},
1489 {"splitlist", Tkapp_SplitList, 1},
1490 {"split", Tkapp_Split, 1},
1491 {"merge", Tkapp_Merge, 0},
1492 {"createcommand", Tkapp_CreateCommand, 1},
1493 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001494#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001495 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1496 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001497#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001498 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001499 {"mainloop", Tkapp_MainLoop, 1},
1500 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001501 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001502 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001503 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001504};
1505
Barry Warsawfa701a81997-01-16 00:15:11 +00001506
1507
Guido van Rossum18468821994-06-20 07:49:28 +00001508/**** Tkapp Type Methods ****/
1509
1510static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001511Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001512 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001513{
Guido van Rossum35d43371997-08-02 00:09:09 +00001514 Tcl_DeleteInterp(Tkapp_Interp(self));
1515 PyMem_DEL(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001516 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001517}
1518
1519static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001520Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001521 PyObject *self;
1522 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001523{
Guido van Rossum35d43371997-08-02 00:09:09 +00001524 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001525}
1526
1527static PyTypeObject Tkapp_Type =
1528{
Guido van Rossum35d43371997-08-02 00:09:09 +00001529 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001530 0, /*ob_size */
1531 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001532 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001533 0, /*tp_itemsize */
1534 Tkapp_Dealloc, /*tp_dealloc */
1535 0, /*tp_print */
1536 Tkapp_GetAttr, /*tp_getattr */
1537 0, /*tp_setattr */
1538 0, /*tp_compare */
1539 0, /*tp_repr */
1540 0, /*tp_as_number */
1541 0, /*tp_as_sequence */
1542 0, /*tp_as_mapping */
1543 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001544};
1545
Barry Warsawfa701a81997-01-16 00:15:11 +00001546
1547
Guido van Rossum18468821994-06-20 07:49:28 +00001548/**** Tkinter Module ****/
1549
1550static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001551Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001552 PyObject *self;
1553 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001554{
Barry Warsawfa701a81997-01-16 00:15:11 +00001555 char *screenName = NULL;
1556 char *baseName = NULL;
1557 char *className = NULL;
1558 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001559
Guido van Rossum35d43371997-08-02 00:09:09 +00001560 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001561 if (baseName != NULL)
1562 baseName++;
1563 else
1564 baseName = Py_GetProgramName();
1565 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001566
Barry Warsawfa701a81997-01-16 00:15:11 +00001567 if (!PyArg_ParseTuple(args, "|zssi",
1568 &screenName, &baseName, &className,
1569 &interactive))
1570 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001571
Barry Warsawfa701a81997-01-16 00:15:11 +00001572 return (PyObject *) Tkapp_New(screenName, baseName, className,
1573 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001574}
1575
1576static PyMethodDef moduleMethods[] =
1577{
Barry Warsawfa701a81997-01-16 00:15:11 +00001578 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001579#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001580 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1581 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001582#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001583 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001584 {"mainloop", Tkapp_MainLoop, 1},
1585 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001586 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001587 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001588};
1589
Guido van Rossum7bf15641998-05-22 18:28:17 +00001590#ifdef WAIT_FOR_STDIN
1591#define WAITFLAG 0
1592
1593static int stdin_ready = 0;
1594
1595static void
1596MyFileProc(clientData, mask)
1597 void *clientData;
1598 int mask;
1599{
1600 stdin_ready = 1;
1601}
1602#else
1603#define WAITFLAG TCL_DONT_WAIT
1604#endif
1605
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001606static PyInterpreterState *event_interp = NULL;
1607
Guido van Rossum18468821994-06-20 07:49:28 +00001608static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001609EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00001610{
Guido van Rossuma59406a1997-10-10 17:39:19 +00001611 PyThreadState *tstate, *save_tstate;
Guido van Rossum7bf15641998-05-22 18:28:17 +00001612#ifdef WAIT_FOR_STDIN
1613 FHANDLE tfile = MAKEFHANDLE(((int)fileno(stdin)));
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001614
Guido van Rossum7bf15641998-05-22 18:28:17 +00001615 stdin_ready = 0;
1616 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
1617#endif
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001618 tstate = PyThreadState_New(event_interp);
Guido van Rossuma59406a1997-10-10 17:39:19 +00001619 save_tstate = PyThreadState_Swap(NULL);
1620 PyEval_RestoreThread(tstate);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001621#ifdef WAIT_FOR_STDIN
1622 while (!errorInCmd && !stdin_ready)
1623#endif
1624 Tcl_DoOneEvent(WAITFLAG);
Barry Warsawfa701a81997-01-16 00:15:11 +00001625 if (errorInCmd) {
1626 errorInCmd = 0;
1627 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1628 excInCmd = valInCmd = trbInCmd = NULL;
1629 PyErr_Print();
1630 }
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001631 PyThreadState_Clear(tstate);
Guido van Rossuma59406a1997-10-10 17:39:19 +00001632 PyEval_SaveThread();
1633 PyThreadState_Swap(save_tstate);
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001634 PyThreadState_Delete(tstate);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001635#ifdef WAIT_FOR_STDIN
1636 Tcl_DeleteFileHandler(tfile);
1637#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001638 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001639}
Guido van Rossum18468821994-06-20 07:49:28 +00001640
Guido van Rossum7bf15641998-05-22 18:28:17 +00001641static void
1642EnableEventHook()
1643{
1644 if (PyOS_InputHook == NULL) {
1645 event_interp = PyThreadState_Get()->interp;
1646 PyOS_InputHook = EventHook;
1647 }
1648}
1649
1650static void
1651DisableEventHook()
1652{
1653 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
1654 PyOS_InputHook = NULL;
1655 }
1656}
1657
Barry Warsawfa701a81997-01-16 00:15:11 +00001658
1659/* all errors will be checked in one fell swoop in init_tkinter() */
1660static void
1661ins_long(d, name, val)
1662 PyObject *d;
1663 char *name;
1664 long val;
1665{
1666 PyObject *v = PyInt_FromLong(val);
1667 if (v) {
1668 PyDict_SetItemString(d, name, v);
1669 Py_DECREF(v);
1670 }
1671}
1672static void
1673ins_string(d, name, val)
1674 PyObject *d;
1675 char *name;
1676 char *val;
1677{
1678 PyObject *v = PyString_FromString(val);
1679 if (v) {
1680 PyDict_SetItemString(d, name, v);
1681 Py_DECREF(v);
1682 }
1683}
1684
1685
Guido van Rossum18468821994-06-20 07:49:28 +00001686void
Guido van Rossum35d43371997-08-02 00:09:09 +00001687init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00001688{
Barry Warsawfa701a81997-01-16 00:15:11 +00001689 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001690
Barry Warsawfa701a81997-01-16 00:15:11 +00001691 Tkapp_Type.ob_type = &PyType_Type;
1692 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossumae92f011996-08-21 19:03:36 +00001693
Barry Warsawfa701a81997-01-16 00:15:11 +00001694 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001695
Barry Warsawfa701a81997-01-16 00:15:11 +00001696 d = PyModule_GetDict(m);
1697 Tkinter_TclError = Py_BuildValue("s", "TclError");
1698 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00001699
Guido van Rossum35d43371997-08-02 00:09:09 +00001700 ins_long(d, "READABLE", TCL_READABLE);
1701 ins_long(d, "WRITABLE", TCL_WRITABLE);
1702 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
1703 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
1704 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
1705 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
1706 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
1707 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
1708 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001709 ins_string(d, "TK_VERSION", TK_VERSION);
1710 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00001711
Guido van Rossum83551bf1997-09-13 00:44:23 +00001712 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
1713 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
1714
Barry Warsawfa701a81997-01-16 00:15:11 +00001715 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001716 return;
1717
Guido van Rossum26216371998-04-20 18:47:52 +00001718#if TKMAJORMINOR >= 8000
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001719 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00001720#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001721
Jack Jansen34cc5c31995-10-31 16:15:12 +00001722#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001723 /*
1724 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
1725 ** Most of the initializations in that routine (toolbox init calls and
1726 ** such) have already been done for us, so we only need these.
1727 */
1728#if TKMAJORMINOR >= 8000
1729 tcl_macQdPtr = &qd;
1730#endif
1731
1732 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00001733#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00001734 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001735#endif /* GENERATINGCFM */
1736#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001737}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001738
Guido van Rossumec22c921996-02-25 04:50:29 +00001739
Barry Warsawfa701a81997-01-16 00:15:11 +00001740
Guido van Rossum9722ad81995-09-22 23:49:28 +00001741#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001742
1743/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001744** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001745*/
1746
Guido van Rossum9722ad81995-09-22 23:49:28 +00001747void
1748panic(char * format, ...)
1749{
Barry Warsawfa701a81997-01-16 00:15:11 +00001750 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001751
Barry Warsawfa701a81997-01-16 00:15:11 +00001752 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001753
Guido van Rossumb41addf1998-05-12 15:02:41 +00001754 vPySys_WriteStderr(format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001755 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001756
Barry Warsawfa701a81997-01-16 00:15:11 +00001757 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001758
Barry Warsawfa701a81997-01-16 00:15:11 +00001759 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00001760}
Jack Jansen40b546d1995-11-14 10:34:45 +00001761
Guido van Rossumec22c921996-02-25 04:50:29 +00001762/*
1763** Pass events to SIOUX before passing them to Tk.
1764*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001765
Guido van Rossumec22c921996-02-25 04:50:29 +00001766static int
1767PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00001768 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001769{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00001770 WindowPtr frontwin;
1771 /*
1772 ** Sioux eats too many events, so we don't pass it everything.
1773 ** We always pass update events to Sioux, and we only pass other events if
1774 ** the Sioux window is frontmost. This means that Tk menus don't work
1775 ** in that case, but at least we can scroll the sioux window.
1776 ** Note that the SIOUXIsAppWindow() routine we use here is not really
1777 ** part of the external interface of Sioux...
1778 */
1779 frontwin = FrontWindow();
1780 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
1781 if (SIOUXHandleOneEvent(eventPtr))
1782 return 0; /* Nothing happened to the Tcl event queue */
1783 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001784 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001785}
1786
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001787#if defined(USE_GUSI) && TKMAJORMINOR < 8000
Guido van Rossum290283b1997-06-02 22:16:43 +00001788/*
1789 * For Python we have to override this routine (from TclMacNotify),
1790 * since we use GUSI for our sockets, not Tcl streams. Hence, we have
1791 * to use GUSI select to see whether our socket is ready. Note that
1792 * createfilehandler (above) sets the type to TCL_UNIX_FD for our
1793 * files and sockets.
1794 *
1795 * NOTE: this code was lifted from Tcl 7.6, it may need to be modified
1796 * for other versions. */
1797
1798int
1799Tcl_FileReady(file, mask)
1800 Tcl_File file; /* File handle for a stream. */
1801 int mask; /* OR'ed combination of TCL_READABLE,
1802 * TCL_WRITABLE, and TCL_EXCEPTION:
1803 * indicates conditions caller cares about. */
1804{
1805 int type;
1806 int fd;
1807
1808 fd = (int) Tcl_GetFileInfo(file, &type);
1809
1810 if (type == TCL_MAC_SOCKET) {
1811 return TclMacSocketReady(file, mask);
1812 } else if (type == TCL_MAC_FILE) {
1813 /*
1814 * Under the Macintosh, files are always ready, so we just
1815 * return the mask that was passed in.
1816 */
1817
1818 return mask;
1819 } else if (type == TCL_UNIX_FD) {
1820 fd_set readset, writeset, excset;
1821 struct timeval tv;
1822
1823 FD_ZERO(&readset);
1824 FD_ZERO(&writeset);
1825 FD_ZERO(&excset);
1826
1827 if ( mask & TCL_READABLE ) FD_SET(fd, &readset);
1828 if ( mask & TCL_WRITABLE ) FD_SET(fd, &writeset);
1829 if ( mask & TCL_EXCEPTION ) FD_SET(fd, &excset);
1830
1831 tv.tv_sec = tv.tv_usec = 0;
1832 if ( select(fd+1, &readset, &writeset, &excset, &tv) <= 0 )
1833 return 0;
1834
1835 mask = 0;
1836 if ( FD_ISSET(fd, &readset) ) mask |= TCL_READABLE;
1837 if ( FD_ISSET(fd, &writeset) ) mask |= TCL_WRITABLE;
1838 if ( FD_ISSET(fd, &excset) ) mask |= TCL_EXCEPTION;
1839
1840 return mask;
1841 }
1842
1843 return 0;
1844}
1845#endif /* USE_GUSI */
1846
Guido van Rossumec22c921996-02-25 04:50:29 +00001847#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001848
1849/*
1850** Additional Mac specific code for dealing with shared libraries.
1851*/
1852
1853#include <Resources.h>
1854#include <CodeFragments.h>
1855
1856static int loaded_from_shlib = 0;
1857static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001858
Jack Jansen34cc5c31995-10-31 16:15:12 +00001859/*
1860** If this module is dynamically loaded the following routine should
1861** be the init routine. It takes care of adding the shared library to
1862** the resource-file chain, so that the tk routines can find their
1863** resources.
1864*/
1865OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001866init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00001867{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00001868 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00001869 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001870 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001871 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1872 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00001873 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00001874 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1875 loaded_from_shlib = 1;
1876 }
1877 return noErr;
1878}
1879
1880/*
1881** Insert the library resources into the search path. Put them after
1882** the resources from the application. Again, we ignore errors.
1883*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001884static
Jack Jansen34cc5c31995-10-31 16:15:12 +00001885mac_addlibresources()
1886{
1887 if ( !loaded_from_shlib )
1888 return;
1889 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1890}
1891
Guido van Rossumec22c921996-02-25 04:50:29 +00001892#endif /* GENERATINGCFM */
1893#endif /* macintosh */