blob: 1315c1b4b64657a0a80b51e88ca1991735b6f0e1 [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
101 {
102 PyObject_HEAD
103 Tcl_Interp *interp;
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000104#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +0000105 Tk_Window tkwin;
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000106#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000107 }
108TkappObject;
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", \
118 (void *) v, ((PyObject *) v)->ob_refcnt))
119
120/**** Error Handling ****/
121
122static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000123static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000124static int errorInCmd = 0;
125static PyObject *excInCmd;
126static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000127static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000128
129static PyObject *
130Tkinter_Error (v)
131 PyObject *v;
132{
Guido van Rossum18468821994-06-20 07:49:28 +0000133 PyErr_SetString (Tkinter_TclError, Tkapp_Result (v));
134 return NULL;
135}
136
137int
138PythonCmd_Error (interp)
139 Tcl_Interp *interp;
140{
141 errorInCmd = 1;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000142 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
Guido van Rossum18468821994-06-20 07:49:28 +0000143 return TCL_ERROR;
144}
145
146/**** Utils ****/
147
148static char *
149AsString (value, tmp)
150 PyObject *value;
151 PyObject *tmp;
152{
153 if (PyString_Check (value))
154 return PyString_AsString (value);
155 else
156 {
157 PyObject *v;
158
Guido van Rossumcd938fc1995-01-17 16:13:48 +0000159 v = PyObject_Str (value);
Guido van Rossum18468821994-06-20 07:49:28 +0000160 PyList_Append (tmp, v);
161 Py_DECREF (v);
162 return PyString_AsString (v);
163 }
164}
165
166#define ARGSZ 64
167
168static char *
169Merge (args)
170 PyObject *args;
171{
172 PyObject *tmp;
173 char *argvStore[ARGSZ];
174 char **argv;
175 int fvStore[ARGSZ];
176 int *fv;
177 int argc;
178 char *res;
179 int i;
180
181 tmp = PyList_New (0);
182 argv = argvStore;
183 fv = fvStore;
184
Guido van Rossum845547d1996-06-26 18:26:04 +0000185 if (args == NULL)
186 {
187 argc = 0;
188 }
189 else if (!PyTuple_Check (args))
Guido van Rossum18468821994-06-20 07:49:28 +0000190 {
191 argc = 1;
192 fv[0] = 0;
193 argv[0] = AsString (args, tmp);
194 }
195 else
196 {
197 PyObject *v;
198
199 if (PyTuple_Size (args) > ARGSZ)
200 {
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000201 argv = (char **) ckalloc (PyTuple_Size (args) * sizeof (char *));
202 fv = (int *) ckalloc (PyTuple_Size (args) * sizeof (int));
Guido van Rossum18468821994-06-20 07:49:28 +0000203 if (argv == NULL || fv == NULL)
204 PyErr_NoMemory ();
205 }
206
207 argc = PyTuple_Size (args);
208 for (i = 0; i < argc; i++)
209 {
210 v = PyTuple_GetItem (args, i);
211 if (PyTuple_Check (v))
212 {
213 fv[i] = 1;
214 argv[i] = Merge (v);
215 }
216 else if (v == Py_None)
217 {
218 argc = i;
219 break;
220 }
221 else
222 {
223 fv[i] = 0;
224 argv[i] = AsString (v, tmp);
225 }
226 }
227 }
228
229 res = Tcl_Merge (argc, argv);
230
231 Py_DECREF (tmp);
232 for (i = 0; i < argc; i++)
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000233 if (fv[i]) ckfree (argv[i]);
Guido van Rossum18468821994-06-20 07:49:28 +0000234 if (argv != argvStore)
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000235 ckfree (FREECAST argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000236 if (fv != fvStore)
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000237 ckfree (FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000238
239 return res;
240}
241
242static PyObject *
243Split (self, list)
244 PyObject *self;
245 char *list;
246{
247 int argc;
248 char **argv;
249 PyObject *v;
250
251 if (list == NULL)
252 {
253 Py_INCREF (Py_None);
254 return Py_None;
255 }
256
257 if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
Guido van Rossum4004e211996-12-17 01:25:36 +0000258 {
259 /* Not a list.
260 Could be a quoted string containing funnies, e.g. {"}.
261 Return the string itself. */
262 PyErr_Clear();
263 return PyString_FromString(list);
264 }
Guido van Rossum18468821994-06-20 07:49:28 +0000265
266 if (argc == 0)
267 v = PyString_FromString ("");
268 else if (argc == 1)
269 v = PyString_FromString (argv[0]);
Guido van Rossum0f868371996-12-17 01:02:18 +0000270 else if ((v = PyTuple_New (argc)) != NULL)
Guido van Rossum18468821994-06-20 07:49:28 +0000271 {
272 int i;
Guido van Rossum0f868371996-12-17 01:02:18 +0000273 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000274
Guido van Rossum0f868371996-12-17 01:02:18 +0000275 for (i = 0; i < argc; i++) {
276 if ((w = Split (self, argv[i])) == NULL)
277 {
278 Py_DECREF(v);
279 v = NULL;
280 break;
281 }
282 PyTuple_SetItem (v, i, w);
283 }
Guido van Rossum18468821994-06-20 07:49:28 +0000284 }
285
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000286 ckfree (FREECAST argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000287 return v;
288}
289
290/**** Tkapp Object ****/
291
292#ifndef WITH_APPINIT
293int
294Tcl_AppInit (interp)
295 Tcl_Interp *interp;
296{
Guido van Rossumec22c921996-02-25 04:50:29 +0000297 Tk_Window main;
298
299 main = Tk_MainWindow(interp);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000300 if (Tcl_Init (interp) == TCL_ERROR) {
301 fprintf(stderr, "Tcl_Init error: %s\n", interp->result);
Guido van Rossum18468821994-06-20 07:49:28 +0000302 return TCL_ERROR;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000303 }
304 if (Tk_Init (interp) == TCL_ERROR) {
305 fprintf(stderr, "Tk_Init error: %s\n", interp->result);
Guido van Rossum18468821994-06-20 07:49:28 +0000306 return TCL_ERROR;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000307 }
Guido van Rossum18468821994-06-20 07:49:28 +0000308 return TCL_OK;
309}
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000310
Guido van Rossum18468821994-06-20 07:49:28 +0000311#endif /* !WITH_APPINIT */
312
313/* Initialize the Tk application; see the `main' function in
314 `tkMain.c'. */
315static TkappObject *
316Tkapp_New (screenName, baseName, className, interactive)
317 char *screenName;
318 char *baseName;
319 char *className;
320 int interactive;
321{
322 TkappObject *v;
Guido van Rossum97867b21996-08-08 19:09:53 +0000323 char *argv0;
Guido van Rossum18468821994-06-20 07:49:28 +0000324
325 v = PyObject_NEW (TkappObject, &Tkapp_Type);
326 if (v == NULL)
327 return NULL;
328
329 v->interp = Tcl_CreateInterp ();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000330
331#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +0000332 v->tkwin = Tk_CreateMainWindow (v->interp, screenName,
333 baseName, className);
334 if (v->tkwin == NULL)
335 return (TkappObject *) Tkinter_Error ((PyObject *) v);
336
337 Tk_GeometryRequest (v->tkwin, 200, 200);
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000338#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000339
340 if (screenName != NULL)
341 Tcl_SetVar2 (v->interp, "env", "DISPLAY", screenName, TCL_GLOBAL_ONLY);
342
343 if (interactive)
344 Tcl_SetVar (v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
345 else
346 Tcl_SetVar (v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
347
Guido van Rossum97867b21996-08-08 19:09:53 +0000348 /* This is used to get the application class for Tk 4.1 and up */
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000349 argv0 = (char*) ckalloc (strlen (className) + 1);
Guido van Rossum97867b21996-08-08 19:09:53 +0000350 if (argv0 != NULL) {
351 strcpy (argv0, className);
352 if (isupper (argv0[0]))
353 argv0[0] = tolower (argv0[0]);
354 Tcl_SetVar (v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000355 ckfree (argv0);
Guido van Rossum97867b21996-08-08 19:09:53 +0000356 }
357
Guido van Rossum18468821994-06-20 07:49:28 +0000358 if (Tcl_AppInit (v->interp) != TCL_OK)
Guido van Rossum845547d1996-06-26 18:26:04 +0000359 return (TkappObject *) Tkinter_Error (v);
Guido van Rossum18468821994-06-20 07:49:28 +0000360
361 return v;
362}
363
364/** Tcl Eval **/
365
366static PyObject *
367Tkapp_Call (self, args)
368 PyObject *self;
369 PyObject *args;
370{
371 char *cmd;
372
373 cmd = Merge (args);
374 if (Tcl_Eval (Tkapp_Interp (self), cmd) == TCL_ERROR)
375 {
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000376 ckfree (cmd);
Guido van Rossum18468821994-06-20 07:49:28 +0000377 return Tkinter_Error (self);
378 }
379
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000380 ckfree (cmd);
Guido van Rossum18468821994-06-20 07:49:28 +0000381 return PyString_FromString (Tkapp_Result (self));
382}
383
384static PyObject *
385Tkapp_GlobalCall (self, args)
386 PyObject *self;
387 PyObject *args;
388{
389 char *cmd;
390
391 cmd = Merge (args);
392 if (Tcl_GlobalEval (Tkapp_Interp (self), cmd) == TCL_ERROR)
393 {
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000394 ckfree (cmd);
Guido van Rossum18468821994-06-20 07:49:28 +0000395 return Tkinter_Error (self);
396 }
397
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000398 ckfree (cmd);
Guido van Rossum18468821994-06-20 07:49:28 +0000399 return PyString_FromString (Tkapp_Result (self));
400}
401
402static PyObject *
403Tkapp_Eval (self, args)
404 PyObject *self;
405 PyObject *args;
406{
407 char *script;
408
409 if (!PyArg_Parse (args, "s", &script))
410 return NULL;
411
412 if (Tcl_Eval (Tkapp_Interp (self), script) == TCL_ERROR)
413 return Tkinter_Error (self);
414
415 return PyString_FromString (Tkapp_Result (self));
416}
417
418static PyObject *
419Tkapp_GlobalEval (self, args)
420 PyObject *self;
421 PyObject *args;
422{
423 char *script;
424
425 if (!PyArg_Parse (args, "s", &script))
426 return NULL;
427
428 if (Tcl_GlobalEval (Tkapp_Interp (self), script) == TCL_ERROR)
429 return Tkinter_Error (self);
430
431 return PyString_FromString (Tkapp_Result (self));
432}
433
434static PyObject *
435Tkapp_EvalFile (self, args)
436 PyObject *self;
437 PyObject *args;
438{
439 char *fileName;
440
441 if (!PyArg_Parse (args, "s", &fileName))
442 return NULL;
443
444 if (Tcl_EvalFile (Tkapp_Interp (self), fileName) == TCL_ERROR)
445 return Tkinter_Error (self);
446
447 return PyString_FromString (Tkapp_Result (self));
448}
449
450static PyObject *
451Tkapp_Record (self, args)
452 PyObject *self;
453 PyObject *args;
454{
455 char *script;
456
457 if (!PyArg_Parse (args, "s", &script))
458 return NULL;
459
460 if (Tcl_RecordAndEval (Tkapp_Interp (self),
461 script, TCL_NO_EVAL) == TCL_ERROR)
462 return Tkinter_Error (self);
463
464 return PyString_FromString (Tkapp_Result (self));
465}
466
467static PyObject *
468Tkapp_AddErrorInfo (self, args)
469 PyObject *self;
470 PyObject *args;
471{
472 char *msg;
473
474 if (!PyArg_Parse (args, "s", &msg))
475 return NULL;
476 Tcl_AddErrorInfo (Tkapp_Interp (self), msg);
477
478 Py_INCREF(Py_None);
479 return Py_None;
480}
481
482/** Tcl Variable **/
483
484static PyObject *
485SetVar (self, args, flags)
486 PyObject *self;
487 PyObject *args;
488 int flags;
489{
490 char *name1, *name2, *ok;
491 PyObject *newValue;
492 PyObject *tmp;
493
494 tmp = PyList_New (0);
495
496 if (PyArg_Parse (args, "(sO)", &name1, &newValue))
497 ok = Tcl_SetVar (Tkapp_Interp (self), name1,
498 AsString (newValue, tmp), flags); /* XXX Merge? */
499 else if (PyArg_Parse (args, "(ssO)", &name1, &name2, &newValue))
500 ok = Tcl_SetVar2 (Tkapp_Interp (self), name1, name2,
501 AsString (newValue, tmp), flags);
502 else
503 {
504 Py_DECREF (tmp);
505 return NULL;
506 }
507 Py_DECREF (tmp);
508
509 if (!ok)
510 return Tkinter_Error (self);
511
512 Py_INCREF (Py_None);
513 return Py_None;
514}
515
516static PyObject *
517Tkapp_SetVar (self, args)
518 PyObject *self;
519 PyObject *args;
520{
521 return SetVar (self, args, TCL_LEAVE_ERR_MSG);
522}
523
524static PyObject *
525Tkapp_GlobalSetVar (self, args)
526 PyObject *self;
527 PyObject *args;
528{
529 return SetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
530}
531
532static PyObject *
533GetVar (self, args, flags)
534 PyObject *self;
535 PyObject *args;
536 int flags;
537{
538 char *name1, *name2, *s;
539
540 if (PyArg_Parse (args, "s", &name1))
541 s = Tcl_GetVar (Tkapp_Interp (self), name1, flags);
542 else if (PyArg_Parse (args, "(ss)", &name1, &name2))
543 s = Tcl_GetVar2 (Tkapp_Interp (self), name1, name2, flags);
544 else
545 return NULL;
546
547 if (s == NULL)
548 return Tkinter_Error (self);
549
550 return PyString_FromString (s);
551}
552
553static PyObject *
554Tkapp_GetVar (self, args)
555 PyObject *self;
556 PyObject *args;
557{
558 return GetVar (self, args, TCL_LEAVE_ERR_MSG);
559}
560
561static PyObject *
562Tkapp_GlobalGetVar (self, args)
563 PyObject *self;
564 PyObject *args;
565{
566 return GetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
567}
568
569static PyObject *
570UnsetVar (self, args, flags)
571 PyObject *self;
572 PyObject *args;
573 int flags;
574{
575 char *name1, *name2;
576 int code;
577
578 if (PyArg_Parse (args, "s", &name1))
579 code = Tcl_UnsetVar (Tkapp_Interp (self), name1, flags);
580 else if (PyArg_Parse (args, "(ss)", &name1, &name2))
581 code = Tcl_UnsetVar2 (Tkapp_Interp (self), name1, name2, flags);
582 else
583 return NULL;
584
585 if (code == TCL_ERROR)
586 return Tkinter_Error (self);
587
588 Py_INCREF (Py_None);
589 return Py_None;
590}
591
592static PyObject *
593Tkapp_UnsetVar (self, args)
594 PyObject *self;
595 PyObject *args;
596{
597 return UnsetVar (self, args, TCL_LEAVE_ERR_MSG);
598}
599
600static PyObject *
601Tkapp_GlobalUnsetVar (self, args)
602 PyObject *self;
603 PyObject *args;
604{
605 return UnsetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
606}
607
608/** Tcl to Python **/
609
610static PyObject *
611Tkapp_GetInt (self, args)
612 PyObject *self;
613 PyObject *args;
614{
615 char *s;
616 int v;
617
618 if (!PyArg_Parse (args, "s", &s))
619 return NULL;
620 if (Tcl_GetInt (Tkapp_Interp (self), s, &v) == TCL_ERROR)
621 return Tkinter_Error (self);
622 return Py_BuildValue ("i", v);
623}
624
625static PyObject *
626Tkapp_GetDouble (self, args)
627 PyObject *self;
628 PyObject *args;
629{
630 char *s;
631 double v;
632
633 if (!PyArg_Parse (args, "s", &s))
634 return NULL;
635 if (Tcl_GetDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
636 return Tkinter_Error (self);
637 return Py_BuildValue ("d", v);
638}
639
640static PyObject *
641Tkapp_GetBoolean (self, args)
642 PyObject *self;
643 PyObject *args;
644{
645 char *s;
646 int v;
647
648 if (!PyArg_Parse (args, "s", &s))
649 return NULL;
650 if (Tcl_GetBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
651 return Tkinter_Error (self);
652 return Py_BuildValue ("i", v);
653}
654
655static PyObject *
656Tkapp_ExprString (self, args)
657 PyObject *self;
658 PyObject *args;
659{
660 char *s;
661
662 if (!PyArg_Parse (args, "s", &s))
663 return NULL;
664 if (Tcl_ExprString (Tkapp_Interp (self), s) == TCL_ERROR)
665 return Tkinter_Error (self);
666 return Py_BuildValue ("s", Tkapp_Result (self));
667}
668
669static PyObject *
670Tkapp_ExprLong (self, args)
671 PyObject *self;
672 PyObject *args;
673{
674 char *s;
675 long v;
676
677 if (!PyArg_Parse (args, "s", &s))
678 return NULL;
679 if (Tcl_ExprLong (Tkapp_Interp (self), s, &v) == TCL_ERROR)
680 return Tkinter_Error (self);
681 return Py_BuildValue ("l", v);
682}
683
684static PyObject *
685Tkapp_ExprDouble (self, args)
686 PyObject *self;
687 PyObject *args;
688{
689 char *s;
690 double v;
691
692 if (!PyArg_Parse (args, "s", &s))
693 return NULL;
694 if (Tcl_ExprDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
695 return Tkinter_Error (self);
696 return Py_BuildValue ("d", v);
697}
698
699static PyObject *
700Tkapp_ExprBoolean (self, args)
701 PyObject *self;
702 PyObject *args;
703{
704 char *s;
705 int v;
706
707 if (!PyArg_Parse (args, "s", &s))
708 return NULL;
709 if (Tcl_ExprBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
710 return Tkinter_Error (self);
711 return Py_BuildValue ("i", v);
712}
713
714static PyObject *
715Tkapp_SplitList (self, args)
716 PyObject *self;
717 PyObject *args;
718{
719 char *list;
720 int argc;
721 char **argv;
722 PyObject *v;
723 int i;
724
725 if (!PyArg_Parse (args, "s", &list))
726 return NULL;
727
728 if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
729 return Tkinter_Error (self);
730
731 v = PyTuple_New (argc);
732 for (i = 0; i < argc; i++)
733 PyTuple_SetItem (v, i, PyString_FromString (argv[i]));
734
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000735 ckfree (FREECAST argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000736 return v;
737}
738
739static PyObject *
740Tkapp_Split (self, args)
741 PyObject *self;
742 PyObject *args;
743{
744 char *list;
745
746 if (!PyArg_Parse (args, "s", &list))
747 return NULL;
748 return Split (self, list);
749}
750
751static PyObject *
752Tkapp_Merge (self, args)
753 PyObject *self;
754 PyObject *args;
755{
756 char *s;
757 PyObject *v;
758
759 s = Merge (args);
760 v = PyString_FromString (s);
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000761 ckfree (s);
Guido van Rossum18468821994-06-20 07:49:28 +0000762 return v;
763}
764
765/** Tcl Command **/
766
767/* This is the Tcl command that acts as a wrapper for Python
768 function or method. */
769static int
770PythonCmd (clientData, interp, argc, argv)
771 ClientData clientData; /* Is (self, func) */
772 Tcl_Interp *interp;
773 int argc;
774 char *argv[];
775{
776 PyObject *self, *func, *arg, *res, *tmp;
777 int i;
778
779 self = PyTuple_GetItem ((PyObject *) clientData, 0);
780 func = PyTuple_GetItem ((PyObject *) clientData, 1);
781
782 /* Create argument list (argv1, ..., argvN) */
783 arg = PyTuple_New (argc - 1);
784 for (i = 0; i < (argc - 1); i++)
785 PyTuple_SetItem (arg, i, PyString_FromString (argv[i + 1]));
786
787 res = PyEval_CallObject (func, arg);
788 Py_DECREF (arg);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000789
Guido van Rossum18468821994-06-20 07:49:28 +0000790 if (res == NULL)
791 return PythonCmd_Error (interp);
792
793 tmp = PyList_New (0);
794 Tcl_SetResult (Tkapp_Interp (self), AsString (res, tmp), TCL_VOLATILE);
795 Py_DECREF (res);
796 Py_DECREF (tmp);
797
798 return TCL_OK;
799}
800
801static void
802PythonCmdDelete (clientData)
803 ClientData clientData; /* Is (self, func) */
804{
805 Py_DECREF ((PyObject *) clientData);
806}
807
808static PyObject *
809Tkapp_CreateCommand (self, args)
810 PyObject *self;
811 PyObject *args;
812{
813 char *cmdName;
814 PyObject *data;
815 PyObject *func;
816
817 /* Args is: (cmdName, func) */
818 if (!PyTuple_Check (args)
819 || !(PyTuple_Size (args) == 2)
820 || !PyString_Check (PyTuple_GetItem (args, 0))
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000821 || !PyCallable_Check (PyTuple_GetItem (args, 1)))
Guido van Rossum18468821994-06-20 07:49:28 +0000822 {
823 PyErr_SetString (PyExc_TypeError, "bad argument list");
824 return NULL;
825 }
826
827 cmdName = PyString_AsString (PyTuple_GetItem (args, 0));
828 func = PyTuple_GetItem (args, 1);
829
830 data = PyTuple_New (2); /* ClientData is: (self, func) */
831
832 Py_INCREF (self);
833 PyTuple_SetItem (data, 0, self);
834
835 Py_INCREF (func);
836 PyTuple_SetItem (data, 1, func);
837
838 Tcl_CreateCommand (Tkapp_Interp (self), cmdName, PythonCmd,
839 (ClientData) data, PythonCmdDelete);
840
841 Py_INCREF (Py_None);
842 return Py_None;
843}
844
845static PyObject *
846Tkapp_DeleteCommand (self, args)
847 PyObject *self;
848 PyObject *args;
849{
850 char *cmdName;
851
852 if (!PyArg_Parse (args, "s", &cmdName))
853 return NULL;
854 if (Tcl_DeleteCommand (Tkapp_Interp (self), cmdName) == -1)
855 {
856 PyErr_SetString (Tkinter_TclError, "can't delete Tcl command");
857 return NULL;
858 }
859 Py_INCREF (Py_None);
860 return Py_None;
861}
862
863/** File Handler **/
864
Guido van Rossuma597dde1995-01-10 20:56:29 +0000865static void
Guido van Rossum18468821994-06-20 07:49:28 +0000866FileHandler (clientData, mask)
Guido van Rossum76875221994-06-27 07:59:42 +0000867 ClientData clientData; /* Is: (func, file) */
Guido van Rossum18468821994-06-20 07:49:28 +0000868 int mask;
869{
Guido van Rossum76875221994-06-27 07:59:42 +0000870 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +0000871
Guido van Rossum76875221994-06-27 07:59:42 +0000872 func = PyTuple_GetItem ((PyObject *) clientData, 0);
873 file = PyTuple_GetItem ((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000874
Guido van Rossum76875221994-06-27 07:59:42 +0000875 arg = Py_BuildValue ("(Oi)", file, (long) mask);
Guido van Rossum18468821994-06-20 07:49:28 +0000876 res = PyEval_CallObject (func, arg);
877 Py_DECREF (arg);
878 if (res == NULL)
879 {
880 errorInCmd = 1;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000881 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
Guido van Rossum18468821994-06-20 07:49:28 +0000882 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000883 Py_XDECREF (res);
884}
885
886static int
887GetFileNo (file)
888 PyObject *file; /* Either an int >= 0 or an object with a
889 .fileno() method that returns an int >= 0 */
890{
Guido van Rossuma597dde1995-01-10 20:56:29 +0000891 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000892 int id;
893 if (PyInt_Check(file)) {
894 id = PyInt_AsLong(file);
895 if (id < 0)
896 PyErr_SetString(PyExc_ValueError, "invalid file id");
897 return id;
898 }
899 meth = PyObject_GetAttrString(file, "fileno");
900 if (meth == NULL)
901 return -1;
902 args = PyTuple_New(0);
903 if (args == NULL)
904 return -1;
905 res = PyEval_CallObject(meth, args);
906 Py_DECREF(args);
907 Py_DECREF(meth);
908 if (res == NULL)
909 return -1;
910 if (PyInt_Check(res))
911 id = PyInt_AsLong(res);
912 else
913 id = -1;
914 if (id < 0)
915 PyErr_SetString(PyExc_ValueError,
916 "invalid fileno() return value");
917 Py_DECREF(res);
918 return id;
Guido van Rossum18468821994-06-20 07:49:28 +0000919}
920
921static PyObject *
922Tkapp_CreateFileHandler (self, args)
923 PyObject *self;
924 PyObject *args; /* Is (file, mask, func) */
925{
Guido van Rossum76875221994-06-27 07:59:42 +0000926 PyObject *file, *func, *data;
927 int mask, id;
Guido van Rossum68784361996-05-16 17:17:31 +0000928#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
929 Tcl_File tfile;
930#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000931
932 if (!PyArg_Parse (args, "(OiO)", &file, &mask, &func))
933 return NULL;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000934 id = GetFileNo (file);
935 if (id < 0)
936 return NULL;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000937 if (!PyCallable_Check(func))
Guido van Rossum18468821994-06-20 07:49:28 +0000938 {
939 PyErr_SetString (PyExc_TypeError, "bad argument list");
940 return NULL;
941 }
942
Guido van Rossum76875221994-06-27 07:59:42 +0000943 /* ClientData is: (func, file) */
944 data = Py_BuildValue ("(OO)", func, file);
945
Guido van Rossum68784361996-05-16 17:17:31 +0000946#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Guido van Rossum07886d01996-09-11 23:31:42 +0000947#ifdef MS_WINDOWS
Guido van Rossum845547d1996-06-26 18:26:04 +0000948 /* We assume this is a socket... */
949 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
950#else
Guido van Rossum68784361996-05-16 17:17:31 +0000951 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +0000952#endif
Guido van Rossum68784361996-05-16 17:17:31 +0000953 /* Oughtta check for null Tcl_File object... */
954 Tcl_CreateFileHandler (tfile, mask, FileHandler, (ClientData) data);
955#else
Guido van Rossum845547d1996-06-26 18:26:04 +0000956 Tk_CreateFileHandler (id, mask, FileHandler, (ClientData) data);
Guido van Rossum68784361996-05-16 17:17:31 +0000957#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000958 /* XXX fileHandlerDict */
Guido van Rossum76875221994-06-27 07:59:42 +0000959
Guido van Rossum18468821994-06-20 07:49:28 +0000960 Py_INCREF (Py_None);
961 return Py_None;
962}
963
964static PyObject *
965Tkapp_DeleteFileHandler (self, args)
966 PyObject *self;
967 PyObject *args; /* Args: file */
968{
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000969 PyObject *file;
Guido van Rossum18468821994-06-20 07:49:28 +0000970 int id;
Guido van Rossum68784361996-05-16 17:17:31 +0000971#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
972 Tcl_File tfile;
973#endif
974
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000975 if (!PyArg_Parse (args, "O", &file))
976 return NULL;
977 id = GetFileNo (file);
978 if (id < 0)
979 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000980
Guido van Rossum68784361996-05-16 17:17:31 +0000981#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Guido van Rossum07886d01996-09-11 23:31:42 +0000982#ifdef MS_WINDOWS
Guido van Rossum845547d1996-06-26 18:26:04 +0000983 /* We assume this is a socket... */
984 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
985#else
986 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
987#endif
Guido van Rossum68784361996-05-16 17:17:31 +0000988 /* Oughtta check for null Tcl_File object... */
989 Tcl_DeleteFileHandler(tfile);
990#else
Guido van Rossum845547d1996-06-26 18:26:04 +0000991 Tk_DeleteFileHandler (id);
Guido van Rossum68784361996-05-16 17:17:31 +0000992#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000993 /* XXX fileHandlerDict */
994 Py_INCREF (Py_None);
995 return Py_None;
996}
997
Guido van Rossumf34cadd1994-11-10 22:50:21 +0000998/**** Tktt Object (timer token) ****/
999
1000staticforward PyTypeObject Tktt_Type;
1001
1002typedef struct
1003 {
1004 PyObject_HEAD
1005 Tk_TimerToken token;
1006 PyObject *func;
1007 }
1008TkttObject;
1009
1010static PyObject *
1011Tktt_DeleteTimerHandler (self, args)
1012 PyObject *self;
1013 PyObject *args;
1014{
1015 TkttObject *v = (TkttObject *) self;
1016
1017 if (!PyArg_Parse (args, ""))
1018 return NULL;
1019 if (v->func != NULL)
1020 {
1021 Tk_DeleteTimerHandler (v->token);
1022 PyMem_DEL (v->func);
1023 v->func = NULL;
1024 }
1025 Py_INCREF (Py_None);
1026 return Py_None;
1027}
1028
1029static PyMethodDef Tktt_methods[] =
1030{
1031 {"deletetimerhandler", Tktt_DeleteTimerHandler},
1032 {NULL, NULL}
1033};
1034
1035static TkttObject *
1036Tktt_New (token, func)
1037 Tk_TimerToken token;
1038 PyObject *func;
1039{
1040 TkttObject *v;
1041
1042 v = PyObject_NEW (TkttObject, &Tktt_Type);
1043 if (v == NULL)
1044 return NULL;
1045
1046 v->token = token;
1047 v->func = func;
1048 Py_INCREF (v->func);
1049 return v;
1050}
1051
1052static void
1053Tktt_Dealloc (self)
1054 PyObject *self;
1055{
1056 PyMem_DEL (self);
1057}
1058
1059static int
1060Tktt_Print (self, fp, flags)
1061 PyObject *self;
1062 FILE *fp;
1063 int flags;
1064{
1065 TkttObject *v = (TkttObject *) self;
1066
Guido van Rossuma376cc51996-12-05 23:43:35 +00001067 fprintf(fp, "<tktimertoken at 0x%lx%s>", (long)v,
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001068 v->func == NULL ? ", handler deleted" : "");
1069 return 0;
1070}
1071
1072static PyObject *
1073Tktt_GetAttr (self, name)
1074 PyObject *self;
1075 char *name;
1076{
1077 return Py_FindMethod (Tktt_methods, self, name);
1078}
1079
1080static PyTypeObject Tktt_Type =
1081{
Guido van Rossumae92f011996-08-21 19:03:36 +00001082 PyObject_HEAD_INIT (NULL)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001083 0, /*ob_size */
1084 "tktimertoken", /*tp_name */
1085 sizeof (TkttObject), /*tp_basicsize */
1086 0, /*tp_itemsize */
1087 Tktt_Dealloc, /*tp_dealloc */
1088 Tktt_Print, /*tp_print */
1089 Tktt_GetAttr, /*tp_getattr */
1090 0, /*tp_setattr */
1091 0, /*tp_compare */
1092 0, /*tp_repr */
1093 0, /*tp_as_number */
1094 0, /*tp_as_sequence */
1095 0, /*tp_as_mapping */
1096 0, /*tp_hash */
1097};
1098
1099/** Timer Handler **/
1100
1101static void
1102TimerHandler (clientData)
1103 ClientData clientData;
1104{
1105 PyObject *func = (PyObject *) clientData;
1106 PyObject *arg, *res;
1107
1108 arg = PyTuple_New (0);
1109 res = PyEval_CallObject (func, arg);
1110 Py_DECREF (arg);
1111 if (res == NULL)
1112 {
1113 errorInCmd = 1;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001114 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001115 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001116 else
1117 Py_DECREF (res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001118}
1119
1120static PyObject *
1121Tkapp_CreateTimerHandler (self, args)
1122 PyObject *self;
1123 PyObject *args; /* Is (milliseconds, func) */
1124{
1125 int milliseconds;
1126 PyObject *func;
1127 Tk_TimerToken token;
1128
1129 if (!PyArg_Parse (args, "(iO)", &milliseconds, &func))
1130 return NULL;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001131 if (!PyCallable_Check(func))
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001132 {
1133 PyErr_SetString (PyExc_TypeError, "bad argument list");
1134 return NULL;
1135 }
1136 token = Tk_CreateTimerHandler(milliseconds, TimerHandler, (ClientData) func);
1137 return (PyObject *) Tktt_New (token, func);
1138}
1139
Guido van Rossum18468821994-06-20 07:49:28 +00001140/** Event Loop **/
1141
Guido van Rossum18468821994-06-20 07:49:28 +00001142static PyObject *
1143Tkapp_MainLoop (self, args)
1144 PyObject *self;
1145 PyObject *args;
1146{
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001147 int threshold = 0;
1148
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001149 if (!PyArg_ParseTuple (args, "|i", &threshold))
1150 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001151
1152 quitMainLoop = 0;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001153 while (Tk_GetNumMainWindows() > threshold && !quitMainLoop && !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001154 {
Guido van Rossuma376cc51996-12-05 23:43:35 +00001155 /* XXX Ought to check for other signals! */
Guido van Rossum18468821994-06-20 07:49:28 +00001156 if (PyOS_InterruptOccurred ())
1157 {
1158 PyErr_SetNone (PyExc_KeyboardInterrupt);
1159 return NULL;
1160 }
1161 Tk_DoOneEvent (0);
1162 }
Guido van Rossum64b24fb1995-09-30 17:00:24 +00001163 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001164
1165 if (errorInCmd)
1166 {
1167 errorInCmd = 0;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001168 PyErr_Restore (excInCmd, valInCmd, trbInCmd);
1169 excInCmd = valInCmd = trbInCmd = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001170 return NULL;
1171 }
1172 Py_INCREF (Py_None);
1173 return Py_None;
1174}
1175
1176static PyObject *
Guido van Rossum062cfb01995-01-10 17:42:51 +00001177Tkapp_DoOneEvent (self, args)
1178 PyObject *self;
1179 PyObject *args;
1180{
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001181 int flags = TK_ALL_EVENTS;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001182 int rv;
1183
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001184 if (!PyArg_ParseTuple (args, "|i", &flags))
1185 return NULL;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001186 rv = Tk_DoOneEvent(flags);
1187 return Py_BuildValue ("i", rv);
1188}
1189
1190static PyObject *
Guido van Rossum18468821994-06-20 07:49:28 +00001191Tkapp_Quit (self, args)
1192 PyObject *self;
1193 PyObject *args;
1194{
1195
1196 if (!PyArg_Parse (args, ""))
1197 return NULL;
1198 quitMainLoop = 1;
1199 Py_INCREF (Py_None);
1200 return Py_None;
1201}
1202
1203/**** Tkapp Method List ****/
1204
1205static PyMethodDef Tkapp_methods[] =
1206{
1207 {"call", Tkapp_Call},
1208 {"globalcall", Tkapp_GlobalCall},
1209 {"eval", Tkapp_Eval},
1210 {"globaleval", Tkapp_GlobalEval},
1211 {"evalfile", Tkapp_EvalFile},
1212 {"record", Tkapp_Record},
1213 {"adderrorinfo", Tkapp_AddErrorInfo},
1214 {"setvar", Tkapp_SetVar},
1215 {"globalsetvar", Tkapp_GlobalSetVar},
1216 {"getvar", Tkapp_GetVar},
1217 {"globalgetvar", Tkapp_GlobalGetVar},
1218 {"unsetvar", Tkapp_UnsetVar},
1219 {"globalunsetvar", Tkapp_GlobalUnsetVar},
1220 {"getint", Tkapp_GetInt},
1221 {"getdouble", Tkapp_GetDouble},
1222 {"getboolean", Tkapp_GetBoolean},
1223 {"exprstring", Tkapp_ExprString},
1224 {"exprlong", Tkapp_ExprLong},
1225 {"exprdouble", Tkapp_ExprDouble},
1226 {"exprboolean", Tkapp_ExprBoolean},
1227 {"splitlist", Tkapp_SplitList},
1228 {"split", Tkapp_Split},
1229 {"merge", Tkapp_Merge},
1230 {"createcommand", Tkapp_CreateCommand},
1231 {"deletecommand", Tkapp_DeleteCommand},
1232 {"createfilehandler", Tkapp_CreateFileHandler},
1233 {"deletefilehandler", Tkapp_DeleteFileHandler},
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001234 {"createtimerhandler", Tkapp_CreateTimerHandler},
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001235 {"mainloop", Tkapp_MainLoop, 1},
1236 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum18468821994-06-20 07:49:28 +00001237 {"quit", Tkapp_Quit},
1238 {NULL, NULL}
1239};
1240
1241/**** Tkapp Type Methods ****/
1242
1243static void
1244Tkapp_Dealloc (self)
1245 PyObject *self;
1246{
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001247#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +00001248 Tk_DestroyWindow (Tkapp_Tkwin (self));
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001249#endif
Guido van Rossum18468821994-06-20 07:49:28 +00001250 Tcl_DeleteInterp (Tkapp_Interp (self));
1251 PyMem_DEL (self);
1252}
1253
1254static PyObject *
1255Tkapp_GetAttr (self, name)
1256 PyObject *self;
1257 char *name;
1258{
1259 return Py_FindMethod (Tkapp_methods, self, name);
1260}
1261
1262static PyTypeObject Tkapp_Type =
1263{
Guido van Rossumae92f011996-08-21 19:03:36 +00001264 PyObject_HEAD_INIT (NULL)
Guido van Rossum18468821994-06-20 07:49:28 +00001265 0, /*ob_size */
1266 "tkapp", /*tp_name */
1267 sizeof (TkappObject), /*tp_basicsize */
1268 0, /*tp_itemsize */
1269 Tkapp_Dealloc, /*tp_dealloc */
1270 0, /*tp_print */
1271 Tkapp_GetAttr, /*tp_getattr */
1272 0, /*tp_setattr */
1273 0, /*tp_compare */
1274 0, /*tp_repr */
1275 0, /*tp_as_number */
1276 0, /*tp_as_sequence */
1277 0, /*tp_as_mapping */
1278 0, /*tp_hash */
1279};
1280
1281/**** Tkinter Module ****/
1282
1283static PyObject *
1284Tkinter_Create (self, args)
1285 PyObject *self;
1286 PyObject *args;
1287{
1288 char *screenName = NULL;
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001289 char *baseName = NULL;
1290 char *className = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001291 int interactive = 0;
1292
Guido van Rossum32aa1a71996-07-31 19:51:15 +00001293 baseName = strrchr (Py_GetProgramName (), '/');
Guido van Rossum18468821994-06-20 07:49:28 +00001294 if (baseName != NULL)
1295 baseName++;
1296 else
Guido van Rossum32aa1a71996-07-31 19:51:15 +00001297 baseName = Py_GetProgramName ();
Guido van Rossum18468821994-06-20 07:49:28 +00001298 className = "Tk";
1299
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001300 if (!PyArg_ParseTuple (args, "|zssi",
1301 &screenName, &baseName, &className, &interactive))
Guido van Rossum18468821994-06-20 07:49:28 +00001302 return NULL;
1303
1304 return (PyObject *) Tkapp_New (screenName, baseName, className,
1305 interactive);
1306}
1307
1308static PyMethodDef moduleMethods[] =
1309{
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001310 {"create", Tkinter_Create, 1},
1311 {"createfilehandler", Tkapp_CreateFileHandler, 0},
1312 {"deletefilehandler", Tkapp_DeleteFileHandler, 0},
1313 {"createtimerhandler", Tkapp_CreateTimerHandler, 0},
1314 {"mainloop", Tkapp_MainLoop, 1},
1315 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001316 {"quit", Tkapp_Quit},
Guido van Rossum18468821994-06-20 07:49:28 +00001317 {NULL, NULL}
1318};
1319
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001320#undef WITH_READLINE /* XXX */
Guido van Rossum18468821994-06-20 07:49:28 +00001321#ifdef WITH_READLINE
1322static int
1323EventHook ()
1324{
1325 if (errorInCmd) /* XXX Reset tty */
1326 {
1327 errorInCmd = 0;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001328 PyErr_Restore (excInCmd, valInCmd, trbInCmd);
1329 excInCmd = valInCmd = trbInCmd = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001330 PyErr_Print ();
1331 }
Guido van Rossum9722ad81995-09-22 23:49:28 +00001332 if (Tk_GetNumMainWindows() > 0)
Guido van Rossume2ca9bd1994-08-03 08:01:43 +00001333 Tk_DoOneEvent (TK_DONT_WAIT);
Guido van Rossum18468821994-06-20 07:49:28 +00001334 return 0;
1335}
1336#endif /* WITH_READLINE */
1337
1338static void
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001339Tkinter_Cleanup ()
1340{
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001341/* This segfault with Tk 4.0 beta and seems unnecessary there as well */
1342#if TK_MAJOR_VERSION < 4
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001343 /* XXX rl_deprep_terminal is static, damned! */
1344 while (tkMainWindowList != 0)
1345 Tk_DestroyWindow (tkMainWindowList->win);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001346#endif
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001347}
1348
Guido van Rossum18468821994-06-20 07:49:28 +00001349void
Guido van Rossumad1f7ee1996-02-13 00:11:37 +00001350init_tkinter ()
Guido van Rossum18468821994-06-20 07:49:28 +00001351{
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001352 static inited = 0;
1353
Guido van Rossum18468821994-06-20 07:49:28 +00001354#ifdef WITH_READLINE
1355 extern int (*rl_event_hook) ();
1356#endif /* WITH_READLINE */
1357 PyObject *m, *d, *v;
1358
Guido van Rossumae92f011996-08-21 19:03:36 +00001359 Tkapp_Type.ob_type = &PyType_Type;
1360 Tktt_Type.ob_type = &PyType_Type;
1361
Jack Jansenba0311e1995-10-23 14:34:14 +00001362 m = Py_InitModule ("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001363
1364 d = PyModule_GetDict (m);
1365 Tkinter_TclError = Py_BuildValue ("s", "TclError");
1366 PyDict_SetItemString (d, "TclError", Tkinter_TclError);
1367
1368 v = Py_BuildValue ("i", TK_READABLE);
1369 PyDict_SetItemString (d, "READABLE", v);
1370 v = Py_BuildValue ("i", TK_WRITABLE);
1371 PyDict_SetItemString (d, "WRITABLE", v);
1372 v = Py_BuildValue ("i", TK_EXCEPTION);
1373 PyDict_SetItemString (d, "EXCEPTION", v);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001374 v = Py_BuildValue ("i", TK_X_EVENTS);
1375 PyDict_SetItemString (d, "X_EVENTS", v);
1376 v = Py_BuildValue ("i", TK_FILE_EVENTS);
1377 PyDict_SetItemString (d, "FILE_EVENTS", v);
1378 v = Py_BuildValue ("i", TK_TIMER_EVENTS);
1379 PyDict_SetItemString (d, "TIMER_EVENTS", v);
1380 v = Py_BuildValue ("i", TK_IDLE_EVENTS);
1381 PyDict_SetItemString (d, "IDLE_EVENTS", v);
1382 v = Py_BuildValue ("i", TK_ALL_EVENTS);
1383 PyDict_SetItemString (d, "ALL_EVENTS", v);
1384 v = Py_BuildValue ("i", TK_DONT_WAIT);
1385 PyDict_SetItemString (d, "DONT_WAIT", v);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001386 v = Py_BuildValue ("s", TK_VERSION);
1387 PyDict_SetItemString (d, "TK_VERSION", v);
1388 v = Py_BuildValue ("s", TCL_VERSION);
1389 PyDict_SetItemString (d, "TCL_VERSION", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001390
Guido van Rossum18468821994-06-20 07:49:28 +00001391#ifdef WITH_READLINE
1392 rl_event_hook = EventHook;
1393#endif /* WITH_READLINE */
1394
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001395 if (!inited)
1396 {
1397 inited = 1;
Guido van Rossume4485b01994-09-07 14:32:49 +00001398 if (Py_AtExit (Tkinter_Cleanup) != 0)
1399 fprintf(stderr,
1400 "Tkinter: warning: cleanup procedure not registered\n");
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001401 }
1402
Guido van Rossum18468821994-06-20 07:49:28 +00001403 if (PyErr_Occurred ())
Jack Jansenba0311e1995-10-23 14:34:14 +00001404 Py_FatalError ("can't initialize module _tkinter");
Jack Jansen34cc5c31995-10-31 16:15:12 +00001405#ifdef macintosh
Guido van Rossumec22c921996-02-25 04:50:29 +00001406 TclMacSetEventProc(PyMacConvertEvent);
1407#if GENERATINGCFM
Jack Jansen34cc5c31995-10-31 16:15:12 +00001408 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001409#endif /* GENERATINGCFM */
1410#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001411}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001412
Guido van Rossumec22c921996-02-25 04:50:29 +00001413
Guido van Rossum9722ad81995-09-22 23:49:28 +00001414#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001415
1416/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001417** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001418*/
1419
Guido van Rossum9722ad81995-09-22 23:49:28 +00001420void
1421panic(char * format, ...)
1422{
1423 va_list varg;
1424
1425 va_start(varg, format);
1426
1427 vfprintf(stderr, format, varg);
1428 (void) fflush(stderr);
1429
1430 va_end(varg);
1431
1432 Py_FatalError("Tcl/Tk panic");
1433}
Jack Jansen40b546d1995-11-14 10:34:45 +00001434
Guido van Rossumec22c921996-02-25 04:50:29 +00001435/*
1436** Pass events to SIOUX before passing them to Tk.
1437*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001438
Guido van Rossumec22c921996-02-25 04:50:29 +00001439static int
1440PyMacConvertEvent(eventPtr)
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001441 EventRecord *eventPtr;
1442{
Guido van Rossumec22c921996-02-25 04:50:29 +00001443 if (SIOUXHandleOneEvent(eventPtr))
1444 return 0; /* Nothing happened to the Tcl event queue */
1445 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001446}
1447
Guido van Rossumec22c921996-02-25 04:50:29 +00001448#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001449
1450/*
1451** Additional Mac specific code for dealing with shared libraries.
1452*/
1453
1454#include <Resources.h>
1455#include <CodeFragments.h>
1456
1457static int loaded_from_shlib = 0;
1458static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001459
Jack Jansen34cc5c31995-10-31 16:15:12 +00001460/*
1461** If this module is dynamically loaded the following routine should
1462** be the init routine. It takes care of adding the shared library to
1463** the resource-file chain, so that the tk routines can find their
1464** resources.
1465*/
1466OSErr pascal
1467init_tkinter_shlib(InitBlockPtr data)
1468{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00001469 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00001470 if ( data == nil ) return noErr;
1471 if ( data->fragLocator.where == kOnDiskFlat ) {
1472 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1473 loaded_from_shlib = 1;
1474 } else if ( data->fragLocator.where == kOnDiskSegmented ) {
1475 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1476 loaded_from_shlib = 1;
1477 }
1478 return noErr;
1479}
1480
1481/*
1482** Insert the library resources into the search path. Put them after
1483** the resources from the application. Again, we ignore errors.
1484*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001485static
Jack Jansen34cc5c31995-10-31 16:15:12 +00001486mac_addlibresources()
1487{
1488 if ( !loaded_from_shlib )
1489 return;
1490 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1491}
1492
Guido van Rossumec22c921996-02-25 04:50:29 +00001493#endif /* GENERATINGCFM */
1494#endif /* macintosh */