blob: ba95310bcc60eb249d7dcb6dc8c7ee7f10d7fe83 [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:
38 This should work with any version from Tcl 4.0 / Tck 7.4.
39 Do not use older versions.
40
41 Mac and Windows:
42 Use Tcl 4.1p1 / Tk 7.5p1 or possibly newer.
43 It does not seem to work reliably with the original 4.1/7.5
44 release. (4.0/7.4 were never released for these platforms.)
45*/
46
Guido van Rossum9722ad81995-09-22 23:49:28 +000047#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000048#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000049
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000050#ifdef macintosh
51#define MAC_TCL
52#endif
53
Guido van Rossum18468821994-06-20 07:49:28 +000054#include <tcl.h>
55#include <tk.h>
56
Guido van Rossum32aa1a71996-07-31 19:51:15 +000057extern char *Py_GetProgramName ();
Guido van Rossumd308e2b1994-07-07 09:25:12 +000058
Guido van Rossum9722ad81995-09-22 23:49:28 +000059/* Internal declarations from tkInt.h. */
60#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
61extern int Tk_GetNumMainWindows();
62#else
Guido van Rossum18468821994-06-20 07:49:28 +000063extern int tk_NumMainWindows;
Guido van Rossum9722ad81995-09-22 23:49:28 +000064#define Tk_GetNumMainWindows() (tk_NumMainWindows)
Guido van Rossumdfd428d1996-02-25 04:46:40 +000065#define NEED_TKCREATEMAINWINDOW 1
Guido van Rossum9722ad81995-09-22 23:49:28 +000066#endif
67
68#if TK_MAJOR_VERSION < 4
Guido van Rossumd308e2b1994-07-07 09:25:12 +000069extern struct { Tk_Window win; } *tkMainWindowList;
Guido van Rossum9722ad81995-09-22 23:49:28 +000070#endif
Guido van Rossum18468821994-06-20 07:49:28 +000071
Guido van Rossumec22c921996-02-25 04:50:29 +000072#ifdef macintosh
73
74/*
75** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +000076** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +000077*/
78
Guido van Rossum7ffa7611996-08-13 21:10:16 +000079/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +000080#define FREECAST (char *)
81
Guido van Rossumec22c921996-02-25 04:50:29 +000082#include <Events.h> /* For EventRecord */
83
84typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
85void TclMacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
86int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
87
88staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
89
90#endif /* macintosh */
91
Guido van Rossum97867b21996-08-08 19:09:53 +000092#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +000093#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +000094#endif
95
Guido van Rossum18468821994-06-20 07:49:28 +000096/**** Tkapp Object Declaration ****/
97
98staticforward PyTypeObject Tkapp_Type;
99
100typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +0000101{
102 PyObject_HEAD
103 Tcl_Interp *interp;
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000104#ifdef NEED_TKCREATEMAINWINDOW
Barry Warsawfa701a81997-01-16 00:15:11 +0000105 Tk_Window tkwin;
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000106#endif
Barry Warsawfa701a81997-01-16 00:15:11 +0000107}
Guido van Rossum18468821994-06-20 07:49:28 +0000108TkappObject;
109
110#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000111#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +0000112#define Tkapp_Tkwin(v) (((TkappObject *) (v))->tkwin)
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000113#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000114#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
115#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
116
117#define DEBUG_REFCNT(v) (printf ("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000118(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000119
Barry Warsawfa701a81997-01-16 00:15:11 +0000120
121
Guido van Rossum18468821994-06-20 07:49:28 +0000122/**** Error Handling ****/
123
124static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000125static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000126static int errorInCmd = 0;
127static PyObject *excInCmd;
128static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000129static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000130
Barry Warsawfa701a81997-01-16 00:15:11 +0000131
132
Guido van Rossum18468821994-06-20 07:49:28 +0000133static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000134Tkinter_Error(v)
135 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000136{
Barry Warsawfa701a81997-01-16 00:15:11 +0000137 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
138 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000139}
140
Barry Warsawfa701a81997-01-16 00:15:11 +0000141
Guido van Rossum18468821994-06-20 07:49:28 +0000142int
Barry Warsawfa701a81997-01-16 00:15:11 +0000143PythonCmd_Error(interp)
144 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000145{
Barry Warsawfa701a81997-01-16 00:15:11 +0000146 errorInCmd = 1;
147 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
148 return TCL_ERROR;
Guido van Rossum18468821994-06-20 07:49:28 +0000149}
150
Barry Warsawfa701a81997-01-16 00:15:11 +0000151
152
Guido van Rossum18468821994-06-20 07:49:28 +0000153/**** Utils ****/
Guido van Rossum18468821994-06-20 07:49:28 +0000154static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000155AsString(value, tmp)
156 PyObject *value;
157 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000158{
Barry Warsawfa701a81997-01-16 00:15:11 +0000159 if (PyString_Check (value))
160 return PyString_AsString (value);
161 else {
162 PyObject *v = PyObject_Str(value);
163 PyList_Append(tmp, v);
164 Py_DECREF(v);
165 return PyString_AsString(v);
166 }
Guido van Rossum18468821994-06-20 07:49:28 +0000167}
168
Barry Warsawfa701a81997-01-16 00:15:11 +0000169
170
Guido van Rossum18468821994-06-20 07:49:28 +0000171#define ARGSZ 64
172
173static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000174Merge(args)
175 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000176{
Barry Warsawfa701a81997-01-16 00:15:11 +0000177 PyObject *tmp = NULL;
178 char *argvStore[ARGSZ];
179 char **argv = NULL;
180 int fvStore[ARGSZ];
181 int *fv = NULL;
182 int argc = 0, i;
183 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000184
Barry Warsawfa701a81997-01-16 00:15:11 +0000185 if (!(tmp = PyList_New(0)))
186 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000187
Barry Warsawfa701a81997-01-16 00:15:11 +0000188 argv = argvStore;
189 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000190
Barry Warsawfa701a81997-01-16 00:15:11 +0000191 if (args == NULL)
192 argc = 0;
193
194 else if (!PyTuple_Check(args)) {
195 argc = 1;
196 fv[0] = 0;
197 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000198 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000199 else {
200 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000201
Barry Warsawfa701a81997-01-16 00:15:11 +0000202 if (argc > ARGSZ) {
203 argv = (char **)ckalloc(argc * sizeof (char *));
204 fv = (int *)ckalloc(argc * sizeof (int));
205 if (argv == NULL || fv == NULL) {
206 PyErr_NoMemory();
207 goto finally;
208 }
209 }
210
211 for (i = 0; i < argc; i++) {
212 PyObject *v = PyTuple_GetItem(args, i);
213 if (PyTuple_Check(v)) {
214 fv[i] = 1;
215 if (!(argv[i] = Merge(v)))
216 goto finally;
217 }
218 else if (v == Py_None) {
219 argc = i;
220 break;
221 }
222 else {
223 fv[i] = 0;
224 argv[i] = AsString(v, tmp);
225 }
226 }
Guido van Rossum18468821994-06-20 07:49:28 +0000227 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000228 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000229
Barry Warsawfa701a81997-01-16 00:15:11 +0000230 finally:
231 for (i = 0; i < argc; i++)
232 if (fv[i]) {
233 ckfree(argv[i]);
234 }
235 if (argv != argvStore)
236 ckfree(FREECAST argv);
237 if (fv != fvStore)
238 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000239
Barry Warsawfa701a81997-01-16 00:15:11 +0000240 Py_DECREF(tmp);
241 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000242}
243
Barry Warsawfa701a81997-01-16 00:15:11 +0000244
245
Guido van Rossum18468821994-06-20 07:49:28 +0000246static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000247Split(self, list)
248 PyObject *self;
249 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000250{
Barry Warsawfa701a81997-01-16 00:15:11 +0000251 int argc;
252 char **argv;
253 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000254
Barry Warsawfa701a81997-01-16 00:15:11 +0000255 if (list == NULL) {
256 Py_INCREF(Py_None);
257 return Py_None;
258 }
Guido van Rossum18468821994-06-20 07:49:28 +0000259
Barry Warsawfa701a81997-01-16 00:15:11 +0000260 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
261 {
262 /* Not a list.
263 * Could be a quoted string containing funnies, e.g. {"}.
264 * Return the string itself.
265 */
266 PyErr_Clear();
267 return PyString_FromString(list);
268 }
Guido van Rossum18468821994-06-20 07:49:28 +0000269
Barry Warsawfa701a81997-01-16 00:15:11 +0000270 if (argc == 0)
271 v = PyString_FromString("");
272 else if (argc == 1)
273 v = PyString_FromString(argv[0]);
274 else if ((v = PyTuple_New (argc)) != NULL) {
275 int i;
276 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000277
Barry Warsawfa701a81997-01-16 00:15:11 +0000278 for (i = 0; i < argc; i++) {
279 if ((w = Split(self, argv[i])) == NULL) {
280 Py_DECREF(v);
281 v = NULL;
282 break;
283 }
284 PyTuple_SetItem(v, i, w);
285 }
286 }
287 ckfree (FREECAST argv);
288 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000289}
290
Barry Warsawfa701a81997-01-16 00:15:11 +0000291
292
Guido van Rossum18468821994-06-20 07:49:28 +0000293/**** Tkapp Object ****/
294
295#ifndef WITH_APPINIT
296int
297Tcl_AppInit (interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000298 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000299{
Barry Warsawfa701a81997-01-16 00:15:11 +0000300 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000301
Barry Warsawfa701a81997-01-16 00:15:11 +0000302 main = Tk_MainWindow(interp);
303 if (Tcl_Init(interp) == TCL_ERROR) {
304 fprintf(stderr, "Tcl_Init error: %s\n", interp->result);
305 return TCL_ERROR;
306 }
307 if (Tk_Init(interp) == TCL_ERROR) {
308 fprintf(stderr, "Tk_Init error: %s\n", interp->result);
309 return TCL_ERROR;
310 }
311 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000312}
313#endif /* !WITH_APPINIT */
314
Guido van Rossum18468821994-06-20 07:49:28 +0000315
Barry Warsawfa701a81997-01-16 00:15:11 +0000316
317
318/* Initialize the Tk application; see the `main' function in
319 * `tkMain.c'.
320 */
321static TkappObject *
322Tkapp_New(screenName, baseName, className, interactive)
323 char *screenName;
324 char *baseName;
325 char *className;
326 int interactive;
327{
328 TkappObject *v;
329 char *argv0;
330
331 v = PyObject_NEW(TkappObject, &Tkapp_Type);
332 if (v == NULL)
333 return NULL;
334
335 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000336
337#ifdef NEED_TKCREATEMAINWINDOW
Barry Warsawfa701a81997-01-16 00:15:11 +0000338 v->tkwin = Tk_CreateMainWindow(v->interp, screenName,
339 baseName, className);
340 if (v->tkwin == NULL)
341 return (TkappObject *)Tkinter_Error((PyObject *) v);
Guido van Rossum18468821994-06-20 07:49:28 +0000342
Barry Warsawfa701a81997-01-16 00:15:11 +0000343 Tk_GeometryRequest(v->tkwin, 200, 200);
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000344#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000345
Barry Warsawfa701a81997-01-16 00:15:11 +0000346 if (screenName != NULL)
347 Tcl_SetVar2(v->interp, "env", "DISPLAY",
348 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000349
Barry Warsawfa701a81997-01-16 00:15:11 +0000350 if (interactive)
351 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
352 else
353 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000354
Barry Warsawfa701a81997-01-16 00:15:11 +0000355 /* This is used to get the application class for Tk 4.1 and up */
356 argv0 = (char*)ckalloc(strlen(className) + 1);
357 if (!argv0) {
358 PyErr_NoMemory();
359 Py_DECREF(v);
360 return NULL;
361 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000362
Barry Warsawfa701a81997-01-16 00:15:11 +0000363 strcpy(argv0, className);
364 if (isupper(argv0[0]))
365 argv0[0] = tolower(argv0[0]);
366 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
367 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000368
Barry Warsawfa701a81997-01-16 00:15:11 +0000369 if (Tcl_AppInit(v->interp) != TCL_OK)
370 return (TkappObject *)Tkinter_Error(v);
371
372 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000373}
374
Barry Warsawfa701a81997-01-16 00:15:11 +0000375
376
Guido van Rossum18468821994-06-20 07:49:28 +0000377/** Tcl Eval **/
378
379static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000380Tkapp_Call(self, args)
381 PyObject *self;
382 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000383{
Barry Warsawfa701a81997-01-16 00:15:11 +0000384 char *cmd = Merge(args);
385 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000386
Barry Warsawfa701a81997-01-16 00:15:11 +0000387 if (!cmd)
388 PyErr_SetString(Tkinter_TclError, "merge failed");
Guido van Rossum18468821994-06-20 07:49:28 +0000389
Barry Warsawfa701a81997-01-16 00:15:11 +0000390 else if (Tcl_Eval(Tkapp_Interp(self), cmd) == TCL_ERROR)
391 res = Tkinter_Error(self);
392
393 else
394 res = PyString_FromString(Tkapp_Result(self));
395
396 if (cmd)
397 ckfree(cmd);
398
399 return res;
400}
401
402
403static PyObject *
404Tkapp_GlobalCall(self, args)
405 PyObject *self;
406 PyObject *args;
407{
408 char *cmd = Merge(args);
409 PyObject *res = NULL;
410
411
412 if (!cmd)
413 PyErr_SetString(Tkinter_TclError, "merge failed");
414
415 else if (Tcl_GlobalEval(Tkapp_Interp(self), cmd) == TCL_ERROR)
416 res = Tkinter_Error(self);
417 else
418 res = PyString_FromString(Tkapp_Result(self));
419
420 if (cmd)
421 ckfree(cmd);
422
423 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000424}
425
426static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000427Tkapp_Eval(self, args)
428 PyObject *self;
429 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000430{
Barry Warsawfa701a81997-01-16 00:15:11 +0000431 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000432
Barry Warsawfa701a81997-01-16 00:15:11 +0000433 if (!PyArg_Parse (args, "s", &script))
434 return NULL;
435
436 if (Tcl_Eval(Tkapp_Interp(self), script) == TCL_ERROR)
437 return Tkinter_Error(self);
438
439 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000440}
441
442static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000443Tkapp_GlobalEval(self, args)
444 PyObject *self;
445 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000446{
Barry Warsawfa701a81997-01-16 00:15:11 +0000447 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000448
Barry Warsawfa701a81997-01-16 00:15:11 +0000449 if (!PyArg_Parse(args, "s", &script))
450 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000451
Barry Warsawfa701a81997-01-16 00:15:11 +0000452 if (Tcl_GlobalEval(Tkapp_Interp(self), script) == TCL_ERROR)
453 return Tkinter_Error (self);
Guido van Rossum18468821994-06-20 07:49:28 +0000454
Barry Warsawfa701a81997-01-16 00:15:11 +0000455 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000456}
457
458static PyObject *
459Tkapp_EvalFile (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000460 PyObject *self;
461 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000462{
Barry Warsawfa701a81997-01-16 00:15:11 +0000463 char *fileName;
Guido van Rossum18468821994-06-20 07:49:28 +0000464
Barry Warsawfa701a81997-01-16 00:15:11 +0000465 if (!PyArg_Parse(args, "s", &fileName))
466 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000467
Barry Warsawfa701a81997-01-16 00:15:11 +0000468 if (Tcl_EvalFile(Tkapp_Interp(self), fileName) == TCL_ERROR)
469 return Tkinter_Error (self);
Guido van Rossum18468821994-06-20 07:49:28 +0000470
Barry Warsawfa701a81997-01-16 00:15:11 +0000471 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000472}
473
474static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000475Tkapp_Record(self, args)
476 PyObject *self;
477 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000478{
Barry Warsawfa701a81997-01-16 00:15:11 +0000479 char *script;
Guido van Rossum18468821994-06-20 07:49:28 +0000480
Barry Warsawfa701a81997-01-16 00:15:11 +0000481 if (!PyArg_Parse(args, "s", &script))
482 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000483
Barry Warsawfa701a81997-01-16 00:15:11 +0000484 if (TCL_ERROR == Tcl_RecordAndEval(Tkapp_Interp(self),
485 script, TCL_NO_EVAL))
486 return Tkinter_Error (self);
Guido van Rossum18468821994-06-20 07:49:28 +0000487
Barry Warsawfa701a81997-01-16 00:15:11 +0000488 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000489}
490
491static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000492Tkapp_AddErrorInfo(self, args)
493 PyObject *self;
494 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000495{
Barry Warsawfa701a81997-01-16 00:15:11 +0000496 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000497
Barry Warsawfa701a81997-01-16 00:15:11 +0000498 if (!PyArg_Parse (args, "s", &msg))
499 return NULL;
500 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum18468821994-06-20 07:49:28 +0000501
Barry Warsawfa701a81997-01-16 00:15:11 +0000502 Py_INCREF(Py_None);
503 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000504}
505
Barry Warsawfa701a81997-01-16 00:15:11 +0000506
507
Guido van Rossum18468821994-06-20 07:49:28 +0000508/** Tcl Variable **/
509
510static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000511SetVar(self, args, flags)
512 PyObject *self;
513 PyObject *args;
514 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000515{
Barry Warsawfa701a81997-01-16 00:15:11 +0000516 char *name1, *name2, *ok;
517 PyObject *newValue;
518 PyObject *tmp = PyList_New(0);
Guido van Rossum18468821994-06-20 07:49:28 +0000519
Barry Warsawfa701a81997-01-16 00:15:11 +0000520 if (!tmp)
521 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000522
Barry Warsawfa701a81997-01-16 00:15:11 +0000523 if (PyArg_Parse(args, "(sO)", &name1, &newValue))
524 /* XXX Merge? */
525 ok = Tcl_SetVar(Tkapp_Interp (self), name1,
526 AsString (newValue, tmp), flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000527
Barry Warsawfa701a81997-01-16 00:15:11 +0000528 else if (PyArg_Parse(args, "(ssO)", &name1, &name2, &newValue))
529 ok = Tcl_SetVar2(Tkapp_Interp (self), name1, name2,
530 AsString (newValue, tmp), flags);
531 else {
532 Py_DECREF (tmp);
533 return NULL;
534 }
535 Py_DECREF (tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000536
Barry Warsawfa701a81997-01-16 00:15:11 +0000537 if (!ok)
538 return Tkinter_Error(self);
539
540 Py_INCREF(Py_None);
541 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000542}
543
544static PyObject *
545Tkapp_SetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000546 PyObject *self;
547 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000548{
Barry Warsawfa701a81997-01-16 00:15:11 +0000549 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000550}
551
552static PyObject *
553Tkapp_GlobalSetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000554 PyObject *self;
555 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000556{
Barry Warsawfa701a81997-01-16 00:15:11 +0000557 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000558}
559
Barry Warsawfa701a81997-01-16 00:15:11 +0000560
561
Guido van Rossum18468821994-06-20 07:49:28 +0000562static PyObject *
563GetVar (self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000564 PyObject *self;
565 PyObject *args;
566 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000567{
Barry Warsawfa701a81997-01-16 00:15:11 +0000568 char *name1, *name2, *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000569
Barry Warsawfa701a81997-01-16 00:15:11 +0000570 if (PyArg_Parse(args, "s", &name1))
571 s = Tcl_GetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000572
Barry Warsawfa701a81997-01-16 00:15:11 +0000573 else if (PyArg_Parse(args, "(ss)", &name1, &name2))
574 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
575 else
576 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000577
Barry Warsawfa701a81997-01-16 00:15:11 +0000578 if (s == NULL)
579 return Tkinter_Error(self);
580
581 return PyString_FromString (s);
Guido van Rossum18468821994-06-20 07:49:28 +0000582}
583
584static PyObject *
585Tkapp_GetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000586 PyObject *self;
587 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000588{
Barry Warsawfa701a81997-01-16 00:15:11 +0000589 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000590}
591
592static PyObject *
593Tkapp_GlobalGetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000594 PyObject *self;
595 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000596{
Barry Warsawfa701a81997-01-16 00:15:11 +0000597 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000598}
599
Barry Warsawfa701a81997-01-16 00:15:11 +0000600
601
Guido van Rossum18468821994-06-20 07:49:28 +0000602static PyObject *
603UnsetVar (self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000604 PyObject *self;
605 PyObject *args;
606 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000607{
Barry Warsawfa701a81997-01-16 00:15:11 +0000608 char *name1, *name2;
609 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000610
Barry Warsawfa701a81997-01-16 00:15:11 +0000611 if (PyArg_Parse(args, "s", &name1))
612 code = Tcl_UnsetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000613
Barry Warsawfa701a81997-01-16 00:15:11 +0000614 else if (PyArg_Parse(args, "(ss)", &name1, &name2))
615 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
616 else
617 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000618
Barry Warsawfa701a81997-01-16 00:15:11 +0000619 if (code == TCL_ERROR)
620 return Tkinter_Error (self);
621
622 Py_INCREF(Py_None);
623 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000624}
625
626static PyObject *
627Tkapp_UnsetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000628 PyObject *self;
629 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000630{
Barry Warsawfa701a81997-01-16 00:15:11 +0000631 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000632}
633
634static PyObject *
635Tkapp_GlobalUnsetVar (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000636 PyObject *self;
637 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000638{
Barry Warsawfa701a81997-01-16 00:15:11 +0000639 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000640}
641
Barry Warsawfa701a81997-01-16 00:15:11 +0000642
643
Guido van Rossum18468821994-06-20 07:49:28 +0000644/** Tcl to Python **/
645
646static PyObject *
647Tkapp_GetInt (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000648 PyObject *self;
649 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000650{
Barry Warsawfa701a81997-01-16 00:15:11 +0000651 char *s;
652 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000653
Barry Warsawfa701a81997-01-16 00:15:11 +0000654 if (!PyArg_Parse(args, "s", &s))
655 return NULL;
656 if (Tcl_GetInt(Tkapp_Interp (self), s, &v) == TCL_ERROR)
657 return Tkinter_Error(self);
658 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000659}
660
661static PyObject *
662Tkapp_GetDouble (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000663 PyObject *self;
664 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000665{
Barry Warsawfa701a81997-01-16 00:15:11 +0000666 char *s;
667 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000668
Barry Warsawfa701a81997-01-16 00:15:11 +0000669 if (!PyArg_Parse(args, "s", &s))
670 return NULL;
671 if (Tcl_GetDouble(Tkapp_Interp (self), s, &v) == TCL_ERROR)
672 return Tkinter_Error(self);
673 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000674}
675
676static PyObject *
677Tkapp_GetBoolean (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000678 PyObject *self;
679 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000680{
Barry Warsawfa701a81997-01-16 00:15:11 +0000681 char *s;
682 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000683
Barry Warsawfa701a81997-01-16 00:15:11 +0000684 if (!PyArg_Parse(args, "s", &s))
685 return NULL;
686 if (Tcl_GetBoolean(Tkapp_Interp (self), s, &v) == TCL_ERROR)
687 return Tkinter_Error (self);
688 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000689}
690
691static PyObject *
692Tkapp_ExprString (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000693 PyObject *self;
694 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000695{
Barry Warsawfa701a81997-01-16 00:15:11 +0000696 char *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000697
Barry Warsawfa701a81997-01-16 00:15:11 +0000698 if (!PyArg_Parse(args, "s", &s))
699 return NULL;
700 if (Tcl_ExprString (Tkapp_Interp (self), s) == TCL_ERROR)
701 return Tkinter_Error(self);
702 return Py_BuildValue("s", Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000703}
704
705static PyObject *
706Tkapp_ExprLong (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000707 PyObject *self;
708 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000709{
Barry Warsawfa701a81997-01-16 00:15:11 +0000710 char *s;
711 long v;
Guido van Rossum18468821994-06-20 07:49:28 +0000712
Barry Warsawfa701a81997-01-16 00:15:11 +0000713 if (!PyArg_Parse(args, "s", &s))
714 return NULL;
715 if (Tcl_ExprLong(Tkapp_Interp(self), s, &v) == TCL_ERROR)
716 return Tkinter_Error(self);
717 return Py_BuildValue("l", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000718}
719
720static PyObject *
721Tkapp_ExprDouble (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000722 PyObject *self;
723 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000724{
Barry Warsawfa701a81997-01-16 00:15:11 +0000725 char *s;
726 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000727
Barry Warsawfa701a81997-01-16 00:15:11 +0000728 if (!PyArg_Parse(args, "s", &s))
729 return NULL;
730 if (Tcl_ExprDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
731 return Tkinter_Error(self);
732 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000733}
734
735static PyObject *
736Tkapp_ExprBoolean (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000737 PyObject *self;
738 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000739{
Barry Warsawfa701a81997-01-16 00:15:11 +0000740 char *s;
741 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000742
Barry Warsawfa701a81997-01-16 00:15:11 +0000743 if (!PyArg_Parse(args, "s", &s))
744 return NULL;
745 if (Tcl_ExprBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
746 return Tkinter_Error(self);
747 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000748}
749
Barry Warsawfa701a81997-01-16 00:15:11 +0000750
751
Guido van Rossum18468821994-06-20 07:49:28 +0000752static PyObject *
753Tkapp_SplitList (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000754 PyObject *self;
755 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000756{
Barry Warsawfa701a81997-01-16 00:15:11 +0000757 char *list;
758 int argc;
759 char **argv;
760 PyObject *v;
761 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000762
Barry Warsawfa701a81997-01-16 00:15:11 +0000763 if (!PyArg_Parse(args, "s", &list))
764 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000765
Barry Warsawfa701a81997-01-16 00:15:11 +0000766 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
767 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000768
Barry Warsawfa701a81997-01-16 00:15:11 +0000769 if (!(v = PyTuple_New(argc)))
770 return NULL;
771
772 for (i = 0; i < argc; i++) {
773 PyObject *s = PyString_FromString(argv[i]);
774 if (!s || PyTuple_SetItem(v, i, s)) {
775 Py_DECREF(v);
776 v = NULL;
777 goto finally;
778 }
779 }
Guido van Rossum18468821994-06-20 07:49:28 +0000780
Barry Warsawfa701a81997-01-16 00:15:11 +0000781 finally:
782 ckfree(FREECAST argv);
783 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000784}
785
786static PyObject *
787Tkapp_Split (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000788 PyObject *self;
789 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000790{
Barry Warsawfa701a81997-01-16 00:15:11 +0000791 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000792
Barry Warsawfa701a81997-01-16 00:15:11 +0000793 if (!PyArg_Parse(args, "s", &list))
794 return NULL;
795 return Split(self, list);
Guido van Rossum18468821994-06-20 07:49:28 +0000796}
797
798static PyObject *
799Tkapp_Merge (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000800 PyObject *self;
801 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000802{
Barry Warsawfa701a81997-01-16 00:15:11 +0000803 char *s = Merge(args);
804 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000805
Barry Warsawfa701a81997-01-16 00:15:11 +0000806 if (s) {
807 res = PyString_FromString(s);
808 ckfree(s);
809 }
810 else
811 PyErr_SetString(Tkinter_TclError, "merge failed");
812
813 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000814}
815
Barry Warsawfa701a81997-01-16 00:15:11 +0000816
817
Guido van Rossum18468821994-06-20 07:49:28 +0000818/** Tcl Command **/
819
820/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +0000821 * function or method.
822 */
Guido van Rossum18468821994-06-20 07:49:28 +0000823static int
824PythonCmd (clientData, interp, argc, argv)
Barry Warsawfa701a81997-01-16 00:15:11 +0000825 ClientData clientData; /* Is (self, func) */
826 Tcl_Interp *interp;
827 int argc;
828 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +0000829{
Barry Warsawfa701a81997-01-16 00:15:11 +0000830 PyObject *self, *func, *arg, *res, *tmp;
831 int i;
Guido van Rossum18468821994-06-20 07:49:28 +0000832
Barry Warsawfa701a81997-01-16 00:15:11 +0000833 /* TBD: no error checking here since we know, via the
834 * Tkapp_CreateCommand() that the client data is a two-tuple
835 */
836 self = PyTuple_GetItem((PyObject *) clientData, 0);
837 func = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000838
Barry Warsawfa701a81997-01-16 00:15:11 +0000839 /* Create argument list (argv1, ..., argvN) */
840 if (!(arg = PyTuple_New(argc - 1)))
841 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000842
Barry Warsawfa701a81997-01-16 00:15:11 +0000843 for (i = 0; i < (argc - 1); i++) {
844 PyObject *s = PyString_FromString(argv[i + 1]);
845 if (!s || PyTuple_SetItem(arg, i, s)) {
846 Py_DECREF(arg);
847 PythonCmd_Error(interp);
848 }
849 }
850 res = PyEval_CallObject(func, arg);
851 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +0000852
Barry Warsawfa701a81997-01-16 00:15:11 +0000853 if (res == NULL)
854 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +0000855
Barry Warsawfa701a81997-01-16 00:15:11 +0000856 if (!(tmp = PyList_New(0))) {
857 Py_DECREF(res);
858 return PythonCmd_Error(interp);
859 }
860
861 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
862 Py_DECREF(res);
863 Py_DECREF(tmp);
864
865 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000866}
867
868static void
869PythonCmdDelete (clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +0000870 ClientData clientData; /* Is (self, func) */
Guido van Rossum18468821994-06-20 07:49:28 +0000871{
Barry Warsawfa701a81997-01-16 00:15:11 +0000872 Py_DECREF((PyObject *) clientData);
Guido van Rossum18468821994-06-20 07:49:28 +0000873}
874
Barry Warsawfa701a81997-01-16 00:15:11 +0000875
876
Guido van Rossum18468821994-06-20 07:49:28 +0000877static PyObject *
878Tkapp_CreateCommand (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000879 PyObject *self;
880 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000881{
Barry Warsawfa701a81997-01-16 00:15:11 +0000882 char *cmdName;
883 PyObject *data;
884 PyObject *func;
Guido van Rossum18468821994-06-20 07:49:28 +0000885
Barry Warsawfa701a81997-01-16 00:15:11 +0000886 /* Args is: (cmdName, func) */
887 if (!PyTuple_Check(args)
888 || !(PyTuple_Size(args) == 2)
889 || !PyString_Check(PyTuple_GetItem(args, 0))
890 || !PyCallable_Check(PyTuple_GetItem(args, 1)))
891 {
892 PyErr_SetString (PyExc_TypeError, "bad argument list");
893 return NULL;
894 }
Guido van Rossum18468821994-06-20 07:49:28 +0000895
Barry Warsawfa701a81997-01-16 00:15:11 +0000896 cmdName = PyString_AsString(PyTuple_GetItem(args, 0));
897 func = PyTuple_GetItem(args, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000898
Barry Warsawfa701a81997-01-16 00:15:11 +0000899 data = PyTuple_New(2); /* ClientData is: (self, func) */
900 if (!data)
901 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000902
Barry Warsawfa701a81997-01-16 00:15:11 +0000903 Py_INCREF(self);
904 PyTuple_SetItem(data, 0, self);
Guido van Rossum18468821994-06-20 07:49:28 +0000905
Barry Warsawfa701a81997-01-16 00:15:11 +0000906 Py_INCREF(func);
907 PyTuple_SetItem(data, 1, func);
Guido van Rossum18468821994-06-20 07:49:28 +0000908
Barry Warsawfa701a81997-01-16 00:15:11 +0000909 Tcl_CreateCommand(Tkapp_Interp (self), cmdName, PythonCmd,
910 (ClientData) data, PythonCmdDelete);
Guido van Rossum18468821994-06-20 07:49:28 +0000911
Barry Warsawfa701a81997-01-16 00:15:11 +0000912 Py_INCREF(Py_None);
913 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000914}
915
Barry Warsawfa701a81997-01-16 00:15:11 +0000916
917
Guido van Rossum18468821994-06-20 07:49:28 +0000918static PyObject *
919Tkapp_DeleteCommand (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000920 PyObject *self;
921 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000922{
Barry Warsawfa701a81997-01-16 00:15:11 +0000923 char *cmdName;
Guido van Rossum18468821994-06-20 07:49:28 +0000924
Barry Warsawfa701a81997-01-16 00:15:11 +0000925 if (!PyArg_Parse(args, "s", &cmdName))
926 return NULL;
927 if (Tcl_DeleteCommand(Tkapp_Interp(self), cmdName) == -1)
928 {
929 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
930 return NULL;
931 }
932 Py_INCREF(Py_None);
933 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000934}
935
Barry Warsawfa701a81997-01-16 00:15:11 +0000936
937
Guido van Rossum18468821994-06-20 07:49:28 +0000938/** File Handler **/
939
Guido van Rossuma597dde1995-01-10 20:56:29 +0000940static void
Guido van Rossum18468821994-06-20 07:49:28 +0000941FileHandler (clientData, mask)
Barry Warsawfa701a81997-01-16 00:15:11 +0000942 ClientData clientData; /* Is: (func, file) */
943 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +0000944{
Barry Warsawfa701a81997-01-16 00:15:11 +0000945 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +0000946
Barry Warsawfa701a81997-01-16 00:15:11 +0000947 func = PyTuple_GetItem((PyObject *) clientData, 0);
948 file = PyTuple_GetItem((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000949
Barry Warsawfa701a81997-01-16 00:15:11 +0000950 arg = Py_BuildValue("(Oi)", file, (long) mask);
951 res = PyEval_CallObject(func, arg);
952 Py_DECREF (arg);
953
954 if (res == NULL) {
955 errorInCmd = 1;
956 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
957 }
958 Py_XDECREF(res);
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000959}
960
961static int
962GetFileNo (file)
Barry Warsawfa701a81997-01-16 00:15:11 +0000963 /* Either an int >= 0 or an object with a
964 *.fileno() method that returns an int >= 0
965 */
966 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000967{
Guido van Rossuma597dde1995-01-10 20:56:29 +0000968 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000969 int id;
970 if (PyInt_Check(file)) {
971 id = PyInt_AsLong(file);
972 if (id < 0)
973 PyErr_SetString(PyExc_ValueError, "invalid file id");
974 return id;
975 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000976 args = PyTuple_New(0);
977 if (args == NULL)
978 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000979
980 meth = PyObject_GetAttrString(file, "fileno");
981 if (meth == NULL) {
982 Py_DECREF(args);
983 return -1;
984 }
985
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000986 res = PyEval_CallObject(meth, args);
987 Py_DECREF(args);
988 Py_DECREF(meth);
989 if (res == NULL)
990 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000991
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000992 if (PyInt_Check(res))
993 id = PyInt_AsLong(res);
994 else
995 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +0000996
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000997 if (id < 0)
998 PyErr_SetString(PyExc_ValueError,
999 "invalid fileno() return value");
1000 Py_DECREF(res);
1001 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001002}
1003
Barry Warsawfa701a81997-01-16 00:15:11 +00001004
1005static PyObject* Tkapp_ClientDataDict = NULL;
1006
Guido van Rossum18468821994-06-20 07:49:28 +00001007static PyObject *
1008Tkapp_CreateFileHandler (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001009 PyObject *self;
1010 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001011{
Barry Warsawfa701a81997-01-16 00:15:11 +00001012 PyObject *file, *func, *data;
1013 PyObject *idkey;
1014 int mask, id;
Guido van Rossum68784361996-05-16 17:17:31 +00001015#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Barry Warsawfa701a81997-01-16 00:15:11 +00001016 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001017#endif
Guido van Rossum18468821994-06-20 07:49:28 +00001018
Barry Warsawfa701a81997-01-16 00:15:11 +00001019 if (!Tkapp_ClientDataDict) {
1020 if (!(Tkapp_ClientDataDict = PyDict_New()))
1021 return NULL;
1022 }
Guido van Rossum18468821994-06-20 07:49:28 +00001023
Barry Warsawfa701a81997-01-16 00:15:11 +00001024 if (!PyArg_Parse(args, "(OiO)", &file, &mask, &func))
1025 return NULL;
1026 id = GetFileNo(file);
1027 if (id < 0)
1028 return NULL;
1029 if (!PyCallable_Check(func)) {
1030 PyErr_SetString (PyExc_TypeError, "bad argument list");
1031 return NULL;
1032 }
1033
1034 if (!(idkey = PyInt_FromLong(id)))
1035 return NULL;
1036
1037 /* ClientData is: (func, file) */
1038 data = Py_BuildValue ("(OO)", func, file);
1039 if (!data || PyDict_SetItem(Tkapp_ClientDataDict, idkey, data)) {
1040 Py_DECREF(idkey);
1041 Py_XDECREF(data);
1042 return NULL;
1043 }
1044 Py_DECREF(idkey);
Guido van Rossum76875221994-06-27 07:59:42 +00001045
Guido van Rossum68784361996-05-16 17:17:31 +00001046#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Guido van Rossum07886d01996-09-11 23:31:42 +00001047#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001048 /* We assume this is a socket... */
1049 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum845547d1996-06-26 18:26:04 +00001050#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001051 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +00001052#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001053 /* Ought to check for null Tcl_File object... */
1054 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum68784361996-05-16 17:17:31 +00001055#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001056 Tk_CreateFileHandler(id, mask, FileHandler, (ClientData) data);
Guido van Rossum68784361996-05-16 17:17:31 +00001057#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001058 /* XXX fileHandlerDict */
1059 Py_INCREF (Py_None);
1060 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001061}
1062
Barry Warsawfa701a81997-01-16 00:15:11 +00001063
Guido van Rossum18468821994-06-20 07:49:28 +00001064static PyObject *
1065Tkapp_DeleteFileHandler (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001066 PyObject *self;
1067 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001068{
Barry Warsawfa701a81997-01-16 00:15:11 +00001069 PyObject *file;
1070 PyObject *idkey;
1071 PyObject *data;
1072 int id;
Guido van Rossum68784361996-05-16 17:17:31 +00001073#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Barry Warsawfa701a81997-01-16 00:15:11 +00001074 Tcl_File tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001075#endif
1076
Barry Warsawfa701a81997-01-16 00:15:11 +00001077 if (!PyArg_Parse(args, "O", &file))
1078 return NULL;
1079 id = GetFileNo(file);
1080 if (id < 0)
1081 return NULL;
1082
1083 if (!(idkey = PyInt_FromLong(id)))
1084 return NULL;
1085
1086 /* find and free the object created in the
1087 * Tkapp_CreateFileHandler() call
1088 */
1089 data = PyDict_GetItem(Tkapp_ClientDataDict, idkey);
1090 Py_XDECREF(data);
1091 PyDict_DelItem(Tkapp_ClientDataDict, idkey);
1092 Py_DECREF(idkey);
Guido van Rossum18468821994-06-20 07:49:28 +00001093
Guido van Rossum68784361996-05-16 17:17:31 +00001094#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Guido van Rossum07886d01996-09-11 23:31:42 +00001095#ifdef MS_WINDOWS
Barry Warsawfa701a81997-01-16 00:15:11 +00001096 /* We assume this is a socket... */
1097 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
Guido van Rossum845547d1996-06-26 18:26:04 +00001098#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001099 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +00001100#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001101 /* Ought to check for null Tcl_File object... */
1102 Tcl_DeleteFileHandler(tfile);
Guido van Rossum68784361996-05-16 17:17:31 +00001103#else
Barry Warsawfa701a81997-01-16 00:15:11 +00001104 Tk_DeleteFileHandler(id);
Guido van Rossum68784361996-05-16 17:17:31 +00001105#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001106 /* XXX fileHandlerDict */
1107 Py_INCREF (Py_None);
1108 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001109}
1110
Barry Warsawfa701a81997-01-16 00:15:11 +00001111
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001112/**** Tktt Object (timer token) ****/
1113
1114staticforward PyTypeObject Tktt_Type;
1115
1116typedef struct
Barry Warsawfa701a81997-01-16 00:15:11 +00001117{
1118 PyObject_HEAD
1119 Tk_TimerToken token;
1120 PyObject *func;
1121}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001122TkttObject;
1123
1124static PyObject *
1125Tktt_DeleteTimerHandler (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001126 PyObject *self;
1127 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001128{
Barry Warsawfa701a81997-01-16 00:15:11 +00001129 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001130
Barry Warsawfa701a81997-01-16 00:15:11 +00001131 if (!PyArg_Parse(args, ""))
1132 return NULL;
1133 if (v->func != NULL) {
1134 Tk_DeleteTimerHandler(v->token);
1135 PyMem_DEL(v->func);
1136 v->func = NULL;
1137 }
1138 Py_INCREF(Py_None);
1139 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001140}
1141
1142static PyMethodDef Tktt_methods[] =
1143{
Barry Warsawfa701a81997-01-16 00:15:11 +00001144 {"deletetimerhandler", Tktt_DeleteTimerHandler},
1145 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001146};
1147
1148static TkttObject *
1149Tktt_New (token, func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001150 Tk_TimerToken token;
1151 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001152{
Barry Warsawfa701a81997-01-16 00:15:11 +00001153 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001154
Barry Warsawfa701a81997-01-16 00:15:11 +00001155 v = PyObject_NEW(TkttObject, &Tktt_Type);
1156 if (v == NULL)
1157 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001158
Barry Warsawfa701a81997-01-16 00:15:11 +00001159 v->token = token;
1160 v->func = func;
1161 Py_INCREF(v->func);
1162 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001163}
1164
1165static void
1166Tktt_Dealloc (self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001167 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001168{
Barry Warsawfa701a81997-01-16 00:15:11 +00001169 PyMem_DEL (self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001170}
1171
1172static int
1173Tktt_Print (self, fp, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +00001174 PyObject *self;
1175 FILE *fp;
1176 int flags;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001177{
Barry Warsawfa701a81997-01-16 00:15:11 +00001178 TkttObject *v = (TkttObject *)self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001179
Barry Warsawfa701a81997-01-16 00:15:11 +00001180 fprintf(fp, "<tktimertoken at 0x%lx%s>", (long)v,
1181 v->func == NULL ? ", handler deleted" : "");
1182 return 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001183}
1184
1185static PyObject *
1186Tktt_GetAttr (self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001187 PyObject *self;
1188 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001189{
Barry Warsawfa701a81997-01-16 00:15:11 +00001190 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001191}
1192
1193static PyTypeObject Tktt_Type =
1194{
Barry Warsawfa701a81997-01-16 00:15:11 +00001195 PyObject_HEAD_INIT (NULL)
1196 0, /*ob_size */
1197 "tktimertoken", /*tp_name */
1198 sizeof (TkttObject), /*tp_basicsize */
1199 0, /*tp_itemsize */
1200 Tktt_Dealloc, /*tp_dealloc */
1201 Tktt_Print, /*tp_print */
1202 Tktt_GetAttr, /*tp_getattr */
1203 0, /*tp_setattr */
1204 0, /*tp_compare */
1205 0, /*tp_repr */
1206 0, /*tp_as_number */
1207 0, /*tp_as_sequence */
1208 0, /*tp_as_mapping */
1209 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001210};
1211
Barry Warsawfa701a81997-01-16 00:15:11 +00001212
1213
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001214/** Timer Handler **/
1215
1216static void
1217TimerHandler (clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001218 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001219{
Barry Warsawfa701a81997-01-16 00:15:11 +00001220 PyObject *func = (PyObject *)clientData;
1221 PyObject *res = PyEval_CallObject(func, NULL);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001222
Barry Warsawfa701a81997-01-16 00:15:11 +00001223 if (res == NULL) {
1224 errorInCmd = 1;
1225 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1226 }
1227 else
1228 Py_DECREF(res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001229}
1230
1231static PyObject *
1232Tkapp_CreateTimerHandler (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001233 PyObject *self;
1234 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001235{
Barry Warsawfa701a81997-01-16 00:15:11 +00001236 int milliseconds;
1237 PyObject *func;
1238 Tk_TimerToken token;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001239
Barry Warsawfa701a81997-01-16 00:15:11 +00001240 if (!PyArg_Parse(args, "(iO)", &milliseconds, &func))
1241 return NULL;
1242 if (!PyCallable_Check(func)) {
1243 PyErr_SetString (PyExc_TypeError, "bad argument list");
1244 return NULL;
1245 }
1246 token = Tk_CreateTimerHandler(milliseconds, TimerHandler,
1247 (ClientData)func);
1248
1249 return (PyObject *) Tktt_New(token, func);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001250}
1251
Barry Warsawfa701a81997-01-16 00:15:11 +00001252
1253
Guido van Rossum18468821994-06-20 07:49:28 +00001254/** Event Loop **/
1255
Guido van Rossum18468821994-06-20 07:49:28 +00001256static PyObject *
1257Tkapp_MainLoop (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001258 PyObject *self;
1259 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001260{
Barry Warsawfa701a81997-01-16 00:15:11 +00001261 int threshold = 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001262
Barry Warsawfa701a81997-01-16 00:15:11 +00001263 if (!PyArg_ParseTuple(args, "|i", &threshold))
1264 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001265
Barry Warsawfa701a81997-01-16 00:15:11 +00001266 quitMainLoop = 0;
1267 while (Tk_GetNumMainWindows() > threshold &&
1268 !quitMainLoop &&
1269 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001270 {
Barry Warsawfa701a81997-01-16 00:15:11 +00001271 /* XXX Ought to check for other signals! */
1272 if (PyOS_InterruptOccurred()) {
1273 PyErr_SetNone(PyExc_KeyboardInterrupt);
1274 return NULL;
1275 }
1276 Tk_DoOneEvent(0);
Guido van Rossum18468821994-06-20 07:49:28 +00001277 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001278 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001279
Barry Warsawfa701a81997-01-16 00:15:11 +00001280 if (errorInCmd) {
1281 errorInCmd = 0;
1282 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1283 excInCmd = valInCmd = trbInCmd = NULL;
1284 return NULL;
1285 }
1286 Py_INCREF(Py_None);
1287 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001288}
1289
1290static PyObject *
Guido van Rossum062cfb01995-01-10 17:42:51 +00001291Tkapp_DoOneEvent (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001292 PyObject *self;
1293 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001294{
Barry Warsawfa701a81997-01-16 00:15:11 +00001295 int flags = TK_ALL_EVENTS;
1296 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001297
Barry Warsawfa701a81997-01-16 00:15:11 +00001298 if (!PyArg_ParseTuple(args, "|i", &flags))
1299 return NULL;
1300
1301 rv = Tk_DoOneEvent(flags);
1302 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001303}
1304
1305static PyObject *
Guido van Rossum18468821994-06-20 07:49:28 +00001306Tkapp_Quit (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001307 PyObject *self;
1308 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001309{
1310
Barry Warsawfa701a81997-01-16 00:15:11 +00001311 if (!PyArg_Parse(args, ""))
1312 return NULL;
1313
1314 quitMainLoop = 1;
1315 Py_INCREF(Py_None);
1316 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001317}
1318
Barry Warsawfa701a81997-01-16 00:15:11 +00001319
1320
Guido van Rossum18468821994-06-20 07:49:28 +00001321/**** Tkapp Method List ****/
1322
1323static PyMethodDef Tkapp_methods[] =
1324{
Barry Warsawfa701a81997-01-16 00:15:11 +00001325 {"call", Tkapp_Call},
1326 {"globalcall", Tkapp_GlobalCall},
1327 {"eval", Tkapp_Eval},
1328 {"globaleval", Tkapp_GlobalEval},
1329 {"evalfile", Tkapp_EvalFile},
1330 {"record", Tkapp_Record},
1331 {"adderrorinfo", Tkapp_AddErrorInfo},
1332 {"setvar", Tkapp_SetVar},
1333 {"globalsetvar", Tkapp_GlobalSetVar},
1334 {"getvar", Tkapp_GetVar},
1335 {"globalgetvar", Tkapp_GlobalGetVar},
1336 {"unsetvar", Tkapp_UnsetVar},
1337 {"globalunsetvar", Tkapp_GlobalUnsetVar},
1338 {"getint", Tkapp_GetInt},
1339 {"getdouble", Tkapp_GetDouble},
1340 {"getboolean", Tkapp_GetBoolean},
1341 {"exprstring", Tkapp_ExprString},
1342 {"exprlong", Tkapp_ExprLong},
1343 {"exprdouble", Tkapp_ExprDouble},
1344 {"exprboolean", Tkapp_ExprBoolean},
1345 {"splitlist", Tkapp_SplitList},
1346 {"split", Tkapp_Split},
1347 {"merge", Tkapp_Merge},
1348 {"createcommand", Tkapp_CreateCommand},
1349 {"deletecommand", Tkapp_DeleteCommand},
1350 {"createfilehandler", Tkapp_CreateFileHandler},
1351 {"deletefilehandler", Tkapp_DeleteFileHandler},
1352 {"createtimerhandler", Tkapp_CreateTimerHandler},
1353 {"mainloop", Tkapp_MainLoop, 1},
1354 {"dooneevent", Tkapp_DoOneEvent, 1},
1355 {"quit", Tkapp_Quit},
1356 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001357};
1358
Barry Warsawfa701a81997-01-16 00:15:11 +00001359
1360
Guido van Rossum18468821994-06-20 07:49:28 +00001361/**** Tkapp Type Methods ****/
1362
1363static void
1364Tkapp_Dealloc (self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001365 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001366{
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001367#ifdef NEED_TKCREATEMAINWINDOW
Barry Warsawfa701a81997-01-16 00:15:11 +00001368 Tk_DestroyWindow (Tkapp_Tkwin (self));
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001369#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001370 Tcl_DeleteInterp (Tkapp_Interp (self));
1371 PyMem_DEL (self);
Guido van Rossum18468821994-06-20 07:49:28 +00001372}
1373
1374static PyObject *
1375Tkapp_GetAttr (self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001376 PyObject *self;
1377 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001378{
Barry Warsawfa701a81997-01-16 00:15:11 +00001379 return Py_FindMethod (Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001380}
1381
1382static PyTypeObject Tkapp_Type =
1383{
Barry Warsawfa701a81997-01-16 00:15:11 +00001384 PyObject_HEAD_INIT (NULL)
1385 0, /*ob_size */
1386 "tkapp", /*tp_name */
1387 sizeof (TkappObject), /*tp_basicsize */
1388 0, /*tp_itemsize */
1389 Tkapp_Dealloc, /*tp_dealloc */
1390 0, /*tp_print */
1391 Tkapp_GetAttr, /*tp_getattr */
1392 0, /*tp_setattr */
1393 0, /*tp_compare */
1394 0, /*tp_repr */
1395 0, /*tp_as_number */
1396 0, /*tp_as_sequence */
1397 0, /*tp_as_mapping */
1398 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001399};
1400
Barry Warsawfa701a81997-01-16 00:15:11 +00001401
1402
Guido van Rossum18468821994-06-20 07:49:28 +00001403/**** Tkinter Module ****/
1404
1405static PyObject *
1406Tkinter_Create (self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001407 PyObject *self;
1408 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001409{
Barry Warsawfa701a81997-01-16 00:15:11 +00001410 char *screenName = NULL;
1411 char *baseName = NULL;
1412 char *className = NULL;
1413 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001414
Barry Warsawfa701a81997-01-16 00:15:11 +00001415 baseName = strrchr(Py_GetProgramName (), '/');
1416 if (baseName != NULL)
1417 baseName++;
1418 else
1419 baseName = Py_GetProgramName();
1420 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001421
Barry Warsawfa701a81997-01-16 00:15:11 +00001422 if (!PyArg_ParseTuple(args, "|zssi",
1423 &screenName, &baseName, &className,
1424 &interactive))
1425 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001426
Barry Warsawfa701a81997-01-16 00:15:11 +00001427 return (PyObject *) Tkapp_New(screenName, baseName, className,
1428 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001429}
1430
1431static PyMethodDef moduleMethods[] =
1432{
Barry Warsawfa701a81997-01-16 00:15:11 +00001433 {"create", Tkinter_Create, 1},
1434 {"createfilehandler", Tkapp_CreateFileHandler, 0},
1435 {"deletefilehandler", Tkapp_DeleteFileHandler, 0},
1436 {"createtimerhandler", Tkapp_CreateTimerHandler, 0},
1437 {"mainloop", Tkapp_MainLoop, 1},
1438 {"dooneevent", Tkapp_DoOneEvent, 1},
1439 {"quit", Tkapp_Quit},
1440 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001441};
1442
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001443#undef WITH_READLINE /* XXX */
Guido van Rossum18468821994-06-20 07:49:28 +00001444#ifdef WITH_READLINE
1445static int
1446EventHook ()
1447{
Barry Warsawfa701a81997-01-16 00:15:11 +00001448 /* XXX Reset tty */
1449 if (errorInCmd) {
1450 errorInCmd = 0;
1451 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1452 excInCmd = valInCmd = trbInCmd = NULL;
1453 PyErr_Print();
1454 }
1455 if (Tk_GetNumMainWindows() > 0)
1456 Tk_DoOneEvent(TK_DONT_WAIT);
1457 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001458}
1459#endif /* WITH_READLINE */
1460
1461static void
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001462Tkinter_Cleanup ()
1463{
Barry Warsawfa701a81997-01-16 00:15:11 +00001464 /* This segfault with Tk 4.0 beta and seems unnecessary there as
1465 * well */
1466
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001467#if TK_MAJOR_VERSION < 4
Barry Warsawfa701a81997-01-16 00:15:11 +00001468 /* XXX rl_deprep_terminal is static, damned! */
1469 while (tkMainWindowList != 0)
1470 Tk_DestroyWindow(tkMainWindowList->win);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001471#endif
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001472}
1473
Barry Warsawfa701a81997-01-16 00:15:11 +00001474
1475/* all errors will be checked in one fell swoop in init_tkinter() */
1476static void
1477ins_long(d, name, val)
1478 PyObject *d;
1479 char *name;
1480 long val;
1481{
1482 PyObject *v = PyInt_FromLong(val);
1483 if (v) {
1484 PyDict_SetItemString(d, name, v);
1485 Py_DECREF(v);
1486 }
1487}
1488static void
1489ins_string(d, name, val)
1490 PyObject *d;
1491 char *name;
1492 char *val;
1493{
1494 PyObject *v = PyString_FromString(val);
1495 if (v) {
1496 PyDict_SetItemString(d, name, v);
1497 Py_DECREF(v);
1498 }
1499}
1500
1501
Guido van Rossum18468821994-06-20 07:49:28 +00001502void
Guido van Rossumad1f7ee1996-02-13 00:11:37 +00001503init_tkinter ()
Guido van Rossum18468821994-06-20 07:49:28 +00001504{
Barry Warsawfa701a81997-01-16 00:15:11 +00001505 static inited = 0;
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001506
Guido van Rossum18468821994-06-20 07:49:28 +00001507#ifdef WITH_READLINE
Barry Warsawfa701a81997-01-16 00:15:11 +00001508 extern int (*rl_event_hook) ();
Guido van Rossum18468821994-06-20 07:49:28 +00001509#endif /* WITH_READLINE */
Barry Warsawfa701a81997-01-16 00:15:11 +00001510 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001511
Barry Warsawfa701a81997-01-16 00:15:11 +00001512 Tkapp_Type.ob_type = &PyType_Type;
1513 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossumae92f011996-08-21 19:03:36 +00001514
Barry Warsawfa701a81997-01-16 00:15:11 +00001515 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001516
Barry Warsawfa701a81997-01-16 00:15:11 +00001517 d = PyModule_GetDict(m);
1518 Tkinter_TclError = Py_BuildValue("s", "TclError");
1519 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00001520
Barry Warsawfa701a81997-01-16 00:15:11 +00001521 ins_long(d, "READABLE", TK_READABLE);
1522 ins_long(d, "WRITABLE", TK_WRITABLE);
1523 ins_long(d, "EXCEPTION", TK_EXCEPTION);
1524 ins_long(d, "X_EVENTS", TK_X_EVENTS);
1525 ins_long(d, "FILE_EVENTS", TK_FILE_EVENTS);
1526 ins_long(d, "TIMER_EVENTS", TK_TIMER_EVENTS);
1527 ins_long(d, "IDLE_EVENTS", TK_IDLE_EVENTS);
1528 ins_long(d, "ALL_EVENTS", TK_ALL_EVENTS);
1529 ins_long(d, "DONT_WAIT", TK_DONT_WAIT);
1530 ins_string(d, "TK_VERSION", TK_VERSION);
1531 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00001532
Guido van Rossum18468821994-06-20 07:49:28 +00001533#ifdef WITH_READLINE
Barry Warsawfa701a81997-01-16 00:15:11 +00001534 rl_event_hook = EventHook;
Guido van Rossum18468821994-06-20 07:49:28 +00001535#endif /* WITH_READLINE */
1536
Barry Warsawfa701a81997-01-16 00:15:11 +00001537 if (!inited) {
1538 inited = 1;
1539 if (Py_AtExit(Tkinter_Cleanup) != 0)
1540 fprintf(stderr,
1541 "Tkinter: warning: cleanup procedure not registered\n");
1542 }
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001543
Barry Warsawfa701a81997-01-16 00:15:11 +00001544 if (PyErr_Occurred())
1545 Py_FatalError ("can't initialize module _tkinter");
Jack Jansen34cc5c31995-10-31 16:15:12 +00001546#ifdef macintosh
Barry Warsawfa701a81997-01-16 00:15:11 +00001547 TclMacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00001548#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00001549 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001550#endif /* GENERATINGCFM */
1551#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001552}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001553
Guido van Rossumec22c921996-02-25 04:50:29 +00001554
Barry Warsawfa701a81997-01-16 00:15:11 +00001555
Guido van Rossum9722ad81995-09-22 23:49:28 +00001556#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001557
1558/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001559** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001560*/
1561
Guido van Rossum9722ad81995-09-22 23:49:28 +00001562void
1563panic(char * format, ...)
1564{
Barry Warsawfa701a81997-01-16 00:15:11 +00001565 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001566
Barry Warsawfa701a81997-01-16 00:15:11 +00001567 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001568
Barry Warsawfa701a81997-01-16 00:15:11 +00001569 vfprintf(stderr, format, varg);
1570 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001571
Barry Warsawfa701a81997-01-16 00:15:11 +00001572 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00001573
Barry Warsawfa701a81997-01-16 00:15:11 +00001574 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00001575}
Jack Jansen40b546d1995-11-14 10:34:45 +00001576
Guido van Rossumec22c921996-02-25 04:50:29 +00001577/*
1578** Pass events to SIOUX before passing them to Tk.
1579*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001580
Guido van Rossumec22c921996-02-25 04:50:29 +00001581static int
1582PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00001583 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001584{
Barry Warsawfa701a81997-01-16 00:15:11 +00001585 if (SIOUXHandleOneEvent(eventPtr))
1586 return 0; /* Nothing happened to the Tcl event queue */
1587 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001588}
1589
Guido van Rossumec22c921996-02-25 04:50:29 +00001590#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001591
1592/*
1593** Additional Mac specific code for dealing with shared libraries.
1594*/
1595
1596#include <Resources.h>
1597#include <CodeFragments.h>
1598
1599static int loaded_from_shlib = 0;
1600static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001601
Jack Jansen34cc5c31995-10-31 16:15:12 +00001602/*
1603** If this module is dynamically loaded the following routine should
1604** be the init routine. It takes care of adding the shared library to
1605** the resource-file chain, so that the tk routines can find their
1606** resources.
1607*/
1608OSErr pascal
1609init_tkinter_shlib(InitBlockPtr data)
1610{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00001611 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00001612 if ( data == nil ) return noErr;
1613 if ( data->fragLocator.where == kOnDiskFlat ) {
1614 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1615 loaded_from_shlib = 1;
1616 } else if ( data->fragLocator.where == kOnDiskSegmented ) {
1617 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1618 loaded_from_shlib = 1;
1619 }
1620 return noErr;
1621}
1622
1623/*
1624** Insert the library resources into the search path. Put them after
1625** the resources from the application. Again, we ignore errors.
1626*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001627static
Jack Jansen34cc5c31995-10-31 16:15:12 +00001628mac_addlibresources()
1629{
1630 if ( !loaded_from_shlib )
1631 return;
1632 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1633}
1634
Guido van Rossumec22c921996-02-25 04:50:29 +00001635#endif /* GENERATINGCFM */
1636#endif /* macintosh */