blob: 70d571b6ebd94315b564be3f64c0a6f8f2296ace [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
Guido van Rossumd266eb41996-10-25 14:44:06 +00008Permission to use, copy, modify, and distribute this software and its
9documentation for any purpose and without fee is hereby granted,
Guido van Rossum845547d1996-06-26 18:26:04 +000010provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000011both that copyright notice and this permission notice appear in
Guido van Rossum845547d1996-06-26 18:26:04 +000012supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000013Centrum or CWI or Corporation for National Research Initiatives or
14CNRI not be used in advertising or publicity pertaining to
15distribution of the software without specific, written prior
16permission.
Guido van Rossum845547d1996-06-26 18:26:04 +000017
Guido van Rossumd266eb41996-10-25 14:44:06 +000018While CWI is the initial source for this software, a modified version
19is made available by the Corporation for National Research Initiatives
20(CNRI) at the Internet address ftp://ftp.python.org.
21
22STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
23REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
24MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
25CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
26DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
27PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
28TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum845547d1996-06-26 18:26:04 +000030
31******************************************************************/
32
33/* _tkinter.c -- Interface to libtk.a and libtcl.a. */
Guido van Rossum18468821994-06-20 07:49:28 +000034
Guido van Rossum7ffa7611996-08-13 21:10:16 +000035/* TCL/TK VERSION INFO:
36
37 Unix:
Guido van Rossum496f8f61997-07-19 19:57:42 +000038 Tcl/Tk 8.0 (even alpha or beta) or 7.6/4.2 are recommended.
Guido van Rossum35d43371997-08-02 00:09:09 +000039 Versions 7.5/4.1 are the earliest versions still supported.
40 Versions 7.4/4.0 or Tk 3.x are no longer supported.
Guido van Rossum7ffa7611996-08-13 21:10:16 +000041
42 Mac and Windows:
Guido van Rossum496f8f61997-07-19 19:57:42 +000043 Use Tcl 8.0 if available (even alpha or beta).
44 The oldest usable version is 4.1p1/7.5p1.
45
Guido van Rossum212643f1998-04-29 16:22:14 +000046 XXX Further speed-up ideas, involving Tcl 8.0 features:
47
48 - In Tcl_Call(), create Tcl objects from the arguments, possibly using
49 intelligent mappings between Python objects and Tcl objects (e.g. ints,
50 floats and Tcl window pointers could be handled specially).
51
52 - Register a new Tcl type, "Python callable", which can be called more
53 efficiently and passed to Tcl_EvalObj() directly (if this is possible).
54
Guido van Rossum7ffa7611996-08-13 21:10:16 +000055*/
56
Guido van Rossum35d43371997-08-02 00:09:09 +000057
Guido van Rossum9722ad81995-09-22 23:49:28 +000058#include "Python.h"
Guido van Rossum97867b21996-08-08 19:09:53 +000059#include <ctype.h>
Guido van Rossum9722ad81995-09-22 23:49:28 +000060
Guido van Rossum00d93061998-05-28 23:06:38 +000061#ifdef WITH_THREAD
62#include "thread.h"
63#endif
64
Guido van Rossum2a5119b1998-05-29 01:28:40 +000065#ifdef MS_WINDOWS
66#include <windows.h>
67#endif
68
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000069#ifdef macintosh
70#define MAC_TCL
Guido van Rossum290283b1997-06-02 22:16:43 +000071#include "myselect.h"
Guido van Rossumbf0dc9f1996-08-20 20:49:56 +000072#endif
73
Guido van Rossum18468821994-06-20 07:49:28 +000074#include <tcl.h>
75#include <tk.h>
76
Guido van Rossum3e819a71997-08-01 19:29:02 +000077#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
78
Guido van Rossum00d93061998-05-28 23:06:38 +000079#if TKMAJORMINOR < 4001
80 #error "Tk 4.0 or 3.x are not supported -- use 4.1 or higher"
81#endif
82
Guido van Rossum0d2390c1997-08-14 19:57:07 +000083#if TKMAJORMINOR >= 8000 && defined(macintosh)
84/* Sigh, we have to include this to get at the tcl qd pointer */
85#include <tkMac.h>
Guido van Rossum2ea1c941998-04-28 16:12:43 +000086/* And this one we need to clear the menu bar */
87#include <Menus.h>
Guido van Rossum0d2390c1997-08-14 19:57:07 +000088#endif
89
Guido van Rossumb0105441997-10-08 15:25:37 +000090#if TKMAJORMINOR < 8000 || !defined(MS_WINDOWS)
Guido van Rossum0d2390c1997-08-14 19:57:07 +000091#define HAVE_CREATEFILEHANDLER
92#endif
93
Guido van Rossum00d93061998-05-28 23:06:38 +000094#ifdef HAVE_CREATEFILEHANDLER
95
96/* Tcl_CreateFileHandler() changed several times; these macros deal with the
97 messiness. In Tcl 8.0 and later, it is not available on Windows (and on
98 Unix, only because Jack added it back); when available on Windows, it only
99 applies to sockets. */
100
Guido van Rossum7bf15641998-05-22 18:28:17 +0000101#ifdef MS_WINDOWS
102#define FHANDLETYPE TCL_WIN_SOCKET
103#else
104#define FHANDLETYPE TCL_UNIX_FD
105#endif
106
107#if TKMAJORMINOR < 8000
108#define FHANDLE Tcl_File
109#define MAKEFHANDLE(fd) Tcl_GetFile((ClientData)(fd), FHANDLETYPE)
110#else
111#define FHANDLE int
112#define MAKEFHANDLE(fd) (fd)
113#endif
114
Guido van Rossum00d93061998-05-28 23:06:38 +0000115/* If Tcl can wait for a Unix file descriptor, define the EventHook() routine
116 which uses this to handle Tcl events while the user is typing commands. */
117
118#if FHANDLETYPE == TCL_UNIX_FD
Guido van Rossum7bf15641998-05-22 18:28:17 +0000119#define WAIT_FOR_STDIN
120#endif
121
Guido van Rossum00d93061998-05-28 23:06:38 +0000122#endif /* HAVE_CREATEFILEHANDLER */
123
Guido van Rossumad4db171998-06-13 13:56:28 +0000124#ifdef MS_WINDOWS
125#include <conio.h>
126#define WAIT_FOR_STDIN
127#endif
128
Guido van Rossum00d93061998-05-28 23:06:38 +0000129#ifdef WITH_THREAD
130
131/* The threading situation is complicated. Tcl is not thread-safe, except for
132 Tcl 8.1, which will probably remain in alpha status for another 6 months
133 (and the README says that Tk will probably remain thread-unsafe forever).
134 So we need to use a lock around all uses of Tcl. Previously, the Python
135 interpreter lock was used for this. However, this causes problems when
136 other Python threads need to run while Tcl is blocked waiting for events.
137
138 To solve this problem, a separate lock for Tcl is introduced. Holding it
139 is incompatible with holding Python's interpreter lock. The following four
140 macros manipulate both locks together.
141
142 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
143 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
144 that could call an event handler, or otherwise affect the state of a Tcl
145 interpreter. These assume that the surrounding code has the Python
146 interpreter lock; inside the brackets, the Python interpreter lock has been
147 released and the lock for Tcl has been acquired.
148
149 By contrast, ENTER_PYTHON(tstate) and LEAVE_PYTHON are used in Tcl event
150 handlers when the handler needs to use Python. Such event handlers are
151 entered while the lock for Tcl is held; the event handler presumably needs
152 to use Python. ENTER_PYTHON(tstate) releases the lock for Tcl and acquires
153 the Python interpreter lock, restoring the appropriate thread state, and
154 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
155 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
156 the code between ENTER_PYTHON(tstate) and LEAVE_PYTHON.
157
158 These locks expand to several statements and brackets; they should not be
159 used in branches of if statements and the like.
160
161*/
162
163static type_lock tcl_lock = 0;
164
165#define ENTER_TCL \
166 Py_BEGIN_ALLOW_THREADS acquire_lock(tcl_lock, 1);
167
168#define LEAVE_TCL \
169 release_lock(tcl_lock); Py_END_ALLOW_THREADS
170
171#define ENTER_PYTHON(tstate) \
172 if (PyThreadState_Swap(NULL) != NULL) \
173 Py_FatalError("ENTER_PYTHON with non-NULL tstate\n"); \
174 release_lock(tcl_lock); PyEval_RestoreThread((tstate));
175
176#define LEAVE_PYTHON \
177 PyEval_SaveThread(); acquire_lock(tcl_lock, 1);
178
179#else
180
181#define ENTER_TCL
182#define LEAVE_TCL
183#define ENTER_PYTHON(tstate)
184#define LEAVE_PYTHON
185
186#endif
187
Guido van Rossum35d43371997-08-02 00:09:09 +0000188extern int Tk_GetNumMainWindows();
189
Guido van Rossumec22c921996-02-25 04:50:29 +0000190#ifdef macintosh
191
192/*
193** Additional cruft needed by Tcl/Tk on the Mac.
Guido van Rossum97867b21996-08-08 19:09:53 +0000194** This is for Tcl 7.5 and Tk 4.1 (patch release 1).
Guido van Rossumec22c921996-02-25 04:50:29 +0000195*/
196
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000197/* ckfree() expects a char* */
Guido van Rossum97867b21996-08-08 19:09:53 +0000198#define FREECAST (char *)
199
Guido van Rossumec22c921996-02-25 04:50:29 +0000200#include <Events.h> /* For EventRecord */
201
202typedef int (*TclMacConvertEventPtr) Py_PROTO((EventRecord *eventPtr));
Guido van Rossum0d2390c1997-08-14 19:57:07 +0000203/* They changed the name... */
204#if TKMAJORMINOR < 8000
205#define Tcl_MacSetEventProc TclMacSetEventProc
206#endif
207void Tcl_MacSetEventProc Py_PROTO((TclMacConvertEventPtr procPtr));
Guido van Rossumec22c921996-02-25 04:50:29 +0000208int TkMacConvertEvent Py_PROTO((EventRecord *eventPtr));
209
210staticforward int PyMacConvertEvent Py_PROTO((EventRecord *eventPtr));
211
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000212#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
213 #pragma import on
214#endif
215
216#include <SIOUX.h>
217extern int SIOUXIsAppWindow(WindowPtr);
218
219#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
220 #pragma import reset
221#endif
Guido van Rossumec22c921996-02-25 04:50:29 +0000222#endif /* macintosh */
223
Guido van Rossum97867b21996-08-08 19:09:53 +0000224#ifndef FREECAST
Guido van Rossum7ffa7611996-08-13 21:10:16 +0000225#define FREECAST (char *)
Guido van Rossum97867b21996-08-08 19:09:53 +0000226#endif
227
Guido van Rossum18468821994-06-20 07:49:28 +0000228/**** Tkapp Object Declaration ****/
229
230staticforward PyTypeObject Tkapp_Type;
231
Guido van Rossum00d93061998-05-28 23:06:38 +0000232typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +0000233 PyObject_HEAD
234 Tcl_Interp *interp;
Guido van Rossum00d93061998-05-28 23:06:38 +0000235} TkappObject;
Guido van Rossum18468821994-06-20 07:49:28 +0000236
237#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
Guido van Rossum18468821994-06-20 07:49:28 +0000238#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
239#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
240
Guido van Rossum35d43371997-08-02 00:09:09 +0000241#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
Barry Warsawfa701a81997-01-16 00:15:11 +0000242(void *) v, ((PyObject *) v)->ob_refcnt))
Guido van Rossum18468821994-06-20 07:49:28 +0000243
Barry Warsawfa701a81997-01-16 00:15:11 +0000244
245
Guido van Rossum18468821994-06-20 07:49:28 +0000246/**** Error Handling ****/
247
248static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000249static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +0000250static int errorInCmd = 0;
251static PyObject *excInCmd;
252static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000253static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +0000254
Barry Warsawfa701a81997-01-16 00:15:11 +0000255
256
Guido van Rossum18468821994-06-20 07:49:28 +0000257static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000258Tkinter_Error(v)
259 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000260{
Barry Warsawfa701a81997-01-16 00:15:11 +0000261 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
262 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000263}
264
Barry Warsawfa701a81997-01-16 00:15:11 +0000265
Barry Warsawfa701a81997-01-16 00:15:11 +0000266
Guido van Rossum18468821994-06-20 07:49:28 +0000267/**** Utils ****/
Guido van Rossum00d93061998-05-28 23:06:38 +0000268
269#ifdef WITH_THREAD
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000270#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +0000271/* Millisecond sleep() for Unix platforms. */
272
273static void
274Sleep(milli)
275 int milli;
276{
277 /* XXX Too bad if you don't have select(). */
278 struct timeval t;
279 double frac;
280 t.tv_sec = milli/1000;
281 t.tv_usec = (milli%1000) * 1000;
282 select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
283}
Guido van Rossum2a5119b1998-05-29 01:28:40 +0000284#endif /* MS_WINDOWS */
Guido van Rossum00d93061998-05-28 23:06:38 +0000285#endif /* WITH_THREAD */
286
287
Guido van Rossum18468821994-06-20 07:49:28 +0000288static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000289AsString(value, tmp)
290 PyObject *value;
291 PyObject *tmp;
Guido van Rossum18468821994-06-20 07:49:28 +0000292{
Guido van Rossum35d43371997-08-02 00:09:09 +0000293 if (PyString_Check(value))
294 return PyString_AsString(value);
Barry Warsawfa701a81997-01-16 00:15:11 +0000295 else {
296 PyObject *v = PyObject_Str(value);
297 PyList_Append(tmp, v);
298 Py_DECREF(v);
299 return PyString_AsString(v);
300 }
Guido van Rossum18468821994-06-20 07:49:28 +0000301}
302
Barry Warsawfa701a81997-01-16 00:15:11 +0000303
304
Guido van Rossum18468821994-06-20 07:49:28 +0000305#define ARGSZ 64
306
307static char *
Barry Warsawfa701a81997-01-16 00:15:11 +0000308Merge(args)
309 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000310{
Barry Warsawfa701a81997-01-16 00:15:11 +0000311 PyObject *tmp = NULL;
312 char *argvStore[ARGSZ];
313 char **argv = NULL;
314 int fvStore[ARGSZ];
315 int *fv = NULL;
316 int argc = 0, i;
317 char *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000318
Barry Warsawfa701a81997-01-16 00:15:11 +0000319 if (!(tmp = PyList_New(0)))
320 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000321
Barry Warsawfa701a81997-01-16 00:15:11 +0000322 argv = argvStore;
323 fv = fvStore;
Guido van Rossum18468821994-06-20 07:49:28 +0000324
Barry Warsawfa701a81997-01-16 00:15:11 +0000325 if (args == NULL)
326 argc = 0;
327
328 else if (!PyTuple_Check(args)) {
329 argc = 1;
330 fv[0] = 0;
331 argv[0] = AsString(args, tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000332 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000333 else {
334 argc = PyTuple_Size(args);
Guido van Rossum18468821994-06-20 07:49:28 +0000335
Barry Warsawfa701a81997-01-16 00:15:11 +0000336 if (argc > ARGSZ) {
Guido van Rossum35d43371997-08-02 00:09:09 +0000337 argv = (char **)ckalloc(argc * sizeof(char *));
338 fv = (int *)ckalloc(argc * sizeof(int));
Barry Warsawfa701a81997-01-16 00:15:11 +0000339 if (argv == NULL || fv == NULL) {
340 PyErr_NoMemory();
341 goto finally;
342 }
343 }
344
345 for (i = 0; i < argc; i++) {
346 PyObject *v = PyTuple_GetItem(args, i);
347 if (PyTuple_Check(v)) {
348 fv[i] = 1;
349 if (!(argv[i] = Merge(v)))
350 goto finally;
351 }
352 else if (v == Py_None) {
353 argc = i;
354 break;
355 }
356 else {
357 fv[i] = 0;
358 argv[i] = AsString(v, tmp);
359 }
360 }
Guido van Rossum18468821994-06-20 07:49:28 +0000361 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000362 res = Tcl_Merge(argc, argv);
Guido van Rossum18468821994-06-20 07:49:28 +0000363
Barry Warsawfa701a81997-01-16 00:15:11 +0000364 finally:
365 for (i = 0; i < argc; i++)
366 if (fv[i]) {
367 ckfree(argv[i]);
368 }
369 if (argv != argvStore)
370 ckfree(FREECAST argv);
371 if (fv != fvStore)
372 ckfree(FREECAST fv);
Guido van Rossum18468821994-06-20 07:49:28 +0000373
Barry Warsawfa701a81997-01-16 00:15:11 +0000374 Py_DECREF(tmp);
375 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000376}
377
Barry Warsawfa701a81997-01-16 00:15:11 +0000378
379
Guido van Rossum18468821994-06-20 07:49:28 +0000380static PyObject *
Guido van Rossum00d93061998-05-28 23:06:38 +0000381Split(list)
Barry Warsawfa701a81997-01-16 00:15:11 +0000382 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +0000383{
Barry Warsawfa701a81997-01-16 00:15:11 +0000384 int argc;
385 char **argv;
386 PyObject *v;
Guido van Rossum18468821994-06-20 07:49:28 +0000387
Barry Warsawfa701a81997-01-16 00:15:11 +0000388 if (list == NULL) {
389 Py_INCREF(Py_None);
390 return Py_None;
391 }
Guido van Rossum18468821994-06-20 07:49:28 +0000392
Guido van Rossum00d93061998-05-28 23:06:38 +0000393 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000394 /* Not a list.
395 * Could be a quoted string containing funnies, e.g. {"}.
396 * Return the string itself.
397 */
Barry Warsawfa701a81997-01-16 00:15:11 +0000398 return PyString_FromString(list);
399 }
Guido van Rossum18468821994-06-20 07:49:28 +0000400
Barry Warsawfa701a81997-01-16 00:15:11 +0000401 if (argc == 0)
402 v = PyString_FromString("");
403 else if (argc == 1)
404 v = PyString_FromString(argv[0]);
Guido van Rossum35d43371997-08-02 00:09:09 +0000405 else if ((v = PyTuple_New(argc)) != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000406 int i;
407 PyObject *w;
Guido van Rossum18468821994-06-20 07:49:28 +0000408
Barry Warsawfa701a81997-01-16 00:15:11 +0000409 for (i = 0; i < argc; i++) {
Guido van Rossum00d93061998-05-28 23:06:38 +0000410 if ((w = Split(argv[i])) == NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000411 Py_DECREF(v);
412 v = NULL;
413 break;
414 }
415 PyTuple_SetItem(v, i, w);
416 }
417 }
Guido van Rossum00d93061998-05-28 23:06:38 +0000418 Tcl_Free(FREECAST argv);
Barry Warsawfa701a81997-01-16 00:15:11 +0000419 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000420}
421
Barry Warsawfa701a81997-01-16 00:15:11 +0000422
423
Guido van Rossum18468821994-06-20 07:49:28 +0000424/**** Tkapp Object ****/
425
426#ifndef WITH_APPINIT
427int
Guido van Rossum35d43371997-08-02 00:09:09 +0000428Tcl_AppInit(interp)
Barry Warsawfa701a81997-01-16 00:15:11 +0000429 Tcl_Interp *interp;
Guido van Rossum18468821994-06-20 07:49:28 +0000430{
Barry Warsawfa701a81997-01-16 00:15:11 +0000431 Tk_Window main;
Guido van Rossumec22c921996-02-25 04:50:29 +0000432
Barry Warsawfa701a81997-01-16 00:15:11 +0000433 main = Tk_MainWindow(interp);
434 if (Tcl_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000435 PySys_WriteStderr("Tcl_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000436 return TCL_ERROR;
437 }
438 if (Tk_Init(interp) == TCL_ERROR) {
Guido van Rossumb41addf1998-05-12 15:02:41 +0000439 PySys_WriteStderr("Tk_Init error: %s\n", interp->result);
Barry Warsawfa701a81997-01-16 00:15:11 +0000440 return TCL_ERROR;
441 }
442 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +0000443}
444#endif /* !WITH_APPINIT */
445
Guido van Rossum18468821994-06-20 07:49:28 +0000446
Barry Warsawfa701a81997-01-16 00:15:11 +0000447
448
449/* Initialize the Tk application; see the `main' function in
450 * `tkMain.c'.
451 */
Guido van Rossum7bf15641998-05-22 18:28:17 +0000452
453static void EnableEventHook(); /* Forward */
454static void DisableEventHook(); /* Forward */
455
Barry Warsawfa701a81997-01-16 00:15:11 +0000456static TkappObject *
457Tkapp_New(screenName, baseName, className, interactive)
458 char *screenName;
459 char *baseName;
460 char *className;
461 int interactive;
462{
463 TkappObject *v;
464 char *argv0;
465
466 v = PyObject_NEW(TkappObject, &Tkapp_Type);
467 if (v == NULL)
468 return NULL;
469
470 v->interp = Tcl_CreateInterp();
Guido van Rossumdfd428d1996-02-25 04:46:40 +0000471
Guido van Rossum2ea1c941998-04-28 16:12:43 +0000472#if defined(macintosh) && TKMAJORMINOR >= 8000
473 /* This seems to be needed since Tk 8.0 */
474 ClearMenuBar();
475 TkMacInitMenus(v->interp);
476#endif
Guido van Rossum1c0d3151998-02-19 21:28:49 +0000477 /* Delete the 'exit' command, which can screw things up */
478 Tcl_DeleteCommand(v->interp, "exit");
479
Barry Warsawfa701a81997-01-16 00:15:11 +0000480 if (screenName != NULL)
481 Tcl_SetVar2(v->interp, "env", "DISPLAY",
482 screenName, TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000483
Barry Warsawfa701a81997-01-16 00:15:11 +0000484 if (interactive)
485 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
486 else
487 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000488
Barry Warsawfa701a81997-01-16 00:15:11 +0000489 /* This is used to get the application class for Tk 4.1 and up */
490 argv0 = (char*)ckalloc(strlen(className) + 1);
491 if (!argv0) {
492 PyErr_NoMemory();
493 Py_DECREF(v);
494 return NULL;
495 }
Guido van Rossum97867b21996-08-08 19:09:53 +0000496
Barry Warsawfa701a81997-01-16 00:15:11 +0000497 strcpy(argv0, className);
Guido van Rossum730806d1998-04-10 22:27:42 +0000498 if (isupper((int)(argv0[0])))
Barry Warsawfa701a81997-01-16 00:15:11 +0000499 argv0[0] = tolower(argv0[0]);
500 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
501 ckfree(argv0);
Guido van Rossum18468821994-06-20 07:49:28 +0000502
Barry Warsawfa701a81997-01-16 00:15:11 +0000503 if (Tcl_AppInit(v->interp) != TCL_OK)
504 return (TkappObject *)Tkinter_Error(v);
505
Guido van Rossum7bf15641998-05-22 18:28:17 +0000506 EnableEventHook();
507
Barry Warsawfa701a81997-01-16 00:15:11 +0000508 return v;
Guido van Rossum18468821994-06-20 07:49:28 +0000509}
510
Barry Warsawfa701a81997-01-16 00:15:11 +0000511
512
Guido van Rossum18468821994-06-20 07:49:28 +0000513/** Tcl Eval **/
514
515static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000516Tkapp_Call(self, args)
517 PyObject *self;
518 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000519{
Guido van Rossum212643f1998-04-29 16:22:14 +0000520 /* This is copied from Merge() */
521 PyObject *tmp = NULL;
522 char *argvStore[ARGSZ];
523 char **argv = NULL;
524 int fvStore[ARGSZ];
525 int *fv = NULL;
526 int argc = 0, i;
527 PyObject *res = NULL; /* except this has a different type */
528 Tcl_CmdInfo info; /* and this is added */
529 Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
Guido van Rossum18468821994-06-20 07:49:28 +0000530
Guido van Rossum212643f1998-04-29 16:22:14 +0000531 if (!(tmp = PyList_New(0)))
532 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000533
Guido van Rossum212643f1998-04-29 16:22:14 +0000534 argv = argvStore;
535 fv = fvStore;
Barry Warsawfa701a81997-01-16 00:15:11 +0000536
Guido van Rossum212643f1998-04-29 16:22:14 +0000537 if (args == NULL)
538 argc = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +0000539
Guido van Rossum212643f1998-04-29 16:22:14 +0000540 else if (!PyTuple_Check(args)) {
541 argc = 1;
542 fv[0] = 0;
543 argv[0] = AsString(args, tmp);
544 }
545 else {
546 argc = PyTuple_Size(args);
547
548 if (argc > ARGSZ) {
549 argv = (char **)ckalloc(argc * sizeof(char *));
550 fv = (int *)ckalloc(argc * sizeof(int));
551 if (argv == NULL || fv == NULL) {
552 PyErr_NoMemory();
553 goto finally;
554 }
555 }
556
557 for (i = 0; i < argc; i++) {
558 PyObject *v = PyTuple_GetItem(args, i);
559 if (PyTuple_Check(v)) {
560 fv[i] = 1;
561 if (!(argv[i] = Merge(v)))
562 goto finally;
563 }
564 else if (v == Py_None) {
565 argc = i;
566 break;
567 }
568 else {
569 fv[i] = 0;
570 argv[i] = AsString(v, tmp);
571 }
572 }
573 }
574 /* End code copied from Merge() */
575
576 /* All this to avoid a call to Tcl_Merge() and the corresponding call
577 to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
578 if (Py_VerboseFlag >= 2) {
579 for (i = 0; i < argc; i++)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000580 PySys_WriteStderr("%s ", argv[i]);
Guido van Rossum212643f1998-04-29 16:22:14 +0000581 }
582 if (argc < 1 ||
583 !Tcl_GetCommandInfo(interp, argv[0], &info) ||
584 info.proc == NULL)
585 {
586 char *cmd;
587 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000588 PySys_WriteStderr("... use TclEval ");
Guido van Rossum212643f1998-04-29 16:22:14 +0000589 cmd = Tcl_Merge(argc, argv);
Guido van Rossum00d93061998-05-28 23:06:38 +0000590 ENTER_TCL
Guido van Rossum212643f1998-04-29 16:22:14 +0000591 i = Tcl_Eval(interp, cmd);
Guido van Rossum00d93061998-05-28 23:06:38 +0000592 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000593 ckfree(cmd);
Guido van Rossum212643f1998-04-29 16:22:14 +0000594 }
595 else {
596 Tcl_ResetResult(interp);
Guido van Rossum00d93061998-05-28 23:06:38 +0000597 ENTER_TCL
Guido van Rossum212643f1998-04-29 16:22:14 +0000598 i = (*info.proc)(info.clientData, interp, argc, argv);
Guido van Rossum00d93061998-05-28 23:06:38 +0000599 LEAVE_TCL
Guido van Rossum212643f1998-04-29 16:22:14 +0000600 }
601 if (i == TCL_ERROR) {
602 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000603 PySys_WriteStderr("... error: '%s'\n",
Guido van Rossum212643f1998-04-29 16:22:14 +0000604 interp->result);
605 Tkinter_Error(self);
606 }
607 else {
608 if (Py_VerboseFlag >= 2)
Guido van Rossumb41addf1998-05-12 15:02:41 +0000609 PySys_WriteStderr("-> '%s'\n", interp->result);
Guido van Rossum212643f1998-04-29 16:22:14 +0000610 res = PyString_FromString(interp->result);
611 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000612
Guido van Rossum212643f1998-04-29 16:22:14 +0000613 /* Copied from Merge() again */
614 finally:
615 for (i = 0; i < argc; i++)
616 if (fv[i]) {
617 ckfree(argv[i]);
618 }
619 if (argv != argvStore)
620 ckfree(FREECAST argv);
621 if (fv != fvStore)
622 ckfree(FREECAST fv);
623
624 Py_DECREF(tmp);
Barry Warsawfa701a81997-01-16 00:15:11 +0000625 return res;
626}
627
628
629static PyObject *
630Tkapp_GlobalCall(self, args)
631 PyObject *self;
632 PyObject *args;
633{
Guido van Rossum212643f1998-04-29 16:22:14 +0000634 /* Could do the same here as for Tkapp_Call(), but this is not used
635 much, so I can't be bothered. Unfortunately Tcl doesn't export a
636 way for the user to do what all its Global* variants do (save and
637 reset the scope pointer, call the local version, restore the saved
638 scope pointer). */
639
Barry Warsawfa701a81997-01-16 00:15:11 +0000640 char *cmd = Merge(args);
641 PyObject *res = NULL;
642
643
644 if (!cmd)
645 PyErr_SetString(Tkinter_TclError, "merge failed");
646
Guido van Rossum00d93061998-05-28 23:06:38 +0000647 else {
648 int err;
649 ENTER_TCL
650 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
651 LEAVE_TCL
652 if (err == TCL_ERROR)
653 res = Tkinter_Error(self);
654 else
655 res = PyString_FromString(Tkapp_Result(self));
656 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000657
658 if (cmd)
659 ckfree(cmd);
660
661 return res;
Guido van Rossum18468821994-06-20 07:49:28 +0000662}
663
664static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000665Tkapp_Eval(self, args)
666 PyObject *self;
667 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000668{
Barry Warsawfa701a81997-01-16 00:15:11 +0000669 char *script;
Guido van Rossum00d93061998-05-28 23:06:38 +0000670 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000671
Guido van Rossum35d43371997-08-02 00:09:09 +0000672 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000673 return NULL;
674
Guido van Rossum00d93061998-05-28 23:06:38 +0000675 ENTER_TCL
676 err = Tcl_Eval(Tkapp_Interp(self), script);
677 LEAVE_TCL
678 if (err == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000679 return Tkinter_Error(self);
680
681 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000682}
683
684static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000685Tkapp_GlobalEval(self, args)
686 PyObject *self;
687 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000688{
Barry Warsawfa701a81997-01-16 00:15:11 +0000689 char *script;
Guido van Rossum00d93061998-05-28 23:06:38 +0000690 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000691
Guido van Rossum35d43371997-08-02 00:09:09 +0000692 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000693 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000694
Guido van Rossum00d93061998-05-28 23:06:38 +0000695 ENTER_TCL
696 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
697 LEAVE_TCL
698 if (err == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000699 return Tkinter_Error(self);
Guido van Rossum00d93061998-05-28 23:06:38 +0000700
Barry Warsawfa701a81997-01-16 00:15:11 +0000701 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000702}
703
704static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000705Tkapp_EvalFile(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000706 PyObject *self;
707 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000708{
Barry Warsawfa701a81997-01-16 00:15:11 +0000709 char *fileName;
Guido van Rossum00d93061998-05-28 23:06:38 +0000710 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000711
Guido van Rossum35d43371997-08-02 00:09:09 +0000712 if (!PyArg_ParseTuple(args, "s", &fileName))
Barry Warsawfa701a81997-01-16 00:15:11 +0000713 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000714
Guido van Rossum00d93061998-05-28 23:06:38 +0000715 ENTER_TCL
716 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
717 LEAVE_TCL
718 if (err == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000719 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000720
Barry Warsawfa701a81997-01-16 00:15:11 +0000721 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000722}
723
724static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000725Tkapp_Record(self, args)
726 PyObject *self;
727 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000728{
Barry Warsawfa701a81997-01-16 00:15:11 +0000729 char *script;
Guido van Rossum00d93061998-05-28 23:06:38 +0000730 int err;
Guido van Rossum18468821994-06-20 07:49:28 +0000731
Guido van Rossum35d43371997-08-02 00:09:09 +0000732 if (!PyArg_ParseTuple(args, "s", &script))
Barry Warsawfa701a81997-01-16 00:15:11 +0000733 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000734
Guido van Rossum00d93061998-05-28 23:06:38 +0000735 ENTER_TCL
736 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
737 LEAVE_TCL
738 if (err == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000739 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +0000740
Barry Warsawfa701a81997-01-16 00:15:11 +0000741 return PyString_FromString(Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000742}
743
744static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000745Tkapp_AddErrorInfo(self, args)
746 PyObject *self;
747 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000748{
Barry Warsawfa701a81997-01-16 00:15:11 +0000749 char *msg;
Guido van Rossum18468821994-06-20 07:49:28 +0000750
Guido van Rossum35d43371997-08-02 00:09:09 +0000751 if (!PyArg_ParseTuple(args, "s", &msg))
Barry Warsawfa701a81997-01-16 00:15:11 +0000752 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000753 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +0000754 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
Guido van Rossum00d93061998-05-28 23:06:38 +0000755 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000756
Barry Warsawfa701a81997-01-16 00:15:11 +0000757 Py_INCREF(Py_None);
758 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000759}
760
Barry Warsawfa701a81997-01-16 00:15:11 +0000761
762
Guido van Rossum18468821994-06-20 07:49:28 +0000763/** Tcl Variable **/
764
765static PyObject *
Barry Warsawfa701a81997-01-16 00:15:11 +0000766SetVar(self, args, flags)
767 PyObject *self;
768 PyObject *args;
769 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000770{
Guido van Rossum00d93061998-05-28 23:06:38 +0000771 char *name1, *name2, *ok, *s;
Barry Warsawfa701a81997-01-16 00:15:11 +0000772 PyObject *newValue;
773 PyObject *tmp = PyList_New(0);
Guido van Rossum18468821994-06-20 07:49:28 +0000774
Barry Warsawfa701a81997-01-16 00:15:11 +0000775 if (!tmp)
776 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000777
Guido van Rossum00d93061998-05-28 23:06:38 +0000778 if (PyArg_ParseTuple(args, "sO", &name1, &newValue)) {
Barry Warsawfa701a81997-01-16 00:15:11 +0000779 /* XXX Merge? */
Guido van Rossum00d93061998-05-28 23:06:38 +0000780 s = AsString(newValue, tmp);
781 ENTER_TCL
782 ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
783 LEAVE_TCL
784 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000785 else {
Guido van Rossum35d43371997-08-02 00:09:09 +0000786 PyErr_Clear();
Guido van Rossum00d93061998-05-28 23:06:38 +0000787 if (PyArg_ParseTuple(args, "ssO", &name1, &name2, &newValue)) {
788 s = AsString (newValue, tmp);
789 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000790 ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
Guido van Rossum00d93061998-05-28 23:06:38 +0000791 s, flags);
792 LEAVE_TCL
793 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000794 else {
Guido van Rossum00d93061998-05-28 23:06:38 +0000795 Py_DECREF(tmp);
Guido van Rossum35d43371997-08-02 00:09:09 +0000796 return NULL;
797 }
Barry Warsawfa701a81997-01-16 00:15:11 +0000798 }
Guido van Rossum35d43371997-08-02 00:09:09 +0000799 Py_DECREF(tmp);
Guido van Rossum18468821994-06-20 07:49:28 +0000800
Barry Warsawfa701a81997-01-16 00:15:11 +0000801 if (!ok)
802 return Tkinter_Error(self);
803
804 Py_INCREF(Py_None);
805 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000806}
807
808static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000809Tkapp_SetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000810 PyObject *self;
811 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000812{
Barry Warsawfa701a81997-01-16 00:15:11 +0000813 return SetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000814}
815
816static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000817Tkapp_GlobalSetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000818 PyObject *self;
819 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000820{
Barry Warsawfa701a81997-01-16 00:15:11 +0000821 return SetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000822}
823
Barry Warsawfa701a81997-01-16 00:15:11 +0000824
825
Guido van Rossum18468821994-06-20 07:49:28 +0000826static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000827GetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000828 PyObject *self;
829 PyObject *args;
830 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000831{
Guido van Rossum35d43371997-08-02 00:09:09 +0000832 char *name1, *name2=NULL, *s;
Guido van Rossum18468821994-06-20 07:49:28 +0000833
Guido van Rossum35d43371997-08-02 00:09:09 +0000834 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
835 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000836 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000837 if (name2 == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +0000838 s = Tcl_GetVar(Tkapp_Interp (self), name1, flags);
Guido van Rossum18468821994-06-20 07:49:28 +0000839
Barry Warsawfa701a81997-01-16 00:15:11 +0000840 else
Guido van Rossum35d43371997-08-02 00:09:09 +0000841 s = Tcl_GetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum00d93061998-05-28 23:06:38 +0000842 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000843
Barry Warsawfa701a81997-01-16 00:15:11 +0000844 if (s == NULL)
845 return Tkinter_Error(self);
846
Guido van Rossum35d43371997-08-02 00:09:09 +0000847 return PyString_FromString(s);
Guido van Rossum18468821994-06-20 07:49:28 +0000848}
849
850static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000851Tkapp_GetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000852 PyObject *self;
853 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000854{
Barry Warsawfa701a81997-01-16 00:15:11 +0000855 return GetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000856}
857
858static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000859Tkapp_GlobalGetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000860 PyObject *self;
861 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000862{
Barry Warsawfa701a81997-01-16 00:15:11 +0000863 return GetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000864}
865
Barry Warsawfa701a81997-01-16 00:15:11 +0000866
867
Guido van Rossum18468821994-06-20 07:49:28 +0000868static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000869UnsetVar(self, args, flags)
Barry Warsawfa701a81997-01-16 00:15:11 +0000870 PyObject *self;
871 PyObject *args;
872 int flags;
Guido van Rossum18468821994-06-20 07:49:28 +0000873{
Guido van Rossum35d43371997-08-02 00:09:09 +0000874 char *name1, *name2=NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +0000875 int code;
Guido van Rossum18468821994-06-20 07:49:28 +0000876
Guido van Rossum35d43371997-08-02 00:09:09 +0000877 if (!PyArg_ParseTuple(args, "s|s", &name1, &name2))
Barry Warsawfa701a81997-01-16 00:15:11 +0000878 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000879 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +0000880 if (name2 == NULL)
881 code = Tcl_UnsetVar(Tkapp_Interp(self), name1, flags);
882
883 else
884 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
Guido van Rossum00d93061998-05-28 23:06:38 +0000885 LEAVE_TCL
Guido van Rossum18468821994-06-20 07:49:28 +0000886
Barry Warsawfa701a81997-01-16 00:15:11 +0000887 if (code == TCL_ERROR)
Guido van Rossum35d43371997-08-02 00:09:09 +0000888 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000889
890 Py_INCREF(Py_None);
891 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +0000892}
893
894static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000895Tkapp_UnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000896 PyObject *self;
897 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000898{
Barry Warsawfa701a81997-01-16 00:15:11 +0000899 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG);
Guido van Rossum18468821994-06-20 07:49:28 +0000900}
901
902static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000903Tkapp_GlobalUnsetVar(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000904 PyObject *self;
905 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000906{
Barry Warsawfa701a81997-01-16 00:15:11 +0000907 return UnsetVar(self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
Guido van Rossum18468821994-06-20 07:49:28 +0000908}
909
Barry Warsawfa701a81997-01-16 00:15:11 +0000910
911
Guido van Rossum18468821994-06-20 07:49:28 +0000912/** Tcl to Python **/
913
914static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000915Tkapp_GetInt(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000916 PyObject *self;
917 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000918{
Barry Warsawfa701a81997-01-16 00:15:11 +0000919 char *s;
920 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000921
Guido van Rossum35d43371997-08-02 00:09:09 +0000922 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000923 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000924 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000925 return Tkinter_Error(self);
926 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000927}
928
929static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000930Tkapp_GetDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000931 PyObject *self;
932 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000933{
Barry Warsawfa701a81997-01-16 00:15:11 +0000934 char *s;
935 double v;
Guido van Rossum18468821994-06-20 07:49:28 +0000936
Guido van Rossum35d43371997-08-02 00:09:09 +0000937 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000938 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000939 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000940 return Tkinter_Error(self);
941 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000942}
943
944static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000945Tkapp_GetBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000946 PyObject *self;
947 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000948{
Barry Warsawfa701a81997-01-16 00:15:11 +0000949 char *s;
950 int v;
Guido van Rossum18468821994-06-20 07:49:28 +0000951
Guido van Rossum35d43371997-08-02 00:09:09 +0000952 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000953 return NULL;
Guido van Rossum35d43371997-08-02 00:09:09 +0000954 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
955 return Tkinter_Error(self);
Barry Warsawfa701a81997-01-16 00:15:11 +0000956 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000957}
958
959static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000960Tkapp_ExprString(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000961 PyObject *self;
962 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000963{
Barry Warsawfa701a81997-01-16 00:15:11 +0000964 char *s;
Guido van Rossum00d93061998-05-28 23:06:38 +0000965 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +0000966
Guido van Rossum35d43371997-08-02 00:09:09 +0000967 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000968 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000969 ENTER_TCL
970 retval = Tcl_ExprString(Tkapp_Interp(self), s);
971 LEAVE_TCL
972 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000973 return Tkinter_Error(self);
974 return Py_BuildValue("s", Tkapp_Result(self));
Guido van Rossum18468821994-06-20 07:49:28 +0000975}
976
977static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000978Tkapp_ExprLong(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000979 PyObject *self;
980 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +0000981{
Barry Warsawfa701a81997-01-16 00:15:11 +0000982 char *s;
Guido van Rossum00d93061998-05-28 23:06:38 +0000983 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +0000984 long v;
Guido van Rossum18468821994-06-20 07:49:28 +0000985
Guido van Rossum35d43371997-08-02 00:09:09 +0000986 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +0000987 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +0000988 ENTER_TCL
989 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
990 LEAVE_TCL
991 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +0000992 return Tkinter_Error(self);
993 return Py_BuildValue("l", v);
Guido van Rossum18468821994-06-20 07:49:28 +0000994}
995
996static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +0000997Tkapp_ExprDouble(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +0000998 PyObject *self;
999 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001000{
Barry Warsawfa701a81997-01-16 00:15:11 +00001001 char *s;
1002 double v;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001003 int retval;
Guido van Rossum18468821994-06-20 07:49:28 +00001004
Guido van Rossum35d43371997-08-02 00:09:09 +00001005 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001006 return NULL;
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001007 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
Guido van Rossum00d93061998-05-28 23:06:38 +00001008 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001009 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
Guido van Rossum00d93061998-05-28 23:06:38 +00001010 LEAVE_TCL
Guido van Rossum45b83911997-03-14 04:32:50 +00001011 PyFPE_END_PROTECT(retval)
Guido van Rossum52fa3a61997-02-14 22:59:58 +00001012 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001013 return Tkinter_Error(self);
1014 return Py_BuildValue("d", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001015}
1016
1017static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001018Tkapp_ExprBoolean(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001019 PyObject *self;
1020 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001021{
Barry Warsawfa701a81997-01-16 00:15:11 +00001022 char *s;
Guido van Rossum00d93061998-05-28 23:06:38 +00001023 int retval;
Barry Warsawfa701a81997-01-16 00:15:11 +00001024 int v;
Guido van Rossum18468821994-06-20 07:49:28 +00001025
Guido van Rossum35d43371997-08-02 00:09:09 +00001026 if (!PyArg_ParseTuple(args, "s", &s))
Barry Warsawfa701a81997-01-16 00:15:11 +00001027 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001028 ENTER_TCL
1029 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
1030 LEAVE_TCL
1031 if (retval == TCL_ERROR)
Barry Warsawfa701a81997-01-16 00:15:11 +00001032 return Tkinter_Error(self);
1033 return Py_BuildValue("i", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001034}
1035
Barry Warsawfa701a81997-01-16 00:15:11 +00001036
1037
Guido van Rossum18468821994-06-20 07:49:28 +00001038static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001039Tkapp_SplitList(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001040 PyObject *self;
1041 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001042{
Barry Warsawfa701a81997-01-16 00:15:11 +00001043 char *list;
1044 int argc;
1045 char **argv;
1046 PyObject *v;
1047 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001048
Guido van Rossum35d43371997-08-02 00:09:09 +00001049 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001050 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001051
Barry Warsawfa701a81997-01-16 00:15:11 +00001052 if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR)
1053 return Tkinter_Error(self);
Guido van Rossum18468821994-06-20 07:49:28 +00001054
Barry Warsawfa701a81997-01-16 00:15:11 +00001055 if (!(v = PyTuple_New(argc)))
1056 return NULL;
1057
1058 for (i = 0; i < argc; i++) {
1059 PyObject *s = PyString_FromString(argv[i]);
1060 if (!s || PyTuple_SetItem(v, i, s)) {
1061 Py_DECREF(v);
1062 v = NULL;
1063 goto finally;
1064 }
1065 }
Guido van Rossum18468821994-06-20 07:49:28 +00001066
Barry Warsawfa701a81997-01-16 00:15:11 +00001067 finally:
1068 ckfree(FREECAST argv);
1069 return v;
Guido van Rossum18468821994-06-20 07:49:28 +00001070}
1071
1072static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001073Tkapp_Split(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001074 PyObject *self;
1075 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001076{
Barry Warsawfa701a81997-01-16 00:15:11 +00001077 char *list;
Guido van Rossum18468821994-06-20 07:49:28 +00001078
Guido van Rossum35d43371997-08-02 00:09:09 +00001079 if (!PyArg_ParseTuple(args, "s", &list))
Barry Warsawfa701a81997-01-16 00:15:11 +00001080 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001081 return Split(list);
Guido van Rossum18468821994-06-20 07:49:28 +00001082}
1083
1084static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001085Tkapp_Merge(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001086 PyObject *self;
1087 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001088{
Barry Warsawfa701a81997-01-16 00:15:11 +00001089 char *s = Merge(args);
1090 PyObject *res = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001091
Barry Warsawfa701a81997-01-16 00:15:11 +00001092 if (s) {
1093 res = PyString_FromString(s);
1094 ckfree(s);
1095 }
1096 else
1097 PyErr_SetString(Tkinter_TclError, "merge failed");
1098
1099 return res;
Guido van Rossum18468821994-06-20 07:49:28 +00001100}
1101
Barry Warsawfa701a81997-01-16 00:15:11 +00001102
1103
Guido van Rossum18468821994-06-20 07:49:28 +00001104/** Tcl Command **/
1105
Guido van Rossum00d93061998-05-28 23:06:38 +00001106/* Client data struct */
1107typedef struct {
1108 PyThreadState *tstate;
1109 PyObject *self;
1110 PyObject *func;
1111} PythonCmd_ClientData;
1112
1113static int
1114PythonCmd_Error(interp)
1115 Tcl_Interp *interp;
1116{
1117 errorInCmd = 1;
1118 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1119 LEAVE_PYTHON
1120 return TCL_ERROR;
1121}
1122
Guido van Rossum18468821994-06-20 07:49:28 +00001123/* This is the Tcl command that acts as a wrapper for Python
Barry Warsawfa701a81997-01-16 00:15:11 +00001124 * function or method.
1125 */
Guido van Rossum18468821994-06-20 07:49:28 +00001126static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001127PythonCmd(clientData, interp, argc, argv)
Guido van Rossum00d93061998-05-28 23:06:38 +00001128 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001129 Tcl_Interp *interp;
1130 int argc;
1131 char *argv[];
Guido van Rossum18468821994-06-20 07:49:28 +00001132{
Guido van Rossum00d93061998-05-28 23:06:38 +00001133 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001134 PyObject *self, *func, *arg, *res, *tmp;
1135 int i;
Guido van Rossum18468821994-06-20 07:49:28 +00001136
Guido van Rossum00d93061998-05-28 23:06:38 +00001137 /* XXX Should create fresh thread state? */
1138 ENTER_PYTHON(data->tstate)
1139
Barry Warsawfa701a81997-01-16 00:15:11 +00001140 /* TBD: no error checking here since we know, via the
1141 * Tkapp_CreateCommand() that the client data is a two-tuple
1142 */
Guido van Rossum00d93061998-05-28 23:06:38 +00001143 self = data->self;
1144 func = data->func;
Guido van Rossum18468821994-06-20 07:49:28 +00001145
Barry Warsawfa701a81997-01-16 00:15:11 +00001146 /* Create argument list (argv1, ..., argvN) */
1147 if (!(arg = PyTuple_New(argc - 1)))
1148 return PythonCmd_Error(interp);
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001149
Barry Warsawfa701a81997-01-16 00:15:11 +00001150 for (i = 0; i < (argc - 1); i++) {
1151 PyObject *s = PyString_FromString(argv[i + 1]);
1152 if (!s || PyTuple_SetItem(arg, i, s)) {
1153 Py_DECREF(arg);
1154 PythonCmd_Error(interp);
1155 }
1156 }
1157 res = PyEval_CallObject(func, arg);
1158 Py_DECREF(arg);
Guido van Rossum18468821994-06-20 07:49:28 +00001159
Barry Warsawfa701a81997-01-16 00:15:11 +00001160 if (res == NULL)
1161 return PythonCmd_Error(interp);
Guido van Rossum18468821994-06-20 07:49:28 +00001162
Barry Warsawfa701a81997-01-16 00:15:11 +00001163 if (!(tmp = PyList_New(0))) {
1164 Py_DECREF(res);
1165 return PythonCmd_Error(interp);
1166 }
1167
1168 Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
1169 Py_DECREF(res);
1170 Py_DECREF(tmp);
1171
Guido van Rossum00d93061998-05-28 23:06:38 +00001172 LEAVE_PYTHON
1173
Barry Warsawfa701a81997-01-16 00:15:11 +00001174 return TCL_OK;
Guido van Rossum18468821994-06-20 07:49:28 +00001175}
1176
1177static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001178PythonCmdDelete(clientData)
Guido van Rossum00d93061998-05-28 23:06:38 +00001179 ClientData clientData;
Guido van Rossum18468821994-06-20 07:49:28 +00001180{
Guido van Rossum00d93061998-05-28 23:06:38 +00001181 PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
1182
1183 ENTER_PYTHON(data->tstate)
1184 Py_XDECREF(data->self);
1185 Py_XDECREF(data->func);
1186 PyMem_DEL(data);
1187 LEAVE_PYTHON
Guido van Rossum18468821994-06-20 07:49:28 +00001188}
1189
Barry Warsawfa701a81997-01-16 00:15:11 +00001190
1191
Guido van Rossum18468821994-06-20 07:49:28 +00001192static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001193Tkapp_CreateCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001194 PyObject *self;
1195 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001196{
Guido van Rossum00d93061998-05-28 23:06:38 +00001197 PythonCmd_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001198 char *cmdName;
Barry Warsawfa701a81997-01-16 00:15:11 +00001199 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001200 Tcl_Command err;
Guido van Rossum35d43371997-08-02 00:09:09 +00001201
1202 if (!PyArg_ParseTuple(args, "sO", &cmdName, &func))
1203 return NULL;
1204 if (!PyCallable_Check(func)) {
1205 PyErr_SetString(PyExc_TypeError, "command not callable");
Barry Warsawfa701a81997-01-16 00:15:11 +00001206 return NULL;
1207 }
Guido van Rossum18468821994-06-20 07:49:28 +00001208
Guido van Rossum00d93061998-05-28 23:06:38 +00001209 data = PyMem_NEW(PythonCmd_ClientData, 1);
Barry Warsawfa701a81997-01-16 00:15:11 +00001210 if (!data)
1211 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001212 data->tstate = PyThreadState_Get();
1213 Py_XINCREF(self);
1214 Py_XINCREF(func);
1215 data->self = self;
1216 data->func = func;
Guido van Rossum18468821994-06-20 07:49:28 +00001217
Guido van Rossum00d93061998-05-28 23:06:38 +00001218 ENTER_TCL
1219 err = Tcl_CreateCommand(Tkapp_Interp(self), cmdName, PythonCmd,
1220 (ClientData)data, PythonCmdDelete);
1221 LEAVE_TCL
1222 if (err == NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001223 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
Guido van Rossum00d93061998-05-28 23:06:38 +00001224 PyMem_DEL(data);
Guido van Rossum35d43371997-08-02 00:09:09 +00001225 return NULL;
1226 }
Guido van Rossum18468821994-06-20 07:49:28 +00001227
Barry Warsawfa701a81997-01-16 00:15:11 +00001228 Py_INCREF(Py_None);
1229 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001230}
1231
Barry Warsawfa701a81997-01-16 00:15:11 +00001232
1233
Guido van Rossum18468821994-06-20 07:49:28 +00001234static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001235Tkapp_DeleteCommand(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001236 PyObject *self;
1237 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001238{
Barry Warsawfa701a81997-01-16 00:15:11 +00001239 char *cmdName;
Guido van Rossum00d93061998-05-28 23:06:38 +00001240 int err;
Guido van Rossum18468821994-06-20 07:49:28 +00001241
Guido van Rossum35d43371997-08-02 00:09:09 +00001242 if (!PyArg_ParseTuple(args, "s", &cmdName))
Barry Warsawfa701a81997-01-16 00:15:11 +00001243 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001244 ENTER_TCL
1245 err = Tcl_DeleteCommand(Tkapp_Interp(self), cmdName);
1246 LEAVE_TCL
1247 if (err == -1) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001248 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
1249 return NULL;
1250 }
1251 Py_INCREF(Py_None);
1252 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001253}
1254
Barry Warsawfa701a81997-01-16 00:15:11 +00001255
1256
Guido van Rossum00d93061998-05-28 23:06:38 +00001257#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum18468821994-06-20 07:49:28 +00001258/** File Handler **/
1259
Guido van Rossum00d93061998-05-28 23:06:38 +00001260typedef struct _fhcdata {
1261 PyThreadState *tstate;
1262 PyObject *func;
1263 PyObject *file;
1264 int id;
1265 struct _fhcdata *next;
1266} FileHandler_ClientData;
1267
1268static FileHandler_ClientData *HeadFHCD;
1269
1270static FileHandler_ClientData *
1271NewFHCD(func, file, id)
1272 PyObject *func;
1273 PyObject *file;
1274 int id;
1275{
1276 FileHandler_ClientData *p;
1277 p = PyMem_NEW(FileHandler_ClientData, 1);
1278 if (p != NULL) {
1279 Py_XINCREF(func);
1280 Py_XINCREF(file);
1281 p->tstate = PyThreadState_Get();
1282 p->func = func;
1283 p->file = file;
1284 p->id = id;
1285 p->next = HeadFHCD;
1286 HeadFHCD = p;
1287 }
1288 return p;
1289}
1290
1291static void
1292DeleteFHCD(id)
1293 int id;
1294{
1295 FileHandler_ClientData *p, **pp;
1296
1297 pp = &HeadFHCD;
1298 while ((p = *pp) != NULL) {
1299 if (p->id == id) {
1300 *pp = p->next;
1301 Py_XDECREF(p->func);
1302 Py_XDECREF(p->file);
1303 PyMem_DEL(p);
1304 }
1305 else
1306 pp = &p->next;
1307 }
1308}
1309
Guido van Rossuma597dde1995-01-10 20:56:29 +00001310static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001311FileHandler(clientData, mask)
Guido van Rossum00d93061998-05-28 23:06:38 +00001312 ClientData clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001313 int mask;
Guido van Rossum18468821994-06-20 07:49:28 +00001314{
Guido van Rossum00d93061998-05-28 23:06:38 +00001315 FileHandler_ClientData *data = (FileHandler_ClientData *)clientData;
Barry Warsawfa701a81997-01-16 00:15:11 +00001316 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +00001317
Guido van Rossum00d93061998-05-28 23:06:38 +00001318 /* XXX Should create fresh thread state? */
1319 ENTER_PYTHON(data->tstate)
1320 func = data->func;
1321 file = data->file;
Guido van Rossum18468821994-06-20 07:49:28 +00001322
Barry Warsawfa701a81997-01-16 00:15:11 +00001323 arg = Py_BuildValue("(Oi)", file, (long) mask);
1324 res = PyEval_CallObject(func, arg);
Guido van Rossum35d43371997-08-02 00:09:09 +00001325 Py_DECREF(arg);
Barry Warsawfa701a81997-01-16 00:15:11 +00001326
1327 if (res == NULL) {
1328 errorInCmd = 1;
1329 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1330 }
1331 Py_XDECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001332 LEAVE_PYTHON
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001333}
1334
1335static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001336GetFileNo(file)
Barry Warsawfa701a81997-01-16 00:15:11 +00001337 /* Either an int >= 0 or an object with a
1338 *.fileno() method that returns an int >= 0
1339 */
1340 PyObject *file;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001341{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001342 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001343 int id;
1344 if (PyInt_Check(file)) {
1345 id = PyInt_AsLong(file);
1346 if (id < 0)
1347 PyErr_SetString(PyExc_ValueError, "invalid file id");
1348 return id;
1349 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001350 args = PyTuple_New(0);
1351 if (args == NULL)
1352 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001353
1354 meth = PyObject_GetAttrString(file, "fileno");
1355 if (meth == NULL) {
1356 Py_DECREF(args);
1357 return -1;
1358 }
1359
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001360 res = PyEval_CallObject(meth, args);
1361 Py_DECREF(args);
1362 Py_DECREF(meth);
1363 if (res == NULL)
1364 return -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001365
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001366 if (PyInt_Check(res))
1367 id = PyInt_AsLong(res);
1368 else
1369 id = -1;
Barry Warsawfa701a81997-01-16 00:15:11 +00001370
Guido van Rossum9bb4fd61994-08-09 14:15:19 +00001371 if (id < 0)
1372 PyErr_SetString(PyExc_ValueError,
1373 "invalid fileno() return value");
1374 Py_DECREF(res);
1375 return id;
Guido van Rossum18468821994-06-20 07:49:28 +00001376}
1377
1378static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001379Tkapp_CreateFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001380 PyObject *self;
1381 PyObject *args; /* Is (file, mask, func) */
Guido van Rossum18468821994-06-20 07:49:28 +00001382{
Guido van Rossum00d93061998-05-28 23:06:38 +00001383 FileHandler_ClientData *data;
1384 PyObject *file, *func;
Barry Warsawfa701a81997-01-16 00:15:11 +00001385 int mask, id;
Guido van Rossum7bf15641998-05-22 18:28:17 +00001386 FHANDLE tfile;
Guido van Rossum18468821994-06-20 07:49:28 +00001387
Guido van Rossum35d43371997-08-02 00:09:09 +00001388 if (!PyArg_ParseTuple(args, "OiO", &file, &mask, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001389 return NULL;
1390 id = GetFileNo(file);
1391 if (id < 0)
1392 return NULL;
1393 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001394 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001395 return NULL;
1396 }
1397
Guido van Rossum00d93061998-05-28 23:06:38 +00001398 data = NewFHCD(func, file, id);
1399 if (data == NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001400 return NULL;
1401
Guido van Rossum7bf15641998-05-22 18:28:17 +00001402 tfile = MAKEFHANDLE(id);
Barry Warsawfa701a81997-01-16 00:15:11 +00001403 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001404 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001405 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
Guido van Rossum00d93061998-05-28 23:06:38 +00001406 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001407 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001408 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001409}
1410
1411static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001412Tkapp_DeleteFileHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001413 PyObject *self;
1414 PyObject *args; /* Args: file */
Guido van Rossum18468821994-06-20 07:49:28 +00001415{
Barry Warsawfa701a81997-01-16 00:15:11 +00001416 PyObject *file;
Guido van Rossum00d93061998-05-28 23:06:38 +00001417 FileHandler_ClientData *data;
Barry Warsawfa701a81997-01-16 00:15:11 +00001418 int id;
Guido van Rossum7bf15641998-05-22 18:28:17 +00001419 FHANDLE tfile;
Guido van Rossum68784361996-05-16 17:17:31 +00001420
Guido van Rossum35d43371997-08-02 00:09:09 +00001421 if (!PyArg_ParseTuple(args, "O", &file))
Barry Warsawfa701a81997-01-16 00:15:11 +00001422 return NULL;
1423 id = GetFileNo(file);
1424 if (id < 0)
1425 return NULL;
1426
Guido van Rossum00d93061998-05-28 23:06:38 +00001427 DeleteFHCD(id);
Guido van Rossum18468821994-06-20 07:49:28 +00001428
Guido van Rossum7bf15641998-05-22 18:28:17 +00001429 tfile = MAKEFHANDLE(id);
Barry Warsawfa701a81997-01-16 00:15:11 +00001430 /* Ought to check for null Tcl_File object... */
Guido van Rossum00d93061998-05-28 23:06:38 +00001431 ENTER_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001432 Tcl_DeleteFileHandler(tfile);
Guido van Rossum00d93061998-05-28 23:06:38 +00001433 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001434 Py_INCREF(Py_None);
Barry Warsawfa701a81997-01-16 00:15:11 +00001435 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001436}
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001437#endif /* HAVE_CREATEFILEHANDLER */
Guido van Rossum18468821994-06-20 07:49:28 +00001438
Barry Warsawfa701a81997-01-16 00:15:11 +00001439
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001440/**** Tktt Object (timer token) ****/
1441
1442staticforward PyTypeObject Tktt_Type;
1443
Guido van Rossum00d93061998-05-28 23:06:38 +00001444typedef struct {
Barry Warsawfa701a81997-01-16 00:15:11 +00001445 PyObject_HEAD
Guido van Rossum35d43371997-08-02 00:09:09 +00001446 Tcl_TimerToken token;
Barry Warsawfa701a81997-01-16 00:15:11 +00001447 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001448 PyThreadState *tstate;
1449} TkttObject;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001450
1451static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001452Tktt_DeleteTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001453 PyObject *self;
1454 PyObject *args;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001455{
Barry Warsawfa701a81997-01-16 00:15:11 +00001456 TkttObject *v = (TkttObject *)self;
Guido van Rossum00d93061998-05-28 23:06:38 +00001457 PyObject *func = v->func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001458
Guido van Rossum35d43371997-08-02 00:09:09 +00001459 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001460 return NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001461 if (v->token != NULL) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001462 Tcl_DeleteTimerHandler(v->token);
Guido van Rossum00d93061998-05-28 23:06:38 +00001463 v->token = NULL;
1464 }
1465 if (func != NULL) {
Barry Warsawfa701a81997-01-16 00:15:11 +00001466 v->func = NULL;
Guido van Rossum00d93061998-05-28 23:06:38 +00001467 Py_DECREF(func);
1468 Py_DECREF(v); /* See Tktt_New() */
Barry Warsawfa701a81997-01-16 00:15:11 +00001469 }
1470 Py_INCREF(Py_None);
1471 return Py_None;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001472}
1473
1474static PyMethodDef Tktt_methods[] =
1475{
Guido van Rossum35d43371997-08-02 00:09:09 +00001476 {"deletetimerhandler", Tktt_DeleteTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001477 {NULL, NULL}
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001478};
1479
1480static TkttObject *
Guido van Rossum00d93061998-05-28 23:06:38 +00001481Tktt_New(func)
Barry Warsawfa701a81997-01-16 00:15:11 +00001482 PyObject *func;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001483{
Barry Warsawfa701a81997-01-16 00:15:11 +00001484 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001485
Barry Warsawfa701a81997-01-16 00:15:11 +00001486 v = PyObject_NEW(TkttObject, &Tktt_Type);
1487 if (v == NULL)
1488 return NULL;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001489
Guido van Rossum00d93061998-05-28 23:06:38 +00001490 Py_INCREF(func);
1491 v->token = NULL;
Barry Warsawfa701a81997-01-16 00:15:11 +00001492 v->func = func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001493 v->tstate = PyThreadState_Get();
1494
1495 /* Extra reference, deleted when called or when handler is deleted */
1496 Py_INCREF(v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001497 return v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001498}
1499
1500static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001501Tktt_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001502 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001503{
Guido van Rossum00d93061998-05-28 23:06:38 +00001504 TkttObject *v = (TkttObject *)self;
1505 PyObject *func = v->func;
1506
1507 Py_XDECREF(func);
1508
Guido van Rossum35d43371997-08-02 00:09:09 +00001509 PyMem_DEL(self);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001510}
1511
Guido van Rossum597ac201998-05-12 14:36:19 +00001512static PyObject *
1513Tktt_Repr(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001514 PyObject *self;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001515{
Barry Warsawfa701a81997-01-16 00:15:11 +00001516 TkttObject *v = (TkttObject *)self;
Guido van Rossum597ac201998-05-12 14:36:19 +00001517 char buf[100];
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001518
Guido van Rossum597ac201998-05-12 14:36:19 +00001519 sprintf(buf, "<tktimertoken at 0x%lx%s>", (long)v,
Barry Warsawfa701a81997-01-16 00:15:11 +00001520 v->func == NULL ? ", handler deleted" : "");
Guido van Rossum597ac201998-05-12 14:36:19 +00001521 return PyString_FromString(buf);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001522}
1523
1524static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001525Tktt_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001526 PyObject *self;
1527 char *name;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001528{
Barry Warsawfa701a81997-01-16 00:15:11 +00001529 return Py_FindMethod(Tktt_methods, self, name);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001530}
1531
1532static PyTypeObject Tktt_Type =
1533{
Guido van Rossum35d43371997-08-02 00:09:09 +00001534 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001535 0, /*ob_size */
1536 "tktimertoken", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001537 sizeof(TkttObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001538 0, /*tp_itemsize */
1539 Tktt_Dealloc, /*tp_dealloc */
Guido van Rossum597ac201998-05-12 14:36:19 +00001540 0, /*tp_print */
Barry Warsawfa701a81997-01-16 00:15:11 +00001541 Tktt_GetAttr, /*tp_getattr */
1542 0, /*tp_setattr */
1543 0, /*tp_compare */
Guido van Rossum597ac201998-05-12 14:36:19 +00001544 Tktt_Repr, /*tp_repr */
Barry Warsawfa701a81997-01-16 00:15:11 +00001545 0, /*tp_as_number */
1546 0, /*tp_as_sequence */
1547 0, /*tp_as_mapping */
1548 0, /*tp_hash */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001549};
1550
Barry Warsawfa701a81997-01-16 00:15:11 +00001551
1552
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001553/** Timer Handler **/
1554
1555static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001556TimerHandler(clientData)
Barry Warsawfa701a81997-01-16 00:15:11 +00001557 ClientData clientData;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001558{
Guido van Rossum00d93061998-05-28 23:06:38 +00001559 TkttObject *v = (TkttObject *)clientData;
1560 PyObject *func = v->func;
1561 PyObject *res;
1562
1563 if (func == NULL)
1564 return;
1565
1566 v->func = NULL;
1567
1568 ENTER_PYTHON(v->tstate)
1569
1570 res = PyEval_CallObject(func, NULL);
1571 Py_DECREF(func);
1572 Py_DECREF(v); /* See Tktt_New() */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001573
Barry Warsawfa701a81997-01-16 00:15:11 +00001574 if (res == NULL) {
1575 errorInCmd = 1;
1576 PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd);
1577 }
1578 else
1579 Py_DECREF(res);
Guido van Rossum00d93061998-05-28 23:06:38 +00001580
1581 LEAVE_PYTHON
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001582}
1583
1584static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001585Tkapp_CreateTimerHandler(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001586 PyObject *self;
1587 PyObject *args; /* Is (milliseconds, func) */
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001588{
Barry Warsawfa701a81997-01-16 00:15:11 +00001589 int milliseconds;
1590 PyObject *func;
Guido van Rossum00d93061998-05-28 23:06:38 +00001591 TkttObject *v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001592
Guido van Rossum35d43371997-08-02 00:09:09 +00001593 if (!PyArg_ParseTuple(args, "iO", &milliseconds, &func))
Barry Warsawfa701a81997-01-16 00:15:11 +00001594 return NULL;
1595 if (!PyCallable_Check(func)) {
Guido van Rossum35d43371997-08-02 00:09:09 +00001596 PyErr_SetString(PyExc_TypeError, "bad argument list");
Barry Warsawfa701a81997-01-16 00:15:11 +00001597 return NULL;
1598 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001599 v = Tktt_New(func);
1600 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
1601 (ClientData)v);
Barry Warsawfa701a81997-01-16 00:15:11 +00001602
Guido van Rossum00d93061998-05-28 23:06:38 +00001603 return (PyObject *) v;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001604}
1605
Barry Warsawfa701a81997-01-16 00:15:11 +00001606
Guido van Rossum18468821994-06-20 07:49:28 +00001607/** Event Loop **/
1608
Guido van Rossum18468821994-06-20 07:49:28 +00001609static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001610Tkapp_MainLoop(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001611 PyObject *self;
1612 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001613{
Barry Warsawfa701a81997-01-16 00:15:11 +00001614 int threshold = 0;
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001615
Barry Warsawfa701a81997-01-16 00:15:11 +00001616 if (!PyArg_ParseTuple(args, "|i", &threshold))
1617 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001618
Barry Warsawfa701a81997-01-16 00:15:11 +00001619 quitMainLoop = 0;
1620 while (Tk_GetNumMainWindows() > threshold &&
1621 !quitMainLoop &&
1622 !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001623 {
Guido van Rossum35d43371997-08-02 00:09:09 +00001624 int result;
Guido van Rossum00d93061998-05-28 23:06:38 +00001625
1626#ifdef WITH_THREAD
1627 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001628 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
Guido van Rossum00d93061998-05-28 23:06:38 +00001629 release_lock(tcl_lock);
1630 if (result == 0)
1631 Sleep(20);
Guido van Rossum35d43371997-08-02 00:09:09 +00001632 Py_END_ALLOW_THREADS
Guido van Rossum5b020781997-08-19 01:00:50 +00001633#else
1634 result = Tcl_DoOneEvent(0);
1635#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001636
Guido van Rossum35d43371997-08-02 00:09:09 +00001637 if (PyErr_CheckSignals() != 0)
1638 return NULL;
1639 if (result < 0)
1640 break;
Guido van Rossum18468821994-06-20 07:49:28 +00001641 }
Barry Warsawfa701a81997-01-16 00:15:11 +00001642 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001643
Barry Warsawfa701a81997-01-16 00:15:11 +00001644 if (errorInCmd) {
1645 errorInCmd = 0;
1646 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1647 excInCmd = valInCmd = trbInCmd = NULL;
1648 return NULL;
1649 }
1650 Py_INCREF(Py_None);
1651 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001652}
1653
1654static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001655Tkapp_DoOneEvent(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001656 PyObject *self;
1657 PyObject *args;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001658{
Guido van Rossum35d43371997-08-02 00:09:09 +00001659 int flags = 0;
Barry Warsawfa701a81997-01-16 00:15:11 +00001660 int rv;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001661
Barry Warsawfa701a81997-01-16 00:15:11 +00001662 if (!PyArg_ParseTuple(args, "|i", &flags))
1663 return NULL;
1664
Guido van Rossum00d93061998-05-28 23:06:38 +00001665 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001666 rv = Tcl_DoOneEvent(flags);
Guido van Rossum00d93061998-05-28 23:06:38 +00001667 LEAVE_TCL
Barry Warsawfa701a81997-01-16 00:15:11 +00001668 return Py_BuildValue("i", rv);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001669}
1670
1671static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001672Tkapp_Quit(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001673 PyObject *self;
1674 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001675{
1676
Guido van Rossum35d43371997-08-02 00:09:09 +00001677 if (!PyArg_ParseTuple(args, ""))
Barry Warsawfa701a81997-01-16 00:15:11 +00001678 return NULL;
1679
1680 quitMainLoop = 1;
1681 Py_INCREF(Py_None);
1682 return Py_None;
Guido van Rossum18468821994-06-20 07:49:28 +00001683}
1684
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001685static PyObject *
1686Tkapp_InterpAddr(self, args)
1687 PyObject *self;
1688 PyObject *args;
1689{
1690
1691 if (!PyArg_ParseTuple(args, ""))
1692 return NULL;
1693
1694 return PyInt_FromLong((long)Tkapp_Interp(self));
1695}
1696
Barry Warsawfa701a81997-01-16 00:15:11 +00001697
1698
Guido van Rossum18468821994-06-20 07:49:28 +00001699/**** Tkapp Method List ****/
1700
1701static PyMethodDef Tkapp_methods[] =
1702{
Guido van Rossum35d43371997-08-02 00:09:09 +00001703 {"call", Tkapp_Call, 0},
1704 {"globalcall", Tkapp_GlobalCall, 0},
1705 {"eval", Tkapp_Eval, 1},
1706 {"globaleval", Tkapp_GlobalEval, 1},
1707 {"evalfile", Tkapp_EvalFile, 1},
1708 {"record", Tkapp_Record, 1},
1709 {"adderrorinfo", Tkapp_AddErrorInfo, 1},
1710 {"setvar", Tkapp_SetVar, 1},
1711 {"globalsetvar", Tkapp_GlobalSetVar, 1},
1712 {"getvar", Tkapp_GetVar, 1},
1713 {"globalgetvar", Tkapp_GlobalGetVar, 1},
1714 {"unsetvar", Tkapp_UnsetVar, 1},
1715 {"globalunsetvar", Tkapp_GlobalUnsetVar, 1},
1716 {"getint", Tkapp_GetInt, 1},
1717 {"getdouble", Tkapp_GetDouble, 1},
1718 {"getboolean", Tkapp_GetBoolean, 1},
1719 {"exprstring", Tkapp_ExprString, 1},
1720 {"exprlong", Tkapp_ExprLong, 1},
1721 {"exprdouble", Tkapp_ExprDouble, 1},
1722 {"exprboolean", Tkapp_ExprBoolean, 1},
1723 {"splitlist", Tkapp_SplitList, 1},
1724 {"split", Tkapp_Split, 1},
1725 {"merge", Tkapp_Merge, 0},
1726 {"createcommand", Tkapp_CreateCommand, 1},
1727 {"deletecommand", Tkapp_DeleteCommand, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001728#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001729 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1730 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001731#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001732 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001733 {"mainloop", Tkapp_MainLoop, 1},
1734 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001735 {"quit", Tkapp_Quit, 1},
Guido van Rossum9d1b7ae1998-04-29 16:17:01 +00001736 {"interpaddr", Tkapp_InterpAddr, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001737 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001738};
1739
Barry Warsawfa701a81997-01-16 00:15:11 +00001740
1741
Guido van Rossum18468821994-06-20 07:49:28 +00001742/**** Tkapp Type Methods ****/
1743
1744static void
Guido van Rossum35d43371997-08-02 00:09:09 +00001745Tkapp_Dealloc(self)
Barry Warsawfa701a81997-01-16 00:15:11 +00001746 PyObject *self;
Guido van Rossum18468821994-06-20 07:49:28 +00001747{
Guido van Rossum00d93061998-05-28 23:06:38 +00001748 ENTER_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001749 Tcl_DeleteInterp(Tkapp_Interp(self));
Guido van Rossum00d93061998-05-28 23:06:38 +00001750 LEAVE_TCL
Guido van Rossum35d43371997-08-02 00:09:09 +00001751 PyMem_DEL(self);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001752 DisableEventHook();
Guido van Rossum18468821994-06-20 07:49:28 +00001753}
1754
1755static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001756Tkapp_GetAttr(self, name)
Barry Warsawfa701a81997-01-16 00:15:11 +00001757 PyObject *self;
1758 char *name;
Guido van Rossum18468821994-06-20 07:49:28 +00001759{
Guido van Rossum35d43371997-08-02 00:09:09 +00001760 return Py_FindMethod(Tkapp_methods, self, name);
Guido van Rossum18468821994-06-20 07:49:28 +00001761}
1762
1763static PyTypeObject Tkapp_Type =
1764{
Guido van Rossum35d43371997-08-02 00:09:09 +00001765 PyObject_HEAD_INIT(NULL)
Barry Warsawfa701a81997-01-16 00:15:11 +00001766 0, /*ob_size */
1767 "tkapp", /*tp_name */
Guido van Rossum35d43371997-08-02 00:09:09 +00001768 sizeof(TkappObject), /*tp_basicsize */
Barry Warsawfa701a81997-01-16 00:15:11 +00001769 0, /*tp_itemsize */
1770 Tkapp_Dealloc, /*tp_dealloc */
1771 0, /*tp_print */
1772 Tkapp_GetAttr, /*tp_getattr */
1773 0, /*tp_setattr */
1774 0, /*tp_compare */
1775 0, /*tp_repr */
1776 0, /*tp_as_number */
1777 0, /*tp_as_sequence */
1778 0, /*tp_as_mapping */
1779 0, /*tp_hash */
Guido van Rossum18468821994-06-20 07:49:28 +00001780};
1781
Barry Warsawfa701a81997-01-16 00:15:11 +00001782
1783
Guido van Rossum18468821994-06-20 07:49:28 +00001784/**** Tkinter Module ****/
1785
1786static PyObject *
Guido van Rossum35d43371997-08-02 00:09:09 +00001787Tkinter_Create(self, args)
Barry Warsawfa701a81997-01-16 00:15:11 +00001788 PyObject *self;
1789 PyObject *args;
Guido van Rossum18468821994-06-20 07:49:28 +00001790{
Barry Warsawfa701a81997-01-16 00:15:11 +00001791 char *screenName = NULL;
1792 char *baseName = NULL;
1793 char *className = NULL;
1794 int interactive = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001795
Guido van Rossum35d43371997-08-02 00:09:09 +00001796 baseName = strrchr(Py_GetProgramName(), '/');
Barry Warsawfa701a81997-01-16 00:15:11 +00001797 if (baseName != NULL)
1798 baseName++;
1799 else
1800 baseName = Py_GetProgramName();
1801 className = "Tk";
Guido van Rossum18468821994-06-20 07:49:28 +00001802
Barry Warsawfa701a81997-01-16 00:15:11 +00001803 if (!PyArg_ParseTuple(args, "|zssi",
1804 &screenName, &baseName, &className,
1805 &interactive))
1806 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001807
Barry Warsawfa701a81997-01-16 00:15:11 +00001808 return (PyObject *) Tkapp_New(screenName, baseName, className,
1809 interactive);
Guido van Rossum18468821994-06-20 07:49:28 +00001810}
1811
1812static PyMethodDef moduleMethods[] =
1813{
Barry Warsawfa701a81997-01-16 00:15:11 +00001814 {"create", Tkinter_Create, 1},
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001815#ifdef HAVE_CREATEFILEHANDLER
Guido van Rossum35d43371997-08-02 00:09:09 +00001816 {"createfilehandler", Tkapp_CreateFileHandler, 1},
1817 {"deletefilehandler", Tkapp_DeleteFileHandler, 1},
Guido van Rossum02c04671997-08-07 00:12:22 +00001818#endif
Guido van Rossum35d43371997-08-02 00:09:09 +00001819 {"createtimerhandler", Tkapp_CreateTimerHandler, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001820 {"mainloop", Tkapp_MainLoop, 1},
1821 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum35d43371997-08-02 00:09:09 +00001822 {"quit", Tkapp_Quit, 1},
Barry Warsawfa701a81997-01-16 00:15:11 +00001823 {NULL, NULL}
Guido van Rossum18468821994-06-20 07:49:28 +00001824};
1825
Guido van Rossum7bf15641998-05-22 18:28:17 +00001826#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001827
1828static int stdin_ready = 0;
1829
Guido van Rossumad4db171998-06-13 13:56:28 +00001830#ifndef MS_WINDOWS
Guido van Rossum7bf15641998-05-22 18:28:17 +00001831static void
1832MyFileProc(clientData, mask)
1833 void *clientData;
1834 int mask;
1835{
1836 stdin_ready = 1;
1837}
Guido van Rossumad4db171998-06-13 13:56:28 +00001838#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001839
Guido van Rossum00d93061998-05-28 23:06:38 +00001840static PyThreadState *event_tstate = NULL;
Guido van Rossum0e8457c1997-10-07 18:51:41 +00001841
Guido van Rossum18468821994-06-20 07:49:28 +00001842static int
Guido van Rossum35d43371997-08-02 00:09:09 +00001843EventHook()
Guido van Rossum18468821994-06-20 07:49:28 +00001844{
Guido van Rossumad4db171998-06-13 13:56:28 +00001845#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00001846 FHANDLE tfile;
Guido van Rossumad4db171998-06-13 13:56:28 +00001847#endif
1848 if (PyThreadState_Swap(NULL) != NULL)
1849 Py_FatalError("EventHook with non-NULL tstate\n");
1850 PyEval_RestoreThread(event_tstate);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001851 stdin_ready = 0;
Guido van Rossumad4db171998-06-13 13:56:28 +00001852 errorInCmd = 0;
1853#ifndef MS_WINDOWS
1854 tfile = MAKEFHANDLE(fileno(stdin));
Guido van Rossum7bf15641998-05-22 18:28:17 +00001855 Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Guido van Rossumad4db171998-06-13 13:56:28 +00001856#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001857 while (!errorInCmd && !stdin_ready) {
1858 int result;
Guido van Rossumad4db171998-06-13 13:56:28 +00001859#ifdef MS_WINDOWS
1860 if (_kbhit()) {
1861 stdin_ready = 1;
1862 break;
1863 }
1864#endif
1865#if defined(WITH_THREAD) || defined(MS_WINDOWS)
Guido van Rossum00d93061998-05-28 23:06:38 +00001866 ENTER_TCL
1867 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
1868 release_lock(tcl_lock);
1869 if (result == 0)
1870 Sleep(20);
1871 Py_END_ALLOW_THREADS
1872#else
1873 result = Tcl_DoOneEvent(0);
Guido van Rossum7bf15641998-05-22 18:28:17 +00001874#endif
Guido van Rossum00d93061998-05-28 23:06:38 +00001875
1876 if (result < 0)
1877 break;
1878 }
Guido van Rossumad4db171998-06-13 13:56:28 +00001879#ifndef MS_WINDOWS
Guido van Rossum00d93061998-05-28 23:06:38 +00001880 Tcl_DeleteFileHandler(tfile);
Guido van Rossumad4db171998-06-13 13:56:28 +00001881#endif
Barry Warsawfa701a81997-01-16 00:15:11 +00001882 if (errorInCmd) {
1883 errorInCmd = 0;
1884 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
1885 excInCmd = valInCmd = trbInCmd = NULL;
1886 PyErr_Print();
1887 }
Guido van Rossumad4db171998-06-13 13:56:28 +00001888 PyEval_SaveThread();
Barry Warsawfa701a81997-01-16 00:15:11 +00001889 return 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001890}
Guido van Rossum18468821994-06-20 07:49:28 +00001891
Guido van Rossum00d93061998-05-28 23:06:38 +00001892#endif
1893
Guido van Rossum7bf15641998-05-22 18:28:17 +00001894static void
1895EnableEventHook()
1896{
Guido van Rossum00d93061998-05-28 23:06:38 +00001897#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001898 if (PyOS_InputHook == NULL) {
Guido van Rossum00d93061998-05-28 23:06:38 +00001899 event_tstate = PyThreadState_Get();
Guido van Rossum7bf15641998-05-22 18:28:17 +00001900 PyOS_InputHook = EventHook;
1901 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001902#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001903}
1904
1905static void
1906DisableEventHook()
1907{
Guido van Rossum00d93061998-05-28 23:06:38 +00001908#ifdef WAIT_FOR_STDIN
Guido van Rossum7bf15641998-05-22 18:28:17 +00001909 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
1910 PyOS_InputHook = NULL;
1911 }
Guido van Rossum00d93061998-05-28 23:06:38 +00001912#endif
Guido van Rossum7bf15641998-05-22 18:28:17 +00001913}
1914
Barry Warsawfa701a81997-01-16 00:15:11 +00001915
1916/* all errors will be checked in one fell swoop in init_tkinter() */
1917static void
1918ins_long(d, name, val)
1919 PyObject *d;
1920 char *name;
1921 long val;
1922{
1923 PyObject *v = PyInt_FromLong(val);
1924 if (v) {
1925 PyDict_SetItemString(d, name, v);
1926 Py_DECREF(v);
1927 }
1928}
1929static void
1930ins_string(d, name, val)
1931 PyObject *d;
1932 char *name;
1933 char *val;
1934{
1935 PyObject *v = PyString_FromString(val);
1936 if (v) {
1937 PyDict_SetItemString(d, name, v);
1938 Py_DECREF(v);
1939 }
1940}
1941
1942
Guido van Rossum18468821994-06-20 07:49:28 +00001943void
Guido van Rossum35d43371997-08-02 00:09:09 +00001944init_tkinter()
Guido van Rossum18468821994-06-20 07:49:28 +00001945{
Barry Warsawfa701a81997-01-16 00:15:11 +00001946 PyObject *m, *d;
Guido van Rossum18468821994-06-20 07:49:28 +00001947
Barry Warsawfa701a81997-01-16 00:15:11 +00001948 Tkapp_Type.ob_type = &PyType_Type;
Guido van Rossum00d93061998-05-28 23:06:38 +00001949
1950#ifdef WITH_THREAD
1951 tcl_lock = allocate_lock();
1952#endif
Guido van Rossumae92f011996-08-21 19:03:36 +00001953
Barry Warsawfa701a81997-01-16 00:15:11 +00001954 m = Py_InitModule("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001955
Barry Warsawfa701a81997-01-16 00:15:11 +00001956 d = PyModule_GetDict(m);
1957 Tkinter_TclError = Py_BuildValue("s", "TclError");
1958 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
Guido van Rossum18468821994-06-20 07:49:28 +00001959
Guido van Rossum35d43371997-08-02 00:09:09 +00001960 ins_long(d, "READABLE", TCL_READABLE);
1961 ins_long(d, "WRITABLE", TCL_WRITABLE);
1962 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
1963 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
1964 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
1965 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
1966 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
1967 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
1968 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
Barry Warsawfa701a81997-01-16 00:15:11 +00001969 ins_string(d, "TK_VERSION", TK_VERSION);
1970 ins_string(d, "TCL_VERSION", TCL_VERSION);
Guido van Rossum18468821994-06-20 07:49:28 +00001971
Guido van Rossum83551bf1997-09-13 00:44:23 +00001972 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
Guido van Rossum00d93061998-05-28 23:06:38 +00001973
1974 Tktt_Type.ob_type = &PyType_Type;
Guido van Rossum83551bf1997-09-13 00:44:23 +00001975 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
1976
Barry Warsawfa701a81997-01-16 00:15:11 +00001977 if (PyErr_Occurred())
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001978 return;
1979
Guido van Rossum26216371998-04-20 18:47:52 +00001980#if TKMAJORMINOR >= 8000
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001981 Py_AtExit(Tcl_Finalize);
Guido van Rossum26216371998-04-20 18:47:52 +00001982#endif
Guido van Rossum07e9fbf1998-02-06 22:35:46 +00001983
Jack Jansen34cc5c31995-10-31 16:15:12 +00001984#ifdef macintosh
Guido van Rossum0d2390c1997-08-14 19:57:07 +00001985 /*
1986 ** Part of this code is stolen from MacintoshInit in tkMacAppInit.
1987 ** Most of the initializations in that routine (toolbox init calls and
1988 ** such) have already been done for us, so we only need these.
1989 */
1990#if TKMAJORMINOR >= 8000
1991 tcl_macQdPtr = &qd;
1992#endif
1993
1994 Tcl_MacSetEventProc(PyMacConvertEvent);
Guido van Rossumec22c921996-02-25 04:50:29 +00001995#if GENERATINGCFM
Barry Warsawfa701a81997-01-16 00:15:11 +00001996 mac_addlibresources();
Guido van Rossumec22c921996-02-25 04:50:29 +00001997#endif /* GENERATINGCFM */
1998#endif /* macintosh */
Guido van Rossum18468821994-06-20 07:49:28 +00001999}
Guido van Rossum9722ad81995-09-22 23:49:28 +00002000
Guido van Rossumec22c921996-02-25 04:50:29 +00002001
Barry Warsawfa701a81997-01-16 00:15:11 +00002002
Guido van Rossum9722ad81995-09-22 23:49:28 +00002003#ifdef macintosh
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002004
2005/*
Guido van Rossumec22c921996-02-25 04:50:29 +00002006** Anyone who embeds Tcl/Tk on the Mac must define panic().
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002007*/
2008
Guido van Rossum9722ad81995-09-22 23:49:28 +00002009void
2010panic(char * format, ...)
2011{
Barry Warsawfa701a81997-01-16 00:15:11 +00002012 va_list varg;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002013
Barry Warsawfa701a81997-01-16 00:15:11 +00002014 va_start(varg, format);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002015
Guido van Rossumb41addf1998-05-12 15:02:41 +00002016 vPySys_WriteStderr(format, varg);
Barry Warsawfa701a81997-01-16 00:15:11 +00002017 (void) fflush(stderr);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002018
Barry Warsawfa701a81997-01-16 00:15:11 +00002019 va_end(varg);
Guido van Rossum9722ad81995-09-22 23:49:28 +00002020
Barry Warsawfa701a81997-01-16 00:15:11 +00002021 Py_FatalError("Tcl/Tk panic");
Guido van Rossum9722ad81995-09-22 23:49:28 +00002022}
Jack Jansen40b546d1995-11-14 10:34:45 +00002023
Guido van Rossumec22c921996-02-25 04:50:29 +00002024/*
2025** Pass events to SIOUX before passing them to Tk.
2026*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002027
Guido van Rossumec22c921996-02-25 04:50:29 +00002028static int
2029PyMacConvertEvent(eventPtr)
Barry Warsawfa701a81997-01-16 00:15:11 +00002030 EventRecord *eventPtr;
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002031{
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002032 WindowPtr frontwin;
2033 /*
Guido van Rossum00d93061998-05-28 23:06:38 +00002034 ** Sioux eats too many events, so we don't pass it everything. We
2035 ** always pass update events to Sioux, and we only pass other events if
Guido van Rossum2ea1c941998-04-28 16:12:43 +00002036 ** the Sioux window is frontmost. This means that Tk menus don't work
2037 ** in that case, but at least we can scroll the sioux window.
2038 ** Note that the SIOUXIsAppWindow() routine we use here is not really
2039 ** part of the external interface of Sioux...
2040 */
2041 frontwin = FrontWindow();
2042 if ( eventPtr->what == updateEvt || SIOUXIsAppWindow(frontwin) ) {
2043 if (SIOUXHandleOneEvent(eventPtr))
2044 return 0; /* Nothing happened to the Tcl event queue */
2045 }
Barry Warsawfa701a81997-01-16 00:15:11 +00002046 return TkMacConvertEvent(eventPtr);
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002047}
2048
Guido van Rossum0d2390c1997-08-14 19:57:07 +00002049#if defined(USE_GUSI) && TKMAJORMINOR < 8000
Guido van Rossum290283b1997-06-02 22:16:43 +00002050/*
2051 * For Python we have to override this routine (from TclMacNotify),
2052 * since we use GUSI for our sockets, not Tcl streams. Hence, we have
2053 * to use GUSI select to see whether our socket is ready. Note that
2054 * createfilehandler (above) sets the type to TCL_UNIX_FD for our
2055 * files and sockets.
2056 *
2057 * NOTE: this code was lifted from Tcl 7.6, it may need to be modified
2058 * for other versions. */
2059
2060int
2061Tcl_FileReady(file, mask)
2062 Tcl_File file; /* File handle for a stream. */
2063 int mask; /* OR'ed combination of TCL_READABLE,
2064 * TCL_WRITABLE, and TCL_EXCEPTION:
2065 * indicates conditions caller cares about. */
2066{
2067 int type;
2068 int fd;
2069
2070 fd = (int) Tcl_GetFileInfo(file, &type);
2071
2072 if (type == TCL_MAC_SOCKET) {
2073 return TclMacSocketReady(file, mask);
2074 } else if (type == TCL_MAC_FILE) {
2075 /*
2076 * Under the Macintosh, files are always ready, so we just
2077 * return the mask that was passed in.
2078 */
2079
2080 return mask;
2081 } else if (type == TCL_UNIX_FD) {
2082 fd_set readset, writeset, excset;
2083 struct timeval tv;
2084
2085 FD_ZERO(&readset);
2086 FD_ZERO(&writeset);
2087 FD_ZERO(&excset);
2088
2089 if ( mask & TCL_READABLE ) FD_SET(fd, &readset);
2090 if ( mask & TCL_WRITABLE ) FD_SET(fd, &writeset);
2091 if ( mask & TCL_EXCEPTION ) FD_SET(fd, &excset);
2092
2093 tv.tv_sec = tv.tv_usec = 0;
2094 if ( select(fd+1, &readset, &writeset, &excset, &tv) <= 0 )
2095 return 0;
2096
2097 mask = 0;
2098 if ( FD_ISSET(fd, &readset) ) mask |= TCL_READABLE;
2099 if ( FD_ISSET(fd, &writeset) ) mask |= TCL_WRITABLE;
2100 if ( FD_ISSET(fd, &excset) ) mask |= TCL_EXCEPTION;
2101
2102 return mask;
2103 }
2104
2105 return 0;
2106}
2107#endif /* USE_GUSI */
2108
Guido van Rossumec22c921996-02-25 04:50:29 +00002109#if GENERATINGCFM
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002110
2111/*
2112** Additional Mac specific code for dealing with shared libraries.
2113*/
2114
2115#include <Resources.h>
2116#include <CodeFragments.h>
2117
2118static int loaded_from_shlib = 0;
2119static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +00002120
Jack Jansen34cc5c31995-10-31 16:15:12 +00002121/*
2122** If this module is dynamically loaded the following routine should
2123** be the init routine. It takes care of adding the shared library to
2124** the resource-file chain, so that the tk routines can find their
2125** resources.
2126*/
2127OSErr pascal
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002128init_tkinter_shlib(CFragInitBlockPtr data)
Jack Jansen34cc5c31995-10-31 16:15:12 +00002129{
Guido van Rossumc9970ee1996-08-26 14:37:15 +00002130 __initialize();
Jack Jansen34cc5c31995-10-31 16:15:12 +00002131 if ( data == nil ) return noErr;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002132 if ( data->fragLocator.where == kDataForkCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002133 library_fss = *data->fragLocator.u.onDisk.fileSpec;
2134 loaded_from_shlib = 1;
Guido van Rossum8ec9e631997-04-29 15:49:04 +00002135 } else if ( data->fragLocator.where == kResourceCFragLocator ) {
Jack Jansen34cc5c31995-10-31 16:15:12 +00002136 library_fss = *data->fragLocator.u.inSegs.fileSpec;
2137 loaded_from_shlib = 1;
2138 }
2139 return noErr;
2140}
2141
2142/*
2143** Insert the library resources into the search path. Put them after
2144** the resources from the application. Again, we ignore errors.
2145*/
Guido van Rossumdfd428d1996-02-25 04:46:40 +00002146static
Jack Jansen34cc5c31995-10-31 16:15:12 +00002147mac_addlibresources()
2148{
2149 if ( !loaded_from_shlib )
2150 return;
2151 (void)FSpOpenResFile(&library_fss, fsRdPerm);
2152}
2153
Guido van Rossumec22c921996-02-25 04:50:29 +00002154#endif /* GENERATINGCFM */
2155#endif /* macintosh */