blob: f198e7510a000b7da61f204ef3ac1c878e27f366 [file] [log] [blame]
Guido van Rossum845547d1996-06-26 18:26:04 +00001/***********************************************************
2Copyright (C) 1994 Steen Lumholt.
3Copyright 1994-1995 by Stichting Mathematisch Centrum, Amsterdam,
4The Netherlands.
5
6 All Rights Reserved
7
8Permission to use, copy, modify, and distribute this software and its
9documentation for any purpose and without fee is hereby granted,
10provided that the above copyright notice appear in all copies and that
11both that copyright notice and this permission notice appear in
12supporting documentation, and that the names of Stichting Mathematisch
13Centrum or CWI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior permission.
15
16STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
17THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
19FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
22OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
24******************************************************************/
25
26/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +000027
Guido van Rossum7ffa7611996-08-13 21:10:16 +000028/* TCL/TK VERSION INFO:
29
30 Unix:
31 This should work with any version from Tcl 4.0 / Tck 7.4.
32 Do not use older versions.
33
34 Mac and Windows:
35 Use Tcl 4.1p1 / Tk 7.5p1 or possibly newer.
36 It does not seem to work reliably with the original 4.1/7.5
37 release. (4.0/7.4 were never released for these platforms.)
38*/
39
Guido van Rossum9722ad81995-09-22 23:49:28 +000040#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000041#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000042
Guido van Rossum18468821994-06-20 07:49:28 +000043#include <tcl.h>
44#include <tk.h>
45
Guido van Rossum32aa1a71996-07-31 19:51:15 +000046extern char *Py_GetProgramName ();
Guido van Rossumd308e2b1994-07-07 09:25:12 +000047
Guido van Rossum9722ad81995-09-22 23:49:28 +000048/* Internal declarations from tkInt.h. */
49#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
50extern int Tk_GetNumMainWindows();
51#else
Guido van Rossum18468821994-06-20 07:49:28 +000052extern int tk_NumMainWindows;
Guido van Rossum9722ad81995-09-22 23:49:28 +000053#define Tk_GetNumMainWindows() (tk_NumMainWindows)
Guido van Rossumdfd428d1996-02-25 04:46:40 +000054#define NEED_TKCREATEMAINWINDOW 1
Guido van Rossum9722ad81995-09-22 23:49:28 +000055#endif
56
57#if TK_MAJOR_VERSION < 4
Guido van Rossumd308e2b1994-07-07 09:25:12 +000058extern struct { Tk_Window win; } *tkMainWindowList;
Guido van Rossum9722ad81995-09-22 23:49:28 +000059#endif
Guido van Rossum18468821994-06-20 07:49:28 +000060
Guido van Rossumec22c921996-02-25 04:50:29 +000061#ifdef macintosh
62
63/*
64** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +000065** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +000066*/
67
Guido van Rossum7ffa7611996-08-13 21:10:16 +000068/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +000069#define FREECAST (char *)
70
Guido van Rossumec22c921996-02-25 04:50:29 +000071#include <Events.h> /* For EventRecord */
72
73typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
74void TclMacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
75int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
76
77staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
78
79#endif /* macintosh */
80
Guido van Rossum97867b21996-08-08 19:09:53 +000081#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +000082#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +000083#endif
84
Guido van Rossum18468821994-06-20 07:49:28 +000085/**** Tkapp Object Declaration ****/
86
87staticforward PyTypeObject Tkapp_Type;
88
89typedef struct
90 {
91 PyObject_HEAD
92 Tcl_Interp *interp;
Guido van Rossumdfd428d1996-02-25 04:46:40 +000093#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +000094 Tk_Window tkwin;
Guido van Rossumdfd428d1996-02-25 04:46:40 +000095#endif
Guido van Rossum18468821994-06-20 07:49:28 +000096 }
97TkappObject;
98
99#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000100#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +0000101#define Tkapp_Tkwin(v) (((TkappObject *) (v))->tkwin)
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000102#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000103#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
104#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
105
106#define DEBUG_REFCNT(v) (printf ("DEBUG: id=%p, refcnt=%i\n", \
107 (void *) v, ((PyObject *) v)->ob_refcnt))
108
109/**** Error Handling ****/
110
111static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000112static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000113static int errorInCmd = 0;
114static PyObject *excInCmd;
115static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000116static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000117
118static PyObject *
119Tkinter_Error (v)
120 PyObject *v;
121{
Guido van Rossum18468821994-06-20 07:49:28 +0000122 PyErr_SetString (Tkinter_TclError, Tkapp_Result (v));
123 return NULL;
124}
125
126int
127PythonCmd_Error (interp)
128 Tcl_Interp *interp;
129{
130 errorInCmd = 1;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000131 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
Guido van Rossum18468821994-06-20 07:49:28 +0000132 return TCL_ERROR;
133}
134
135/**** Utils ****/
136
137static char *
138AsString (value, tmp)
139 PyObject *value;
140 PyObject *tmp;
141{
142 if (PyString_Check (value))
143 return PyString_AsString (value);
144 else
145 {
146 PyObject *v;
147
Guido van Rossumcd938fc1995-01-17 16:13:48 +0000148 v = PyObject_Str (value);
Guido van Rossum18468821994-06-20 07:49:28 +0000149 PyList_Append (tmp, v);
150 Py_DECREF (v);
151 return PyString_AsString (v);
152 }
153}
154
155#define ARGSZ 64
156
157static char *
158Merge (args)
159 PyObject *args;
160{
161 PyObject *tmp;
162 char *argvStore[ARGSZ];
163 char **argv;
164 int fvStore[ARGSZ];
165 int *fv;
166 int argc;
167 char *res;
168 int i;
169
170 tmp = PyList_New (0);
171 argv = argvStore;
172 fv = fvStore;
173
Guido van Rossum845547d1996-06-26 18:26:04 +0000174 if (args == NULL)
175 {
176 argc = 0;
177 }
178 else if (!PyTuple_Check (args))
Guido van Rossum18468821994-06-20 07:49:28 +0000179 {
180 argc = 1;
181 fv[0] = 0;
182 argv[0] = AsString (args, tmp);
183 }
184 else
185 {
186 PyObject *v;
187
188 if (PyTuple_Size (args) > ARGSZ)
189 {
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000190 argv = (char **) ckalloc (PyTuple_Size (args) * sizeof (char *));
191 fv = (int *) ckalloc (PyTuple_Size (args) * sizeof (int));
Guido van Rossum18468821994-06-20 07:49:28 +0000192 if (argv == NULL || fv == NULL)
193 PyErr_NoMemory ();
194 }
195
196 argc = PyTuple_Size (args);
197 for (i = 0; i < argc; i++)
198 {
199 v = PyTuple_GetItem (args, i);
200 if (PyTuple_Check (v))
201 {
202 fv[i] = 1;
203 argv[i] = Merge (v);
204 }
205 else if (v == Py_None)
206 {
207 argc = i;
208 break;
209 }
210 else
211 {
212 fv[i] = 0;
213 argv[i] = AsString (v, tmp);
214 }
215 }
216 }
217
218 res = Tcl_Merge (argc, argv);
219
220 Py_DECREF (tmp);
221 for (i = 0; i < argc; i++)
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000222 if (fv[i]) ckfree (argv[i]);
Guido van Rossum18468821994-06-20 07:49:28 +0000223 if (argv != argvStore)
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000224 ckfree (FREECAST argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000225 if (fv != fvStore)
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000226 ckfree (FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000227
228 return res;
229}
230
231static PyObject *
232Split (self, list)
233 PyObject *self;
234 char *list;
235{
236 int argc;
237 char **argv;
238 PyObject *v;
239
240 if (list == NULL)
241 {
242 Py_INCREF (Py_None);
243 return Py_None;
244 }
245
246 if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
247 return Tkinter_Error (self);
248
249 if (argc == 0)
250 v = PyString_FromString ("");
251 else if (argc == 1)
252 v = PyString_FromString (argv[0]);
253 else
254 {
255 int i;
256
257 v = PyTuple_New (argc);
258 for (i = 0; i < argc; i++)
259 PyTuple_SetItem (v, i, Split (self, argv[i]));
260 }
261
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000262 ckfree (FREECAST argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000263 return v;
264}
265
266/**** Tkapp Object ****/
267
268#ifndef WITH_APPINIT
269int
270Tcl_AppInit (interp)
271 Tcl_Interp *interp;
272{
Guido van Rossumec22c921996-02-25 04:50:29 +0000273 Tk_Window main;
274
275 main = Tk_MainWindow(interp);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000276 if (Tcl_Init (interp) == TCL_ERROR) {
277 fprintf(stderr, "Tcl_Init error: %s\n", interp->result);
Guido van Rossum18468821994-06-20 07:49:28 +0000278 return TCL_ERROR;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000279 }
280 if (Tk_Init (interp) == TCL_ERROR) {
281 fprintf(stderr, "Tk_Init error: %s\n", interp->result);
Guido van Rossum18468821994-06-20 07:49:28 +0000282 return TCL_ERROR;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000283 }
Guido van Rossum18468821994-06-20 07:49:28 +0000284 return TCL_OK;
285}
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000286
Guido van Rossum18468821994-06-20 07:49:28 +0000287#endif /* !WITH_APPINIT */
288
289/* Initialize the Tk application; see the `main' function in
290 `tkMain.c'. */
291static TkappObject *
292Tkapp_New (screenName, baseName, className, interactive)
293 char *screenName;
294 char *baseName;
295 char *className;
296 int interactive;
297{
298 TkappObject *v;
Guido van Rossum97867b21996-08-08 19:09:53 +0000299 char *argv0;
Guido van Rossum18468821994-06-20 07:49:28 +0000300
301 v = PyObject_NEW (TkappObject, &Tkapp_Type);
302 if (v == NULL)
303 return NULL;
304
305 v->interp = Tcl_CreateInterp ();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000306
307#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +0000308 v->tkwin = Tk_CreateMainWindow (v->interp, screenName,
309 baseName, className);
310 if (v->tkwin == NULL)
311 return (TkappObject *) Tkinter_Error ((PyObject *) v);
312
313 Tk_GeometryRequest (v->tkwin, 200, 200);
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000314#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000315
316 if (screenName != NULL)
317 Tcl_SetVar2 (v->interp, "env", "DISPLAY", screenName, TCL_GLOBAL_ONLY);
318
319 if (interactive)
320 Tcl_SetVar (v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
321 else
322 Tcl_SetVar (v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
323
Guido van Rossum97867b21996-08-08 19:09:53 +0000324 /* This is used to get the application class for Tk 4.1 and up */
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000325 argv0 = (char*) ckalloc (strlen (className) + 1);
Guido van Rossum97867b21996-08-08 19:09:53 +0000326 if (argv0 != NULL) {
327 strcpy (argv0, className);
328 if (isupper (argv0[0]))
329 argv0[0] = tolower (argv0[0]);
330 Tcl_SetVar (v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000331 ckfree (argv0);
Guido van Rossum97867b21996-08-08 19:09:53 +0000332 }
333
Guido van Rossum18468821994-06-20 07:49:28 +0000334 if (Tcl_AppInit (v->interp) != TCL_OK)
Guido van Rossum845547d1996-06-26 18:26:04 +0000335 return (TkappObject *) Tkinter_Error (v);
Guido van Rossum18468821994-06-20 07:49:28 +0000336
337 return v;
338}
339
340/** Tcl Eval **/
341
342static PyObject *
343Tkapp_Call (self, args)
344 PyObject *self;
345 PyObject *args;
346{
347 char *cmd;
348
349 cmd = Merge (args);
350 if (Tcl_Eval (Tkapp_Interp (self), cmd) == TCL_ERROR)
351 {
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000352 ckfree (cmd);
Guido van Rossum18468821994-06-20 07:49:28 +0000353 return Tkinter_Error (self);
354 }
355
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000356 ckfree (cmd);
Guido van Rossum18468821994-06-20 07:49:28 +0000357 return PyString_FromString (Tkapp_Result (self));
358}
359
360static PyObject *
361Tkapp_GlobalCall (self, args)
362 PyObject *self;
363 PyObject *args;
364{
365 char *cmd;
366
367 cmd = Merge (args);
368 if (Tcl_GlobalEval (Tkapp_Interp (self), cmd) == TCL_ERROR)
369 {
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000370 ckfree (cmd);
Guido van Rossum18468821994-06-20 07:49:28 +0000371 return Tkinter_Error (self);
372 }
373
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000374 ckfree (cmd);
Guido van Rossum18468821994-06-20 07:49:28 +0000375 return PyString_FromString (Tkapp_Result (self));
376}
377
378static PyObject *
379Tkapp_Eval (self, args)
380 PyObject *self;
381 PyObject *args;
382{
383 char *script;
384
385 if (!PyArg_Parse (args, "s", &script))
386 return NULL;
387
388 if (Tcl_Eval (Tkapp_Interp (self), script) == TCL_ERROR)
389 return Tkinter_Error (self);
390
391 return PyString_FromString (Tkapp_Result (self));
392}
393
394static PyObject *
395Tkapp_GlobalEval (self, args)
396 PyObject *self;
397 PyObject *args;
398{
399 char *script;
400
401 if (!PyArg_Parse (args, "s", &script))
402 return NULL;
403
404 if (Tcl_GlobalEval (Tkapp_Interp (self), script) == TCL_ERROR)
405 return Tkinter_Error (self);
406
407 return PyString_FromString (Tkapp_Result (self));
408}
409
410static PyObject *
411Tkapp_EvalFile (self, args)
412 PyObject *self;
413 PyObject *args;
414{
415 char *fileName;
416
417 if (!PyArg_Parse (args, "s", &fileName))
418 return NULL;
419
420 if (Tcl_EvalFile (Tkapp_Interp (self), fileName) == TCL_ERROR)
421 return Tkinter_Error (self);
422
423 return PyString_FromString (Tkapp_Result (self));
424}
425
426static PyObject *
427Tkapp_Record (self, args)
428 PyObject *self;
429 PyObject *args;
430{
431 char *script;
432
433 if (!PyArg_Parse (args, "s", &script))
434 return NULL;
435
436 if (Tcl_RecordAndEval (Tkapp_Interp (self),
437 script, TCL_NO_EVAL) == TCL_ERROR)
438 return Tkinter_Error (self);
439
440 return PyString_FromString (Tkapp_Result (self));
441}
442
443static PyObject *
444Tkapp_AddErrorInfo (self, args)
445 PyObject *self;
446 PyObject *args;
447{
448 char *msg;
449
450 if (!PyArg_Parse (args, "s", &msg))
451 return NULL;
452 Tcl_AddErrorInfo (Tkapp_Interp (self), msg);
453
454 Py_INCREF(Py_None);
455 return Py_None;
456}
457
458/** Tcl Variable **/
459
460static PyObject *
461SetVar (self, args, flags)
462 PyObject *self;
463 PyObject *args;
464 int flags;
465{
466 char *name1, *name2, *ok;
467 PyObject *newValue;
468 PyObject *tmp;
469
470 tmp = PyList_New (0);
471
472 if (PyArg_Parse (args, "(sO)", &name1, &newValue))
473 ok = Tcl_SetVar (Tkapp_Interp (self), name1,
474 AsString (newValue, tmp), flags); /* XXX Merge? */
475 else if (PyArg_Parse (args, "(ssO)", &name1, &name2, &newValue))
476 ok = Tcl_SetVar2 (Tkapp_Interp (self), name1, name2,
477 AsString (newValue, tmp), flags);
478 else
479 {
480 Py_DECREF (tmp);
481 return NULL;
482 }
483 Py_DECREF (tmp);
484
485 if (!ok)
486 return Tkinter_Error (self);
487
488 Py_INCREF (Py_None);
489 return Py_None;
490}
491
492static PyObject *
493Tkapp_SetVar (self, args)
494 PyObject *self;
495 PyObject *args;
496{
497 return SetVar (self, args, TCL_LEAVE_ERR_MSG);
498}
499
500static PyObject *
501Tkapp_GlobalSetVar (self, args)
502 PyObject *self;
503 PyObject *args;
504{
505 return SetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
506}
507
508static PyObject *
509GetVar (self, args, flags)
510 PyObject *self;
511 PyObject *args;
512 int flags;
513{
514 char *name1, *name2, *s;
515
516 if (PyArg_Parse (args, "s", &name1))
517 s = Tcl_GetVar (Tkapp_Interp (self), name1, flags);
518 else if (PyArg_Parse (args, "(ss)", &name1, &name2))
519 s = Tcl_GetVar2 (Tkapp_Interp (self), name1, name2, flags);
520 else
521 return NULL;
522
523 if (s == NULL)
524 return Tkinter_Error (self);
525
526 return PyString_FromString (s);
527}
528
529static PyObject *
530Tkapp_GetVar (self, args)
531 PyObject *self;
532 PyObject *args;
533{
534 return GetVar (self, args, TCL_LEAVE_ERR_MSG);
535}
536
537static PyObject *
538Tkapp_GlobalGetVar (self, args)
539 PyObject *self;
540 PyObject *args;
541{
542 return GetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
543}
544
545static PyObject *
546UnsetVar (self, args, flags)
547 PyObject *self;
548 PyObject *args;
549 int flags;
550{
551 char *name1, *name2;
552 int code;
553
554 if (PyArg_Parse (args, "s", &name1))
555 code = Tcl_UnsetVar (Tkapp_Interp (self), name1, flags);
556 else if (PyArg_Parse (args, "(ss)", &name1, &name2))
557 code = Tcl_UnsetVar2 (Tkapp_Interp (self), name1, name2, flags);
558 else
559 return NULL;
560
561 if (code == TCL_ERROR)
562 return Tkinter_Error (self);
563
564 Py_INCREF (Py_None);
565 return Py_None;
566}
567
568static PyObject *
569Tkapp_UnsetVar (self, args)
570 PyObject *self;
571 PyObject *args;
572{
573 return UnsetVar (self, args, TCL_LEAVE_ERR_MSG);
574}
575
576static PyObject *
577Tkapp_GlobalUnsetVar (self, args)
578 PyObject *self;
579 PyObject *args;
580{
581 return UnsetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
582}
583
584/** Tcl to Python **/
585
586static PyObject *
587Tkapp_GetInt (self, args)
588 PyObject *self;
589 PyObject *args;
590{
591 char *s;
592 int v;
593
594 if (!PyArg_Parse (args, "s", &s))
595 return NULL;
596 if (Tcl_GetInt (Tkapp_Interp (self), s, &v) == TCL_ERROR)
597 return Tkinter_Error (self);
598 return Py_BuildValue ("i", v);
599}
600
601static PyObject *
602Tkapp_GetDouble (self, args)
603 PyObject *self;
604 PyObject *args;
605{
606 char *s;
607 double v;
608
609 if (!PyArg_Parse (args, "s", &s))
610 return NULL;
611 if (Tcl_GetDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
612 return Tkinter_Error (self);
613 return Py_BuildValue ("d", v);
614}
615
616static PyObject *
617Tkapp_GetBoolean (self, args)
618 PyObject *self;
619 PyObject *args;
620{
621 char *s;
622 int v;
623
624 if (!PyArg_Parse (args, "s", &s))
625 return NULL;
626 if (Tcl_GetBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
627 return Tkinter_Error (self);
628 return Py_BuildValue ("i", v);
629}
630
631static PyObject *
632Tkapp_ExprString (self, args)
633 PyObject *self;
634 PyObject *args;
635{
636 char *s;
637
638 if (!PyArg_Parse (args, "s", &s))
639 return NULL;
640 if (Tcl_ExprString (Tkapp_Interp (self), s) == TCL_ERROR)
641 return Tkinter_Error (self);
642 return Py_BuildValue ("s", Tkapp_Result (self));
643}
644
645static PyObject *
646Tkapp_ExprLong (self, args)
647 PyObject *self;
648 PyObject *args;
649{
650 char *s;
651 long v;
652
653 if (!PyArg_Parse (args, "s", &s))
654 return NULL;
655 if (Tcl_ExprLong (Tkapp_Interp (self), s, &v) == TCL_ERROR)
656 return Tkinter_Error (self);
657 return Py_BuildValue ("l", v);
658}
659
660static PyObject *
661Tkapp_ExprDouble (self, args)
662 PyObject *self;
663 PyObject *args;
664{
665 char *s;
666 double v;
667
668 if (!PyArg_Parse (args, "s", &s))
669 return NULL;
670 if (Tcl_ExprDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
671 return Tkinter_Error (self);
672 return Py_BuildValue ("d", v);
673}
674
675static PyObject *
676Tkapp_ExprBoolean (self, args)
677 PyObject *self;
678 PyObject *args;
679{
680 char *s;
681 int v;
682
683 if (!PyArg_Parse (args, "s", &s))
684 return NULL;
685 if (Tcl_ExprBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
686 return Tkinter_Error (self);
687 return Py_BuildValue ("i", v);
688}
689
690static PyObject *
691Tkapp_SplitList (self, args)
692 PyObject *self;
693 PyObject *args;
694{
695 char *list;
696 int argc;
697 char **argv;
698 PyObject *v;
699 int i;
700
701 if (!PyArg_Parse (args, "s", &list))
702 return NULL;
703
704 if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
705 return Tkinter_Error (self);
706
707 v = PyTuple_New (argc);
708 for (i = 0; i < argc; i++)
709 PyTuple_SetItem (v, i, PyString_FromString (argv[i]));
710
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000711 ckfree (FREECAST argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000712 return v;
713}
714
715static PyObject *
716Tkapp_Split (self, args)
717 PyObject *self;
718 PyObject *args;
719{
720 char *list;
721
722 if (!PyArg_Parse (args, "s", &list))
723 return NULL;
724 return Split (self, list);
725}
726
727static PyObject *
728Tkapp_Merge (self, args)
729 PyObject *self;
730 PyObject *args;
731{
732 char *s;
733 PyObject *v;
734
735 s = Merge (args);
736 v = PyString_FromString (s);
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000737 ckfree (s);
Guido van Rossum18468821994-06-20 07:49:28 +0000738 return v;
739}
740
741/** Tcl Command **/
742
743/* This is the Tcl command that acts as a wrapper for Python
744 function or method. */
745static int
746PythonCmd (clientData, interp, argc, argv)
747 ClientData clientData; /* Is (self, func) */
748 Tcl_Interp *interp;
749 int argc;
750 char *argv[];
751{
752 PyObject *self, *func, *arg, *res, *tmp;
753 int i;
754
755 self = PyTuple_GetItem ((PyObject *) clientData, 0);
756 func = PyTuple_GetItem ((PyObject *) clientData, 1);
757
758 /* Create argument list (argv1, ..., argvN) */
759 arg = PyTuple_New (argc - 1);
760 for (i = 0; i < (argc - 1); i++)
761 PyTuple_SetItem (arg, i, PyString_FromString (argv[i + 1]));
762
763 res = PyEval_CallObject (func, arg);
764 Py_DECREF (arg);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000765
Guido van Rossum18468821994-06-20 07:49:28 +0000766 if (res == NULL)
767 return PythonCmd_Error (interp);
768
769 tmp = PyList_New (0);
770 Tcl_SetResult (Tkapp_Interp (self), AsString (res, tmp), TCL_VOLATILE);
771 Py_DECREF (res);
772 Py_DECREF (tmp);
773
774 return TCL_OK;
775}
776
777static void
778PythonCmdDelete (clientData)
779 ClientData clientData; /* Is (self, func) */
780{
781 Py_DECREF ((PyObject *) clientData);
782}
783
784static PyObject *
785Tkapp_CreateCommand (self, args)
786 PyObject *self;
787 PyObject *args;
788{
789 char *cmdName;
790 PyObject *data;
791 PyObject *func;
792
793 /* Args is: (cmdName, func) */
794 if (!PyTuple_Check (args)
795 || !(PyTuple_Size (args) == 2)
796 || !PyString_Check (PyTuple_GetItem (args, 0))
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000797 || !PyCallable_Check (PyTuple_GetItem (args, 1)))
Guido van Rossum18468821994-06-20 07:49:28 +0000798 {
799 PyErr_SetString (PyExc_TypeError, "bad argument list");
800 return NULL;
801 }
802
803 cmdName = PyString_AsString (PyTuple_GetItem (args, 0));
804 func = PyTuple_GetItem (args, 1);
805
806 data = PyTuple_New (2); /* ClientData is: (self, func) */
807
808 Py_INCREF (self);
809 PyTuple_SetItem (data, 0, self);
810
811 Py_INCREF (func);
812 PyTuple_SetItem (data, 1, func);
813
814 Tcl_CreateCommand (Tkapp_Interp (self), cmdName, PythonCmd,
815 (ClientData) data, PythonCmdDelete);
816
817 Py_INCREF (Py_None);
818 return Py_None;
819}
820
821static PyObject *
822Tkapp_DeleteCommand (self, args)
823 PyObject *self;
824 PyObject *args;
825{
826 char *cmdName;
827
828 if (!PyArg_Parse (args, "s", &cmdName))
829 return NULL;
830 if (Tcl_DeleteCommand (Tkapp_Interp (self), cmdName) == -1)
831 {
832 PyErr_SetString (Tkinter_TclError, "can't delete Tcl command");
833 return NULL;
834 }
835 Py_INCREF (Py_None);
836 return Py_None;
837}
838
839/** File Handler **/
840
Guido van Rossuma597dde1995-01-10 20:56:29 +0000841static void
Guido van Rossum18468821994-06-20 07:49:28 +0000842FileHandler (clientData, mask)
Guido van Rossum76875221994-06-27 07:59:42 +0000843 ClientData clientData; /* Is: (func, file) */
Guido van Rossum18468821994-06-20 07:49:28 +0000844 int mask;
845{
Guido van Rossum76875221994-06-27 07:59:42 +0000846 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +0000847
Guido van Rossum76875221994-06-27 07:59:42 +0000848 func = PyTuple_GetItem ((PyObject *) clientData, 0);
849 file = PyTuple_GetItem ((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000850
Guido van Rossum76875221994-06-27 07:59:42 +0000851 arg = Py_BuildValue ("(Oi)", file, (long) mask);
Guido van Rossum18468821994-06-20 07:49:28 +0000852 res = PyEval_CallObject (func, arg);
853 Py_DECREF (arg);
854 if (res == NULL)
855 {
856 errorInCmd = 1;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000857 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
Guido van Rossum18468821994-06-20 07:49:28 +0000858 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000859 Py_XDECREF (res);
860}
861
862static int
863GetFileNo (file)
864 PyObject *file; /* Either an int >= 0 or an object with a
865 .fileno() method that returns an int >= 0 */
866{
Guido van Rossuma597dde1995-01-10 20:56:29 +0000867 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000868 int id;
869 if (PyInt_Check(file)) {
870 id = PyInt_AsLong(file);
871 if (id < 0)
872 PyErr_SetString(PyExc_ValueError, "invalid file id");
873 return id;
874 }
875 meth = PyObject_GetAttrString(file, "fileno");
876 if (meth == NULL)
877 return -1;
878 args = PyTuple_New(0);
879 if (args == NULL)
880 return -1;
881 res = PyEval_CallObject(meth, args);
882 Py_DECREF(args);
883 Py_DECREF(meth);
884 if (res == NULL)
885 return -1;
886 if (PyInt_Check(res))
887 id = PyInt_AsLong(res);
888 else
889 id = -1;
890 if (id < 0)
891 PyErr_SetString(PyExc_ValueError,
892 "invalid fileno() return value");
893 Py_DECREF(res);
894 return id;
Guido van Rossum18468821994-06-20 07:49:28 +0000895}
896
897static PyObject *
898Tkapp_CreateFileHandler (self, args)
899 PyObject *self;
900 PyObject *args; /* Is (file, mask, func) */
901{
Guido van Rossum76875221994-06-27 07:59:42 +0000902 PyObject *file, *func, *data;
903 int mask, id;
Guido van Rossum68784361996-05-16 17:17:31 +0000904#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
905 Tcl_File tfile;
906#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000907
908 if (!PyArg_Parse (args, "(OiO)", &file, &mask, &func))
909 return NULL;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000910 id = GetFileNo (file);
911 if (id < 0)
912 return NULL;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000913 if (!PyCallable_Check(func))
Guido van Rossum18468821994-06-20 07:49:28 +0000914 {
915 PyErr_SetString (PyExc_TypeError, "bad argument list");
916 return NULL;
917 }
918
Guido van Rossum76875221994-06-27 07:59:42 +0000919 /* ClientData is: (func, file) */
920 data = Py_BuildValue ("(OO)", func, file);
921
Guido van Rossum68784361996-05-16 17:17:31 +0000922#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Guido van Rossum845547d1996-06-26 18:26:04 +0000923#ifdef NT
924 /* We assume this is a socket... */
925 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
926#else
Guido van Rossum68784361996-05-16 17:17:31 +0000927 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
Guido van Rossum845547d1996-06-26 18:26:04 +0000928#endif
Guido van Rossum68784361996-05-16 17:17:31 +0000929 /* Oughtta check for null Tcl_File object... */
930 Tcl_CreateFileHandler (tfile, mask, FileHandler, (ClientData) data);
931#else
Guido van Rossum845547d1996-06-26 18:26:04 +0000932 Tk_CreateFileHandler (id, mask, FileHandler, (ClientData) data);
Guido van Rossum68784361996-05-16 17:17:31 +0000933#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000934 /* XXX fileHandlerDict */
Guido van Rossum76875221994-06-27 07:59:42 +0000935
Guido van Rossum18468821994-06-20 07:49:28 +0000936 Py_INCREF (Py_None);
937 return Py_None;
938}
939
940static PyObject *
941Tkapp_DeleteFileHandler (self, args)
942 PyObject *self;
943 PyObject *args; /* Args: file */
944{
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000945 PyObject *file;
Guido van Rossum18468821994-06-20 07:49:28 +0000946 int id;
Guido van Rossum68784361996-05-16 17:17:31 +0000947#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
948 Tcl_File tfile;
949#endif
950
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000951 if (!PyArg_Parse (args, "O", &file))
952 return NULL;
953 id = GetFileNo (file);
954 if (id < 0)
955 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000956
Guido van Rossum68784361996-05-16 17:17:31 +0000957#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
Guido van Rossum845547d1996-06-26 18:26:04 +0000958#ifdef NT
959 /* We assume this is a socket... */
960 tfile = Tcl_GetFile((ClientData)id, TCL_WIN_SOCKET);
961#else
962 tfile = Tcl_GetFile((ClientData)id, TCL_UNIX_FD);
963#endif
Guido van Rossum68784361996-05-16 17:17:31 +0000964 /* Oughtta check for null Tcl_File object... */
965 Tcl_DeleteFileHandler(tfile);
966#else
Guido van Rossum845547d1996-06-26 18:26:04 +0000967 Tk_DeleteFileHandler (id);
Guido van Rossum68784361996-05-16 17:17:31 +0000968#endif
Guido van Rossum18468821994-06-20 07:49:28 +0000969 /* XXX fileHandlerDict */
970 Py_INCREF (Py_None);
971 return Py_None;
972}
973
Guido van Rossumf34cadd1994-11-10 22:50:21 +0000974/**** Tktt Object (timer token) ****/
975
976staticforward PyTypeObject Tktt_Type;
977
978typedef struct
979 {
980 PyObject_HEAD
981 Tk_TimerToken token;
982 PyObject *func;
983 }
984TkttObject;
985
986static PyObject *
987Tktt_DeleteTimerHandler (self, args)
988 PyObject *self;
989 PyObject *args;
990{
991 TkttObject *v = (TkttObject *) self;
992
993 if (!PyArg_Parse (args, ""))
994 return NULL;
995 if (v->func != NULL)
996 {
997 Tk_DeleteTimerHandler (v->token);
998 PyMem_DEL (v->func);
999 v->func = NULL;
1000 }
1001 Py_INCREF (Py_None);
1002 return Py_None;
1003}
1004
1005static PyMethodDef Tktt_methods[] =
1006{
1007 {"deletetimerhandler", Tktt_DeleteTimerHandler},
1008 {NULL, NULL}
1009};
1010
1011static TkttObject *
1012Tktt_New (token, func)
1013 Tk_TimerToken token;
1014 PyObject *func;
1015{
1016 TkttObject *v;
1017
1018 v = PyObject_NEW (TkttObject, &Tktt_Type);
1019 if (v == NULL)
1020 return NULL;
1021
1022 v->token = token;
1023 v->func = func;
1024 Py_INCREF (v->func);
1025 return v;
1026}
1027
1028static void
1029Tktt_Dealloc (self)
1030 PyObject *self;
1031{
1032 PyMem_DEL (self);
1033}
1034
1035static int
1036Tktt_Print (self, fp, flags)
1037 PyObject *self;
1038 FILE *fp;
1039 int flags;
1040{
1041 TkttObject *v = (TkttObject *) self;
1042
1043 fprintf(fp, "<tktimertoken at 0x%x%s>", v,
1044 v->func == NULL ? ", handler deleted" : "");
1045 return 0;
1046}
1047
1048static PyObject *
1049Tktt_GetAttr (self, name)
1050 PyObject *self;
1051 char *name;
1052{
1053 return Py_FindMethod (Tktt_methods, self, name);
1054}
1055
1056static PyTypeObject Tktt_Type =
1057{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001058 PyObject_HEAD_INIT (&PyType_Type)
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001059 0, /*ob_size */
1060 "tktimertoken", /*tp_name */
1061 sizeof (TkttObject), /*tp_basicsize */
1062 0, /*tp_itemsize */
1063 Tktt_Dealloc, /*tp_dealloc */
1064 Tktt_Print, /*tp_print */
1065 Tktt_GetAttr, /*tp_getattr */
1066 0, /*tp_setattr */
1067 0, /*tp_compare */
1068 0, /*tp_repr */
1069 0, /*tp_as_number */
1070 0, /*tp_as_sequence */
1071 0, /*tp_as_mapping */
1072 0, /*tp_hash */
1073};
1074
1075/** Timer Handler **/
1076
1077static void
1078TimerHandler (clientData)
1079 ClientData clientData;
1080{
1081 PyObject *func = (PyObject *) clientData;
1082 PyObject *arg, *res;
1083
1084 arg = PyTuple_New (0);
1085 res = PyEval_CallObject (func, arg);
1086 Py_DECREF (arg);
1087 if (res == NULL)
1088 {
1089 errorInCmd = 1;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001090 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001091 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001092 else
1093 Py_DECREF (res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001094}
1095
1096static PyObject *
1097Tkapp_CreateTimerHandler (self, args)
1098 PyObject *self;
1099 PyObject *args; /* Is (milliseconds, func) */
1100{
1101 int milliseconds;
1102 PyObject *func;
1103 Tk_TimerToken token;
1104
1105 if (!PyArg_Parse (args, "(iO)", &milliseconds, &func))
1106 return NULL;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001107 if (!PyCallable_Check(func))
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001108 {
1109 PyErr_SetString (PyExc_TypeError, "bad argument list");
1110 return NULL;
1111 }
1112 token = Tk_CreateTimerHandler(milliseconds, TimerHandler, (ClientData) func);
1113 return (PyObject *) Tktt_New (token, func);
1114}
1115
Guido van Rossum18468821994-06-20 07:49:28 +00001116/** Event Loop **/
1117
Guido van Rossum18468821994-06-20 07:49:28 +00001118static PyObject *
1119Tkapp_MainLoop (self, args)
1120 PyObject *self;
1121 PyObject *args;
1122{
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001123 int threshold = 0;
1124
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001125 if (!PyArg_ParseTuple (args, "|i", &threshold))
1126 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001127
1128 quitMainLoop = 0;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001129 while (Tk_GetNumMainWindows() > threshold && !quitMainLoop && !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001130 {
1131 if (PyOS_InterruptOccurred ())
1132 {
1133 PyErr_SetNone (PyExc_KeyboardInterrupt);
1134 return NULL;
1135 }
1136 Tk_DoOneEvent (0);
1137 }
Guido van Rossum64b24fb1995-09-30 17:00:24 +00001138 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001139
1140 if (errorInCmd)
1141 {
1142 errorInCmd = 0;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001143 PyErr_Restore (excInCmd, valInCmd, trbInCmd);
1144 excInCmd = valInCmd = trbInCmd = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001145 return NULL;
1146 }
1147 Py_INCREF (Py_None);
1148 return Py_None;
1149}
1150
1151static PyObject *
Guido van Rossum062cfb01995-01-10 17:42:51 +00001152Tkapp_DoOneEvent (self, args)
1153 PyObject *self;
1154 PyObject *args;
1155{
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001156 int flags = TK_ALL_EVENTS;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001157 int rv;
1158
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001159 if (!PyArg_ParseTuple (args, "|i", &flags))
1160 return NULL;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001161 rv = Tk_DoOneEvent(flags);
1162 return Py_BuildValue ("i", rv);
1163}
1164
1165static PyObject *
Guido van Rossum18468821994-06-20 07:49:28 +00001166Tkapp_Quit (self, args)
1167 PyObject *self;
1168 PyObject *args;
1169{
1170
1171 if (!PyArg_Parse (args, ""))
1172 return NULL;
1173 quitMainLoop = 1;
1174 Py_INCREF (Py_None);
1175 return Py_None;
1176}
1177
1178/**** Tkapp Method List ****/
1179
1180static PyMethodDef Tkapp_methods[] =
1181{
1182 {"call", Tkapp_Call},
1183 {"globalcall", Tkapp_GlobalCall},
1184 {"eval", Tkapp_Eval},
1185 {"globaleval", Tkapp_GlobalEval},
1186 {"evalfile", Tkapp_EvalFile},
1187 {"record", Tkapp_Record},
1188 {"adderrorinfo", Tkapp_AddErrorInfo},
1189 {"setvar", Tkapp_SetVar},
1190 {"globalsetvar", Tkapp_GlobalSetVar},
1191 {"getvar", Tkapp_GetVar},
1192 {"globalgetvar", Tkapp_GlobalGetVar},
1193 {"unsetvar", Tkapp_UnsetVar},
1194 {"globalunsetvar", Tkapp_GlobalUnsetVar},
1195 {"getint", Tkapp_GetInt},
1196 {"getdouble", Tkapp_GetDouble},
1197 {"getboolean", Tkapp_GetBoolean},
1198 {"exprstring", Tkapp_ExprString},
1199 {"exprlong", Tkapp_ExprLong},
1200 {"exprdouble", Tkapp_ExprDouble},
1201 {"exprboolean", Tkapp_ExprBoolean},
1202 {"splitlist", Tkapp_SplitList},
1203 {"split", Tkapp_Split},
1204 {"merge", Tkapp_Merge},
1205 {"createcommand", Tkapp_CreateCommand},
1206 {"deletecommand", Tkapp_DeleteCommand},
1207 {"createfilehandler", Tkapp_CreateFileHandler},
1208 {"deletefilehandler", Tkapp_DeleteFileHandler},
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001209 {"createtimerhandler", Tkapp_CreateTimerHandler},
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001210 {"mainloop", Tkapp_MainLoop, 1},
1211 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum18468821994-06-20 07:49:28 +00001212 {"quit", Tkapp_Quit},
1213 {NULL, NULL}
1214};
1215
1216/**** Tkapp Type Methods ****/
1217
1218static void
1219Tkapp_Dealloc (self)
1220 PyObject *self;
1221{
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001222#ifdef NEED_TKCREATEMAINWINDOW
Guido van Rossum18468821994-06-20 07:49:28 +00001223 Tk_DestroyWindow (Tkapp_Tkwin (self));
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001224#endif
Guido van Rossum18468821994-06-20 07:49:28 +00001225 Tcl_DeleteInterp (Tkapp_Interp (self));
1226 PyMem_DEL (self);
1227}
1228
1229static PyObject *
1230Tkapp_GetAttr (self, name)
1231 PyObject *self;
1232 char *name;
1233{
1234 return Py_FindMethod (Tkapp_methods, self, name);
1235}
1236
1237static PyTypeObject Tkapp_Type =
1238{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001239 PyObject_HEAD_INIT (&PyType_Type)
Guido van Rossum18468821994-06-20 07:49:28 +00001240 0, /*ob_size */
1241 "tkapp", /*tp_name */
1242 sizeof (TkappObject), /*tp_basicsize */
1243 0, /*tp_itemsize */
1244 Tkapp_Dealloc, /*tp_dealloc */
1245 0, /*tp_print */
1246 Tkapp_GetAttr, /*tp_getattr */
1247 0, /*tp_setattr */
1248 0, /*tp_compare */
1249 0, /*tp_repr */
1250 0, /*tp_as_number */
1251 0, /*tp_as_sequence */
1252 0, /*tp_as_mapping */
1253 0, /*tp_hash */
1254};
1255
1256/**** Tkinter Module ****/
1257
1258static PyObject *
1259Tkinter_Create (self, args)
1260 PyObject *self;
1261 PyObject *args;
1262{
1263 char *screenName = NULL;
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001264 char *baseName = NULL;
1265 char *className = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001266 int interactive = 0;
1267
Guido van Rossum32aa1a71996-07-31 19:51:15 +00001268 baseName = strrchr (Py_GetProgramName (), '/');
Guido van Rossum18468821994-06-20 07:49:28 +00001269 if (baseName != NULL)
1270 baseName++;
1271 else
Guido van Rossum32aa1a71996-07-31 19:51:15 +00001272 baseName = Py_GetProgramName ();
Guido van Rossum18468821994-06-20 07:49:28 +00001273 className = "Tk";
1274
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001275 if (!PyArg_ParseTuple (args, "|zssi",
1276 &screenName, &baseName, &className, &interactive))
Guido van Rossum18468821994-06-20 07:49:28 +00001277 return NULL;
1278
1279 return (PyObject *) Tkapp_New (screenName, baseName, className,
1280 interactive);
1281}
1282
1283static PyMethodDef moduleMethods[] =
1284{
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001285 {"create", Tkinter_Create, 1},
1286 {"createfilehandler", Tkapp_CreateFileHandler, 0},
1287 {"deletefilehandler", Tkapp_DeleteFileHandler, 0},
1288 {"createtimerhandler", Tkapp_CreateTimerHandler, 0},
1289 {"mainloop", Tkapp_MainLoop, 1},
1290 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001291 {"quit", Tkapp_Quit},
Guido van Rossum18468821994-06-20 07:49:28 +00001292 {NULL, NULL}
1293};
1294
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001295#undef WITH_READLINE /* XXX */
Guido van Rossum18468821994-06-20 07:49:28 +00001296#ifdef WITH_READLINE
1297static int
1298EventHook ()
1299{
1300 if (errorInCmd) /* XXX Reset tty */
1301 {
1302 errorInCmd = 0;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001303 PyErr_Restore (excInCmd, valInCmd, trbInCmd);
1304 excInCmd = valInCmd = trbInCmd = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001305 PyErr_Print ();
1306 }
Guido van Rossum9722ad81995-09-22 23:49:28 +00001307 if (Tk_GetNumMainWindows() > 0)
Guido van Rossume2ca9bd1994-08-03 08:01:43 +00001308 Tk_DoOneEvent (TK_DONT_WAIT);
Guido van Rossum18468821994-06-20 07:49:28 +00001309 return 0;
1310}
1311#endif /* WITH_READLINE */
1312
1313static void
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001314Tkinter_Cleanup ()
1315{
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001316/* This segfault with Tk 4.0 beta and seems unnecessary there as well */
1317#if TK_MAJOR_VERSION < 4
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001318 /* XXX rl_deprep_terminal is static, damned! */
1319 while (tkMainWindowList != 0)
1320 Tk_DestroyWindow (tkMainWindowList->win);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001321#endif
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001322}
1323
Guido van Rossum18468821994-06-20 07:49:28 +00001324void
Guido van Rossumad1f7ee1996-02-13 00:11:37 +00001325init_tkinter ()
Guido van Rossum18468821994-06-20 07:49:28 +00001326{
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001327 static inited = 0;
1328
Guido van Rossum18468821994-06-20 07:49:28 +00001329#ifdef WITH_READLINE
1330 extern int (*rl_event_hook) ();
1331#endif /* WITH_READLINE */
1332 PyObject *m, *d, *v;
1333
Jack Jansenba0311e1995-10-23 14:34:14 +00001334 m = Py_InitModule ("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001335
1336 d = PyModule_GetDict (m);
1337 Tkinter_TclError = Py_BuildValue ("s", "TclError");
1338 PyDict_SetItemString (d, "TclError", Tkinter_TclError);
1339
1340 v = Py_BuildValue ("i", TK_READABLE);
1341 PyDict_SetItemString (d, "READABLE", v);
1342 v = Py_BuildValue ("i", TK_WRITABLE);
1343 PyDict_SetItemString (d, "WRITABLE", v);
1344 v = Py_BuildValue ("i", TK_EXCEPTION);
1345 PyDict_SetItemString (d, "EXCEPTION", v);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001346 v = Py_BuildValue ("i", TK_X_EVENTS);
1347 PyDict_SetItemString (d, "X_EVENTS", v);
1348 v = Py_BuildValue ("i", TK_FILE_EVENTS);
1349 PyDict_SetItemString (d, "FILE_EVENTS", v);
1350 v = Py_BuildValue ("i", TK_TIMER_EVENTS);
1351 PyDict_SetItemString (d, "TIMER_EVENTS", v);
1352 v = Py_BuildValue ("i", TK_IDLE_EVENTS);
1353 PyDict_SetItemString (d, "IDLE_EVENTS", v);
1354 v = Py_BuildValue ("i", TK_ALL_EVENTS);
1355 PyDict_SetItemString (d, "ALL_EVENTS", v);
1356 v = Py_BuildValue ("i", TK_DONT_WAIT);
1357 PyDict_SetItemString (d, "DONT_WAIT", v);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001358 v = Py_BuildValue ("s", TK_VERSION);
1359 PyDict_SetItemString (d, "TK_VERSION", v);
1360 v = Py_BuildValue ("s", TCL_VERSION);
1361 PyDict_SetItemString (d, "TCL_VERSION", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001362
Guido van Rossum18468821994-06-20 07:49:28 +00001363#ifdef WITH_READLINE
1364 rl_event_hook = EventHook;
1365#endif /* WITH_READLINE */
1366
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001367 if (!inited)
1368 {
1369 inited = 1;
Guido van Rossume4485b01994-09-07 14:32:49 +00001370 if (Py_AtExit (Tkinter_Cleanup) != 0)
1371 fprintf(stderr,
1372 "Tkinter: warning: cleanup procedure not registered\n");
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001373 }
1374
Guido van Rossum18468821994-06-20 07:49:28 +00001375 if (PyErr_Occurred ())
Jack Jansenba0311e1995-10-23 14:34:14 +00001376 Py_FatalError ("can't initialize module _tkinter");
Jack Jansen34cc5c31995-10-31 16:15:12 +00001377#ifdef macintosh
Guido van Rossumec22c921996-02-25 04:50:29 +00001378 TclMacSetEventProc(PyMacConvertEvent);
1379#if GENERATINGCFM
Jack Jansen34cc5c31995-10-31 16:15:12 +00001380 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001381#endif /* GENERATINGCFM */
1382#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001383}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001384
Guido van Rossumec22c921996-02-25 04:50:29 +00001385
Guido van Rossum9722ad81995-09-22 23:49:28 +00001386#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001387
1388/*
Guido van Rossumec22c921996-02-25 04:50:29 +00001389** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001390*/
1391
Guido van Rossum9722ad81995-09-22 23:49:28 +00001392void
1393panic(char * format, ...)
1394{
1395 va_list varg;
1396
1397 va_start(varg, format);
1398
1399 vfprintf(stderr, format, varg);
1400 (void) fflush(stderr);
1401
1402 va_end(varg);
1403
1404 Py_FatalError("Tcl/Tk panic");
1405}
Jack Jansen40b546d1995-11-14 10:34:45 +00001406
Guido van Rossumec22c921996-02-25 04:50:29 +00001407/*
1408** Pass events to SIOUX before passing them to Tk.
1409*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001410
Guido van Rossumec22c921996-02-25 04:50:29 +00001411static int
1412PyMacConvertEvent(eventPtr)
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001413 EventRecord *eventPtr;
1414{
Guido van Rossumec22c921996-02-25 04:50:29 +00001415 if (SIOUXHandleOneEvent(eventPtr))
1416 return 0; /* Nothing happened to the Tcl event queue */
1417 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001418}
1419
Guido van Rossumec22c921996-02-25 04:50:29 +00001420#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001421
1422/*
1423** Additional Mac specific code for dealing with shared libraries.
1424*/
1425
1426#include <Resources.h>
1427#include <CodeFragments.h>
1428
1429static int loaded_from_shlib = 0;
1430static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001431
Jack Jansen34cc5c31995-10-31 16:15:12 +00001432/*
1433** If this module is dynamically loaded the following routine should
1434** be the init routine. It takes care of adding the shared library to
1435** the resource-file chain, so that the tk routines can find their
1436** resources.
1437*/
1438OSErr pascal
1439init_tkinter_shlib(InitBlockPtr data)
1440{
Guido van Rossum54ac1891996-05-16 17:14:03 +00001441 __sinit(); /* Sez Jack */
Jack Jansen34cc5c31995-10-31 16:15:12 +00001442 if ( data == nil ) return noErr;
1443 if ( data->fragLocator.where == kOnDiskFlat ) {
1444 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1445 loaded_from_shlib = 1;
1446 } else if ( data->fragLocator.where == kOnDiskSegmented ) {
1447 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1448 loaded_from_shlib = 1;
1449 }
1450 return noErr;
1451}
1452
1453/*
1454** Insert the library resources into the search path. Put them after
1455** the resources from the application. Again, we ignore errors.
1456*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00001457static
Jack Jansen34cc5c31995-10-31 16:15:12 +00001458mac_addlibresources()
1459{
1460 if ( !loaded_from_shlib )
1461 return;
1462 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1463}
1464
Guido van Rossumec22c921996-02-25 04:50:29 +00001465#endif /* GENERATINGCFM */
1466#endif /* macintosh */