blob: 8df8c4a3aa67e8ef82fc5eb69c3e946bb4cf441b [file] [log] [blame]
Jack Jansenba0311e1995-10-23 14:34:14 +00001/* _tkinter.c -- Interface to libtk.a and libtcl.a.
Guido van Rossum18468821994-06-20 07:49:28 +00002 Copyright (C) 1994 Steen Lumholt */
3
Guido van Rossum9722ad81995-09-22 23:49:28 +00004#include "Python.h"
5
Guido van Rossum18468821994-06-20 07:49:28 +00006#include <tcl.h>
7#include <tk.h>
8
9extern char *getprogramname ();
Guido van Rossumd308e2b1994-07-07 09:25:12 +000010
Guido van Rossum9722ad81995-09-22 23:49:28 +000011/* Internal declarations from tkInt.h. */
12#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
13extern int Tk_GetNumMainWindows();
14#else
Guido van Rossum18468821994-06-20 07:49:28 +000015extern int tk_NumMainWindows;
Guido van Rossum9722ad81995-09-22 23:49:28 +000016#define Tk_GetNumMainWindows() (tk_NumMainWindows)
Guido van Rossumdfd428d1996-02-25 04:46:40 +000017#define NEED_TKCREATEMAINWINDOW 1
Guido van Rossum9722ad81995-09-22 23:49:28 +000018#endif
19
20#if TK_MAJOR_VERSION < 4
Guido van Rossumd308e2b1994-07-07 09:25:12 +000021extern struct { Tk_Window win; } *tkMainWindowList;
Guido van Rossum9722ad81995-09-22 23:49:28 +000022#endif
Guido van Rossum18468821994-06-20 07:49:28 +000023
Guido van Rossumec22c921996-02-25 04:50:29 +000024#ifdef macintosh
25
26/*
27** Additional cruft needed by Tcl/Tk on the Mac.
28** Unfortunately this changes with each beta.
29** This is for beta 2 of Tcl 7.5 and Tk 4.1.
30*/
31
32#include <Events.h> /* For EventRecord */
33
34typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
35void TclMacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
36int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
37
38staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
39
40#endif /* macintosh */
41
Guido van Rossum18468821994-06-20 07:49:28 +000042/**** Tkapp Object Declaration ****/
43
44staticforward PyTypeObject Tkapp_Type;
45
46typedef struct
47 {
48 PyObject_HEAD
49 Tcl_Interp *interp;
Guido van Rossumdfd428d1996-02-25 04:46:40 +000050#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +000051 Tk_Window tkwin;
Guido van Rossumdfd428d1996-02-25 04:46:40 +000052#endif
Guido van Rossum18468821994-06-20 07:49:28 +000053 }
54TkappObject;
55
56#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossumdfd428d1996-02-25 04:46:40 +000057#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +000058#define Tkapp_Tkwin(v) (((TkappObject *) (v))->tkwin)
Guido van Rossumdfd428d1996-02-25 04:46:40 +000059#endif
Guido van Rossum18468821994-06-20 07:49:28 +000060#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
61#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
62
63#define DEBUG_REFCNT(v) (printf ("DEBUG: id=%p, refcnt=%i\n", \
64 (void *) v, ((PyObject *) v)->ob_refcnt))
65
66/**** Error Handling ****/
67
68static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +000069static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +000070static int errorInCmd = 0;
71static PyObject *excInCmd;
72static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +000073static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +000074
75static PyObject *
76Tkinter_Error (v)
77 PyObject *v;
78{
Guido van Rossum18468821994-06-20 07:49:28 +000079 PyErr_SetString (Tkinter_TclError, Tkapp_Result (v));
80 return NULL;
81}
82
83int
84PythonCmd_Error (interp)
85 Tcl_Interp *interp;
86{
87 errorInCmd = 1;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +000088 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
Guido van Rossum18468821994-06-20 07:49:28 +000089 return TCL_ERROR;
90}
91
92/**** Utils ****/
93
94static char *
95AsString (value, tmp)
96 PyObject *value;
97 PyObject *tmp;
98{
99 if (PyString_Check (value))
100 return PyString_AsString (value);
101 else
102 {
103 PyObject *v;
104
Guido van Rossumcd938fc1995-01-17 16:13:48 +0000105 v = PyObject_Str (value);
Guido van Rossum18468821994-06-20 07:49:28 +0000106 PyList_Append (tmp, v);
107 Py_DECREF (v);
108 return PyString_AsString (v);
109 }
110}
111
112#define ARGSZ 64
113
114static char *
115Merge (args)
116 PyObject *args;
117{
118 PyObject *tmp;
119 char *argvStore[ARGSZ];
120 char **argv;
121 int fvStore[ARGSZ];
122 int *fv;
123 int argc;
124 char *res;
125 int i;
126
127 tmp = PyList_New (0);
128 argv = argvStore;
129 fv = fvStore;
130
131 if (!PyTuple_Check (args))
132 {
133 argc = 1;
134 fv[0] = 0;
135 argv[0] = AsString (args, tmp);
136 }
137 else
138 {
139 PyObject *v;
140
141 if (PyTuple_Size (args) > ARGSZ)
142 {
Guido van Rossumb6fe7041995-03-09 12:13:43 +0000143 argv = (char **) malloc (PyTuple_Size (args) * sizeof (char *));
144 fv = (int *) malloc (PyTuple_Size (args) * sizeof (int));
Guido van Rossum18468821994-06-20 07:49:28 +0000145 if (argv == NULL || fv == NULL)
146 PyErr_NoMemory ();
147 }
148
149 argc = PyTuple_Size (args);
150 for (i = 0; i < argc; i++)
151 {
152 v = PyTuple_GetItem (args, i);
153 if (PyTuple_Check (v))
154 {
155 fv[i] = 1;
156 argv[i] = Merge (v);
157 }
158 else if (v == Py_None)
159 {
160 argc = i;
161 break;
162 }
163 else
164 {
165 fv[i] = 0;
166 argv[i] = AsString (v, tmp);
167 }
168 }
169 }
170
171 res = Tcl_Merge (argc, argv);
172
173 Py_DECREF (tmp);
174 for (i = 0; i < argc; i++)
175 if (fv[i]) free (argv[i]);
176 if (argv != argvStore)
177 free (argv);
178 if (fv != fvStore)
179 free (fv);
180
181 return res;
182}
183
184static PyObject *
185Split (self, list)
186 PyObject *self;
187 char *list;
188{
189 int argc;
190 char **argv;
191 PyObject *v;
192
193 if (list == NULL)
194 {
195 Py_INCREF (Py_None);
196 return Py_None;
197 }
198
199 if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
200 return Tkinter_Error (self);
201
202 if (argc == 0)
203 v = PyString_FromString ("");
204 else if (argc == 1)
205 v = PyString_FromString (argv[0]);
206 else
207 {
208 int i;
209
210 v = PyTuple_New (argc);
211 for (i = 0; i < argc; i++)
212 PyTuple_SetItem (v, i, Split (self, argv[i]));
213 }
214
215 free (argv);
216 return v;
217}
218
219/**** Tkapp Object ****/
220
221#ifndef WITH_APPINIT
222int
223Tcl_AppInit (interp)
224 Tcl_Interp *interp;
225{
Guido van Rossumec22c921996-02-25 04:50:29 +0000226 Tk_Window main;
227
228 main = Tk_MainWindow(interp);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000229 if (Tcl_Init (interp) == TCL_ERROR) {
230 fprintf(stderr, "Tcl_Init error: %s\n", interp->result);
Guido van Rossum18468821994-06-20 07:49:28 +0000231 return TCL_ERROR;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000232 }
233 if (Tk_Init (interp) == TCL_ERROR) {
234 fprintf(stderr, "Tk_Init error: %s\n", interp->result);
Guido van Rossum18468821994-06-20 07:49:28 +0000235 return TCL_ERROR;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000236 }
Guido van Rossum18468821994-06-20 07:49:28 +0000237 return TCL_OK;
238}
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000239
240char *
241TkDefaultAppName()
242{
243 return "Python";
244}
245
Guido van Rossum18468821994-06-20 07:49:28 +0000246#endif /* !WITH_APPINIT */
247
248/* Initialize the Tk application; see the `main' function in
249 `tkMain.c'. */
250static TkappObject *
251Tkapp_New (screenName, baseName, className, interactive)
252 char *screenName;
253 char *baseName;
254 char *className;
255 int interactive;
256{
257 TkappObject *v;
258
259 v = PyObject_NEW (TkappObject, &Tkapp_Type);
260 if (v == NULL)
261 return NULL;
262
263 v->interp = Tcl_CreateInterp ();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000264
265#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +0000266 v->tkwin = Tk_CreateMainWindow (v->interp, screenName,
267 baseName, className);
268 if (v->tkwin == NULL)
269 return (TkappObject *) Tkinter_Error ((PyObject *) v);
270
271 Tk_GeometryRequest (v->tkwin, 200, 200);
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000272#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000273
274 if (screenName != NULL)
275 Tcl_SetVar2 (v->interp, "env", "DISPLAY", screenName, TCL_GLOBAL_ONLY);
276
277 if (interactive)
278 Tcl_SetVar (v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
279 else
280 Tcl_SetVar (v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
281
Guido van Rossum18468821994-06-20 07:49:28 +0000282 if (Tcl_AppInit (v->interp) != TCL_OK)
283 {
284 PyErr_SetString (Tkinter_TclError, "Tcl_AppInit failed"); /* XXX */
285 return NULL;
286 }
Guido van Rossum18468821994-06-20 07:49:28 +0000287
288 return v;
289}
290
291/** Tcl Eval **/
292
293static PyObject *
294Tkapp_Call (self, args)
295 PyObject *self;
296 PyObject *args;
297{
298 char *cmd;
299
300 cmd = Merge (args);
301 if (Tcl_Eval (Tkapp_Interp (self), cmd) == TCL_ERROR)
302 {
303 free (cmd);
304 return Tkinter_Error (self);
305 }
306
307 free (cmd);
308 return PyString_FromString (Tkapp_Result (self));
309}
310
311static PyObject *
312Tkapp_GlobalCall (self, args)
313 PyObject *self;
314 PyObject *args;
315{
316 char *cmd;
317
318 cmd = Merge (args);
319 if (Tcl_GlobalEval (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_Eval (self, args)
331 PyObject *self;
332 PyObject *args;
333{
334 char *script;
335
336 if (!PyArg_Parse (args, "s", &script))
337 return NULL;
338
339 if (Tcl_Eval (Tkapp_Interp (self), script) == TCL_ERROR)
340 return Tkinter_Error (self);
341
342 return PyString_FromString (Tkapp_Result (self));
343}
344
345static PyObject *
346Tkapp_GlobalEval (self, args)
347 PyObject *self;
348 PyObject *args;
349{
350 char *script;
351
352 if (!PyArg_Parse (args, "s", &script))
353 return NULL;
354
355 if (Tcl_GlobalEval (Tkapp_Interp (self), script) == TCL_ERROR)
356 return Tkinter_Error (self);
357
358 return PyString_FromString (Tkapp_Result (self));
359}
360
361static PyObject *
362Tkapp_EvalFile (self, args)
363 PyObject *self;
364 PyObject *args;
365{
366 char *fileName;
367
368 if (!PyArg_Parse (args, "s", &fileName))
369 return NULL;
370
371 if (Tcl_EvalFile (Tkapp_Interp (self), fileName) == TCL_ERROR)
372 return Tkinter_Error (self);
373
374 return PyString_FromString (Tkapp_Result (self));
375}
376
377static PyObject *
378Tkapp_Record (self, args)
379 PyObject *self;
380 PyObject *args;
381{
382 char *script;
383
384 if (!PyArg_Parse (args, "s", &script))
385 return NULL;
386
387 if (Tcl_RecordAndEval (Tkapp_Interp (self),
388 script, TCL_NO_EVAL) == TCL_ERROR)
389 return Tkinter_Error (self);
390
391 return PyString_FromString (Tkapp_Result (self));
392}
393
394static PyObject *
395Tkapp_AddErrorInfo (self, args)
396 PyObject *self;
397 PyObject *args;
398{
399 char *msg;
400
401 if (!PyArg_Parse (args, "s", &msg))
402 return NULL;
403 Tcl_AddErrorInfo (Tkapp_Interp (self), msg);
404
405 Py_INCREF(Py_None);
406 return Py_None;
407}
408
409/** Tcl Variable **/
410
411static PyObject *
412SetVar (self, args, flags)
413 PyObject *self;
414 PyObject *args;
415 int flags;
416{
417 char *name1, *name2, *ok;
418 PyObject *newValue;
419 PyObject *tmp;
420
421 tmp = PyList_New (0);
422
423 if (PyArg_Parse (args, "(sO)", &name1, &newValue))
424 ok = Tcl_SetVar (Tkapp_Interp (self), name1,
425 AsString (newValue, tmp), flags); /* XXX Merge? */
426 else if (PyArg_Parse (args, "(ssO)", &name1, &name2, &newValue))
427 ok = Tcl_SetVar2 (Tkapp_Interp (self), name1, name2,
428 AsString (newValue, tmp), flags);
429 else
430 {
431 Py_DECREF (tmp);
432 return NULL;
433 }
434 Py_DECREF (tmp);
435
436 if (!ok)
437 return Tkinter_Error (self);
438
439 Py_INCREF (Py_None);
440 return Py_None;
441}
442
443static PyObject *
444Tkapp_SetVar (self, args)
445 PyObject *self;
446 PyObject *args;
447{
448 return SetVar (self, args, TCL_LEAVE_ERR_MSG);
449}
450
451static PyObject *
452Tkapp_GlobalSetVar (self, args)
453 PyObject *self;
454 PyObject *args;
455{
456 return SetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
457}
458
459static PyObject *
460GetVar (self, args, flags)
461 PyObject *self;
462 PyObject *args;
463 int flags;
464{
465 char *name1, *name2, *s;
466
467 if (PyArg_Parse (args, "s", &name1))
468 s = Tcl_GetVar (Tkapp_Interp (self), name1, flags);
469 else if (PyArg_Parse (args, "(ss)", &name1, &name2))
470 s = Tcl_GetVar2 (Tkapp_Interp (self), name1, name2, flags);
471 else
472 return NULL;
473
474 if (s == NULL)
475 return Tkinter_Error (self);
476
477 return PyString_FromString (s);
478}
479
480static PyObject *
481Tkapp_GetVar (self, args)
482 PyObject *self;
483 PyObject *args;
484{
485 return GetVar (self, args, TCL_LEAVE_ERR_MSG);
486}
487
488static PyObject *
489Tkapp_GlobalGetVar (self, args)
490 PyObject *self;
491 PyObject *args;
492{
493 return GetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
494}
495
496static PyObject *
497UnsetVar (self, args, flags)
498 PyObject *self;
499 PyObject *args;
500 int flags;
501{
502 char *name1, *name2;
503 int code;
504
505 if (PyArg_Parse (args, "s", &name1))
506 code = Tcl_UnsetVar (Tkapp_Interp (self), name1, flags);
507 else if (PyArg_Parse (args, "(ss)", &name1, &name2))
508 code = Tcl_UnsetVar2 (Tkapp_Interp (self), name1, name2, flags);
509 else
510 return NULL;
511
512 if (code == TCL_ERROR)
513 return Tkinter_Error (self);
514
515 Py_INCREF (Py_None);
516 return Py_None;
517}
518
519static PyObject *
520Tkapp_UnsetVar (self, args)
521 PyObject *self;
522 PyObject *args;
523{
524 return UnsetVar (self, args, TCL_LEAVE_ERR_MSG);
525}
526
527static PyObject *
528Tkapp_GlobalUnsetVar (self, args)
529 PyObject *self;
530 PyObject *args;
531{
532 return UnsetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
533}
534
535/** Tcl to Python **/
536
537static PyObject *
538Tkapp_GetInt (self, args)
539 PyObject *self;
540 PyObject *args;
541{
542 char *s;
543 int v;
544
545 if (!PyArg_Parse (args, "s", &s))
546 return NULL;
547 if (Tcl_GetInt (Tkapp_Interp (self), s, &v) == TCL_ERROR)
548 return Tkinter_Error (self);
549 return Py_BuildValue ("i", v);
550}
551
552static PyObject *
553Tkapp_GetDouble (self, args)
554 PyObject *self;
555 PyObject *args;
556{
557 char *s;
558 double v;
559
560 if (!PyArg_Parse (args, "s", &s))
561 return NULL;
562 if (Tcl_GetDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
563 return Tkinter_Error (self);
564 return Py_BuildValue ("d", v);
565}
566
567static PyObject *
568Tkapp_GetBoolean (self, args)
569 PyObject *self;
570 PyObject *args;
571{
572 char *s;
573 int v;
574
575 if (!PyArg_Parse (args, "s", &s))
576 return NULL;
577 if (Tcl_GetBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
578 return Tkinter_Error (self);
579 return Py_BuildValue ("i", v);
580}
581
582static PyObject *
583Tkapp_ExprString (self, args)
584 PyObject *self;
585 PyObject *args;
586{
587 char *s;
588
589 if (!PyArg_Parse (args, "s", &s))
590 return NULL;
591 if (Tcl_ExprString (Tkapp_Interp (self), s) == TCL_ERROR)
592 return Tkinter_Error (self);
593 return Py_BuildValue ("s", Tkapp_Result (self));
594}
595
596static PyObject *
597Tkapp_ExprLong (self, args)
598 PyObject *self;
599 PyObject *args;
600{
601 char *s;
602 long v;
603
604 if (!PyArg_Parse (args, "s", &s))
605 return NULL;
606 if (Tcl_ExprLong (Tkapp_Interp (self), s, &v) == TCL_ERROR)
607 return Tkinter_Error (self);
608 return Py_BuildValue ("l", v);
609}
610
611static PyObject *
612Tkapp_ExprDouble (self, args)
613 PyObject *self;
614 PyObject *args;
615{
616 char *s;
617 double v;
618
619 if (!PyArg_Parse (args, "s", &s))
620 return NULL;
621 if (Tcl_ExprDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
622 return Tkinter_Error (self);
623 return Py_BuildValue ("d", v);
624}
625
626static PyObject *
627Tkapp_ExprBoolean (self, args)
628 PyObject *self;
629 PyObject *args;
630{
631 char *s;
632 int v;
633
634 if (!PyArg_Parse (args, "s", &s))
635 return NULL;
636 if (Tcl_ExprBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
637 return Tkinter_Error (self);
638 return Py_BuildValue ("i", v);
639}
640
641static PyObject *
642Tkapp_SplitList (self, args)
643 PyObject *self;
644 PyObject *args;
645{
646 char *list;
647 int argc;
648 char **argv;
649 PyObject *v;
650 int i;
651
652 if (!PyArg_Parse (args, "s", &list))
653 return NULL;
654
655 if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
656 return Tkinter_Error (self);
657
658 v = PyTuple_New (argc);
659 for (i = 0; i < argc; i++)
660 PyTuple_SetItem (v, i, PyString_FromString (argv[i]));
661
662 free (argv);
663 return v;
664}
665
666static PyObject *
667Tkapp_Split (self, args)
668 PyObject *self;
669 PyObject *args;
670{
671 char *list;
672
673 if (!PyArg_Parse (args, "s", &list))
674 return NULL;
675 return Split (self, list);
676}
677
678static PyObject *
679Tkapp_Merge (self, args)
680 PyObject *self;
681 PyObject *args;
682{
683 char *s;
684 PyObject *v;
685
686 s = Merge (args);
687 v = PyString_FromString (s);
688 free (s);
689 return v;
690}
691
692/** Tcl Command **/
693
694/* This is the Tcl command that acts as a wrapper for Python
695 function or method. */
696static int
697PythonCmd (clientData, interp, argc, argv)
698 ClientData clientData; /* Is (self, func) */
699 Tcl_Interp *interp;
700 int argc;
701 char *argv[];
702{
703 PyObject *self, *func, *arg, *res, *tmp;
704 int i;
705
706 self = PyTuple_GetItem ((PyObject *) clientData, 0);
707 func = PyTuple_GetItem ((PyObject *) clientData, 1);
708
709 /* Create argument list (argv1, ..., argvN) */
710 arg = PyTuple_New (argc - 1);
711 for (i = 0; i < (argc - 1); i++)
712 PyTuple_SetItem (arg, i, PyString_FromString (argv[i + 1]));
713
714 res = PyEval_CallObject (func, arg);
715 Py_DECREF (arg);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000716
Guido van Rossum18468821994-06-20 07:49:28 +0000717 if (res == NULL)
718 return PythonCmd_Error (interp);
719
720 tmp = PyList_New (0);
721 Tcl_SetResult (Tkapp_Interp (self), AsString (res, tmp), TCL_VOLATILE);
722 Py_DECREF (res);
723 Py_DECREF (tmp);
724
725 return TCL_OK;
726}
727
728static void
729PythonCmdDelete (clientData)
730 ClientData clientData; /* Is (self, func) */
731{
732 Py_DECREF ((PyObject *) clientData);
733}
734
735static PyObject *
736Tkapp_CreateCommand (self, args)
737 PyObject *self;
738 PyObject *args;
739{
740 char *cmdName;
741 PyObject *data;
742 PyObject *func;
743
744 /* Args is: (cmdName, func) */
745 if (!PyTuple_Check (args)
746 || !(PyTuple_Size (args) == 2)
747 || !PyString_Check (PyTuple_GetItem (args, 0))
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000748 || !PyCallable_Check (PyTuple_GetItem (args, 1)))
Guido van Rossum18468821994-06-20 07:49:28 +0000749 {
750 PyErr_SetString (PyExc_TypeError, "bad argument list");
751 return NULL;
752 }
753
754 cmdName = PyString_AsString (PyTuple_GetItem (args, 0));
755 func = PyTuple_GetItem (args, 1);
756
757 data = PyTuple_New (2); /* ClientData is: (self, func) */
758
759 Py_INCREF (self);
760 PyTuple_SetItem (data, 0, self);
761
762 Py_INCREF (func);
763 PyTuple_SetItem (data, 1, func);
764
765 Tcl_CreateCommand (Tkapp_Interp (self), cmdName, PythonCmd,
766 (ClientData) data, PythonCmdDelete);
767
768 Py_INCREF (Py_None);
769 return Py_None;
770}
771
772static PyObject *
773Tkapp_DeleteCommand (self, args)
774 PyObject *self;
775 PyObject *args;
776{
777 char *cmdName;
778
779 if (!PyArg_Parse (args, "s", &cmdName))
780 return NULL;
781 if (Tcl_DeleteCommand (Tkapp_Interp (self), cmdName) == -1)
782 {
783 PyErr_SetString (Tkinter_TclError, "can't delete Tcl command");
784 return NULL;
785 }
786 Py_INCREF (Py_None);
787 return Py_None;
788}
789
790/** File Handler **/
791
Guido van Rossuma597dde1995-01-10 20:56:29 +0000792static void
Guido van Rossum18468821994-06-20 07:49:28 +0000793FileHandler (clientData, mask)
Guido van Rossum76875221994-06-27 07:59:42 +0000794 ClientData clientData; /* Is: (func, file) */
Guido van Rossum18468821994-06-20 07:49:28 +0000795 int mask;
796{
Guido van Rossum76875221994-06-27 07:59:42 +0000797 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +0000798
Guido van Rossum76875221994-06-27 07:59:42 +0000799 func = PyTuple_GetItem ((PyObject *) clientData, 0);
800 file = PyTuple_GetItem ((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000801
Guido van Rossum76875221994-06-27 07:59:42 +0000802 arg = Py_BuildValue ("(Oi)", file, (long) mask);
Guido van Rossum18468821994-06-20 07:49:28 +0000803 res = PyEval_CallObject (func, arg);
804 Py_DECREF (arg);
805 if (res == NULL)
806 {
807 errorInCmd = 1;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000808 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
Guido van Rossum18468821994-06-20 07:49:28 +0000809 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000810 Py_XDECREF (res);
811}
812
813static int
814GetFileNo (file)
815 PyObject *file; /* Either an int >= 0 or an object with a
816 .fileno() method that returns an int >= 0 */
817{
Guido van Rossuma597dde1995-01-10 20:56:29 +0000818 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000819 int id;
820 if (PyInt_Check(file)) {
821 id = PyInt_AsLong(file);
822 if (id < 0)
823 PyErr_SetString(PyExc_ValueError, "invalid file id");
824 return id;
825 }
826 meth = PyObject_GetAttrString(file, "fileno");
827 if (meth == NULL)
828 return -1;
829 args = PyTuple_New(0);
830 if (args == NULL)
831 return -1;
832 res = PyEval_CallObject(meth, args);
833 Py_DECREF(args);
834 Py_DECREF(meth);
835 if (res == NULL)
836 return -1;
837 if (PyInt_Check(res))
838 id = PyInt_AsLong(res);
839 else
840 id = -1;
841 if (id < 0)
842 PyErr_SetString(PyExc_ValueError,
843 "invalid fileno() return value");
844 Py_DECREF(res);
845 return id;
Guido van Rossum18468821994-06-20 07:49:28 +0000846}
847
848static PyObject *
849Tkapp_CreateFileHandler (self, args)
850 PyObject *self;
851 PyObject *args; /* Is (file, mask, func) */
852{
Guido van Rossum76875221994-06-27 07:59:42 +0000853 PyObject *file, *func, *data;
854 int mask, id;
Guido van Rossum68784361996-05-16 17:17:31 +0000855#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
856 Tcl_File tfile;
857#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000858
859 if (!PyArg_Parse (args, "(OiO)", &file, &mask, &func))
860 return NULL;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000861 id = GetFileNo (file);
862 if (id < 0)
863 return NULL;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000864 if (!PyCallable_Check(func))
Guido van Rossum18468821994-06-20 07:49:28 +0000865 {
866 PyErr_SetString (PyExc_TypeError, "bad argument list");
867 return NULL;
868 }
869
Guido van Rossum76875221994-06-27 07:59:42 +0000870 /* ClientData is: (func, file) */
871 data = Py_BuildValue ("(OO)", func, file);
872
Guido van Rossum68784361996-05-16 17:17:31 +0000873#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
874 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
875 /* Oughtta check for null Tcl_File object... */
876 Tcl_CreateFileHandler (tfile, mask, FileHandler, (ClientData) data);
877#else
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000878 Tk_CreateFileHandler ((ClientData) id, mask, FileHandler, (ClientData) data);
Guido van Rossum68784361996-05-16 17:17:31 +0000879#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000880 /* XXX fileHandlerDict */
Guido van Rossum76875221994-06-27 07:59:42 +0000881
Guido van Rossum18468821994-06-20 07:49:28 +0000882 Py_INCREF (Py_None);
883 return Py_None;
884}
885
886static PyObject *
887Tkapp_DeleteFileHandler (self, args)
888 PyObject *self;
889 PyObject *args; /* Args: file */
890{
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000891 PyObject *file;
Guido van Rossum18468821994-06-20 07:49:28 +0000892 int id;
Guido van Rossum68784361996-05-16 17:17:31 +0000893#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
894 Tcl_File tfile;
895#endif
896
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000897 if (!PyArg_Parse (args, "O", &file))
898 return NULL;
899 id = GetFileNo (file);
900 if (id < 0)
901 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000902
Guido van Rossum68784361996-05-16 17:17:31 +0000903#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
904 tfile = Tcl_GetFile((ClientData) id, TCL_UNIX_FD);
905 /* Oughtta check for null Tcl_File object... */
906 Tcl_DeleteFileHandler(tfile);
907#else
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000908 Tk_DeleteFileHandler ((ClientData) id);
Guido van Rossum68784361996-05-16 17:17:31 +0000909#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000910 /* XXX fileHandlerDict */
911 Py_INCREF (Py_None);
912 return Py_None;
913}
914
Guido van Rossumf34cadd1994-11-10 22:50:21 +0000915/**** Tktt Object (timer token) ****/
916
917staticforward PyTypeObject Tktt_Type;
918
919typedef struct
920 {
921 PyObject_HEAD
922 Tk_TimerToken token;
923 PyObject *func;
924 }
925TkttObject;
926
927static PyObject *
928Tktt_DeleteTimerHandler (self, args)
929 PyObject *self;
930 PyObject *args;
931{
932 TkttObject *v = (TkttObject *) self;
933
934 if (!PyArg_Parse (args, ""))
935 return NULL;
936 if (v->func != NULL)
937 {
938 Tk_DeleteTimerHandler (v->token);
939 PyMem_DEL (v->func);
940 v->func = NULL;
941 }
942 Py_INCREF (Py_None);
943 return Py_None;
944}
945
946static PyMethodDef Tktt_methods[] =
947{
948 {"deletetimerhandler", Tktt_DeleteTimerHandler},
949 {NULL, NULL}
950};
951
952static TkttObject *
953Tktt_New (token, func)
954 Tk_TimerToken token;
955 PyObject *func;
956{
957 TkttObject *v;
958
959 v = PyObject_NEW (TkttObject, &Tktt_Type);
960 if (v == NULL)
961 return NULL;
962
963 v->token = token;
964 v->func = func;
965 Py_INCREF (v->func);
966 return v;
967}
968
969static void
970Tktt_Dealloc (self)
971 PyObject *self;
972{
973 PyMem_DEL (self);
974}
975
976static int
977Tktt_Print (self, fp, flags)
978 PyObject *self;
979 FILE *fp;
980 int flags;
981{
982 TkttObject *v = (TkttObject *) self;
983
984 fprintf(fp, "<tktimertoken at 0x%x%s>", v,
985 v->func == NULL ? ", handler deleted" : "");
986 return 0;
987}
988
989static PyObject *
990Tktt_GetAttr (self, name)
991 PyObject *self;
992 char *name;
993{
994 return Py_FindMethod (Tktt_methods, self, name);
995}
996
997static PyTypeObject Tktt_Type =
998{
Guido van Rossuma597dde1995-01-10 20:56:29 +0000999 PyObject_HEAD_INIT (&PyType_Type)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001000 0, /*ob_size */
1001 "tktimertoken", /*tp_name */
1002 sizeof (TkttObject), /*tp_basicsize */
1003 0, /*tp_itemsize */
1004 Tktt_Dealloc, /*tp_dealloc */
1005 Tktt_Print, /*tp_print */
1006 Tktt_GetAttr, /*tp_getattr */
1007 0, /*tp_setattr */
1008 0, /*tp_compare */
1009 0, /*tp_repr */
1010 0, /*tp_as_number */
1011 0, /*tp_as_sequence */
1012 0, /*tp_as_mapping */
1013 0, /*tp_hash */
1014};
1015
1016/** Timer Handler **/
1017
1018static void
1019TimerHandler (clientData)
1020 ClientData clientData;
1021{
1022 PyObject *func = (PyObject *) clientData;
1023 PyObject *arg, *res;
1024
1025 arg = PyTuple_New (0);
1026 res = PyEval_CallObject (func, arg);
1027 Py_DECREF (arg);
1028 if (res == NULL)
1029 {
1030 errorInCmd = 1;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001031 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001032 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001033 else
1034 Py_DECREF (res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001035}
1036
1037static PyObject *
1038Tkapp_CreateTimerHandler (self, args)
1039 PyObject *self;
1040 PyObject *args; /* Is (milliseconds, func) */
1041{
1042 int milliseconds;
1043 PyObject *func;
1044 Tk_TimerToken token;
1045
1046 if (!PyArg_Parse (args, "(iO)", &milliseconds, &func))
1047 return NULL;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001048 if (!PyCallable_Check(func))
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001049 {
1050 PyErr_SetString (PyExc_TypeError, "bad argument list");
1051 return NULL;
1052 }
1053 token = Tk_CreateTimerHandler(milliseconds, TimerHandler, (ClientData) func);
1054 return (PyObject *) Tktt_New (token, func);
1055}
1056
Guido van Rossum18468821994-06-20 07:49:28 +00001057/** Event Loop **/
1058
Guido van Rossum18468821994-06-20 07:49:28 +00001059static PyObject *
1060Tkapp_MainLoop (self, args)
1061 PyObject *self;
1062 PyObject *args;
1063{
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001064 int threshold = 0;
1065
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001066 if (!PyArg_ParseTuple (args, "|i", &threshold))
1067 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001068
1069 quitMainLoop = 0;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001070 while (Tk_GetNumMainWindows() > threshold && !quitMainLoop && !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001071 {
1072 if (PyOS_InterruptOccurred ())
1073 {
1074 PyErr_SetNone (PyExc_KeyboardInterrupt);
1075 return NULL;
1076 }
1077 Tk_DoOneEvent (0);
1078 }
Guido van Rossum64b24fb1995-09-30 17:00:24 +00001079 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001080
1081 if (errorInCmd)
1082 {
1083 errorInCmd = 0;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001084 PyErr_Restore (excInCmd, valInCmd, trbInCmd);
1085 excInCmd = valInCmd = trbInCmd = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001086 return NULL;
1087 }
1088 Py_INCREF (Py_None);
1089 return Py_None;
1090}
1091
1092static PyObject *
Guido van Rossum062cfb01995-01-10 17:42:51 +00001093Tkapp_DoOneEvent (self, args)
1094 PyObject *self;
1095 PyObject *args;
1096{
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001097 int flags = TK_ALL_EVENTS;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001098 int rv;
1099
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001100 if (!PyArg_ParseTuple (args, "|i", &flags))
1101 return NULL;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001102 rv = Tk_DoOneEvent(flags);
1103 return Py_BuildValue ("i", rv);
1104}
1105
1106static PyObject *
Guido van Rossum18468821994-06-20 07:49:28 +00001107Tkapp_Quit (self, args)
1108 PyObject *self;
1109 PyObject *args;
1110{
1111
1112 if (!PyArg_Parse (args, ""))
1113 return NULL;
1114 quitMainLoop = 1;
1115 Py_INCREF (Py_None);
1116 return Py_None;
1117}
1118
1119/**** Tkapp Method List ****/
1120
1121static PyMethodDef Tkapp_methods[] =
1122{
1123 {"call", Tkapp_Call},
1124 {"globalcall", Tkapp_GlobalCall},
1125 {"eval", Tkapp_Eval},
1126 {"globaleval", Tkapp_GlobalEval},
1127 {"evalfile", Tkapp_EvalFile},
1128 {"record", Tkapp_Record},
1129 {"adderrorinfo", Tkapp_AddErrorInfo},
1130 {"setvar", Tkapp_SetVar},
1131 {"globalsetvar", Tkapp_GlobalSetVar},
1132 {"getvar", Tkapp_GetVar},
1133 {"globalgetvar", Tkapp_GlobalGetVar},
1134 {"unsetvar", Tkapp_UnsetVar},
1135 {"globalunsetvar", Tkapp_GlobalUnsetVar},
1136 {"getint", Tkapp_GetInt},
1137 {"getdouble", Tkapp_GetDouble},
1138 {"getboolean", Tkapp_GetBoolean},
1139 {"exprstring", Tkapp_ExprString},
1140 {"exprlong", Tkapp_ExprLong},
1141 {"exprdouble", Tkapp_ExprDouble},
1142 {"exprboolean", Tkapp_ExprBoolean},
1143 {"splitlist", Tkapp_SplitList},
1144 {"split", Tkapp_Split},
1145 {"merge", Tkapp_Merge},
1146 {"createcommand", Tkapp_CreateCommand},
1147 {"deletecommand", Tkapp_DeleteCommand},
1148 {"createfilehandler", Tkapp_CreateFileHandler},
1149 {"deletefilehandler", Tkapp_DeleteFileHandler},
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001150 {"createtimerhandler", Tkapp_CreateTimerHandler},
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001151 {"mainloop", Tkapp_MainLoop, 1},
1152 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum18468821994-06-20 07:49:28 +00001153 {"quit", Tkapp_Quit},
1154 {NULL, NULL}
1155};
1156
1157/**** Tkapp Type Methods ****/
1158
1159static void
1160Tkapp_Dealloc (self)
1161 PyObject *self;
1162{
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001163#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +00001164 Tk_DestroyWindow (Tkapp_Tkwin (self));
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001165#endif
Guido van Rossum18468821994-06-20 07:49:28 +00001166 Tcl_DeleteInterp (Tkapp_Interp (self));
1167 PyMem_DEL (self);
1168}
1169
1170static PyObject *
1171Tkapp_GetAttr (self, name)
1172 PyObject *self;
1173 char *name;
1174{
1175 return Py_FindMethod (Tkapp_methods, self, name);
1176}
1177
1178static PyTypeObject Tkapp_Type =
1179{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001180 PyObject_HEAD_INIT (&PyType_Type)
Guido van Rossum18468821994-06-20 07:49:28 +00001181 0, /*ob_size */
1182 "tkapp", /*tp_name */
1183 sizeof (TkappObject), /*tp_basicsize */
1184 0, /*tp_itemsize */
1185 Tkapp_Dealloc, /*tp_dealloc */
1186 0, /*tp_print */
1187 Tkapp_GetAttr, /*tp_getattr */
1188 0, /*tp_setattr */
1189 0, /*tp_compare */
1190 0, /*tp_repr */
1191 0, /*tp_as_number */
1192 0, /*tp_as_sequence */
1193 0, /*tp_as_mapping */
1194 0, /*tp_hash */
1195};
1196
1197/**** Tkinter Module ****/
1198
1199static PyObject *
1200Tkinter_Create (self, args)
1201 PyObject *self;
1202 PyObject *args;
1203{
1204 char *screenName = NULL;
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001205 char *baseName = NULL;
1206 char *className = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001207 int interactive = 0;
1208
1209 baseName = strrchr (getprogramname (), '/');
1210 if (baseName != NULL)
1211 baseName++;
1212 else
1213 baseName = getprogramname ();
1214 className = "Tk";
1215
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001216 if (!PyArg_ParseTuple (args, "|zssi",
1217 &screenName, &baseName, &className, &interactive))
Guido van Rossum18468821994-06-20 07:49:28 +00001218 return NULL;
1219
1220 return (PyObject *) Tkapp_New (screenName, baseName, className,
1221 interactive);
1222}
1223
1224static PyMethodDef moduleMethods[] =
1225{
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001226 {"create", Tkinter_Create, 1},
1227 {"createfilehandler", Tkapp_CreateFileHandler, 0},
1228 {"deletefilehandler", Tkapp_DeleteFileHandler, 0},
1229 {"createtimerhandler", Tkapp_CreateTimerHandler, 0},
1230 {"mainloop", Tkapp_MainLoop, 1},
1231 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001232 {"quit", Tkapp_Quit},
Guido van Rossum18468821994-06-20 07:49:28 +00001233 {NULL, NULL}
1234};
1235
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001236#undef WITH_READLINE /* XXX */
Guido van Rossum18468821994-06-20 07:49:28 +00001237#ifdef WITH_READLINE
1238static int
1239EventHook ()
1240{
1241 if (errorInCmd) /* XXX Reset tty */
1242 {
1243 errorInCmd = 0;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001244 PyErr_Restore (excInCmd, valInCmd, trbInCmd);
1245 excInCmd = valInCmd = trbInCmd = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001246 PyErr_Print ();
1247 }
Guido van Rossum9722ad81995-09-22 23:49:28 +00001248 if (Tk_GetNumMainWindows() > 0)
Guido van Rossume2ca9bd1994-08-03 08:01:43 +00001249 Tk_DoOneEvent (TK_DONT_WAIT);
Guido van Rossum18468821994-06-20 07:49:28 +00001250 return 0;
1251}
1252#endif /* WITH_READLINE */
1253
1254static void
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001255Tkinter_Cleanup ()
1256{
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001257/* This segfault with Tk 4.0 beta and seems unnecessary there as well */
1258#if TK_MAJOR_VERSION < 4
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001259 /* XXX rl_deprep_terminal is static, damned! */
1260 while (tkMainWindowList != 0)
1261 Tk_DestroyWindow (tkMainWindowList->win);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001262#endif
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001263}
1264
Guido van Rossum18468821994-06-20 07:49:28 +00001265void
Guido van Rossumad1f7ee1996-02-13 00:11:37 +00001266init_tkinter ()
Guido van Rossum18468821994-06-20 07:49:28 +00001267{
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001268 static inited = 0;
1269
Guido van Rossum18468821994-06-20 07:49:28 +00001270#ifdef WITH_READLINE
1271 extern int (*rl_event_hook) ();
1272#endif /* WITH_READLINE */
1273 PyObject *m, *d, *v;
1274
Jack Jansenba0311e1995-10-23 14:34:14 +00001275 m = Py_InitModule ("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001276
1277 d = PyModule_GetDict (m);
1278 Tkinter_TclError = Py_BuildValue ("s", "TclError");
1279 PyDict_SetItemString (d, "TclError", Tkinter_TclError);
1280
1281 v = Py_BuildValue ("i", TK_READABLE);
1282 PyDict_SetItemString (d, "READABLE", v);
1283 v = Py_BuildValue ("i", TK_WRITABLE);
1284 PyDict_SetItemString (d, "WRITABLE", v);
1285 v = Py_BuildValue ("i", TK_EXCEPTION);
1286 PyDict_SetItemString (d, "EXCEPTION", v);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001287 v = Py_BuildValue ("i", TK_X_EVENTS);
1288 PyDict_SetItemString (d, "X_EVENTS", v);
1289 v = Py_BuildValue ("i", TK_FILE_EVENTS);
1290 PyDict_SetItemString (d, "FILE_EVENTS", v);
1291 v = Py_BuildValue ("i", TK_TIMER_EVENTS);
1292 PyDict_SetItemString (d, "TIMER_EVENTS", v);
1293 v = Py_BuildValue ("i", TK_IDLE_EVENTS);
1294 PyDict_SetItemString (d, "IDLE_EVENTS", v);
1295 v = Py_BuildValue ("i", TK_ALL_EVENTS);
1296 PyDict_SetItemString (d, "ALL_EVENTS", v);
1297 v = Py_BuildValue ("i", TK_DONT_WAIT);
1298 PyDict_SetItemString (d, "DONT_WAIT", v);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001299 v = Py_BuildValue ("s", TK_VERSION);
1300 PyDict_SetItemString (d, "TK_VERSION", v);
1301 v = Py_BuildValue ("s", TCL_VERSION);
1302 PyDict_SetItemString (d, "TCL_VERSION", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001303
Guido van Rossum18468821994-06-20 07:49:28 +00001304#ifdef WITH_READLINE
1305 rl_event_hook = EventHook;
1306#endif /* WITH_READLINE */
1307
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001308 if (!inited)
1309 {
1310 inited = 1;
Guido van Rossume4485b01994-09-07 14:32:49 +00001311 if (Py_AtExit (Tkinter_Cleanup) != 0)
1312 fprintf(stderr,
1313 "Tkinter: warning: cleanup procedure not registered\n");
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001314 }
1315
Guido van Rossum18468821994-06-20 07:49:28 +00001316 if (PyErr_Occurred ())
Jack Jansenba0311e1995-10-23 14:34:14 +00001317 Py_FatalError ("can't initialize module _tkinter");
Jack Jansen34cc5c31995-10-31 16:15:12 +00001318#ifdef macintosh
Guido van Rossumec22c921996-02-25 04:50:29 +00001319 TclMacSetEventProc(PyMacConvertEvent);
1320#if GENERATINGCFM
Jack Jansen34cc5c31995-10-31 16:15:12 +00001321 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001322#endif /* GENERATINGCFM */
1323#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001324}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001325
Guido van Rossumec22c921996-02-25 04:50:29 +00001326
Guido van Rossum9722ad81995-09-22 23:49:28 +00001327#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001328
1329/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001330** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001331*/
1332
Guido van Rossum9722ad81995-09-22 23:49:28 +00001333void
1334panic(char * format, ...)
1335{
1336 va_list varg;
1337
1338 va_start(varg, format);
1339
1340 vfprintf(stderr, format, varg);
1341 (void) fflush(stderr);
1342
1343 va_end(varg);
1344
1345 Py_FatalError("Tcl/Tk panic");
1346}
Jack Jansen40b546d1995-11-14 10:34:45 +00001347
Guido van Rossumec22c921996-02-25 04:50:29 +00001348/*
1349** Pass events to SIOUX before passing them to Tk.
1350*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001351
Guido van Rossumec22c921996-02-25 04:50:29 +00001352static int
1353PyMacConvertEvent(eventPtr)
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001354 EventRecord *eventPtr;
1355{
Guido van Rossumec22c921996-02-25 04:50:29 +00001356 if (SIOUXHandleOneEvent(eventPtr))
1357 return 0; /* Nothing happened to the Tcl event queue */
1358 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001359}
1360
Guido van Rossumec22c921996-02-25 04:50:29 +00001361#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001362
1363/*
1364** Additional Mac specific code for dealing with shared libraries.
1365*/
1366
1367#include <Resources.h>
1368#include <CodeFragments.h>
1369
1370static int loaded_from_shlib = 0;
1371static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001372
Jack Jansen34cc5c31995-10-31 16:15:12 +00001373/*
1374** If this module is dynamically loaded the following routine should
1375** be the init routine. It takes care of adding the shared library to
1376** the resource-file chain, so that the tk routines can find their
1377** resources.
1378*/
1379OSErr pascal
1380init_tkinter_shlib(InitBlockPtr data)
1381{
Guido van Rossum54ac1891996-05-16 17:14:03 +00001382 __sinit(); /* Sez Jack */
Jack Jansen34cc5c31995-10-31 16:15:12 +00001383 if ( data == nil ) return noErr;
1384 if ( data->fragLocator.where == kOnDiskFlat ) {
1385 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1386 loaded_from_shlib = 1;
1387 } else if ( data->fragLocator.where == kOnDiskSegmented ) {
1388 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1389 loaded_from_shlib = 1;
1390 }
1391 return noErr;
1392}
1393
1394/*
1395** Insert the library resources into the search path. Put them after
1396** the resources from the application. Again, we ignore errors.
1397*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001398static
Jack Jansen34cc5c31995-10-31 16:15:12 +00001399mac_addlibresources()
1400{
1401 if ( !loaded_from_shlib )
1402 return;
1403 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1404}
1405
Guido van Rossumec22c921996-02-25 04:50:29 +00001406#endif /* GENERATINGCFM */
1407#endif /* macintosh */