improve treatment of multi-line replies, ignore empty lines
[python/dscho.git] / Modules / _tkinter.c
blob9675da5d053473b739cd7e675d1b072b3651b2ef
1 /* tkintermodule.c -- Interface to libtk.a and libtcl.a.
2 Copyright (C) 1994 Steen Lumholt */
4 #include <Python.h>
6 #define PyInit_tkinter inittkinter
8 #include <tcl.h>
9 #include <tk.h>
11 extern char *getprogramname ();
13 /* Internal declarations from tkInt.h. */
14 extern int tk_NumMainWindows;
15 extern struct { Tk_Window win; } *tkMainWindowList;
17 /**** Tkapp Object Declaration ****/
19 staticforward PyTypeObject Tkapp_Type;
21 typedef struct
23 PyObject_HEAD
24 Tcl_Interp *interp;
25 Tk_Window tkwin;
27 TkappObject;
29 #define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
30 #define Tkapp_Tkwin(v) (((TkappObject *) (v))->tkwin)
31 #define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
32 #define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
34 #define DEBUG_REFCNT(v) (printf ("DEBUG: id=%p, refcnt=%i\n", \
35 (void *) v, ((PyObject *) v)->ob_refcnt))
37 /**** Error Handling ****/
39 static PyObject *Tkinter_TclError;
40 static int quitMainLoop = 0;
41 static int errorInCmd = 0;
42 static PyObject *excInCmd;
43 static PyObject *valInCmd;
44 static PyObject *trbInCmd;
46 static PyObject *
47 Tkinter_Error (v)
48 PyObject *v;
50 PyErr_SetString (Tkinter_TclError, Tkapp_Result (v));
51 return NULL;
54 int
55 PythonCmd_Error (interp)
56 Tcl_Interp *interp;
58 errorInCmd = 1;
59 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
60 return TCL_ERROR;
63 /**** Utils ****/
65 static char *
66 AsString (value, tmp)
67 PyObject *value;
68 PyObject *tmp;
70 if (PyString_Check (value))
71 return PyString_AsString (value);
72 else
74 PyObject *v;
76 v = strobject (value);
77 PyList_Append (tmp, v);
78 Py_DECREF (v);
79 return PyString_AsString (v);
83 #define ARGSZ 64
85 static char *
86 Merge (args)
87 PyObject *args;
89 PyObject *tmp;
90 char *argvStore[ARGSZ];
91 char **argv;
92 int fvStore[ARGSZ];
93 int *fv;
94 int argc;
95 char *res;
96 int i;
98 tmp = PyList_New (0);
99 argv = argvStore;
100 fv = fvStore;
102 if (!PyTuple_Check (args))
104 argc = 1;
105 fv[0] = 0;
106 argv[0] = AsString (args, tmp);
108 else
110 PyObject *v;
112 if (PyTuple_Size (args) > ARGSZ)
114 argv = malloc (PyTuple_Size (args) * sizeof (char *));
115 fv = malloc (PyTuple_Size (args) * sizeof (int));
116 if (argv == NULL || fv == NULL)
117 PyErr_NoMemory ();
120 argc = PyTuple_Size (args);
121 for (i = 0; i < argc; i++)
123 v = PyTuple_GetItem (args, i);
124 if (PyTuple_Check (v))
126 fv[i] = 1;
127 argv[i] = Merge (v);
129 else if (v == Py_None)
131 argc = i;
132 break;
134 else
136 fv[i] = 0;
137 argv[i] = AsString (v, tmp);
142 res = Tcl_Merge (argc, argv);
144 Py_DECREF (tmp);
145 for (i = 0; i < argc; i++)
146 if (fv[i]) free (argv[i]);
147 if (argv != argvStore)
148 free (argv);
149 if (fv != fvStore)
150 free (fv);
152 return res;
155 static PyObject *
156 Split (self, list)
157 PyObject *self;
158 char *list;
160 int argc;
161 char **argv;
162 PyObject *v;
164 if (list == NULL)
166 Py_INCREF (Py_None);
167 return Py_None;
170 if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
171 return Tkinter_Error (self);
173 if (argc == 0)
174 v = PyString_FromString ("");
175 else if (argc == 1)
176 v = PyString_FromString (argv[0]);
177 else
179 int i;
181 v = PyTuple_New (argc);
182 for (i = 0; i < argc; i++)
183 PyTuple_SetItem (v, i, Split (self, argv[i]));
186 free (argv);
187 return v;
190 /**** Tkapp Object ****/
192 #ifndef WITH_APPINIT
194 Tcl_AppInit (interp)
195 Tcl_Interp *interp;
197 if (Tcl_Init (interp) == TCL_ERROR)
198 return TCL_ERROR;
199 if (Tk_Init (interp) == TCL_ERROR)
200 return TCL_ERROR;
201 return TCL_OK;
203 #endif /* !WITH_APPINIT */
205 /* Initialize the Tk application; see the `main' function in
206 `tkMain.c'. */
207 static TkappObject *
208 Tkapp_New (screenName, baseName, className, interactive)
209 char *screenName;
210 char *baseName;
211 char *className;
212 int interactive;
214 TkappObject *v;
216 v = PyObject_NEW (TkappObject, &Tkapp_Type);
217 if (v == NULL)
218 return NULL;
220 v->interp = Tcl_CreateInterp ();
221 v->tkwin = Tk_CreateMainWindow (v->interp, screenName,
222 baseName, className);
223 if (v->tkwin == NULL)
224 return (TkappObject *) Tkinter_Error ((PyObject *) v);
226 Tk_GeometryRequest (v->tkwin, 200, 200);
228 if (screenName != NULL)
229 Tcl_SetVar2 (v->interp, "env", "DISPLAY", screenName, TCL_GLOBAL_ONLY);
231 if (interactive)
232 Tcl_SetVar (v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
233 else
234 Tcl_SetVar (v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
236 if (Tcl_AppInit (v->interp) != TCL_OK)
238 PyErr_SetString (Tkinter_TclError, "Tcl_AppInit failed"); /* XXX */
239 return NULL;
242 return v;
245 /** Tcl Eval **/
247 static PyObject *
248 Tkapp_Call (self, args)
249 PyObject *self;
250 PyObject *args;
252 char *cmd;
254 cmd = Merge (args);
255 if (Tcl_Eval (Tkapp_Interp (self), cmd) == TCL_ERROR)
257 free (cmd);
258 return Tkinter_Error (self);
261 free (cmd);
262 return PyString_FromString (Tkapp_Result (self));
265 static PyObject *
266 Tkapp_GlobalCall (self, args)
267 PyObject *self;
268 PyObject *args;
270 char *cmd;
272 cmd = Merge (args);
273 if (Tcl_GlobalEval (Tkapp_Interp (self), cmd) == TCL_ERROR)
275 free (cmd);
276 return Tkinter_Error (self);
279 free (cmd);
280 return PyString_FromString (Tkapp_Result (self));
283 static PyObject *
284 Tkapp_Eval (self, args)
285 PyObject *self;
286 PyObject *args;
288 char *script;
290 if (!PyArg_Parse (args, "s", &script))
291 return NULL;
293 if (Tcl_Eval (Tkapp_Interp (self), script) == TCL_ERROR)
294 return Tkinter_Error (self);
296 return PyString_FromString (Tkapp_Result (self));
299 static PyObject *
300 Tkapp_GlobalEval (self, args)
301 PyObject *self;
302 PyObject *args;
304 char *script;
306 if (!PyArg_Parse (args, "s", &script))
307 return NULL;
309 if (Tcl_GlobalEval (Tkapp_Interp (self), script) == TCL_ERROR)
310 return Tkinter_Error (self);
312 return PyString_FromString (Tkapp_Result (self));
315 static PyObject *
316 Tkapp_EvalFile (self, args)
317 PyObject *self;
318 PyObject *args;
320 char *fileName;
322 if (!PyArg_Parse (args, "s", &fileName))
323 return NULL;
325 if (Tcl_EvalFile (Tkapp_Interp (self), fileName) == TCL_ERROR)
326 return Tkinter_Error (self);
328 return PyString_FromString (Tkapp_Result (self));
331 static PyObject *
332 Tkapp_Record (self, args)
333 PyObject *self;
334 PyObject *args;
336 char *script;
338 if (!PyArg_Parse (args, "s", &script))
339 return NULL;
341 if (Tcl_RecordAndEval (Tkapp_Interp (self),
342 script, TCL_NO_EVAL) == TCL_ERROR)
343 return Tkinter_Error (self);
345 return PyString_FromString (Tkapp_Result (self));
348 static PyObject *
349 Tkapp_AddErrorInfo (self, args)
350 PyObject *self;
351 PyObject *args;
353 char *msg;
355 if (!PyArg_Parse (args, "s", &msg))
356 return NULL;
357 Tcl_AddErrorInfo (Tkapp_Interp (self), msg);
359 Py_INCREF(Py_None);
360 return Py_None;
363 /** Tcl Variable **/
365 static PyObject *
366 SetVar (self, args, flags)
367 PyObject *self;
368 PyObject *args;
369 int flags;
371 char *name1, *name2, *ok;
372 PyObject *newValue;
373 PyObject *tmp;
375 tmp = PyList_New (0);
377 if (PyArg_Parse (args, "(sO)", &name1, &newValue))
378 ok = Tcl_SetVar (Tkapp_Interp (self), name1,
379 AsString (newValue, tmp), flags); /* XXX Merge? */
380 else if (PyArg_Parse (args, "(ssO)", &name1, &name2, &newValue))
381 ok = Tcl_SetVar2 (Tkapp_Interp (self), name1, name2,
382 AsString (newValue, tmp), flags);
383 else
385 Py_DECREF (tmp);
386 return NULL;
388 Py_DECREF (tmp);
390 if (!ok)
391 return Tkinter_Error (self);
393 Py_INCREF (Py_None);
394 return Py_None;
397 static PyObject *
398 Tkapp_SetVar (self, args)
399 PyObject *self;
400 PyObject *args;
402 return SetVar (self, args, TCL_LEAVE_ERR_MSG);
405 static PyObject *
406 Tkapp_GlobalSetVar (self, args)
407 PyObject *self;
408 PyObject *args;
410 return SetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
413 static PyObject *
414 GetVar (self, args, flags)
415 PyObject *self;
416 PyObject *args;
417 int flags;
419 char *name1, *name2, *s;
421 if (PyArg_Parse (args, "s", &name1))
422 s = Tcl_GetVar (Tkapp_Interp (self), name1, flags);
423 else if (PyArg_Parse (args, "(ss)", &name1, &name2))
424 s = Tcl_GetVar2 (Tkapp_Interp (self), name1, name2, flags);
425 else
426 return NULL;
428 if (s == NULL)
429 return Tkinter_Error (self);
431 return PyString_FromString (s);
434 static PyObject *
435 Tkapp_GetVar (self, args)
436 PyObject *self;
437 PyObject *args;
439 return GetVar (self, args, TCL_LEAVE_ERR_MSG);
442 static PyObject *
443 Tkapp_GlobalGetVar (self, args)
444 PyObject *self;
445 PyObject *args;
447 return GetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
450 static PyObject *
451 UnsetVar (self, args, flags)
452 PyObject *self;
453 PyObject *args;
454 int flags;
456 char *name1, *name2;
457 int code;
459 if (PyArg_Parse (args, "s", &name1))
460 code = Tcl_UnsetVar (Tkapp_Interp (self), name1, flags);
461 else if (PyArg_Parse (args, "(ss)", &name1, &name2))
462 code = Tcl_UnsetVar2 (Tkapp_Interp (self), name1, name2, flags);
463 else
464 return NULL;
466 if (code == TCL_ERROR)
467 return Tkinter_Error (self);
469 Py_INCREF (Py_None);
470 return Py_None;
473 static PyObject *
474 Tkapp_UnsetVar (self, args)
475 PyObject *self;
476 PyObject *args;
478 return UnsetVar (self, args, TCL_LEAVE_ERR_MSG);
481 static PyObject *
482 Tkapp_GlobalUnsetVar (self, args)
483 PyObject *self;
484 PyObject *args;
486 return UnsetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
489 /** Tcl to Python **/
491 static PyObject *
492 Tkapp_GetInt (self, args)
493 PyObject *self;
494 PyObject *args;
496 char *s;
497 int v;
499 if (!PyArg_Parse (args, "s", &s))
500 return NULL;
501 if (Tcl_GetInt (Tkapp_Interp (self), s, &v) == TCL_ERROR)
502 return Tkinter_Error (self);
503 return Py_BuildValue ("i", v);
506 static PyObject *
507 Tkapp_GetDouble (self, args)
508 PyObject *self;
509 PyObject *args;
511 char *s;
512 double v;
514 if (!PyArg_Parse (args, "s", &s))
515 return NULL;
516 if (Tcl_GetDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
517 return Tkinter_Error (self);
518 return Py_BuildValue ("d", v);
521 static PyObject *
522 Tkapp_GetBoolean (self, args)
523 PyObject *self;
524 PyObject *args;
526 char *s;
527 int v;
529 if (!PyArg_Parse (args, "s", &s))
530 return NULL;
531 if (Tcl_GetBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
532 return Tkinter_Error (self);
533 return Py_BuildValue ("i", v);
536 static PyObject *
537 Tkapp_ExprString (self, args)
538 PyObject *self;
539 PyObject *args;
541 char *s;
543 if (!PyArg_Parse (args, "s", &s))
544 return NULL;
545 if (Tcl_ExprString (Tkapp_Interp (self), s) == TCL_ERROR)
546 return Tkinter_Error (self);
547 return Py_BuildValue ("s", Tkapp_Result (self));
550 static PyObject *
551 Tkapp_ExprLong (self, args)
552 PyObject *self;
553 PyObject *args;
555 char *s;
556 long v;
558 if (!PyArg_Parse (args, "s", &s))
559 return NULL;
560 if (Tcl_ExprLong (Tkapp_Interp (self), s, &v) == TCL_ERROR)
561 return Tkinter_Error (self);
562 return Py_BuildValue ("l", v);
565 static PyObject *
566 Tkapp_ExprDouble (self, args)
567 PyObject *self;
568 PyObject *args;
570 char *s;
571 double v;
573 if (!PyArg_Parse (args, "s", &s))
574 return NULL;
575 if (Tcl_ExprDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
576 return Tkinter_Error (self);
577 return Py_BuildValue ("d", v);
580 static PyObject *
581 Tkapp_ExprBoolean (self, args)
582 PyObject *self;
583 PyObject *args;
585 char *s;
586 int v;
588 if (!PyArg_Parse (args, "s", &s))
589 return NULL;
590 if (Tcl_ExprBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
591 return Tkinter_Error (self);
592 return Py_BuildValue ("i", v);
595 static PyObject *
596 Tkapp_SplitList (self, args)
597 PyObject *self;
598 PyObject *args;
600 char *list;
601 int argc;
602 char **argv;
603 PyObject *v;
604 int i;
606 if (!PyArg_Parse (args, "s", &list))
607 return NULL;
609 if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
610 return Tkinter_Error (self);
612 v = PyTuple_New (argc);
613 for (i = 0; i < argc; i++)
614 PyTuple_SetItem (v, i, PyString_FromString (argv[i]));
616 free (argv);
617 return v;
620 static PyObject *
621 Tkapp_Split (self, args)
622 PyObject *self;
623 PyObject *args;
625 char *list;
627 if (!PyArg_Parse (args, "s", &list))
628 return NULL;
629 return Split (self, list);
632 static PyObject *
633 Tkapp_Merge (self, args)
634 PyObject *self;
635 PyObject *args;
637 char *s;
638 PyObject *v;
640 s = Merge (args);
641 v = PyString_FromString (s);
642 free (s);
643 return v;
646 /** Tcl Command **/
648 /* This is the Tcl command that acts as a wrapper for Python
649 function or method. */
650 static int
651 PythonCmd (clientData, interp, argc, argv)
652 ClientData clientData; /* Is (self, func) */
653 Tcl_Interp *interp;
654 int argc;
655 char *argv[];
657 PyObject *self, *func, *arg, *res, *tmp;
658 int i;
660 self = PyTuple_GetItem ((PyObject *) clientData, 0);
661 func = PyTuple_GetItem ((PyObject *) clientData, 1);
663 /* Create argument list (argv1, ..., argvN) */
664 arg = PyTuple_New (argc - 1);
665 for (i = 0; i < (argc - 1); i++)
666 PyTuple_SetItem (arg, i, PyString_FromString (argv[i + 1]));
668 res = PyEval_CallObject (func, arg);
669 Py_DECREF (arg);
671 if (res == NULL)
672 return PythonCmd_Error (interp);
674 tmp = PyList_New (0);
675 Tcl_SetResult (Tkapp_Interp (self), AsString (res, tmp), TCL_VOLATILE);
676 Py_DECREF (res);
677 Py_DECREF (tmp);
679 return TCL_OK;
682 static void
683 PythonCmdDelete (clientData)
684 ClientData clientData; /* Is (self, func) */
686 Py_DECREF ((PyObject *) clientData);
689 static PyObject *
690 Tkapp_CreateCommand (self, args)
691 PyObject *self;
692 PyObject *args;
694 char *cmdName;
695 PyObject *data;
696 PyObject *func;
698 /* Args is: (cmdName, func) */
699 if (!PyTuple_Check (args)
700 || !(PyTuple_Size (args) == 2)
701 || !PyString_Check (PyTuple_GetItem (args, 0))
702 || !(PyMethod_Check (PyTuple_GetItem (args, 1))
703 || PyFunction_Check (PyTuple_GetItem (args, 1))))
705 PyErr_SetString (PyExc_TypeError, "bad argument list");
706 return NULL;
709 cmdName = PyString_AsString (PyTuple_GetItem (args, 0));
710 func = PyTuple_GetItem (args, 1);
712 data = PyTuple_New (2); /* ClientData is: (self, func) */
714 Py_INCREF (self);
715 PyTuple_SetItem (data, 0, self);
717 Py_INCREF (func);
718 PyTuple_SetItem (data, 1, func);
720 Tcl_CreateCommand (Tkapp_Interp (self), cmdName, PythonCmd,
721 (ClientData) data, PythonCmdDelete);
723 Py_INCREF (Py_None);
724 return Py_None;
727 static PyObject *
728 Tkapp_DeleteCommand (self, args)
729 PyObject *self;
730 PyObject *args;
732 char *cmdName;
734 if (!PyArg_Parse (args, "s", &cmdName))
735 return NULL;
736 if (Tcl_DeleteCommand (Tkapp_Interp (self), cmdName) == -1)
738 PyErr_SetString (Tkinter_TclError, "can't delete Tcl command");
739 return NULL;
741 Py_INCREF (Py_None);
742 return Py_None;
745 /** File Handler **/
747 static void
748 FileHandler (clientData, mask)
749 ClientData clientData; /* Is: (func, file) */
750 int mask;
752 PyObject *func, *file, *arg, *res;
754 func = PyTuple_GetItem ((PyObject *) clientData, 0);
755 file = PyTuple_GetItem ((PyObject *) clientData, 1);
757 arg = Py_BuildValue ("(Oi)", file, (long) mask);
758 res = PyEval_CallObject (func, arg);
759 Py_DECREF (arg);
760 if (res == NULL)
762 errorInCmd = 1;
763 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
765 Py_XDECREF (res);
768 static int
769 GetFileNo (file)
770 PyObject *file; /* Either an int >= 0 or an object with a
771 .fileno() method that returns an int >= 0 */
773 PyObject *meth, *args, *res;
774 int id;
775 if (PyInt_Check(file)) {
776 id = PyInt_AsLong(file);
777 if (id < 0)
778 PyErr_SetString(PyExc_ValueError, "invalid file id");
779 return id;
781 meth = PyObject_GetAttrString(file, "fileno");
782 if (meth == NULL)
783 return -1;
784 args = PyTuple_New(0);
785 if (args == NULL)
786 return -1;
787 res = PyEval_CallObject(meth, args);
788 Py_DECREF(args);
789 Py_DECREF(meth);
790 if (res == NULL)
791 return -1;
792 if (PyInt_Check(res))
793 id = PyInt_AsLong(res);
794 else
795 id = -1;
796 if (id < 0)
797 PyErr_SetString(PyExc_ValueError,
798 "invalid fileno() return value");
799 Py_DECREF(res);
800 return id;
803 static PyObject *
804 Tkapp_CreateFileHandler (self, args)
805 PyObject *self;
806 PyObject *args; /* Is (file, mask, func) */
808 PyObject *file, *func, *data;
809 int mask, id;
811 if (!PyArg_Parse (args, "(OiO)", &file, &mask, &func))
812 return NULL;
813 id = GetFileNo (file);
814 if (id < 0)
815 return NULL;
816 if (!(PyMethod_Check(func) || PyFunction_Check(func)))
818 PyErr_SetString (PyExc_TypeError, "bad argument list");
819 return NULL;
822 /* ClientData is: (func, file) */
823 data = Py_BuildValue ("(OO)", func, file);
825 Tk_CreateFileHandler (id, mask, FileHandler, (ClientData) data);
826 /* XXX fileHandlerDict */
828 Py_INCREF (Py_None);
829 return Py_None;
832 static PyObject *
833 Tkapp_DeleteFileHandler (self, args)
834 PyObject *self;
835 PyObject *args; /* Args: file */
837 PyObject *file;
838 int id;
840 if (!PyArg_Parse (args, "O", &file))
841 return NULL;
842 id = GetFileNo (file);
843 if (id < 0)
844 return NULL;
846 Tk_DeleteFileHandler (id);
847 /* XXX fileHandlerDict */
848 Py_INCREF (Py_None);
849 return Py_None;
852 /**** Tktt Object (timer token) ****/
854 staticforward PyTypeObject Tktt_Type;
856 typedef struct
858 PyObject_HEAD
859 Tk_TimerToken token;
860 PyObject *func;
862 TkttObject;
864 static PyObject *
865 Tktt_DeleteTimerHandler (self, args)
866 PyObject *self;
867 PyObject *args;
869 TkttObject *v = (TkttObject *) self;
871 if (!PyArg_Parse (args, ""))
872 return NULL;
873 if (v->func != NULL)
875 Tk_DeleteTimerHandler (v->token);
876 PyMem_DEL (v->func);
877 v->func = NULL;
879 Py_INCREF (Py_None);
880 return Py_None;
883 static PyMethodDef Tktt_methods[] =
885 {"deletetimerhandler", Tktt_DeleteTimerHandler},
886 {NULL, NULL}
889 static TkttObject *
890 Tktt_New (token, func)
891 Tk_TimerToken token;
892 PyObject *func;
894 TkttObject *v;
896 v = PyObject_NEW (TkttObject, &Tktt_Type);
897 if (v == NULL)
898 return NULL;
900 v->token = token;
901 v->func = func;
902 Py_INCREF (v->func);
903 return v;
906 static void
907 Tktt_Dealloc (self)
908 PyObject *self;
910 PyMem_DEL (self);
913 static int
914 Tktt_Print (self, fp, flags)
915 PyObject *self;
916 FILE *fp;
917 int flags;
919 TkttObject *v = (TkttObject *) self;
921 fprintf(fp, "<tktimertoken at 0x%x%s>", v,
922 v->func == NULL ? ", handler deleted" : "");
923 return 0;
926 static PyObject *
927 Tktt_GetAttr (self, name)
928 PyObject *self;
929 char *name;
931 return Py_FindMethod (Tktt_methods, self, name);
934 static PyTypeObject Tktt_Type =
936 PyObject_HEAD_INIT (&PyType_Type)
937 0, /*ob_size */
938 "tktimertoken", /*tp_name */
939 sizeof (TkttObject), /*tp_basicsize */
940 0, /*tp_itemsize */
941 Tktt_Dealloc, /*tp_dealloc */
942 Tktt_Print, /*tp_print */
943 Tktt_GetAttr, /*tp_getattr */
944 0, /*tp_setattr */
945 0, /*tp_compare */
946 0, /*tp_repr */
947 0, /*tp_as_number */
948 0, /*tp_as_sequence */
949 0, /*tp_as_mapping */
950 0, /*tp_hash */
953 /** Timer Handler **/
955 static void
956 TimerHandler (clientData)
957 ClientData clientData;
959 PyObject *func = (PyObject *) clientData;
960 PyObject *arg, *res;
962 arg = PyTuple_New (0);
963 res = PyEval_CallObject (func, arg);
964 Py_DECREF (arg);
965 if (res == NULL)
967 errorInCmd = 1;
968 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
970 else
971 Py_DECREF (res);
974 static PyObject *
975 Tkapp_CreateTimerHandler (self, args)
976 PyObject *self;
977 PyObject *args; /* Is (milliseconds, func) */
979 int milliseconds;
980 PyObject *func;
981 Tk_TimerToken token;
983 if (!PyArg_Parse (args, "(iO)", &milliseconds, &func))
984 return NULL;
985 if (!(PyMethod_Check(func) || PyFunction_Check(func) ||
986 PyCFunction_Check(func)))
988 PyErr_SetString (PyExc_TypeError, "bad argument list");
989 return NULL;
991 token = Tk_CreateTimerHandler(milliseconds, TimerHandler, (ClientData) func);
992 return (PyObject *) Tktt_New (token, func);
995 /** Event Loop **/
997 static PyObject *
998 Tkapp_MainLoop (self, args)
999 PyObject *self;
1000 PyObject *args;
1002 int threshold = 0;
1004 if (!PyArg_Parse (args, ""))
1006 PyErr_Clear();
1007 if (!PyArg_Parse (args, "i", &threshold))
1008 return NULL;
1011 quitMainLoop = 0;
1012 while (tk_NumMainWindows > threshold && !quitMainLoop && !errorInCmd)
1014 if (PyOS_InterruptOccurred ())
1016 PyErr_SetNone (PyExc_KeyboardInterrupt);
1017 return NULL;
1019 Tk_DoOneEvent (0);
1022 if (errorInCmd)
1024 errorInCmd = 0;
1025 PyErr_Restore (excInCmd, valInCmd, trbInCmd);
1026 excInCmd = valInCmd = trbInCmd = NULL;
1027 return NULL;
1029 Py_INCREF (Py_None);
1030 return Py_None;
1033 static PyObject *
1034 Tkapp_DoOneEvent (self, args)
1035 PyObject *self;
1036 PyObject *args;
1038 int flags;
1039 int rv;
1041 if (PyArg_Parse (args, ""))
1042 flags = TK_ALL_EVENTS;
1043 else
1045 PyErr_Clear();
1046 if (!PyArg_Parse (args, "i", &flags))
1047 return NULL;
1049 rv = Tk_DoOneEvent(flags);
1050 return Py_BuildValue ("i", rv);
1053 static PyObject *
1054 Tkapp_Quit (self, args)
1055 PyObject *self;
1056 PyObject *args;
1059 if (!PyArg_Parse (args, ""))
1060 return NULL;
1061 quitMainLoop = 1;
1062 Py_INCREF (Py_None);
1063 return Py_None;
1066 /**** Tkapp Method List ****/
1068 static PyMethodDef Tkapp_methods[] =
1070 {"call", Tkapp_Call},
1071 {"globalcall", Tkapp_GlobalCall},
1072 {"eval", Tkapp_Eval},
1073 {"globaleval", Tkapp_GlobalEval},
1074 {"evalfile", Tkapp_EvalFile},
1075 {"record", Tkapp_Record},
1076 {"adderrorinfo", Tkapp_AddErrorInfo},
1077 {"setvar", Tkapp_SetVar},
1078 {"globalsetvar", Tkapp_GlobalSetVar},
1079 {"getvar", Tkapp_GetVar},
1080 {"globalgetvar", Tkapp_GlobalGetVar},
1081 {"unsetvar", Tkapp_UnsetVar},
1082 {"globalunsetvar", Tkapp_GlobalUnsetVar},
1083 {"getint", Tkapp_GetInt},
1084 {"getdouble", Tkapp_GetDouble},
1085 {"getboolean", Tkapp_GetBoolean},
1086 {"exprstring", Tkapp_ExprString},
1087 {"exprlong", Tkapp_ExprLong},
1088 {"exprdouble", Tkapp_ExprDouble},
1089 {"exprboolean", Tkapp_ExprBoolean},
1090 {"splitlist", Tkapp_SplitList},
1091 {"split", Tkapp_Split},
1092 {"merge", Tkapp_Merge},
1093 {"createcommand", Tkapp_CreateCommand},
1094 {"deletecommand", Tkapp_DeleteCommand},
1095 {"createfilehandler", Tkapp_CreateFileHandler},
1096 {"deletefilehandler", Tkapp_DeleteFileHandler},
1097 {"createtimerhandler", Tkapp_CreateTimerHandler},
1098 {"mainloop", Tkapp_MainLoop},
1099 {"dooneevent", Tkapp_DoOneEvent},
1100 {"quit", Tkapp_Quit},
1101 {NULL, NULL}
1104 /**** Tkapp Type Methods ****/
1106 static void
1107 Tkapp_Dealloc (self)
1108 PyObject *self;
1110 Tk_DestroyWindow (Tkapp_Tkwin (self));
1111 Tcl_DeleteInterp (Tkapp_Interp (self));
1112 PyMem_DEL (self);
1115 static PyObject *
1116 Tkapp_GetAttr (self, name)
1117 PyObject *self;
1118 char *name;
1120 return Py_FindMethod (Tkapp_methods, self, name);
1123 static PyTypeObject Tkapp_Type =
1125 PyObject_HEAD_INIT (&PyType_Type)
1126 0, /*ob_size */
1127 "tkapp", /*tp_name */
1128 sizeof (TkappObject), /*tp_basicsize */
1129 0, /*tp_itemsize */
1130 Tkapp_Dealloc, /*tp_dealloc */
1131 0, /*tp_print */
1132 Tkapp_GetAttr, /*tp_getattr */
1133 0, /*tp_setattr */
1134 0, /*tp_compare */
1135 0, /*tp_repr */
1136 0, /*tp_as_number */
1137 0, /*tp_as_sequence */
1138 0, /*tp_as_mapping */
1139 0, /*tp_hash */
1142 /**** Tkinter Module ****/
1144 static PyObject *
1145 Tkinter_Create (self, args)
1146 PyObject *self;
1147 PyObject *args;
1149 char *screenName = NULL;
1150 char *baseName;
1151 char *className;
1152 int interactive = 0;
1154 baseName = strrchr (getprogramname (), '/');
1155 if (baseName != NULL)
1156 baseName++;
1157 else
1158 baseName = getprogramname ();
1159 className = "Tk";
1161 if (PyArg_Parse (args, ""))
1162 /* VOID */ ;
1163 else if (PyArg_Parse (args, "z",
1164 &screenName))
1165 /* VOID */ ;
1166 else if (PyArg_Parse (args, "(zs)",
1167 &screenName, &baseName))
1168 /* VOID */ ;
1169 else if (PyArg_Parse (args, "(zss)",
1170 &screenName, &baseName, &className))
1171 /* VOID */ ;
1172 else if (PyArg_Parse (args, "(zssi)",
1173 &screenName, &baseName, &className, &interactive))
1174 /* VOID */ ;
1175 else
1176 return NULL;
1178 return (PyObject *) Tkapp_New (screenName, baseName, className,
1179 interactive);
1182 static PyMethodDef moduleMethods[] =
1184 {"create", Tkinter_Create},
1185 {"createfilehandler", Tkapp_CreateFileHandler},
1186 {"deletefilehandler", Tkapp_DeleteFileHandler},
1187 {"createtimerhandler", Tkapp_CreateTimerHandler},
1188 {"mainloop", Tkapp_MainLoop},
1189 {"dooneevent", Tkapp_DoOneEvent},
1190 {"quit", Tkapp_Quit},
1191 {NULL, NULL}
1194 #ifdef WITH_READLINE
1195 static int
1196 EventHook ()
1198 if (errorInCmd) /* XXX Reset tty */
1200 errorInCmd = 0;
1201 PyErr_Restore (excInCmd, valInCmd, trbInCmd);
1202 excInCmd = valInCmd = trbInCmd = NULL;
1203 PyErr_Print ();
1205 if (tk_NumMainWindows > 0)
1206 Tk_DoOneEvent (TK_DONT_WAIT);
1207 return 0;
1209 #endif /* WITH_READLINE */
1211 static void
1212 Tkinter_Cleanup ()
1214 /* XXX rl_deprep_terminal is static, damned! */
1215 while (tkMainWindowList != 0)
1216 Tk_DestroyWindow (tkMainWindowList->win);
1219 void
1220 PyInit_tkinter ()
1222 static inited = 0;
1224 #ifdef WITH_READLINE
1225 extern int (*rl_event_hook) ();
1226 #endif /* WITH_READLINE */
1227 PyObject *m, *d, *v;
1229 m = Py_InitModule ("tkinter", moduleMethods);
1231 d = PyModule_GetDict (m);
1232 Tkinter_TclError = Py_BuildValue ("s", "TclError");
1233 PyDict_SetItemString (d, "TclError", Tkinter_TclError);
1235 v = Py_BuildValue ("i", TK_READABLE);
1236 PyDict_SetItemString (d, "READABLE", v);
1237 v = Py_BuildValue ("i", TK_WRITABLE);
1238 PyDict_SetItemString (d, "WRITABLE", v);
1239 v = Py_BuildValue ("i", TK_EXCEPTION);
1240 PyDict_SetItemString (d, "EXCEPTION", v);
1241 v = Py_BuildValue ("i", TK_X_EVENTS);
1242 PyDict_SetItemString (d, "X_EVENTS", v);
1243 v = Py_BuildValue ("i", TK_FILE_EVENTS);
1244 PyDict_SetItemString (d, "FILE_EVENTS", v);
1245 v = Py_BuildValue ("i", TK_TIMER_EVENTS);
1246 PyDict_SetItemString (d, "TIMER_EVENTS", v);
1247 v = Py_BuildValue ("i", TK_IDLE_EVENTS);
1248 PyDict_SetItemString (d, "IDLE_EVENTS", v);
1249 v = Py_BuildValue ("i", TK_ALL_EVENTS);
1250 PyDict_SetItemString (d, "ALL_EVENTS", v);
1251 v = Py_BuildValue ("i", TK_DONT_WAIT);
1252 PyDict_SetItemString (d, "DONT_WAIT", v);
1254 #ifdef WITH_READLINE
1255 rl_event_hook = EventHook;
1256 #endif /* WITH_READLINE */
1258 if (!inited)
1260 inited = 1;
1261 if (Py_AtExit (Tkinter_Cleanup) != 0)
1262 fprintf(stderr,
1263 "Tkinter: warning: cleanup procedure not registered\n");
1266 if (PyErr_Occurred ())
1267 Py_FatalError ("can't initialize module tkinter");