blob: bbada358e8b3d832a1c75b9614c7f8d6bbd0683e [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
8Permission to use, copy, modify, and distribute this software and its
9documentation for any purpose and without fee is hereby granted,
10provided that the above copyright notice appear in all copies and that
11both that copyright notice and this permission notice appear in
12supporting documentation, and that the names of Stichting Mathematisch
13Centrum or CWI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior permission.
15
16STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
17THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
19FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
22OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
24******************************************************************/
25
26/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +000027
Guido van Rossum9722ad81995-09-22 23:49:28 +000028#include "Python.h"
29
Guido van Rossum18468821994-06-20 07:49:28 +000030#include <tcl.h>
31#include <tk.h>
32
Guido van Rossum32aa1a71996-07-31 19:51:15 +000033extern char *Py_GetProgramName ();
Guido van Rossumd308e2b1994-07-07 09:25:12 +000034
Guido van Rossum9722ad81995-09-22 23:49:28 +000035/* Internal declarations from tkInt.h. */
36#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
37extern int Tk_GetNumMainWindows();
38#else
Guido van Rossum18468821994-06-20 07:49:28 +000039extern int tk_NumMainWindows;
Guido van Rossum9722ad81995-09-22 23:49:28 +000040#define Tk_GetNumMainWindows() (tk_NumMainWindows)
Guido van Rossumdfd428d1996-02-25 04:46:40 +000041#define NEED_TKCREATEMAINWINDOW 1
Guido van Rossum9722ad81995-09-22 23:49:28 +000042#endif
43
44#if TK_MAJOR_VERSION < 4
Guido van Rossumd308e2b1994-07-07 09:25:12 +000045extern struct { Tk_Window win; } *tkMainWindowList;
Guido van Rossum9722ad81995-09-22 23:49:28 +000046#endif
Guido van Rossum18468821994-06-20 07:49:28 +000047
Guido van Rossumec22c921996-02-25 04:50:29 +000048#ifdef macintosh
49
50/*
51** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum845547d1996-06-26 18:26:04 +000052** This is for Tcl 7.5 and Tk 4.1 (final releases).
Guido van Rossumec22c921996-02-25 04:50:29 +000053*/
54
55#include <Events.h> /* For EventRecord */
56
57typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
58void TclMacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
59int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
60
61staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
62
63#endif /* macintosh */
64
Guido van Rossum18468821994-06-20 07:49:28 +000065/**** Tkapp Object Declaration ****/
66
67staticforward PyTypeObject Tkapp_Type;
68
69typedef struct
70 {
71 PyObject_HEAD
72 Tcl_Interp *interp;
Guido van Rossumdfd428d1996-02-25 04:46:40 +000073#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +000074 Tk_Window tkwin;
Guido van Rossumdfd428d1996-02-25 04:46:40 +000075#endif
Guido van Rossum18468821994-06-20 07:49:28 +000076 }
77TkappObject;
78
79#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossumdfd428d1996-02-25 04:46:40 +000080#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +000081#define Tkapp_Tkwin(v) (((TkappObject *) (v))->tkwin)
Guido van Rossumdfd428d1996-02-25 04:46:40 +000082#endif
Guido van Rossum18468821994-06-20 07:49:28 +000083#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
84#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
85
86#define DEBUG_REFCNT(v) (printf ("DEBUG: id=%p, refcnt=%i\n", \
87 (void *) v, ((PyObject *) v)->ob_refcnt))
88
89/**** Error Handling ****/
90
91static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +000092static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +000093static int errorInCmd = 0;
94static PyObject *excInCmd;
95static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +000096static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +000097
98static PyObject *
99Tkinter_Error (v)
100 PyObject *v;
101{
Guido van Rossum18468821994-06-20 07:49:28 +0000102 PyErr_SetString (Tkinter_TclError, Tkapp_Result (v));
103 return NULL;
104}
105
106int
107PythonCmd_Error (interp)
108 Tcl_Interp *interp;
109{
110 errorInCmd = 1;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000111 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
Guido van Rossum18468821994-06-20 07:49:28 +0000112 return TCL_ERROR;
113}
114
115/**** Utils ****/
116
117static char *
118AsString (value, tmp)
119 PyObject *value;
120 PyObject *tmp;
121{
122 if (PyString_Check (value))
123 return PyString_AsString (value);
124 else
125 {
126 PyObject *v;
127
Guido van Rossumcd938fc1995-01-17 16:13:48 +0000128 v = PyObject_Str (value);
Guido van Rossum18468821994-06-20 07:49:28 +0000129 PyList_Append (tmp, v);
130 Py_DECREF (v);
131 return PyString_AsString (v);
132 }
133}
134
135#define ARGSZ 64
136
137static char *
138Merge (args)
139 PyObject *args;
140{
141 PyObject *tmp;
142 char *argvStore[ARGSZ];
143 char **argv;
144 int fvStore[ARGSZ];
145 int *fv;
146 int argc;
147 char *res;
148 int i;
149
150 tmp = PyList_New (0);
151 argv = argvStore;
152 fv = fvStore;
153
Guido van Rossum845547d1996-06-26 18:26:04 +0000154 if (args == NULL)
155 {
156 argc = 0;
157 }
158 else if (!PyTuple_Check (args))
Guido van Rossum18468821994-06-20 07:49:28 +0000159 {
160 argc = 1;
161 fv[0] = 0;
162 argv[0] = AsString (args, tmp);
163 }
164 else
165 {
166 PyObject *v;
167
168 if (PyTuple_Size (args) > ARGSZ)
169 {
Guido van Rossumb6fe7041995-03-09 12:13:43 +0000170 argv = (char **) malloc (PyTuple_Size (args) * sizeof (char *));
171 fv = (int *) malloc (PyTuple_Size (args) * sizeof (int));
Guido van Rossum18468821994-06-20 07:49:28 +0000172 if (argv == NULL || fv == NULL)
173 PyErr_NoMemory ();
174 }
175
176 argc = PyTuple_Size (args);
177 for (i = 0; i < argc; i++)
178 {
179 v = PyTuple_GetItem (args, i);
180 if (PyTuple_Check (v))
181 {
182 fv[i] = 1;
183 argv[i] = Merge (v);
184 }
185 else if (v == Py_None)
186 {
187 argc = i;
188 break;
189 }
190 else
191 {
192 fv[i] = 0;
193 argv[i] = AsString (v, tmp);
194 }
195 }
196 }
197
198 res = Tcl_Merge (argc, argv);
199
200 Py_DECREF (tmp);
201 for (i = 0; i < argc; i++)
202 if (fv[i]) free (argv[i]);
203 if (argv != argvStore)
204 free (argv);
205 if (fv != fvStore)
206 free (fv);
207
208 return res;
209}
210
211static PyObject *
212Split (self, list)
213 PyObject *self;
214 char *list;
215{
216 int argc;
217 char **argv;
218 PyObject *v;
219
220 if (list == NULL)
221 {
222 Py_INCREF (Py_None);
223 return Py_None;
224 }
225
226 if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
227 return Tkinter_Error (self);
228
229 if (argc == 0)
230 v = PyString_FromString ("");
231 else if (argc == 1)
232 v = PyString_FromString (argv[0]);
233 else
234 {
235 int i;
236
237 v = PyTuple_New (argc);
238 for (i = 0; i < argc; i++)
239 PyTuple_SetItem (v, i, Split (self, argv[i]));
240 }
241
242 free (argv);
243 return v;
244}
245
246/**** Tkapp Object ****/
247
248#ifndef WITH_APPINIT
249int
250Tcl_AppInit (interp)
251 Tcl_Interp *interp;
252{
Guido van Rossumec22c921996-02-25 04:50:29 +0000253 Tk_Window main;
254
255 main = Tk_MainWindow(interp);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000256 if (Tcl_Init (interp) == TCL_ERROR) {
257 fprintf(stderr, "Tcl_Init error: %s\n", interp->result);
Guido van Rossum18468821994-06-20 07:49:28 +0000258 return TCL_ERROR;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000259 }
260 if (Tk_Init (interp) == TCL_ERROR) {
261 fprintf(stderr, "Tk_Init error: %s\n", interp->result);
Guido van Rossum18468821994-06-20 07:49:28 +0000262 return TCL_ERROR;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000263 }
Guido van Rossum18468821994-06-20 07:49:28 +0000264 return TCL_OK;
265}
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000266
Guido van Rossum18468821994-06-20 07:49:28 +0000267#endif /* !WITH_APPINIT */
268
269/* Initialize the Tk application; see the `main' function in
270 `tkMain.c'. */
271static TkappObject *
272Tkapp_New (screenName, baseName, className, interactive)
273 char *screenName;
274 char *baseName;
275 char *className;
276 int interactive;
277{
278 TkappObject *v;
279
280 v = PyObject_NEW (TkappObject, &Tkapp_Type);
281 if (v == NULL)
282 return NULL;
283
284 v->interp = Tcl_CreateInterp ();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000285
286#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +0000287 v->tkwin = Tk_CreateMainWindow (v->interp, screenName,
288 baseName, className);
289 if (v->tkwin == NULL)
290 return (TkappObject *) Tkinter_Error ((PyObject *) v);
291
292 Tk_GeometryRequest (v->tkwin, 200, 200);
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000293#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000294
295 if (screenName != NULL)
296 Tcl_SetVar2 (v->interp, "env", "DISPLAY", screenName, TCL_GLOBAL_ONLY);
297
298 if (interactive)
299 Tcl_SetVar (v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
300 else
301 Tcl_SetVar (v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
302
Guido van Rossum18468821994-06-20 07:49:28 +0000303 if (Tcl_AppInit (v->interp) != TCL_OK)
Guido van Rossum845547d1996-06-26 18:26:04 +0000304 return (TkappObject *) Tkinter_Error (v);
Guido van Rossum18468821994-06-20 07:49:28 +0000305
306 return v;
307}
308
309/** Tcl Eval **/
310
311static PyObject *
312Tkapp_Call (self, args)
313 PyObject *self;
314 PyObject *args;
315{
316 char *cmd;
317
318 cmd = Merge (args);
319 if (Tcl_Eval (Tkapp_Interp (self), cmd) == TCL_ERROR)
320 {
321 free (cmd);
322 return Tkinter_Error (self);
323 }
324
325 free (cmd);
326 return PyString_FromString (Tkapp_Result (self));
327}
328
329static PyObject *
330Tkapp_GlobalCall (self, args)
331 PyObject *self;
332 PyObject *args;
333{
334 char *cmd;
335
336 cmd = Merge (args);
337 if (Tcl_GlobalEval (Tkapp_Interp (self), cmd) == TCL_ERROR)
338 {
339 free (cmd);
340 return Tkinter_Error (self);
341 }
342
343 free (cmd);
344 return PyString_FromString (Tkapp_Result (self));
345}
346
347static PyObject *
348Tkapp_Eval (self, args)
349 PyObject *self;
350 PyObject *args;
351{
352 char *script;
353
354 if (!PyArg_Parse (args, "s", &script))
355 return NULL;
356
357 if (Tcl_Eval (Tkapp_Interp (self), script) == TCL_ERROR)
358 return Tkinter_Error (self);
359
360 return PyString_FromString (Tkapp_Result (self));
361}
362
363static PyObject *
364Tkapp_GlobalEval (self, args)
365 PyObject *self;
366 PyObject *args;
367{
368 char *script;
369
370 if (!PyArg_Parse (args, "s", &script))
371 return NULL;
372
373 if (Tcl_GlobalEval (Tkapp_Interp (self), script) == TCL_ERROR)
374 return Tkinter_Error (self);
375
376 return PyString_FromString (Tkapp_Result (self));
377}
378
379static PyObject *
380Tkapp_EvalFile (self, args)
381 PyObject *self;
382 PyObject *args;
383{
384 char *fileName;
385
386 if (!PyArg_Parse (args, "s", &fileName))
387 return NULL;
388
389 if (Tcl_EvalFile (Tkapp_Interp (self), fileName) == TCL_ERROR)
390 return Tkinter_Error (self);
391
392 return PyString_FromString (Tkapp_Result (self));
393}
394
395static PyObject *
396Tkapp_Record (self, args)
397 PyObject *self;
398 PyObject *args;
399{
400 char *script;
401
402 if (!PyArg_Parse (args, "s", &script))
403 return NULL;
404
405 if (Tcl_RecordAndEval (Tkapp_Interp (self),
406 script, TCL_NO_EVAL) == TCL_ERROR)
407 return Tkinter_Error (self);
408
409 return PyString_FromString (Tkapp_Result (self));
410}
411
412static PyObject *
413Tkapp_AddErrorInfo (self, args)
414 PyObject *self;
415 PyObject *args;
416{
417 char *msg;
418
419 if (!PyArg_Parse (args, "s", &msg))
420 return NULL;
421 Tcl_AddErrorInfo (Tkapp_Interp (self), msg);
422
423 Py_INCREF(Py_None);
424 return Py_None;
425}
426
427/** Tcl Variable **/
428
429static PyObject *
430SetVar (self, args, flags)
431 PyObject *self;
432 PyObject *args;
433 int flags;
434{
435 char *name1, *name2, *ok;
436 PyObject *newValue;
437 PyObject *tmp;
438
439 tmp = PyList_New (0);
440
441 if (PyArg_Parse (args, "(sO)", &name1, &newValue))
442 ok = Tcl_SetVar (Tkapp_Interp (self), name1,
443 AsString (newValue, tmp), flags); /* XXX Merge? */
444 else if (PyArg_Parse (args, "(ssO)", &name1, &name2, &newValue))
445 ok = Tcl_SetVar2 (Tkapp_Interp (self), name1, name2,
446 AsString (newValue, tmp), flags);
447 else
448 {
449 Py_DECREF (tmp);
450 return NULL;
451 }
452 Py_DECREF (tmp);
453
454 if (!ok)
455 return Tkinter_Error (self);
456
457 Py_INCREF (Py_None);
458 return Py_None;
459}
460
461static PyObject *
462Tkapp_SetVar (self, args)
463 PyObject *self;
464 PyObject *args;
465{
466 return SetVar (self, args, TCL_LEAVE_ERR_MSG);
467}
468
469static PyObject *
470Tkapp_GlobalSetVar (self, args)
471 PyObject *self;
472 PyObject *args;
473{
474 return SetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
475}
476
477static PyObject *
478GetVar (self, args, flags)
479 PyObject *self;
480 PyObject *args;
481 int flags;
482{
483 char *name1, *name2, *s;
484
485 if (PyArg_Parse (args, "s", &name1))
486 s = Tcl_GetVar (Tkapp_Interp (self), name1, flags);
487 else if (PyArg_Parse (args, "(ss)", &name1, &name2))
488 s = Tcl_GetVar2 (Tkapp_Interp (self), name1, name2, flags);
489 else
490 return NULL;
491
492 if (s == NULL)
493 return Tkinter_Error (self);
494
495 return PyString_FromString (s);
496}
497
498static PyObject *
499Tkapp_GetVar (self, args)
500 PyObject *self;
501 PyObject *args;
502{
503 return GetVar (self, args, TCL_LEAVE_ERR_MSG);
504}
505
506static PyObject *
507Tkapp_GlobalGetVar (self, args)
508 PyObject *self;
509 PyObject *args;
510{
511 return GetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
512}
513
514static PyObject *
515UnsetVar (self, args, flags)
516 PyObject *self;
517 PyObject *args;
518 int flags;
519{
520 char *name1, *name2;
521 int code;
522
523 if (PyArg_Parse (args, "s", &name1))
524 code = Tcl_UnsetVar (Tkapp_Interp (self), name1, flags);
525 else if (PyArg_Parse (args, "(ss)", &name1, &name2))
526 code = Tcl_UnsetVar2 (Tkapp_Interp (self), name1, name2, flags);
527 else
528 return NULL;
529
530 if (code == TCL_ERROR)
531 return Tkinter_Error (self);
532
533 Py_INCREF (Py_None);
534 return Py_None;
535}
536
537static PyObject *
538Tkapp_UnsetVar (self, args)
539 PyObject *self;
540 PyObject *args;
541{
542 return UnsetVar (self, args, TCL_LEAVE_ERR_MSG);
543}
544
545static PyObject *
546Tkapp_GlobalUnsetVar (self, args)
547 PyObject *self;
548 PyObject *args;
549{
550 return UnsetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
551}
552
553/** Tcl to Python **/
554
555static PyObject *
556Tkapp_GetInt (self, args)
557 PyObject *self;
558 PyObject *args;
559{
560 char *s;
561 int v;
562
563 if (!PyArg_Parse (args, "s", &s))
564 return NULL;
565 if (Tcl_GetInt (Tkapp_Interp (self), s, &v) == TCL_ERROR)
566 return Tkinter_Error (self);
567 return Py_BuildValue ("i", v);
568}
569
570static PyObject *
571Tkapp_GetDouble (self, args)
572 PyObject *self;
573 PyObject *args;
574{
575 char *s;
576 double v;
577
578 if (!PyArg_Parse (args, "s", &s))
579 return NULL;
580 if (Tcl_GetDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
581 return Tkinter_Error (self);
582 return Py_BuildValue ("d", v);
583}
584
585static PyObject *
586Tkapp_GetBoolean (self, args)
587 PyObject *self;
588 PyObject *args;
589{
590 char *s;
591 int v;
592
593 if (!PyArg_Parse (args, "s", &s))
594 return NULL;
595 if (Tcl_GetBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
596 return Tkinter_Error (self);
597 return Py_BuildValue ("i", v);
598}
599
600static PyObject *
601Tkapp_ExprString (self, args)
602 PyObject *self;
603 PyObject *args;
604{
605 char *s;
606
607 if (!PyArg_Parse (args, "s", &s))
608 return NULL;
609 if (Tcl_ExprString (Tkapp_Interp (self), s) == TCL_ERROR)
610 return Tkinter_Error (self);
611 return Py_BuildValue ("s", Tkapp_Result (self));
612}
613
614static PyObject *
615Tkapp_ExprLong (self, args)
616 PyObject *self;
617 PyObject *args;
618{
619 char *s;
620 long v;
621
622 if (!PyArg_Parse (args, "s", &s))
623 return NULL;
624 if (Tcl_ExprLong (Tkapp_Interp (self), s, &v) == TCL_ERROR)
625 return Tkinter_Error (self);
626 return Py_BuildValue ("l", v);
627}
628
629static PyObject *
630Tkapp_ExprDouble (self, args)
631 PyObject *self;
632 PyObject *args;
633{
634 char *s;
635 double v;
636
637 if (!PyArg_Parse (args, "s", &s))
638 return NULL;
639 if (Tcl_ExprDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
640 return Tkinter_Error (self);
641 return Py_BuildValue ("d", v);
642}
643
644static PyObject *
645Tkapp_ExprBoolean (self, args)
646 PyObject *self;
647 PyObject *args;
648{
649 char *s;
650 int v;
651
652 if (!PyArg_Parse (args, "s", &s))
653 return NULL;
654 if (Tcl_ExprBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
655 return Tkinter_Error (self);
656 return Py_BuildValue ("i", v);
657}
658
659static PyObject *
660Tkapp_SplitList (self, args)
661 PyObject *self;
662 PyObject *args;
663{
664 char *list;
665 int argc;
666 char **argv;
667 PyObject *v;
668 int i;
669
670 if (!PyArg_Parse (args, "s", &list))
671 return NULL;
672
673 if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
674 return Tkinter_Error (self);
675
676 v = PyTuple_New (argc);
677 for (i = 0; i < argc; i++)
678 PyTuple_SetItem (v, i, PyString_FromString (argv[i]));
679
680 free (argv);
681 return v;
682}
683
684static PyObject *
685Tkapp_Split (self, args)
686 PyObject *self;
687 PyObject *args;
688{
689 char *list;
690
691 if (!PyArg_Parse (args, "s", &list))
692 return NULL;
693 return Split (self, list);
694}
695
696static PyObject *
697Tkapp_Merge (self, args)
698 PyObject *self;
699 PyObject *args;
700{
701 char *s;
702 PyObject *v;
703
704 s = Merge (args);
705 v = PyString_FromString (s);
706 free (s);
707 return v;
708}
709
710/** Tcl Command **/
711
712/* This is the Tcl command that acts as a wrapper for Python
713 function or method. */
714static int
715PythonCmd (clientData, interp, argc, argv)
716 ClientData clientData; /* Is (self, func) */
717 Tcl_Interp *interp;
718 int argc;
719 char *argv[];
720{
721 PyObject *self, *func, *arg, *res, *tmp;
722 int i;
723
724 self = PyTuple_GetItem ((PyObject *) clientData, 0);
725 func = PyTuple_GetItem ((PyObject *) clientData, 1);
726
727 /* Create argument list (argv1, ..., argvN) */
728 arg = PyTuple_New (argc - 1);
729 for (i = 0; i < (argc - 1); i++)
730 PyTuple_SetItem (arg, i, PyString_FromString (argv[i + 1]));
731
732 res = PyEval_CallObject (func, arg);
733 Py_DECREF (arg);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000734
Guido van Rossum18468821994-06-20 07:49:28 +0000735 if (res == NULL)
736 return PythonCmd_Error (interp);
737
738 tmp = PyList_New (0);
739 Tcl_SetResult (Tkapp_Interp (self), AsString (res, tmp), TCL_VOLATILE);
740 Py_DECREF (res);
741 Py_DECREF (tmp);
742
743 return TCL_OK;
744}
745
746static void
747PythonCmdDelete (clientData)
748 ClientData clientData; /* Is (self, func) */
749{
750 Py_DECREF ((PyObject *) clientData);
751}
752
753static PyObject *
754Tkapp_CreateCommand (self, args)
755 PyObject *self;
756 PyObject *args;
757{
758 char *cmdName;
759 PyObject *data;
760 PyObject *func;
761
762 /* Args is: (cmdName, func) */
763 if (!PyTuple_Check (args)
764 || !(PyTuple_Size (args) == 2)
765 || !PyString_Check (PyTuple_GetItem (args, 0))
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000766 || !PyCallable_Check (PyTuple_GetItem (args, 1)))
Guido van Rossum18468821994-06-20 07:49:28 +0000767 {
768 PyErr_SetString (PyExc_TypeError, "bad argument list");
769 return NULL;
770 }
771
772 cmdName = PyString_AsString (PyTuple_GetItem (args, 0));
773 func = PyTuple_GetItem (args, 1);
774
775 data = PyTuple_New (2); /* ClientData is: (self, func) */
776
777 Py_INCREF (self);
778 PyTuple_SetItem (data, 0, self);
779
780 Py_INCREF (func);
781 PyTuple_SetItem (data, 1, func);
782
783 Tcl_CreateCommand (Tkapp_Interp (self), cmdName, PythonCmd,
784 (ClientData) data, PythonCmdDelete);
785
786 Py_INCREF (Py_None);
787 return Py_None;
788}
789
790static PyObject *
791Tkapp_DeleteCommand (self, args)
792 PyObject *self;
793 PyObject *args;
794{
795 char *cmdName;
796
797 if (!PyArg_Parse (args, "s", &cmdName))
798 return NULL;
799 if (Tcl_DeleteCommand (Tkapp_Interp (self), cmdName) == -1)
800 {
801 PyErr_SetString (Tkinter_TclError, "can't delete Tcl command");
802 return NULL;
803 }
804 Py_INCREF (Py_None);
805 return Py_None;
806}
807
808/** File Handler **/
809
Guido van Rossuma597dde1995-01-10 20:56:29 +0000810static void
Guido van Rossum18468821994-06-20 07:49:28 +0000811FileHandler (clientData, mask)
Guido van Rossum76875221994-06-27 07:59:42 +0000812 ClientData clientData; /* Is: (func, file) */
Guido van Rossum18468821994-06-20 07:49:28 +0000813 int mask;
814{
Guido van Rossum76875221994-06-27 07:59:42 +0000815 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +0000816
Guido van Rossum76875221994-06-27 07:59:42 +0000817 func = PyTuple_GetItem ((PyObject *) clientData, 0);
818 file = PyTuple_GetItem ((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000819
Guido van Rossum76875221994-06-27 07:59:42 +0000820 arg = Py_BuildValue ("(Oi)", file, (long) mask);
Guido van Rossum18468821994-06-20 07:49:28 +0000821 res = PyEval_CallObject (func, arg);
822 Py_DECREF (arg);
823 if (res == NULL)
824 {
825 errorInCmd = 1;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000826 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
Guido van Rossum18468821994-06-20 07:49:28 +0000827 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000828 Py_XDECREF (res);
829}
830
831static int
832GetFileNo (file)
833 PyObject *file; /* Either an int >= 0 or an object with a
834 .fileno() method that returns an int >= 0 */
835{
Guido van Rossuma597dde1995-01-10 20:56:29 +0000836 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000837 int id;
838 if (PyInt_Check(file)) {
839 id = PyInt_AsLong(file);
840 if (id < 0)
841 PyErr_SetString(PyExc_ValueError, "invalid file id");
842 return id;
843 }
844 meth = PyObject_GetAttrString(file, "fileno");
845 if (meth == NULL)
846 return -1;
847 args = PyTuple_New(0);
848 if (args == NULL)
849 return -1;
850 res = PyEval_CallObject(meth, args);
851 Py_DECREF(args);
852 Py_DECREF(meth);
853 if (res == NULL)
854 return -1;
855 if (PyInt_Check(res))
856 id = PyInt_AsLong(res);
857 else
858 id = -1;
859 if (id < 0)
860 PyErr_SetString(PyExc_ValueError,
861 "invalid fileno() return value");
862 Py_DECREF(res);
863 return id;
Guido van Rossum18468821994-06-20 07:49:28 +0000864}
865
866static PyObject *
867Tkapp_CreateFileHandler (self, args)
868 PyObject *self;
869 PyObject *args; /* Is (file, mask, func) */
870{
Guido van Rossum76875221994-06-27 07:59:42 +0000871 PyObject *file, *func, *data;
872 int mask, id;
Guido van Rossum68784361996-05-16 17:17:31 +0000873#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
874 Tcl_File tfile;
875#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000876
877 if (!PyArg_Parse (args, "(OiO)", &file, &mask, &func))
878 return NULL;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000879 id = GetFileNo (file);
880 if (id < 0)
881 return NULL;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000882 if (!PyCallable_Check(func))
Guido van Rossum18468821994-06-20 07:49:28 +0000883 {
884 PyErr_SetString (PyExc_TypeError, "bad argument list");
885 return NULL;
886 }
887
Guido van Rossum76875221994-06-27 07:59:42 +0000888 /* ClientData is: (func, file) */
889 data = Py_BuildValue ("(OO)", func, file);
890
Guido van Rossum68784361996-05-16 17:17:31 +0000891#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Guido van Rossum845547d1996-06-26 18:26:04 +0000892#ifdef NT
893 /* We assume this is a socket... */
894 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
895#else
Guido van Rossum68784361996-05-16 17:17:31 +0000896 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +0000897#endif
Guido van Rossum68784361996-05-16 17:17:31 +0000898 /* Oughtta check for null Tcl_File object... */
899 Tcl_CreateFileHandler (tfile, mask, FileHandler, (ClientData) data);
900#else
Guido van Rossum845547d1996-06-26 18:26:04 +0000901 Tk_CreateFileHandler (id, mask, FileHandler, (ClientData) data);
Guido van Rossum68784361996-05-16 17:17:31 +0000902#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000903 /* XXX fileHandlerDict */
Guido van Rossum76875221994-06-27 07:59:42 +0000904
Guido van Rossum18468821994-06-20 07:49:28 +0000905 Py_INCREF (Py_None);
906 return Py_None;
907}
908
909static PyObject *
910Tkapp_DeleteFileHandler (self, args)
911 PyObject *self;
912 PyObject *args; /* Args: file */
913{
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000914 PyObject *file;
Guido van Rossum18468821994-06-20 07:49:28 +0000915 int id;
Guido van Rossum68784361996-05-16 17:17:31 +0000916#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
917 Tcl_File tfile;
918#endif
919
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000920 if (!PyArg_Parse (args, "O", &file))
921 return NULL;
922 id = GetFileNo (file);
923 if (id < 0)
924 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000925
Guido van Rossum68784361996-05-16 17:17:31 +0000926#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Guido van Rossum845547d1996-06-26 18:26:04 +0000927#ifdef NT
928 /* We assume this is a socket... */
929 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
930#else
931 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
932#endif
Guido van Rossum68784361996-05-16 17:17:31 +0000933 /* Oughtta check for null Tcl_File object... */
934 Tcl_DeleteFileHandler(tfile);
935#else
Guido van Rossum845547d1996-06-26 18:26:04 +0000936 Tk_DeleteFileHandler (id);
Guido van Rossum68784361996-05-16 17:17:31 +0000937#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000938 /* XXX fileHandlerDict */
939 Py_INCREF (Py_None);
940 return Py_None;
941}
942
Guido van Rossumf34cadd1994-11-10 22:50:21 +0000943/**** Tktt Object (timer token) ****/
944
945staticforward PyTypeObject Tktt_Type;
946
947typedef struct
948 {
949 PyObject_HEAD
950 Tk_TimerToken token;
951 PyObject *func;
952 }
953TkttObject;
954
955static PyObject *
956Tktt_DeleteTimerHandler (self, args)
957 PyObject *self;
958 PyObject *args;
959{
960 TkttObject *v = (TkttObject *) self;
961
962 if (!PyArg_Parse (args, ""))
963 return NULL;
964 if (v->func != NULL)
965 {
966 Tk_DeleteTimerHandler (v->token);
967 PyMem_DEL (v->func);
968 v->func = NULL;
969 }
970 Py_INCREF (Py_None);
971 return Py_None;
972}
973
974static PyMethodDef Tktt_methods[] =
975{
976 {"deletetimerhandler", Tktt_DeleteTimerHandler},
977 {NULL, NULL}
978};
979
980static TkttObject *
981Tktt_New (token, func)
982 Tk_TimerToken token;
983 PyObject *func;
984{
985 TkttObject *v;
986
987 v = PyObject_NEW (TkttObject, &Tktt_Type);
988 if (v == NULL)
989 return NULL;
990
991 v->token = token;
992 v->func = func;
993 Py_INCREF (v->func);
994 return v;
995}
996
997static void
998Tktt_Dealloc (self)
999 PyObject *self;
1000{
1001 PyMem_DEL (self);
1002}
1003
1004static int
1005Tktt_Print (self, fp, flags)
1006 PyObject *self;
1007 FILE *fp;
1008 int flags;
1009{
1010 TkttObject *v = (TkttObject *) self;
1011
1012 fprintf(fp, "<tktimertoken at 0x%x%s>", v,
1013 v->func == NULL ? ", handler deleted" : "");
1014 return 0;
1015}
1016
1017static PyObject *
1018Tktt_GetAttr (self, name)
1019 PyObject *self;
1020 char *name;
1021{
1022 return Py_FindMethod (Tktt_methods, self, name);
1023}
1024
1025static PyTypeObject Tktt_Type =
1026{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001027 PyObject_HEAD_INIT (&PyType_Type)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001028 0, /*ob_size */
1029 "tktimertoken", /*tp_name */
1030 sizeof (TkttObject), /*tp_basicsize */
1031 0, /*tp_itemsize */
1032 Tktt_Dealloc, /*tp_dealloc */
1033 Tktt_Print, /*tp_print */
1034 Tktt_GetAttr, /*tp_getattr */
1035 0, /*tp_setattr */
1036 0, /*tp_compare */
1037 0, /*tp_repr */
1038 0, /*tp_as_number */
1039 0, /*tp_as_sequence */
1040 0, /*tp_as_mapping */
1041 0, /*tp_hash */
1042};
1043
1044/** Timer Handler **/
1045
1046static void
1047TimerHandler (clientData)
1048 ClientData clientData;
1049{
1050 PyObject *func = (PyObject *) clientData;
1051 PyObject *arg, *res;
1052
1053 arg = PyTuple_New (0);
1054 res = PyEval_CallObject (func, arg);
1055 Py_DECREF (arg);
1056 if (res == NULL)
1057 {
1058 errorInCmd = 1;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001059 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001060 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001061 else
1062 Py_DECREF (res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001063}
1064
1065static PyObject *
1066Tkapp_CreateTimerHandler (self, args)
1067 PyObject *self;
1068 PyObject *args; /* Is (milliseconds, func) */
1069{
1070 int milliseconds;
1071 PyObject *func;
1072 Tk_TimerToken token;
1073
1074 if (!PyArg_Parse (args, "(iO)", &milliseconds, &func))
1075 return NULL;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001076 if (!PyCallable_Check(func))
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001077 {
1078 PyErr_SetString (PyExc_TypeError, "bad argument list");
1079 return NULL;
1080 }
1081 token = Tk_CreateTimerHandler(milliseconds, TimerHandler, (ClientData) func);
1082 return (PyObject *) Tktt_New (token, func);
1083}
1084
Guido van Rossum18468821994-06-20 07:49:28 +00001085/** Event Loop **/
1086
Guido van Rossum18468821994-06-20 07:49:28 +00001087static PyObject *
1088Tkapp_MainLoop (self, args)
1089 PyObject *self;
1090 PyObject *args;
1091{
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001092 int threshold = 0;
1093
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001094 if (!PyArg_ParseTuple (args, "|i", &threshold))
1095 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001096
1097 quitMainLoop = 0;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001098 while (Tk_GetNumMainWindows() > threshold && !quitMainLoop && !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001099 {
1100 if (PyOS_InterruptOccurred ())
1101 {
1102 PyErr_SetNone (PyExc_KeyboardInterrupt);
1103 return NULL;
1104 }
1105 Tk_DoOneEvent (0);
1106 }
Guido van Rossum64b24fb1995-09-30 17:00:24 +00001107 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001108
1109 if (errorInCmd)
1110 {
1111 errorInCmd = 0;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001112 PyErr_Restore (excInCmd, valInCmd, trbInCmd);
1113 excInCmd = valInCmd = trbInCmd = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001114 return NULL;
1115 }
1116 Py_INCREF (Py_None);
1117 return Py_None;
1118}
1119
1120static PyObject *
Guido van Rossum062cfb01995-01-10 17:42:51 +00001121Tkapp_DoOneEvent (self, args)
1122 PyObject *self;
1123 PyObject *args;
1124{
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001125 int flags = TK_ALL_EVENTS;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001126 int rv;
1127
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001128 if (!PyArg_ParseTuple (args, "|i", &flags))
1129 return NULL;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001130 rv = Tk_DoOneEvent(flags);
1131 return Py_BuildValue ("i", rv);
1132}
1133
1134static PyObject *
Guido van Rossum18468821994-06-20 07:49:28 +00001135Tkapp_Quit (self, args)
1136 PyObject *self;
1137 PyObject *args;
1138{
1139
1140 if (!PyArg_Parse (args, ""))
1141 return NULL;
1142 quitMainLoop = 1;
1143 Py_INCREF (Py_None);
1144 return Py_None;
1145}
1146
1147/**** Tkapp Method List ****/
1148
1149static PyMethodDef Tkapp_methods[] =
1150{
1151 {"call", Tkapp_Call},
1152 {"globalcall", Tkapp_GlobalCall},
1153 {"eval", Tkapp_Eval},
1154 {"globaleval", Tkapp_GlobalEval},
1155 {"evalfile", Tkapp_EvalFile},
1156 {"record", Tkapp_Record},
1157 {"adderrorinfo", Tkapp_AddErrorInfo},
1158 {"setvar", Tkapp_SetVar},
1159 {"globalsetvar", Tkapp_GlobalSetVar},
1160 {"getvar", Tkapp_GetVar},
1161 {"globalgetvar", Tkapp_GlobalGetVar},
1162 {"unsetvar", Tkapp_UnsetVar},
1163 {"globalunsetvar", Tkapp_GlobalUnsetVar},
1164 {"getint", Tkapp_GetInt},
1165 {"getdouble", Tkapp_GetDouble},
1166 {"getboolean", Tkapp_GetBoolean},
1167 {"exprstring", Tkapp_ExprString},
1168 {"exprlong", Tkapp_ExprLong},
1169 {"exprdouble", Tkapp_ExprDouble},
1170 {"exprboolean", Tkapp_ExprBoolean},
1171 {"splitlist", Tkapp_SplitList},
1172 {"split", Tkapp_Split},
1173 {"merge", Tkapp_Merge},
1174 {"createcommand", Tkapp_CreateCommand},
1175 {"deletecommand", Tkapp_DeleteCommand},
1176 {"createfilehandler", Tkapp_CreateFileHandler},
1177 {"deletefilehandler", Tkapp_DeleteFileHandler},
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001178 {"createtimerhandler", Tkapp_CreateTimerHandler},
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001179 {"mainloop", Tkapp_MainLoop, 1},
1180 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum18468821994-06-20 07:49:28 +00001181 {"quit", Tkapp_Quit},
1182 {NULL, NULL}
1183};
1184
1185/**** Tkapp Type Methods ****/
1186
1187static void
1188Tkapp_Dealloc (self)
1189 PyObject *self;
1190{
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001191#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +00001192 Tk_DestroyWindow (Tkapp_Tkwin (self));
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001193#endif
Guido van Rossum18468821994-06-20 07:49:28 +00001194 Tcl_DeleteInterp (Tkapp_Interp (self));
1195 PyMem_DEL (self);
1196}
1197
1198static PyObject *
1199Tkapp_GetAttr (self, name)
1200 PyObject *self;
1201 char *name;
1202{
1203 return Py_FindMethod (Tkapp_methods, self, name);
1204}
1205
1206static PyTypeObject Tkapp_Type =
1207{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001208 PyObject_HEAD_INIT (&PyType_Type)
Guido van Rossum18468821994-06-20 07:49:28 +00001209 0, /*ob_size */
1210 "tkapp", /*tp_name */
1211 sizeof (TkappObject), /*tp_basicsize */
1212 0, /*tp_itemsize */
1213 Tkapp_Dealloc, /*tp_dealloc */
1214 0, /*tp_print */
1215 Tkapp_GetAttr, /*tp_getattr */
1216 0, /*tp_setattr */
1217 0, /*tp_compare */
1218 0, /*tp_repr */
1219 0, /*tp_as_number */
1220 0, /*tp_as_sequence */
1221 0, /*tp_as_mapping */
1222 0, /*tp_hash */
1223};
1224
1225/**** Tkinter Module ****/
1226
1227static PyObject *
1228Tkinter_Create (self, args)
1229 PyObject *self;
1230 PyObject *args;
1231{
1232 char *screenName = NULL;
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001233 char *baseName = NULL;
1234 char *className = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001235 int interactive = 0;
1236
Guido van Rossum32aa1a71996-07-31 19:51:15 +00001237 baseName = strrchr (Py_GetProgramName (), '/');
Guido van Rossum18468821994-06-20 07:49:28 +00001238 if (baseName != NULL)
1239 baseName++;
1240 else
Guido van Rossum32aa1a71996-07-31 19:51:15 +00001241 baseName = Py_GetProgramName ();
Guido van Rossum18468821994-06-20 07:49:28 +00001242 className = "Tk";
1243
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001244 if (!PyArg_ParseTuple (args, "|zssi",
1245 &screenName, &baseName, &className, &interactive))
Guido van Rossum18468821994-06-20 07:49:28 +00001246 return NULL;
1247
1248 return (PyObject *) Tkapp_New (screenName, baseName, className,
1249 interactive);
1250}
1251
1252static PyMethodDef moduleMethods[] =
1253{
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001254 {"create", Tkinter_Create, 1},
1255 {"createfilehandler", Tkapp_CreateFileHandler, 0},
1256 {"deletefilehandler", Tkapp_DeleteFileHandler, 0},
1257 {"createtimerhandler", Tkapp_CreateTimerHandler, 0},
1258 {"mainloop", Tkapp_MainLoop, 1},
1259 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001260 {"quit", Tkapp_Quit},
Guido van Rossum18468821994-06-20 07:49:28 +00001261 {NULL, NULL}
1262};
1263
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001264#undef WITH_READLINE /* XXX */
Guido van Rossum18468821994-06-20 07:49:28 +00001265#ifdef WITH_READLINE
1266static int
1267EventHook ()
1268{
1269 if (errorInCmd) /* XXX Reset tty */
1270 {
1271 errorInCmd = 0;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001272 PyErr_Restore (excInCmd, valInCmd, trbInCmd);
1273 excInCmd = valInCmd = trbInCmd = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001274 PyErr_Print ();
1275 }
Guido van Rossum9722ad81995-09-22 23:49:28 +00001276 if (Tk_GetNumMainWindows() > 0)
Guido van Rossume2ca9bd1994-08-03 08:01:43 +00001277 Tk_DoOneEvent (TK_DONT_WAIT);
Guido van Rossum18468821994-06-20 07:49:28 +00001278 return 0;
1279}
1280#endif /* WITH_READLINE */
1281
1282static void
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001283Tkinter_Cleanup ()
1284{
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001285/* This segfault with Tk 4.0 beta and seems unnecessary there as well */
1286#if TK_MAJOR_VERSION < 4
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001287 /* XXX rl_deprep_terminal is static, damned! */
1288 while (tkMainWindowList != 0)
1289 Tk_DestroyWindow (tkMainWindowList->win);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001290#endif
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001291}
1292
Guido van Rossum18468821994-06-20 07:49:28 +00001293void
Guido van Rossumad1f7ee1996-02-13 00:11:37 +00001294init_tkinter ()
Guido van Rossum18468821994-06-20 07:49:28 +00001295{
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001296 static inited = 0;
1297
Guido van Rossum18468821994-06-20 07:49:28 +00001298#ifdef WITH_READLINE
1299 extern int (*rl_event_hook) ();
1300#endif /* WITH_READLINE */
1301 PyObject *m, *d, *v;
1302
Jack Jansenba0311e1995-10-23 14:34:14 +00001303 m = Py_InitModule ("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001304
1305 d = PyModule_GetDict (m);
1306 Tkinter_TclError = Py_BuildValue ("s", "TclError");
1307 PyDict_SetItemString (d, "TclError", Tkinter_TclError);
1308
1309 v = Py_BuildValue ("i", TK_READABLE);
1310 PyDict_SetItemString (d, "READABLE", v);
1311 v = Py_BuildValue ("i", TK_WRITABLE);
1312 PyDict_SetItemString (d, "WRITABLE", v);
1313 v = Py_BuildValue ("i", TK_EXCEPTION);
1314 PyDict_SetItemString (d, "EXCEPTION", v);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001315 v = Py_BuildValue ("i", TK_X_EVENTS);
1316 PyDict_SetItemString (d, "X_EVENTS", v);
1317 v = Py_BuildValue ("i", TK_FILE_EVENTS);
1318 PyDict_SetItemString (d, "FILE_EVENTS", v);
1319 v = Py_BuildValue ("i", TK_TIMER_EVENTS);
1320 PyDict_SetItemString (d, "TIMER_EVENTS", v);
1321 v = Py_BuildValue ("i", TK_IDLE_EVENTS);
1322 PyDict_SetItemString (d, "IDLE_EVENTS", v);
1323 v = Py_BuildValue ("i", TK_ALL_EVENTS);
1324 PyDict_SetItemString (d, "ALL_EVENTS", v);
1325 v = Py_BuildValue ("i", TK_DONT_WAIT);
1326 PyDict_SetItemString (d, "DONT_WAIT", v);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001327 v = Py_BuildValue ("s", TK_VERSION);
1328 PyDict_SetItemString (d, "TK_VERSION", v);
1329 v = Py_BuildValue ("s", TCL_VERSION);
1330 PyDict_SetItemString (d, "TCL_VERSION", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001331
Guido van Rossum18468821994-06-20 07:49:28 +00001332#ifdef WITH_READLINE
1333 rl_event_hook = EventHook;
1334#endif /* WITH_READLINE */
1335
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001336 if (!inited)
1337 {
1338 inited = 1;
Guido van Rossume4485b01994-09-07 14:32:49 +00001339 if (Py_AtExit (Tkinter_Cleanup) != 0)
1340 fprintf(stderr,
1341 "Tkinter: warning: cleanup procedure not registered\n");
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001342 }
1343
Guido van Rossum18468821994-06-20 07:49:28 +00001344 if (PyErr_Occurred ())
Jack Jansenba0311e1995-10-23 14:34:14 +00001345 Py_FatalError ("can't initialize module _tkinter");
Jack Jansen34cc5c31995-10-31 16:15:12 +00001346#ifdef macintosh
Guido van Rossumec22c921996-02-25 04:50:29 +00001347 TclMacSetEventProc(PyMacConvertEvent);
1348#if GENERATINGCFM
Jack Jansen34cc5c31995-10-31 16:15:12 +00001349 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001350#endif /* GENERATINGCFM */
1351#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001352}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001353
Guido van Rossumec22c921996-02-25 04:50:29 +00001354
Guido van Rossum9722ad81995-09-22 23:49:28 +00001355#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001356
1357/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001358** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001359*/
1360
Guido van Rossum9722ad81995-09-22 23:49:28 +00001361void
1362panic(char * format, ...)
1363{
1364 va_list varg;
1365
1366 va_start(varg, format);
1367
1368 vfprintf(stderr, format, varg);
1369 (void) fflush(stderr);
1370
1371 va_end(varg);
1372
1373 Py_FatalError("Tcl/Tk panic");
1374}
Jack Jansen40b546d1995-11-14 10:34:45 +00001375
Guido van Rossumec22c921996-02-25 04:50:29 +00001376/*
1377** Pass events to SIOUX before passing them to Tk.
1378*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001379
Guido van Rossumec22c921996-02-25 04:50:29 +00001380static int
1381PyMacConvertEvent(eventPtr)
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001382 EventRecord *eventPtr;
1383{
Guido van Rossumec22c921996-02-25 04:50:29 +00001384 if (SIOUXHandleOneEvent(eventPtr))
1385 return 0; /* Nothing happened to the Tcl event queue */
1386 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001387}
1388
Guido van Rossumec22c921996-02-25 04:50:29 +00001389#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001390
1391/*
1392** Additional Mac specific code for dealing with shared libraries.
1393*/
1394
1395#include <Resources.h>
1396#include <CodeFragments.h>
1397
1398static int loaded_from_shlib = 0;
1399static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001400
Jack Jansen34cc5c31995-10-31 16:15:12 +00001401/*
1402** If this module is dynamically loaded the following routine should
1403** be the init routine. It takes care of adding the shared library to
1404** the resource-file chain, so that the tk routines can find their
1405** resources.
1406*/
1407OSErr pascal
1408init_tkinter_shlib(InitBlockPtr data)
1409{
Guido van Rossum54ac1891996-05-16 17:14:03 +00001410 __sinit(); /* Sez Jack */
Jack Jansen34cc5c31995-10-31 16:15:12 +00001411 if ( data == nil ) return noErr;
1412 if ( data->fragLocator.where == kOnDiskFlat ) {
1413 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1414 loaded_from_shlib = 1;
1415 } else if ( data->fragLocator.where == kOnDiskSegmented ) {
1416 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1417 loaded_from_shlib = 1;
1418 }
1419 return noErr;
1420}
1421
1422/*
1423** Insert the library resources into the search path. Put them after
1424** the resources from the application. Again, we ignore errors.
1425*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001426static
Jack Jansen34cc5c31995-10-31 16:15:12 +00001427mac_addlibresources()
1428{
1429 if ( !loaded_from_shlib )
1430 return;
1431 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1432}
1433
Guido van Rossumec22c921996-02-25 04:50:29 +00001434#endif /* GENERATINGCFM */
1435#endif /* macintosh */