blob: 9db12df1630000a32f417a6ee753b517854f898d [file] [log] [blame]
Guido van Rossum18468821994-06-20 07:49:28 +00001/* tkintermodule.c -- Interface to libtk.a and libtcl.a.
2 Copyright (C) 1994 Steen Lumholt */
3
4#if 0
5#include <Py/Python.h>
6#else
7
8#include "allobjects.h"
9#include "pythonrun.h"
10#include "intrcheck.h"
11#include "modsupport.h"
12#include "sysmodule.h"
13
14#define PyObject object
15typedef struct methodlist PyMethodDef;
16#define PyInit_tkinter inittkinter
17
18#undef Py_True
19#define Py_True ((object *) &TrueObject)
20#undef True
21
22#undef Py_False
23#define Py_False ((object *) &FalseObject)
24#undef False
25
26#undef Py_None
27#define Py_None (&NoObject)
28#undef None
29
30#endif /* 0 */
31
32#include <tcl.h>
33#include <tk.h>
34
35extern char *getprogramname ();
Guido van Rossumd308e2b1994-07-07 09:25:12 +000036
37/* Internal declarations from tkInt.h. */
Guido van Rossum18468821994-06-20 07:49:28 +000038extern int tk_NumMainWindows;
Guido van Rossumd308e2b1994-07-07 09:25:12 +000039extern struct { Tk_Window win; } *tkMainWindowList;
Guido van Rossum18468821994-06-20 07:49:28 +000040
41/**** Tkapp Object Declaration ****/
42
43staticforward PyTypeObject Tkapp_Type;
44
45typedef struct
46 {
47 PyObject_HEAD
48 Tcl_Interp *interp;
49 Tk_Window tkwin;
50 }
51TkappObject;
52
53#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
54#define Tkapp_Tkwin(v) (((TkappObject *) (v))->tkwin)
55#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
56#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
57
58#define DEBUG_REFCNT(v) (printf ("DEBUG: id=%p, refcnt=%i\n", \
59 (void *) v, ((PyObject *) v)->ob_refcnt))
60
61/**** Error Handling ****/
62
63static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +000064static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +000065static int errorInCmd = 0;
66static PyObject *excInCmd;
67static PyObject *valInCmd;
68
69static PyObject *
70Tkinter_Error (v)
71 PyObject *v;
72{
Guido van Rossum18468821994-06-20 07:49:28 +000073 PyErr_SetString (Tkinter_TclError, Tkapp_Result (v));
74 return NULL;
75}
76
77int
78PythonCmd_Error (interp)
79 Tcl_Interp *interp;
80{
81 errorInCmd = 1;
82 PyErr_GetAndClear (&excInCmd, &valInCmd);
83 return TCL_ERROR;
84}
85
86/**** Utils ****/
87
88static char *
89AsString (value, tmp)
90 PyObject *value;
91 PyObject *tmp;
92{
93 if (PyString_Check (value))
94 return PyString_AsString (value);
95 else
96 {
97 PyObject *v;
98
99 v = strobject (value);
100 PyList_Append (tmp, v);
101 Py_DECREF (v);
102 return PyString_AsString (v);
103 }
104}
105
106#define ARGSZ 64
107
108static char *
109Merge (args)
110 PyObject *args;
111{
112 PyObject *tmp;
113 char *argvStore[ARGSZ];
114 char **argv;
115 int fvStore[ARGSZ];
116 int *fv;
117 int argc;
118 char *res;
119 int i;
120
121 tmp = PyList_New (0);
122 argv = argvStore;
123 fv = fvStore;
124
125 if (!PyTuple_Check (args))
126 {
127 argc = 1;
128 fv[0] = 0;
129 argv[0] = AsString (args, tmp);
130 }
131 else
132 {
133 PyObject *v;
134
135 if (PyTuple_Size (args) > ARGSZ)
136 {
137 argv = malloc (PyTuple_Size (args) * sizeof (char *));
138 fv = malloc (PyTuple_Size (args) * sizeof (int));
139 if (argv == NULL || fv == NULL)
140 PyErr_NoMemory ();
141 }
142
143 argc = PyTuple_Size (args);
144 for (i = 0; i < argc; i++)
145 {
146 v = PyTuple_GetItem (args, i);
147 if (PyTuple_Check (v))
148 {
149 fv[i] = 1;
150 argv[i] = Merge (v);
151 }
152 else if (v == Py_None)
153 {
154 argc = i;
155 break;
156 }
157 else
158 {
159 fv[i] = 0;
160 argv[i] = AsString (v, tmp);
161 }
162 }
163 }
164
165 res = Tcl_Merge (argc, argv);
166
167 Py_DECREF (tmp);
168 for (i = 0; i < argc; i++)
169 if (fv[i]) free (argv[i]);
170 if (argv != argvStore)
171 free (argv);
172 if (fv != fvStore)
173 free (fv);
174
175 return res;
176}
177
178static PyObject *
179Split (self, list)
180 PyObject *self;
181 char *list;
182{
183 int argc;
184 char **argv;
185 PyObject *v;
186
187 if (list == NULL)
188 {
189 Py_INCREF (Py_None);
190 return Py_None;
191 }
192
193 if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
194 return Tkinter_Error (self);
195
196 if (argc == 0)
197 v = PyString_FromString ("");
198 else if (argc == 1)
199 v = PyString_FromString (argv[0]);
200 else
201 {
202 int i;
203
204 v = PyTuple_New (argc);
205 for (i = 0; i < argc; i++)
206 PyTuple_SetItem (v, i, Split (self, argv[i]));
207 }
208
209 free (argv);
210 return v;
211}
212
213/**** Tkapp Object ****/
214
215#ifndef WITH_APPINIT
216int
217Tcl_AppInit (interp)
218 Tcl_Interp *interp;
219{
220 if (Tcl_Init (interp) == TCL_ERROR)
221 return TCL_ERROR;
222 if (Tk_Init (interp) == TCL_ERROR)
223 return TCL_ERROR;
224 return TCL_OK;
225}
226#endif /* !WITH_APPINIT */
227
228/* Initialize the Tk application; see the `main' function in
229 `tkMain.c'. */
230static TkappObject *
231Tkapp_New (screenName, baseName, className, interactive)
232 char *screenName;
233 char *baseName;
234 char *className;
235 int interactive;
236{
237 TkappObject *v;
238
239 v = PyObject_NEW (TkappObject, &Tkapp_Type);
240 if (v == NULL)
241 return NULL;
242
243 v->interp = Tcl_CreateInterp ();
244 v->tkwin = Tk_CreateMainWindow (v->interp, screenName,
245 baseName, className);
246 if (v->tkwin == NULL)
247 return (TkappObject *) Tkinter_Error ((PyObject *) v);
248
249 Tk_GeometryRequest (v->tkwin, 200, 200);
250
251 if (screenName != NULL)
252 Tcl_SetVar2 (v->interp, "env", "DISPLAY", screenName, TCL_GLOBAL_ONLY);
253
254 if (interactive)
255 Tcl_SetVar (v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
256 else
257 Tcl_SetVar (v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
258
Guido van Rossum18468821994-06-20 07:49:28 +0000259 if (Tcl_AppInit (v->interp) != TCL_OK)
260 {
261 PyErr_SetString (Tkinter_TclError, "Tcl_AppInit failed"); /* XXX */
262 return NULL;
263 }
Guido van Rossum18468821994-06-20 07:49:28 +0000264
265 return v;
266}
267
268/** Tcl Eval **/
269
270static PyObject *
271Tkapp_Call (self, args)
272 PyObject *self;
273 PyObject *args;
274{
275 char *cmd;
276
277 cmd = Merge (args);
278 if (Tcl_Eval (Tkapp_Interp (self), cmd) == TCL_ERROR)
279 {
280 free (cmd);
281 return Tkinter_Error (self);
282 }
283
284 free (cmd);
285 return PyString_FromString (Tkapp_Result (self));
286}
287
288static PyObject *
289Tkapp_GlobalCall (self, args)
290 PyObject *self;
291 PyObject *args;
292{
293 char *cmd;
294
295 cmd = Merge (args);
296 if (Tcl_GlobalEval (Tkapp_Interp (self), cmd) == TCL_ERROR)
297 {
298 free (cmd);
299 return Tkinter_Error (self);
300 }
301
302 free (cmd);
303 return PyString_FromString (Tkapp_Result (self));
304}
305
306static PyObject *
307Tkapp_Eval (self, args)
308 PyObject *self;
309 PyObject *args;
310{
311 char *script;
312
313 if (!PyArg_Parse (args, "s", &script))
314 return NULL;
315
316 if (Tcl_Eval (Tkapp_Interp (self), script) == TCL_ERROR)
317 return Tkinter_Error (self);
318
319 return PyString_FromString (Tkapp_Result (self));
320}
321
322static PyObject *
323Tkapp_GlobalEval (self, args)
324 PyObject *self;
325 PyObject *args;
326{
327 char *script;
328
329 if (!PyArg_Parse (args, "s", &script))
330 return NULL;
331
332 if (Tcl_GlobalEval (Tkapp_Interp (self), script) == TCL_ERROR)
333 return Tkinter_Error (self);
334
335 return PyString_FromString (Tkapp_Result (self));
336}
337
338static PyObject *
339Tkapp_EvalFile (self, args)
340 PyObject *self;
341 PyObject *args;
342{
343 char *fileName;
344
345 if (!PyArg_Parse (args, "s", &fileName))
346 return NULL;
347
348 if (Tcl_EvalFile (Tkapp_Interp (self), fileName) == TCL_ERROR)
349 return Tkinter_Error (self);
350
351 return PyString_FromString (Tkapp_Result (self));
352}
353
354static PyObject *
355Tkapp_Record (self, args)
356 PyObject *self;
357 PyObject *args;
358{
359 char *script;
360
361 if (!PyArg_Parse (args, "s", &script))
362 return NULL;
363
364 if (Tcl_RecordAndEval (Tkapp_Interp (self),
365 script, TCL_NO_EVAL) == TCL_ERROR)
366 return Tkinter_Error (self);
367
368 return PyString_FromString (Tkapp_Result (self));
369}
370
371static PyObject *
372Tkapp_AddErrorInfo (self, args)
373 PyObject *self;
374 PyObject *args;
375{
376 char *msg;
377
378 if (!PyArg_Parse (args, "s", &msg))
379 return NULL;
380 Tcl_AddErrorInfo (Tkapp_Interp (self), msg);
381
382 Py_INCREF(Py_None);
383 return Py_None;
384}
385
386/** Tcl Variable **/
387
388static PyObject *
389SetVar (self, args, flags)
390 PyObject *self;
391 PyObject *args;
392 int flags;
393{
394 char *name1, *name2, *ok;
395 PyObject *newValue;
396 PyObject *tmp;
397
398 tmp = PyList_New (0);
399
400 if (PyArg_Parse (args, "(sO)", &name1, &newValue))
401 ok = Tcl_SetVar (Tkapp_Interp (self), name1,
402 AsString (newValue, tmp), flags); /* XXX Merge? */
403 else if (PyArg_Parse (args, "(ssO)", &name1, &name2, &newValue))
404 ok = Tcl_SetVar2 (Tkapp_Interp (self), name1, name2,
405 AsString (newValue, tmp), flags);
406 else
407 {
408 Py_DECREF (tmp);
409 return NULL;
410 }
411 Py_DECREF (tmp);
412
413 if (!ok)
414 return Tkinter_Error (self);
415
416 Py_INCREF (Py_None);
417 return Py_None;
418}
419
420static PyObject *
421Tkapp_SetVar (self, args)
422 PyObject *self;
423 PyObject *args;
424{
425 return SetVar (self, args, TCL_LEAVE_ERR_MSG);
426}
427
428static PyObject *
429Tkapp_GlobalSetVar (self, args)
430 PyObject *self;
431 PyObject *args;
432{
433 return SetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
434}
435
436static PyObject *
437GetVar (self, args, flags)
438 PyObject *self;
439 PyObject *args;
440 int flags;
441{
442 char *name1, *name2, *s;
443
444 if (PyArg_Parse (args, "s", &name1))
445 s = Tcl_GetVar (Tkapp_Interp (self), name1, flags);
446 else if (PyArg_Parse (args, "(ss)", &name1, &name2))
447 s = Tcl_GetVar2 (Tkapp_Interp (self), name1, name2, flags);
448 else
449 return NULL;
450
451 if (s == NULL)
452 return Tkinter_Error (self);
453
454 return PyString_FromString (s);
455}
456
457static PyObject *
458Tkapp_GetVar (self, args)
459 PyObject *self;
460 PyObject *args;
461{
462 return GetVar (self, args, TCL_LEAVE_ERR_MSG);
463}
464
465static PyObject *
466Tkapp_GlobalGetVar (self, args)
467 PyObject *self;
468 PyObject *args;
469{
470 return GetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
471}
472
473static PyObject *
474UnsetVar (self, args, flags)
475 PyObject *self;
476 PyObject *args;
477 int flags;
478{
479 char *name1, *name2;
480 int code;
481
482 if (PyArg_Parse (args, "s", &name1))
483 code = Tcl_UnsetVar (Tkapp_Interp (self), name1, flags);
484 else if (PyArg_Parse (args, "(ss)", &name1, &name2))
485 code = Tcl_UnsetVar2 (Tkapp_Interp (self), name1, name2, flags);
486 else
487 return NULL;
488
489 if (code == TCL_ERROR)
490 return Tkinter_Error (self);
491
492 Py_INCREF (Py_None);
493 return Py_None;
494}
495
496static PyObject *
497Tkapp_UnsetVar (self, args)
498 PyObject *self;
499 PyObject *args;
500{
501 return UnsetVar (self, args, TCL_LEAVE_ERR_MSG);
502}
503
504static PyObject *
505Tkapp_GlobalUnsetVar (self, args)
506 PyObject *self;
507 PyObject *args;
508{
509 return UnsetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
510}
511
512/** Tcl to Python **/
513
514static PyObject *
515Tkapp_GetInt (self, args)
516 PyObject *self;
517 PyObject *args;
518{
519 char *s;
520 int v;
521
522 if (!PyArg_Parse (args, "s", &s))
523 return NULL;
524 if (Tcl_GetInt (Tkapp_Interp (self), s, &v) == TCL_ERROR)
525 return Tkinter_Error (self);
526 return Py_BuildValue ("i", v);
527}
528
529static PyObject *
530Tkapp_GetDouble (self, args)
531 PyObject *self;
532 PyObject *args;
533{
534 char *s;
535 double v;
536
537 if (!PyArg_Parse (args, "s", &s))
538 return NULL;
539 if (Tcl_GetDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
540 return Tkinter_Error (self);
541 return Py_BuildValue ("d", v);
542}
543
544static PyObject *
545Tkapp_GetBoolean (self, args)
546 PyObject *self;
547 PyObject *args;
548{
549 char *s;
550 int v;
551
552 if (!PyArg_Parse (args, "s", &s))
553 return NULL;
554 if (Tcl_GetBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
555 return Tkinter_Error (self);
556 return Py_BuildValue ("i", v);
557}
558
559static PyObject *
560Tkapp_ExprString (self, args)
561 PyObject *self;
562 PyObject *args;
563{
564 char *s;
565
566 if (!PyArg_Parse (args, "s", &s))
567 return NULL;
568 if (Tcl_ExprString (Tkapp_Interp (self), s) == TCL_ERROR)
569 return Tkinter_Error (self);
570 return Py_BuildValue ("s", Tkapp_Result (self));
571}
572
573static PyObject *
574Tkapp_ExprLong (self, args)
575 PyObject *self;
576 PyObject *args;
577{
578 char *s;
579 long v;
580
581 if (!PyArg_Parse (args, "s", &s))
582 return NULL;
583 if (Tcl_ExprLong (Tkapp_Interp (self), s, &v) == TCL_ERROR)
584 return Tkinter_Error (self);
585 return Py_BuildValue ("l", v);
586}
587
588static PyObject *
589Tkapp_ExprDouble (self, args)
590 PyObject *self;
591 PyObject *args;
592{
593 char *s;
594 double v;
595
596 if (!PyArg_Parse (args, "s", &s))
597 return NULL;
598 if (Tcl_ExprDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
599 return Tkinter_Error (self);
600 return Py_BuildValue ("d", v);
601}
602
603static PyObject *
604Tkapp_ExprBoolean (self, args)
605 PyObject *self;
606 PyObject *args;
607{
608 char *s;
609 int v;
610
611 if (!PyArg_Parse (args, "s", &s))
612 return NULL;
613 if (Tcl_ExprBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
614 return Tkinter_Error (self);
615 return Py_BuildValue ("i", v);
616}
617
618static PyObject *
619Tkapp_SplitList (self, args)
620 PyObject *self;
621 PyObject *args;
622{
623 char *list;
624 int argc;
625 char **argv;
626 PyObject *v;
627 int i;
628
629 if (!PyArg_Parse (args, "s", &list))
630 return NULL;
631
632 if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
633 return Tkinter_Error (self);
634
635 v = PyTuple_New (argc);
636 for (i = 0; i < argc; i++)
637 PyTuple_SetItem (v, i, PyString_FromString (argv[i]));
638
639 free (argv);
640 return v;
641}
642
643static PyObject *
644Tkapp_Split (self, args)
645 PyObject *self;
646 PyObject *args;
647{
648 char *list;
649
650 if (!PyArg_Parse (args, "s", &list))
651 return NULL;
652 return Split (self, list);
653}
654
655static PyObject *
656Tkapp_Merge (self, args)
657 PyObject *self;
658 PyObject *args;
659{
660 char *s;
661 PyObject *v;
662
663 s = Merge (args);
664 v = PyString_FromString (s);
665 free (s);
666 return v;
667}
668
669/** Tcl Command **/
670
671/* This is the Tcl command that acts as a wrapper for Python
672 function or method. */
673static int
674PythonCmd (clientData, interp, argc, argv)
675 ClientData clientData; /* Is (self, func) */
676 Tcl_Interp *interp;
677 int argc;
678 char *argv[];
679{
680 PyObject *self, *func, *arg, *res, *tmp;
681 int i;
682
683 self = PyTuple_GetItem ((PyObject *) clientData, 0);
684 func = PyTuple_GetItem ((PyObject *) clientData, 1);
685
686 /* Create argument list (argv1, ..., argvN) */
687 arg = PyTuple_New (argc - 1);
688 for (i = 0; i < (argc - 1); i++)
689 PyTuple_SetItem (arg, i, PyString_FromString (argv[i + 1]));
690
691 res = PyEval_CallObject (func, arg);
692 Py_DECREF (arg);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000693
Guido van Rossum18468821994-06-20 07:49:28 +0000694 if (res == NULL)
695 return PythonCmd_Error (interp);
696
697 tmp = PyList_New (0);
698 Tcl_SetResult (Tkapp_Interp (self), AsString (res, tmp), TCL_VOLATILE);
699 Py_DECREF (res);
700 Py_DECREF (tmp);
701
702 return TCL_OK;
703}
704
705static void
706PythonCmdDelete (clientData)
707 ClientData clientData; /* Is (self, func) */
708{
709 Py_DECREF ((PyObject *) clientData);
710}
711
712static PyObject *
713Tkapp_CreateCommand (self, args)
714 PyObject *self;
715 PyObject *args;
716{
717 char *cmdName;
718 PyObject *data;
719 PyObject *func;
720
721 /* Args is: (cmdName, func) */
722 if (!PyTuple_Check (args)
723 || !(PyTuple_Size (args) == 2)
724 || !PyString_Check (PyTuple_GetItem (args, 0))
725 || !(PyMethod_Check (PyTuple_GetItem (args, 1))
726 || PyFunction_Check (PyTuple_GetItem (args, 1))))
727 {
728 PyErr_SetString (PyExc_TypeError, "bad argument list");
729 return NULL;
730 }
731
732 cmdName = PyString_AsString (PyTuple_GetItem (args, 0));
733 func = PyTuple_GetItem (args, 1);
734
735 data = PyTuple_New (2); /* ClientData is: (self, func) */
736
737 Py_INCREF (self);
738 PyTuple_SetItem (data, 0, self);
739
740 Py_INCREF (func);
741 PyTuple_SetItem (data, 1, func);
742
743 Tcl_CreateCommand (Tkapp_Interp (self), cmdName, PythonCmd,
744 (ClientData) data, PythonCmdDelete);
745
746 Py_INCREF (Py_None);
747 return Py_None;
748}
749
750static PyObject *
751Tkapp_DeleteCommand (self, args)
752 PyObject *self;
753 PyObject *args;
754{
755 char *cmdName;
756
757 if (!PyArg_Parse (args, "s", &cmdName))
758 return NULL;
759 if (Tcl_DeleteCommand (Tkapp_Interp (self), cmdName) == -1)
760 {
761 PyErr_SetString (Tkinter_TclError, "can't delete Tcl command");
762 return NULL;
763 }
764 Py_INCREF (Py_None);
765 return Py_None;
766}
767
768/** File Handler **/
769
770void
771FileHandler (clientData, mask)
Guido van Rossum76875221994-06-27 07:59:42 +0000772 ClientData clientData; /* Is: (func, file) */
Guido van Rossum18468821994-06-20 07:49:28 +0000773 int mask;
774{
Guido van Rossum76875221994-06-27 07:59:42 +0000775 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +0000776
Guido van Rossum76875221994-06-27 07:59:42 +0000777 func = PyTuple_GetItem ((PyObject *) clientData, 0);
778 file = PyTuple_GetItem ((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000779
Guido van Rossum76875221994-06-27 07:59:42 +0000780 arg = Py_BuildValue ("(Oi)", file, (long) mask);
Guido van Rossum18468821994-06-20 07:49:28 +0000781 res = PyEval_CallObject (func, arg);
782 Py_DECREF (arg);
783 if (res == NULL)
784 {
785 errorInCmd = 1;
786 PyErr_GetAndClear (&excInCmd, &valInCmd);
787 }
Guido van Rossum76875221994-06-27 07:59:42 +0000788 Py_DECREF (res);
Guido van Rossum18468821994-06-20 07:49:28 +0000789}
790
791static PyObject *
792Tkapp_CreateFileHandler (self, args)
793 PyObject *self;
794 PyObject *args; /* Is (file, mask, func) */
795{
Guido van Rossum76875221994-06-27 07:59:42 +0000796 PyObject *file, *func, *data;
797 int mask, id;
Guido van Rossum18468821994-06-20 07:49:28 +0000798
799 if (!PyArg_Parse (args, "(OiO)", &file, &mask, &func))
800 return NULL;
801 if (!PyFile_Check (file)
802 || !(PyMethod_Check(func) || PyFunction_Check(func)))
803 {
804 PyErr_SetString (PyExc_TypeError, "bad argument list");
805 return NULL;
806 }
807
Guido van Rossum76875221994-06-27 07:59:42 +0000808 /* ClientData is: (func, file) */
809 data = Py_BuildValue ("(OO)", func, file);
810
Guido van Rossum18468821994-06-20 07:49:28 +0000811 id = fileno (PyFile_AsFile (file));
Guido van Rossum76875221994-06-27 07:59:42 +0000812 Tk_CreateFileHandler (id, mask, FileHandler, (ClientData) data);
Guido van Rossum18468821994-06-20 07:49:28 +0000813 /* XXX fileHandlerDict */
Guido van Rossum76875221994-06-27 07:59:42 +0000814
Guido van Rossum18468821994-06-20 07:49:28 +0000815 Py_INCREF (Py_None);
816 return Py_None;
817}
818
819static PyObject *
820Tkapp_DeleteFileHandler (self, args)
821 PyObject *self;
822 PyObject *args; /* Args: file */
823{
824 int id;
825
826 if (!PyFile_Check (args))
827 {
828 PyErr_SetString (PyExc_TypeError, "bad argument list");
829 return NULL;
830 }
831
832 id = fileno (PyFile_AsFile (args));
833 Tk_DeleteFileHandler (id);
834 /* XXX fileHandlerDict */
835 Py_INCREF (Py_None);
836 return Py_None;
837}
838
839/** Event Loop **/
840
Guido van Rossum18468821994-06-20 07:49:28 +0000841static PyObject *
842Tkapp_MainLoop (self, args)
843 PyObject *self;
844 PyObject *args;
845{
846 if (!PyArg_Parse (args, ""))
847 return NULL;
848
849 quitMainLoop = 0;
850 while (tk_NumMainWindows > 0 && !quitMainLoop && !errorInCmd)
851 {
852 if (PyOS_InterruptOccurred ())
853 {
854 PyErr_SetNone (PyExc_KeyboardInterrupt);
855 return NULL;
856 }
857 Tk_DoOneEvent (0);
858 }
859
860 if (errorInCmd)
861 {
862 errorInCmd = 0;
863 PyErr_SetObject (excInCmd, valInCmd);
864 return NULL;
865 }
866 Py_INCREF (Py_None);
867 return Py_None;
868}
869
870static PyObject *
871Tkapp_Quit (self, args)
872 PyObject *self;
873 PyObject *args;
874{
875
876 if (!PyArg_Parse (args, ""))
877 return NULL;
878 quitMainLoop = 1;
879 Py_INCREF (Py_None);
880 return Py_None;
881}
882
883/**** Tkapp Method List ****/
884
885static PyMethodDef Tkapp_methods[] =
886{
887 {"call", Tkapp_Call},
888 {"globalcall", Tkapp_GlobalCall},
889 {"eval", Tkapp_Eval},
890 {"globaleval", Tkapp_GlobalEval},
891 {"evalfile", Tkapp_EvalFile},
892 {"record", Tkapp_Record},
893 {"adderrorinfo", Tkapp_AddErrorInfo},
894 {"setvar", Tkapp_SetVar},
895 {"globalsetvar", Tkapp_GlobalSetVar},
896 {"getvar", Tkapp_GetVar},
897 {"globalgetvar", Tkapp_GlobalGetVar},
898 {"unsetvar", Tkapp_UnsetVar},
899 {"globalunsetvar", Tkapp_GlobalUnsetVar},
900 {"getint", Tkapp_GetInt},
901 {"getdouble", Tkapp_GetDouble},
902 {"getboolean", Tkapp_GetBoolean},
903 {"exprstring", Tkapp_ExprString},
904 {"exprlong", Tkapp_ExprLong},
905 {"exprdouble", Tkapp_ExprDouble},
906 {"exprboolean", Tkapp_ExprBoolean},
907 {"splitlist", Tkapp_SplitList},
908 {"split", Tkapp_Split},
909 {"merge", Tkapp_Merge},
910 {"createcommand", Tkapp_CreateCommand},
911 {"deletecommand", Tkapp_DeleteCommand},
912 {"createfilehandler", Tkapp_CreateFileHandler},
913 {"deletefilehandler", Tkapp_DeleteFileHandler},
914 {"mainloop", Tkapp_MainLoop},
915 {"quit", Tkapp_Quit},
916 {NULL, NULL}
917};
918
919/**** Tkapp Type Methods ****/
920
921static void
922Tkapp_Dealloc (self)
923 PyObject *self;
924{
925 Tk_DestroyWindow (Tkapp_Tkwin (self));
926 Tcl_DeleteInterp (Tkapp_Interp (self));
927 PyMem_DEL (self);
928}
929
930static PyObject *
931Tkapp_GetAttr (self, name)
932 PyObject *self;
933 char *name;
934{
935 return Py_FindMethod (Tkapp_methods, self, name);
936}
937
938static PyTypeObject Tkapp_Type =
939{
940 OB_HEAD_INIT (&PyType_Type)
941 0, /*ob_size */
942 "tkapp", /*tp_name */
943 sizeof (TkappObject), /*tp_basicsize */
944 0, /*tp_itemsize */
945 Tkapp_Dealloc, /*tp_dealloc */
946 0, /*tp_print */
947 Tkapp_GetAttr, /*tp_getattr */
948 0, /*tp_setattr */
949 0, /*tp_compare */
950 0, /*tp_repr */
951 0, /*tp_as_number */
952 0, /*tp_as_sequence */
953 0, /*tp_as_mapping */
954 0, /*tp_hash */
955};
956
957/**** Tkinter Module ****/
958
959static PyObject *
960Tkinter_Create (self, args)
961 PyObject *self;
962 PyObject *args;
963{
964 char *screenName = NULL;
965 char *baseName;
966 char *className;
967 int interactive = 0;
968
969 baseName = strrchr (getprogramname (), '/');
970 if (baseName != NULL)
971 baseName++;
972 else
973 baseName = getprogramname ();
974 className = "Tk";
975
976 if (PyArg_Parse (args, ""))
977 /* VOID */ ;
978 else if (PyArg_Parse (args, "z",
979 &screenName))
980 /* VOID */ ;
981 else if (PyArg_Parse (args, "(zs)",
982 &screenName, &baseName))
983 /* VOID */ ;
984 else if (PyArg_Parse (args, "(zss)",
985 &screenName, &baseName, &className))
986 /* VOID */ ;
987 else if (PyArg_Parse (args, "(zssi)",
988 &screenName, &baseName, &className, &interactive))
989 /* VOID */ ;
990 else
991 return NULL;
992
993 return (PyObject *) Tkapp_New (screenName, baseName, className,
994 interactive);
995}
996
997static PyMethodDef moduleMethods[] =
998{
999 {"create", Tkinter_Create},
1000 {NULL, NULL}
1001};
1002
1003#ifdef WITH_READLINE
1004static int
1005EventHook ()
1006{
1007 if (errorInCmd) /* XXX Reset tty */
1008 {
1009 errorInCmd = 0;
1010 PyErr_SetObject (excInCmd, valInCmd);
1011 PyErr_Print ();
1012 }
1013 if (tk_NumMainWindows > 0)
Guido van Rossume2ca9bd1994-08-03 08:01:43 +00001014 Tk_DoOneEvent (TK_DONT_WAIT);
Guido van Rossum18468821994-06-20 07:49:28 +00001015 return 0;
1016}
1017#endif /* WITH_READLINE */
1018
1019static void
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001020Tkinter_Cleanup ()
1021{
1022 /* XXX rl_deprep_terminal is static, damned! */
1023 while (tkMainWindowList != 0)
1024 Tk_DestroyWindow (tkMainWindowList->win);
1025}
1026
Guido van Rossum18468821994-06-20 07:49:28 +00001027void
1028PyInit_tkinter ()
1029{
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001030 static inited = 0;
1031
Guido van Rossum18468821994-06-20 07:49:28 +00001032#ifdef WITH_READLINE
1033 extern int (*rl_event_hook) ();
1034#endif /* WITH_READLINE */
1035 PyObject *m, *d, *v;
1036
1037 m = Py_InitModule ("tkinter", moduleMethods);
1038
1039 d = PyModule_GetDict (m);
1040 Tkinter_TclError = Py_BuildValue ("s", "TclError");
1041 PyDict_SetItemString (d, "TclError", Tkinter_TclError);
1042
1043 v = Py_BuildValue ("i", TK_READABLE);
1044 PyDict_SetItemString (d, "READABLE", v);
1045 v = Py_BuildValue ("i", TK_WRITABLE);
1046 PyDict_SetItemString (d, "WRITABLE", v);
1047 v = Py_BuildValue ("i", TK_EXCEPTION);
1048 PyDict_SetItemString (d, "EXCEPTION", v);
1049
Guido van Rossum18468821994-06-20 07:49:28 +00001050#ifdef WITH_READLINE
1051 rl_event_hook = EventHook;
1052#endif /* WITH_READLINE */
1053
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001054 if (!inited)
1055 {
1056 inited = 1;
1057 if (atexit (Tkinter_Cleanup))
1058 PyErr_SetFromErrno (Tkinter_TclError);
1059 }
1060
Guido van Rossum18468821994-06-20 07:49:28 +00001061 if (PyErr_Occurred ())
1062 Py_FatalError ("can't initialize module tkinter");
1063}