blob: 0108795e6c93808f3212405ffb31f5f7bcbd616b [file] [log] [blame]
Jack Jansenba0311e1995-10-23 14:34:14 +00001/* _tkinter.c -- Interface to libtk.a and libtcl.a.
Guido van Rossum18468821994-06-20 07:49:28 +00002 Copyright (C) 1994 Steen Lumholt */
3
Guido van Rossum9722ad81995-09-22 23:49:28 +00004#include "Python.h"
5
6#ifdef macintosh
7#define MAC_TCL
Jack Jansen34cc5c31995-10-31 16:15:12 +00008
9#include <CodeFragments.h>
10static int loaded_from_shlib = 0;
11static FSSpec library_fss;
Guido van Rossum9722ad81995-09-22 23:49:28 +000012#endif
13
14#ifdef MAC_TCL
15#define WITH_APPINIT
Jack Jansen40b546d1995-11-14 10:34:45 +000016#ifdef __MWERKS__
17void GUSISetup (void (*socketfamily)());
18void GUSIwithInternetSockets (void);
19void GUSIwithSIOUXSockets (void);
20#endif
Guido van Rossum9722ad81995-09-22 23:49:28 +000021#endif
Guido van Rossum18468821994-06-20 07:49:28 +000022
Jack Jansenba0311e1995-10-23 14:34:14 +000023#define PyInit__tkinter init_tkinter
Guido van Rossum18468821994-06-20 07:49:28 +000024
Guido van Rossum18468821994-06-20 07:49:28 +000025#include <tcl.h>
26#include <tk.h>
27
28extern char *getprogramname ();
Guido van Rossumd308e2b1994-07-07 09:25:12 +000029
Guido van Rossum9722ad81995-09-22 23:49:28 +000030/* Internal declarations from tkInt.h. */
31#if (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION) >= 4001
32extern int Tk_GetNumMainWindows();
33#else
Guido van Rossum18468821994-06-20 07:49:28 +000034extern int tk_NumMainWindows;
Guido van Rossum9722ad81995-09-22 23:49:28 +000035#define Tk_GetNumMainWindows() (tk_NumMainWindows)
36#endif
37
38#if TK_MAJOR_VERSION < 4
Guido van Rossumd308e2b1994-07-07 09:25:12 +000039extern struct { Tk_Window win; } *tkMainWindowList;
Guido van Rossum9722ad81995-09-22 23:49:28 +000040#endif
Guido van Rossum18468821994-06-20 07:49:28 +000041
42/**** Tkapp Object Declaration ****/
43
44staticforward PyTypeObject Tkapp_Type;
45
46typedef struct
47 {
48 PyObject_HEAD
49 Tcl_Interp *interp;
50 Tk_Window tkwin;
51 }
52TkappObject;
53
54#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
55#define Tkapp_Tkwin(v) (((TkappObject *) (v))->tkwin)
56#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
57#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
58
59#define DEBUG_REFCNT(v) (printf ("DEBUG: id=%p, refcnt=%i\n", \
60 (void *) v, ((PyObject *) v)->ob_refcnt))
61
62/**** Error Handling ****/
63
64static PyObject *Tkinter_TclError;
Guido van Rossumd308e2b1994-07-07 09:25:12 +000065static int quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +000066static int errorInCmd = 0;
67static PyObject *excInCmd;
68static PyObject *valInCmd;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +000069static PyObject *trbInCmd;
Guido van Rossum18468821994-06-20 07:49:28 +000070
71static PyObject *
72Tkinter_Error (v)
73 PyObject *v;
74{
Guido van Rossum18468821994-06-20 07:49:28 +000075 PyErr_SetString (Tkinter_TclError, Tkapp_Result (v));
76 return NULL;
77}
78
79int
80PythonCmd_Error (interp)
81 Tcl_Interp *interp;
82{
83 errorInCmd = 1;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +000084 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
Guido van Rossum18468821994-06-20 07:49:28 +000085 return TCL_ERROR;
86}
87
88/**** Utils ****/
89
90static char *
91AsString (value, tmp)
92 PyObject *value;
93 PyObject *tmp;
94{
95 if (PyString_Check (value))
96 return PyString_AsString (value);
97 else
98 {
99 PyObject *v;
100
Guido van Rossumcd938fc1995-01-17 16:13:48 +0000101 v = PyObject_Str (value);
Guido van Rossum18468821994-06-20 07:49:28 +0000102 PyList_Append (tmp, v);
103 Py_DECREF (v);
104 return PyString_AsString (v);
105 }
106}
107
108#define ARGSZ 64
109
110static char *
111Merge (args)
112 PyObject *args;
113{
114 PyObject *tmp;
115 char *argvStore[ARGSZ];
116 char **argv;
117 int fvStore[ARGSZ];
118 int *fv;
119 int argc;
120 char *res;
121 int i;
122
123 tmp = PyList_New (0);
124 argv = argvStore;
125 fv = fvStore;
126
127 if (!PyTuple_Check (args))
128 {
129 argc = 1;
130 fv[0] = 0;
131 argv[0] = AsString (args, tmp);
132 }
133 else
134 {
135 PyObject *v;
136
137 if (PyTuple_Size (args) > ARGSZ)
138 {
Guido van Rossumb6fe7041995-03-09 12:13:43 +0000139 argv = (char **) malloc (PyTuple_Size (args) * sizeof (char *));
140 fv = (int *) malloc (PyTuple_Size (args) * sizeof (int));
Guido van Rossum18468821994-06-20 07:49:28 +0000141 if (argv == NULL || fv == NULL)
142 PyErr_NoMemory ();
143 }
144
145 argc = PyTuple_Size (args);
146 for (i = 0; i < argc; i++)
147 {
148 v = PyTuple_GetItem (args, i);
149 if (PyTuple_Check (v))
150 {
151 fv[i] = 1;
152 argv[i] = Merge (v);
153 }
154 else if (v == Py_None)
155 {
156 argc = i;
157 break;
158 }
159 else
160 {
161 fv[i] = 0;
162 argv[i] = AsString (v, tmp);
163 }
164 }
165 }
166
167 res = Tcl_Merge (argc, argv);
168
169 Py_DECREF (tmp);
170 for (i = 0; i < argc; i++)
171 if (fv[i]) free (argv[i]);
172 if (argv != argvStore)
173 free (argv);
174 if (fv != fvStore)
175 free (fv);
176
177 return res;
178}
179
180static PyObject *
181Split (self, list)
182 PyObject *self;
183 char *list;
184{
185 int argc;
186 char **argv;
187 PyObject *v;
188
189 if (list == NULL)
190 {
191 Py_INCREF (Py_None);
192 return Py_None;
193 }
194
195 if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
196 return Tkinter_Error (self);
197
198 if (argc == 0)
199 v = PyString_FromString ("");
200 else if (argc == 1)
201 v = PyString_FromString (argv[0]);
202 else
203 {
204 int i;
205
206 v = PyTuple_New (argc);
207 for (i = 0; i < argc; i++)
208 PyTuple_SetItem (v, i, Split (self, argv[i]));
209 }
210
211 free (argv);
212 return v;
213}
214
215/**** Tkapp Object ****/
216
217#ifndef WITH_APPINIT
218int
219Tcl_AppInit (interp)
220 Tcl_Interp *interp;
221{
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000222 Tk_Window main;
223 main = Tk_MainWindow(interp);
224 if (Tcl_Init (interp) == TCL_ERROR) {
225 fprintf(stderr, "Tcl_Init error: %s\n", interp->result);
Guido van Rossum18468821994-06-20 07:49:28 +0000226 return TCL_ERROR;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000227 }
228 if (Tk_Init (interp) == TCL_ERROR) {
229 fprintf(stderr, "Tk_Init error: %s\n", interp->result);
Guido van Rossum18468821994-06-20 07:49:28 +0000230 return TCL_ERROR;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000231 }
Guido van Rossum18468821994-06-20 07:49:28 +0000232 return TCL_OK;
233}
234#endif /* !WITH_APPINIT */
235
236/* Initialize the Tk application; see the `main' function in
237 `tkMain.c'. */
238static TkappObject *
239Tkapp_New (screenName, baseName, className, interactive)
240 char *screenName;
241 char *baseName;
242 char *className;
243 int interactive;
244{
245 TkappObject *v;
246
247 v = PyObject_NEW (TkappObject, &Tkapp_Type);
248 if (v == NULL)
249 return NULL;
250
251 v->interp = Tcl_CreateInterp ();
252 v->tkwin = Tk_CreateMainWindow (v->interp, screenName,
253 baseName, className);
254 if (v->tkwin == NULL)
255 return (TkappObject *) Tkinter_Error ((PyObject *) v);
256
257 Tk_GeometryRequest (v->tkwin, 200, 200);
258
259 if (screenName != NULL)
260 Tcl_SetVar2 (v->interp, "env", "DISPLAY", screenName, TCL_GLOBAL_ONLY);
261
262 if (interactive)
263 Tcl_SetVar (v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
264 else
265 Tcl_SetVar (v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
266
Guido van Rossum18468821994-06-20 07:49:28 +0000267 if (Tcl_AppInit (v->interp) != TCL_OK)
268 {
269 PyErr_SetString (Tkinter_TclError, "Tcl_AppInit failed"); /* XXX */
270 return NULL;
271 }
Guido van Rossum18468821994-06-20 07:49:28 +0000272
273 return v;
274}
275
276/** Tcl Eval **/
277
278static PyObject *
279Tkapp_Call (self, args)
280 PyObject *self;
281 PyObject *args;
282{
283 char *cmd;
284
285 cmd = Merge (args);
286 if (Tcl_Eval (Tkapp_Interp (self), cmd) == TCL_ERROR)
287 {
288 free (cmd);
289 return Tkinter_Error (self);
290 }
291
292 free (cmd);
293 return PyString_FromString (Tkapp_Result (self));
294}
295
296static PyObject *
297Tkapp_GlobalCall (self, args)
298 PyObject *self;
299 PyObject *args;
300{
301 char *cmd;
302
303 cmd = Merge (args);
304 if (Tcl_GlobalEval (Tkapp_Interp (self), cmd) == TCL_ERROR)
305 {
306 free (cmd);
307 return Tkinter_Error (self);
308 }
309
310 free (cmd);
311 return PyString_FromString (Tkapp_Result (self));
312}
313
314static PyObject *
315Tkapp_Eval (self, args)
316 PyObject *self;
317 PyObject *args;
318{
319 char *script;
320
321 if (!PyArg_Parse (args, "s", &script))
322 return NULL;
323
324 if (Tcl_Eval (Tkapp_Interp (self), script) == TCL_ERROR)
325 return Tkinter_Error (self);
326
327 return PyString_FromString (Tkapp_Result (self));
328}
329
330static PyObject *
331Tkapp_GlobalEval (self, args)
332 PyObject *self;
333 PyObject *args;
334{
335 char *script;
336
337 if (!PyArg_Parse (args, "s", &script))
338 return NULL;
339
340 if (Tcl_GlobalEval (Tkapp_Interp (self), script) == TCL_ERROR)
341 return Tkinter_Error (self);
342
343 return PyString_FromString (Tkapp_Result (self));
344}
345
346static PyObject *
347Tkapp_EvalFile (self, args)
348 PyObject *self;
349 PyObject *args;
350{
351 char *fileName;
352
353 if (!PyArg_Parse (args, "s", &fileName))
354 return NULL;
355
356 if (Tcl_EvalFile (Tkapp_Interp (self), fileName) == TCL_ERROR)
357 return Tkinter_Error (self);
358
359 return PyString_FromString (Tkapp_Result (self));
360}
361
362static PyObject *
363Tkapp_Record (self, args)
364 PyObject *self;
365 PyObject *args;
366{
367 char *script;
368
369 if (!PyArg_Parse (args, "s", &script))
370 return NULL;
371
372 if (Tcl_RecordAndEval (Tkapp_Interp (self),
373 script, TCL_NO_EVAL) == TCL_ERROR)
374 return Tkinter_Error (self);
375
376 return PyString_FromString (Tkapp_Result (self));
377}
378
379static PyObject *
380Tkapp_AddErrorInfo (self, args)
381 PyObject *self;
382 PyObject *args;
383{
384 char *msg;
385
386 if (!PyArg_Parse (args, "s", &msg))
387 return NULL;
388 Tcl_AddErrorInfo (Tkapp_Interp (self), msg);
389
390 Py_INCREF(Py_None);
391 return Py_None;
392}
393
394/** Tcl Variable **/
395
396static PyObject *
397SetVar (self, args, flags)
398 PyObject *self;
399 PyObject *args;
400 int flags;
401{
402 char *name1, *name2, *ok;
403 PyObject *newValue;
404 PyObject *tmp;
405
406 tmp = PyList_New (0);
407
408 if (PyArg_Parse (args, "(sO)", &name1, &newValue))
409 ok = Tcl_SetVar (Tkapp_Interp (self), name1,
410 AsString (newValue, tmp), flags); /* XXX Merge? */
411 else if (PyArg_Parse (args, "(ssO)", &name1, &name2, &newValue))
412 ok = Tcl_SetVar2 (Tkapp_Interp (self), name1, name2,
413 AsString (newValue, tmp), flags);
414 else
415 {
416 Py_DECREF (tmp);
417 return NULL;
418 }
419 Py_DECREF (tmp);
420
421 if (!ok)
422 return Tkinter_Error (self);
423
424 Py_INCREF (Py_None);
425 return Py_None;
426}
427
428static PyObject *
429Tkapp_SetVar (self, args)
430 PyObject *self;
431 PyObject *args;
432{
433 return SetVar (self, args, TCL_LEAVE_ERR_MSG);
434}
435
436static PyObject *
437Tkapp_GlobalSetVar (self, args)
438 PyObject *self;
439 PyObject *args;
440{
441 return SetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
442}
443
444static PyObject *
445GetVar (self, args, flags)
446 PyObject *self;
447 PyObject *args;
448 int flags;
449{
450 char *name1, *name2, *s;
451
452 if (PyArg_Parse (args, "s", &name1))
453 s = Tcl_GetVar (Tkapp_Interp (self), name1, flags);
454 else if (PyArg_Parse (args, "(ss)", &name1, &name2))
455 s = Tcl_GetVar2 (Tkapp_Interp (self), name1, name2, flags);
456 else
457 return NULL;
458
459 if (s == NULL)
460 return Tkinter_Error (self);
461
462 return PyString_FromString (s);
463}
464
465static PyObject *
466Tkapp_GetVar (self, args)
467 PyObject *self;
468 PyObject *args;
469{
470 return GetVar (self, args, TCL_LEAVE_ERR_MSG);
471}
472
473static PyObject *
474Tkapp_GlobalGetVar (self, args)
475 PyObject *self;
476 PyObject *args;
477{
478 return GetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
479}
480
481static PyObject *
482UnsetVar (self, args, flags)
483 PyObject *self;
484 PyObject *args;
485 int flags;
486{
487 char *name1, *name2;
488 int code;
489
490 if (PyArg_Parse (args, "s", &name1))
491 code = Tcl_UnsetVar (Tkapp_Interp (self), name1, flags);
492 else if (PyArg_Parse (args, "(ss)", &name1, &name2))
493 code = Tcl_UnsetVar2 (Tkapp_Interp (self), name1, name2, flags);
494 else
495 return NULL;
496
497 if (code == TCL_ERROR)
498 return Tkinter_Error (self);
499
500 Py_INCREF (Py_None);
501 return Py_None;
502}
503
504static PyObject *
505Tkapp_UnsetVar (self, args)
506 PyObject *self;
507 PyObject *args;
508{
509 return UnsetVar (self, args, TCL_LEAVE_ERR_MSG);
510}
511
512static PyObject *
513Tkapp_GlobalUnsetVar (self, args)
514 PyObject *self;
515 PyObject *args;
516{
517 return UnsetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
518}
519
520/** Tcl to Python **/
521
522static PyObject *
523Tkapp_GetInt (self, args)
524 PyObject *self;
525 PyObject *args;
526{
527 char *s;
528 int v;
529
530 if (!PyArg_Parse (args, "s", &s))
531 return NULL;
532 if (Tcl_GetInt (Tkapp_Interp (self), s, &v) == TCL_ERROR)
533 return Tkinter_Error (self);
534 return Py_BuildValue ("i", v);
535}
536
537static PyObject *
538Tkapp_GetDouble (self, args)
539 PyObject *self;
540 PyObject *args;
541{
542 char *s;
543 double v;
544
545 if (!PyArg_Parse (args, "s", &s))
546 return NULL;
547 if (Tcl_GetDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
548 return Tkinter_Error (self);
549 return Py_BuildValue ("d", v);
550}
551
552static PyObject *
553Tkapp_GetBoolean (self, args)
554 PyObject *self;
555 PyObject *args;
556{
557 char *s;
558 int v;
559
560 if (!PyArg_Parse (args, "s", &s))
561 return NULL;
562 if (Tcl_GetBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
563 return Tkinter_Error (self);
564 return Py_BuildValue ("i", v);
565}
566
567static PyObject *
568Tkapp_ExprString (self, args)
569 PyObject *self;
570 PyObject *args;
571{
572 char *s;
573
574 if (!PyArg_Parse (args, "s", &s))
575 return NULL;
576 if (Tcl_ExprString (Tkapp_Interp (self), s) == TCL_ERROR)
577 return Tkinter_Error (self);
578 return Py_BuildValue ("s", Tkapp_Result (self));
579}
580
581static PyObject *
582Tkapp_ExprLong (self, args)
583 PyObject *self;
584 PyObject *args;
585{
586 char *s;
587 long v;
588
589 if (!PyArg_Parse (args, "s", &s))
590 return NULL;
591 if (Tcl_ExprLong (Tkapp_Interp (self), s, &v) == TCL_ERROR)
592 return Tkinter_Error (self);
593 return Py_BuildValue ("l", v);
594}
595
596static PyObject *
597Tkapp_ExprDouble (self, args)
598 PyObject *self;
599 PyObject *args;
600{
601 char *s;
602 double v;
603
604 if (!PyArg_Parse (args, "s", &s))
605 return NULL;
606 if (Tcl_ExprDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
607 return Tkinter_Error (self);
608 return Py_BuildValue ("d", v);
609}
610
611static PyObject *
612Tkapp_ExprBoolean (self, args)
613 PyObject *self;
614 PyObject *args;
615{
616 char *s;
617 int v;
618
619 if (!PyArg_Parse (args, "s", &s))
620 return NULL;
621 if (Tcl_ExprBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
622 return Tkinter_Error (self);
623 return Py_BuildValue ("i", v);
624}
625
626static PyObject *
627Tkapp_SplitList (self, args)
628 PyObject *self;
629 PyObject *args;
630{
631 char *list;
632 int argc;
633 char **argv;
634 PyObject *v;
635 int i;
636
637 if (!PyArg_Parse (args, "s", &list))
638 return NULL;
639
640 if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
641 return Tkinter_Error (self);
642
643 v = PyTuple_New (argc);
644 for (i = 0; i < argc; i++)
645 PyTuple_SetItem (v, i, PyString_FromString (argv[i]));
646
647 free (argv);
648 return v;
649}
650
651static PyObject *
652Tkapp_Split (self, args)
653 PyObject *self;
654 PyObject *args;
655{
656 char *list;
657
658 if (!PyArg_Parse (args, "s", &list))
659 return NULL;
660 return Split (self, list);
661}
662
663static PyObject *
664Tkapp_Merge (self, args)
665 PyObject *self;
666 PyObject *args;
667{
668 char *s;
669 PyObject *v;
670
671 s = Merge (args);
672 v = PyString_FromString (s);
673 free (s);
674 return v;
675}
676
677/** Tcl Command **/
678
679/* This is the Tcl command that acts as a wrapper for Python
680 function or method. */
681static int
682PythonCmd (clientData, interp, argc, argv)
683 ClientData clientData; /* Is (self, func) */
684 Tcl_Interp *interp;
685 int argc;
686 char *argv[];
687{
688 PyObject *self, *func, *arg, *res, *tmp;
689 int i;
690
691 self = PyTuple_GetItem ((PyObject *) clientData, 0);
692 func = PyTuple_GetItem ((PyObject *) clientData, 1);
693
694 /* Create argument list (argv1, ..., argvN) */
695 arg = PyTuple_New (argc - 1);
696 for (i = 0; i < (argc - 1); i++)
697 PyTuple_SetItem (arg, i, PyString_FromString (argv[i + 1]));
698
699 res = PyEval_CallObject (func, arg);
700 Py_DECREF (arg);
Guido van Rossumd308e2b1994-07-07 09:25:12 +0000701
Guido van Rossum18468821994-06-20 07:49:28 +0000702 if (res == NULL)
703 return PythonCmd_Error (interp);
704
705 tmp = PyList_New (0);
706 Tcl_SetResult (Tkapp_Interp (self), AsString (res, tmp), TCL_VOLATILE);
707 Py_DECREF (res);
708 Py_DECREF (tmp);
709
710 return TCL_OK;
711}
712
713static void
714PythonCmdDelete (clientData)
715 ClientData clientData; /* Is (self, func) */
716{
717 Py_DECREF ((PyObject *) clientData);
718}
719
720static PyObject *
721Tkapp_CreateCommand (self, args)
722 PyObject *self;
723 PyObject *args;
724{
725 char *cmdName;
726 PyObject *data;
727 PyObject *func;
728
729 /* Args is: (cmdName, func) */
730 if (!PyTuple_Check (args)
731 || !(PyTuple_Size (args) == 2)
732 || !PyString_Check (PyTuple_GetItem (args, 0))
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000733 || !PyCallable_Check (PyTuple_GetItem (args, 1)))
Guido van Rossum18468821994-06-20 07:49:28 +0000734 {
735 PyErr_SetString (PyExc_TypeError, "bad argument list");
736 return NULL;
737 }
738
739 cmdName = PyString_AsString (PyTuple_GetItem (args, 0));
740 func = PyTuple_GetItem (args, 1);
741
742 data = PyTuple_New (2); /* ClientData is: (self, func) */
743
744 Py_INCREF (self);
745 PyTuple_SetItem (data, 0, self);
746
747 Py_INCREF (func);
748 PyTuple_SetItem (data, 1, func);
749
750 Tcl_CreateCommand (Tkapp_Interp (self), cmdName, PythonCmd,
751 (ClientData) data, PythonCmdDelete);
752
753 Py_INCREF (Py_None);
754 return Py_None;
755}
756
757static PyObject *
758Tkapp_DeleteCommand (self, args)
759 PyObject *self;
760 PyObject *args;
761{
762 char *cmdName;
763
764 if (!PyArg_Parse (args, "s", &cmdName))
765 return NULL;
766 if (Tcl_DeleteCommand (Tkapp_Interp (self), cmdName) == -1)
767 {
768 PyErr_SetString (Tkinter_TclError, "can't delete Tcl command");
769 return NULL;
770 }
771 Py_INCREF (Py_None);
772 return Py_None;
773}
774
775/** File Handler **/
776
Guido van Rossuma597dde1995-01-10 20:56:29 +0000777static void
Guido van Rossum18468821994-06-20 07:49:28 +0000778FileHandler (clientData, mask)
Guido van Rossum76875221994-06-27 07:59:42 +0000779 ClientData clientData; /* Is: (func, file) */
Guido van Rossum18468821994-06-20 07:49:28 +0000780 int mask;
781{
Guido van Rossum76875221994-06-27 07:59:42 +0000782 PyObject *func, *file, *arg, *res;
Guido van Rossum18468821994-06-20 07:49:28 +0000783
Guido van Rossum76875221994-06-27 07:59:42 +0000784 func = PyTuple_GetItem ((PyObject *) clientData, 0);
785 file = PyTuple_GetItem ((PyObject *) clientData, 1);
Guido van Rossum18468821994-06-20 07:49:28 +0000786
Guido van Rossum76875221994-06-27 07:59:42 +0000787 arg = Py_BuildValue ("(Oi)", file, (long) mask);
Guido van Rossum18468821994-06-20 07:49:28 +0000788 res = PyEval_CallObject (func, arg);
789 Py_DECREF (arg);
790 if (res == NULL)
791 {
792 errorInCmd = 1;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000793 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
Guido van Rossum18468821994-06-20 07:49:28 +0000794 }
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000795 Py_XDECREF (res);
796}
797
798static int
799GetFileNo (file)
800 PyObject *file; /* Either an int >= 0 or an object with a
801 .fileno() method that returns an int >= 0 */
802{
Guido van Rossuma597dde1995-01-10 20:56:29 +0000803 PyObject *meth, *args, *res;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000804 int id;
805 if (PyInt_Check(file)) {
806 id = PyInt_AsLong(file);
807 if (id < 0)
808 PyErr_SetString(PyExc_ValueError, "invalid file id");
809 return id;
810 }
811 meth = PyObject_GetAttrString(file, "fileno");
812 if (meth == NULL)
813 return -1;
814 args = PyTuple_New(0);
815 if (args == NULL)
816 return -1;
817 res = PyEval_CallObject(meth, args);
818 Py_DECREF(args);
819 Py_DECREF(meth);
820 if (res == NULL)
821 return -1;
822 if (PyInt_Check(res))
823 id = PyInt_AsLong(res);
824 else
825 id = -1;
826 if (id < 0)
827 PyErr_SetString(PyExc_ValueError,
828 "invalid fileno() return value");
829 Py_DECREF(res);
830 return id;
Guido van Rossum18468821994-06-20 07:49:28 +0000831}
832
833static PyObject *
834Tkapp_CreateFileHandler (self, args)
835 PyObject *self;
836 PyObject *args; /* Is (file, mask, func) */
837{
Guido van Rossum76875221994-06-27 07:59:42 +0000838 PyObject *file, *func, *data;
839 int mask, id;
Guido van Rossum18468821994-06-20 07:49:28 +0000840
841 if (!PyArg_Parse (args, "(OiO)", &file, &mask, &func))
842 return NULL;
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000843 id = GetFileNo (file);
844 if (id < 0)
845 return NULL;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +0000846 if (!PyCallable_Check(func))
Guido van Rossum18468821994-06-20 07:49:28 +0000847 {
848 PyErr_SetString (PyExc_TypeError, "bad argument list");
849 return NULL;
850 }
851
Guido van Rossum76875221994-06-27 07:59:42 +0000852 /* ClientData is: (func, file) */
853 data = Py_BuildValue ("(OO)", func, file);
854
Guido van Rossum76875221994-06-27 07:59:42 +0000855 Tk_CreateFileHandler (id, mask, FileHandler, (ClientData) data);
Guido van Rossum18468821994-06-20 07:49:28 +0000856 /* XXX fileHandlerDict */
Guido van Rossum76875221994-06-27 07:59:42 +0000857
Guido van Rossum18468821994-06-20 07:49:28 +0000858 Py_INCREF (Py_None);
859 return Py_None;
860}
861
862static PyObject *
863Tkapp_DeleteFileHandler (self, args)
864 PyObject *self;
865 PyObject *args; /* Args: file */
866{
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000867 PyObject *file;
Guido van Rossum18468821994-06-20 07:49:28 +0000868 int id;
869
Guido van Rossum9bb4fd61994-08-09 14:15:19 +0000870 if (!PyArg_Parse (args, "O", &file))
871 return NULL;
872 id = GetFileNo (file);
873 if (id < 0)
874 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +0000875
Guido van Rossum18468821994-06-20 07:49:28 +0000876 Tk_DeleteFileHandler (id);
877 /* XXX fileHandlerDict */
878 Py_INCREF (Py_None);
879 return Py_None;
880}
881
Guido van Rossumf34cadd1994-11-10 22:50:21 +0000882/**** Tktt Object (timer token) ****/
883
884staticforward PyTypeObject Tktt_Type;
885
886typedef struct
887 {
888 PyObject_HEAD
889 Tk_TimerToken token;
890 PyObject *func;
891 }
892TkttObject;
893
894static PyObject *
895Tktt_DeleteTimerHandler (self, args)
896 PyObject *self;
897 PyObject *args;
898{
899 TkttObject *v = (TkttObject *) self;
900
901 if (!PyArg_Parse (args, ""))
902 return NULL;
903 if (v->func != NULL)
904 {
905 Tk_DeleteTimerHandler (v->token);
906 PyMem_DEL (v->func);
907 v->func = NULL;
908 }
909 Py_INCREF (Py_None);
910 return Py_None;
911}
912
913static PyMethodDef Tktt_methods[] =
914{
915 {"deletetimerhandler", Tktt_DeleteTimerHandler},
916 {NULL, NULL}
917};
918
919static TkttObject *
920Tktt_New (token, func)
921 Tk_TimerToken token;
922 PyObject *func;
923{
924 TkttObject *v;
925
926 v = PyObject_NEW (TkttObject, &Tktt_Type);
927 if (v == NULL)
928 return NULL;
929
930 v->token = token;
931 v->func = func;
932 Py_INCREF (v->func);
933 return v;
934}
935
936static void
937Tktt_Dealloc (self)
938 PyObject *self;
939{
940 PyMem_DEL (self);
941}
942
943static int
944Tktt_Print (self, fp, flags)
945 PyObject *self;
946 FILE *fp;
947 int flags;
948{
949 TkttObject *v = (TkttObject *) self;
950
951 fprintf(fp, "<tktimertoken at 0x%x%s>", v,
952 v->func == NULL ? ", handler deleted" : "");
953 return 0;
954}
955
956static PyObject *
957Tktt_GetAttr (self, name)
958 PyObject *self;
959 char *name;
960{
961 return Py_FindMethod (Tktt_methods, self, name);
962}
963
964static PyTypeObject Tktt_Type =
965{
Guido van Rossuma597dde1995-01-10 20:56:29 +0000966 PyObject_HEAD_INIT (&PyType_Type)
Guido van Rossumf34cadd1994-11-10 22:50:21 +0000967 0, /*ob_size */
968 "tktimertoken", /*tp_name */
969 sizeof (TkttObject), /*tp_basicsize */
970 0, /*tp_itemsize */
971 Tktt_Dealloc, /*tp_dealloc */
972 Tktt_Print, /*tp_print */
973 Tktt_GetAttr, /*tp_getattr */
974 0, /*tp_setattr */
975 0, /*tp_compare */
976 0, /*tp_repr */
977 0, /*tp_as_number */
978 0, /*tp_as_sequence */
979 0, /*tp_as_mapping */
980 0, /*tp_hash */
981};
982
983/** Timer Handler **/
984
985static void
986TimerHandler (clientData)
987 ClientData clientData;
988{
989 PyObject *func = (PyObject *) clientData;
990 PyObject *arg, *res;
991
992 arg = PyTuple_New (0);
993 res = PyEval_CallObject (func, arg);
994 Py_DECREF (arg);
995 if (res == NULL)
996 {
997 errorInCmd = 1;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000998 PyErr_Fetch (&excInCmd, &valInCmd, &trbInCmd);
Guido van Rossumf34cadd1994-11-10 22:50:21 +0000999 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001000 else
1001 Py_DECREF (res);
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001002}
1003
1004static PyObject *
1005Tkapp_CreateTimerHandler (self, args)
1006 PyObject *self;
1007 PyObject *args; /* Is (milliseconds, func) */
1008{
1009 int milliseconds;
1010 PyObject *func;
1011 Tk_TimerToken token;
1012
1013 if (!PyArg_Parse (args, "(iO)", &milliseconds, &func))
1014 return NULL;
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001015 if (!PyCallable_Check(func))
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001016 {
1017 PyErr_SetString (PyExc_TypeError, "bad argument list");
1018 return NULL;
1019 }
1020 token = Tk_CreateTimerHandler(milliseconds, TimerHandler, (ClientData) func);
1021 return (PyObject *) Tktt_New (token, func);
1022}
1023
Guido van Rossum18468821994-06-20 07:49:28 +00001024/** Event Loop **/
1025
Guido van Rossum18468821994-06-20 07:49:28 +00001026static PyObject *
1027Tkapp_MainLoop (self, args)
1028 PyObject *self;
1029 PyObject *args;
1030{
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001031 int threshold = 0;
1032
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001033 if (!PyArg_ParseTuple (args, "|i", &threshold))
1034 return NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001035
1036 quitMainLoop = 0;
Guido van Rossum9722ad81995-09-22 23:49:28 +00001037 while (Tk_GetNumMainWindows() > threshold && !quitMainLoop && !errorInCmd)
Guido van Rossum18468821994-06-20 07:49:28 +00001038 {
1039 if (PyOS_InterruptOccurred ())
1040 {
1041 PyErr_SetNone (PyExc_KeyboardInterrupt);
1042 return NULL;
1043 }
1044 Tk_DoOneEvent (0);
1045 }
Guido van Rossum64b24fb1995-09-30 17:00:24 +00001046 quitMainLoop = 0;
Guido van Rossum18468821994-06-20 07:49:28 +00001047
1048 if (errorInCmd)
1049 {
1050 errorInCmd = 0;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001051 PyErr_Restore (excInCmd, valInCmd, trbInCmd);
1052 excInCmd = valInCmd = trbInCmd = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001053 return NULL;
1054 }
1055 Py_INCREF (Py_None);
1056 return Py_None;
1057}
1058
1059static PyObject *
Guido van Rossum062cfb01995-01-10 17:42:51 +00001060Tkapp_DoOneEvent (self, args)
1061 PyObject *self;
1062 PyObject *args;
1063{
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001064 int flags = TK_ALL_EVENTS;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001065 int rv;
1066
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001067 if (!PyArg_ParseTuple (args, "|i", &flags))
1068 return NULL;
Guido van Rossum062cfb01995-01-10 17:42:51 +00001069 rv = Tk_DoOneEvent(flags);
1070 return Py_BuildValue ("i", rv);
1071}
1072
1073static PyObject *
Guido van Rossum18468821994-06-20 07:49:28 +00001074Tkapp_Quit (self, args)
1075 PyObject *self;
1076 PyObject *args;
1077{
1078
1079 if (!PyArg_Parse (args, ""))
1080 return NULL;
1081 quitMainLoop = 1;
1082 Py_INCREF (Py_None);
1083 return Py_None;
1084}
1085
1086/**** Tkapp Method List ****/
1087
1088static PyMethodDef Tkapp_methods[] =
1089{
1090 {"call", Tkapp_Call},
1091 {"globalcall", Tkapp_GlobalCall},
1092 {"eval", Tkapp_Eval},
1093 {"globaleval", Tkapp_GlobalEval},
1094 {"evalfile", Tkapp_EvalFile},
1095 {"record", Tkapp_Record},
1096 {"adderrorinfo", Tkapp_AddErrorInfo},
1097 {"setvar", Tkapp_SetVar},
1098 {"globalsetvar", Tkapp_GlobalSetVar},
1099 {"getvar", Tkapp_GetVar},
1100 {"globalgetvar", Tkapp_GlobalGetVar},
1101 {"unsetvar", Tkapp_UnsetVar},
1102 {"globalunsetvar", Tkapp_GlobalUnsetVar},
1103 {"getint", Tkapp_GetInt},
1104 {"getdouble", Tkapp_GetDouble},
1105 {"getboolean", Tkapp_GetBoolean},
1106 {"exprstring", Tkapp_ExprString},
1107 {"exprlong", Tkapp_ExprLong},
1108 {"exprdouble", Tkapp_ExprDouble},
1109 {"exprboolean", Tkapp_ExprBoolean},
1110 {"splitlist", Tkapp_SplitList},
1111 {"split", Tkapp_Split},
1112 {"merge", Tkapp_Merge},
1113 {"createcommand", Tkapp_CreateCommand},
1114 {"deletecommand", Tkapp_DeleteCommand},
1115 {"createfilehandler", Tkapp_CreateFileHandler},
1116 {"deletefilehandler", Tkapp_DeleteFileHandler},
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001117 {"createtimerhandler", Tkapp_CreateTimerHandler},
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001118 {"mainloop", Tkapp_MainLoop, 1},
1119 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossum18468821994-06-20 07:49:28 +00001120 {"quit", Tkapp_Quit},
1121 {NULL, NULL}
1122};
1123
1124/**** Tkapp Type Methods ****/
1125
1126static void
1127Tkapp_Dealloc (self)
1128 PyObject *self;
1129{
1130 Tk_DestroyWindow (Tkapp_Tkwin (self));
1131 Tcl_DeleteInterp (Tkapp_Interp (self));
1132 PyMem_DEL (self);
1133}
1134
1135static PyObject *
1136Tkapp_GetAttr (self, name)
1137 PyObject *self;
1138 char *name;
1139{
1140 return Py_FindMethod (Tkapp_methods, self, name);
1141}
1142
1143static PyTypeObject Tkapp_Type =
1144{
Guido van Rossuma597dde1995-01-10 20:56:29 +00001145 PyObject_HEAD_INIT (&PyType_Type)
Guido van Rossum18468821994-06-20 07:49:28 +00001146 0, /*ob_size */
1147 "tkapp", /*tp_name */
1148 sizeof (TkappObject), /*tp_basicsize */
1149 0, /*tp_itemsize */
1150 Tkapp_Dealloc, /*tp_dealloc */
1151 0, /*tp_print */
1152 Tkapp_GetAttr, /*tp_getattr */
1153 0, /*tp_setattr */
1154 0, /*tp_compare */
1155 0, /*tp_repr */
1156 0, /*tp_as_number */
1157 0, /*tp_as_sequence */
1158 0, /*tp_as_mapping */
1159 0, /*tp_hash */
1160};
1161
1162/**** Tkinter Module ****/
1163
1164static PyObject *
1165Tkinter_Create (self, args)
1166 PyObject *self;
1167 PyObject *args;
1168{
1169 char *screenName = NULL;
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001170 char *baseName = NULL;
1171 char *className = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001172 int interactive = 0;
1173
1174 baseName = strrchr (getprogramname (), '/');
1175 if (baseName != NULL)
1176 baseName++;
1177 else
1178 baseName = getprogramname ();
1179 className = "Tk";
1180
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001181 if (!PyArg_ParseTuple (args, "|zssi",
1182 &screenName, &baseName, &className, &interactive))
Guido van Rossum18468821994-06-20 07:49:28 +00001183 return NULL;
1184
1185 return (PyObject *) Tkapp_New (screenName, baseName, className,
1186 interactive);
1187}
1188
1189static PyMethodDef moduleMethods[] =
1190{
Guido van Rossume42fc2f1995-07-26 17:29:45 +00001191 {"create", Tkinter_Create, 1},
1192 {"createfilehandler", Tkapp_CreateFileHandler, 0},
1193 {"deletefilehandler", Tkapp_DeleteFileHandler, 0},
1194 {"createtimerhandler", Tkapp_CreateTimerHandler, 0},
1195 {"mainloop", Tkapp_MainLoop, 1},
1196 {"dooneevent", Tkapp_DoOneEvent, 1},
Guido van Rossumf34cadd1994-11-10 22:50:21 +00001197 {"quit", Tkapp_Quit},
Guido van Rossum18468821994-06-20 07:49:28 +00001198 {NULL, NULL}
1199};
1200
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001201#undef WITH_READLINE /* XXX */
Guido van Rossum18468821994-06-20 07:49:28 +00001202#ifdef WITH_READLINE
1203static int
1204EventHook ()
1205{
1206 if (errorInCmd) /* XXX Reset tty */
1207 {
1208 errorInCmd = 0;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +00001209 PyErr_Restore (excInCmd, valInCmd, trbInCmd);
1210 excInCmd = valInCmd = trbInCmd = NULL;
Guido van Rossum18468821994-06-20 07:49:28 +00001211 PyErr_Print ();
1212 }
Guido van Rossum9722ad81995-09-22 23:49:28 +00001213 if (Tk_GetNumMainWindows() > 0)
Guido van Rossume2ca9bd1994-08-03 08:01:43 +00001214 Tk_DoOneEvent (TK_DONT_WAIT);
Guido van Rossum18468821994-06-20 07:49:28 +00001215 return 0;
1216}
1217#endif /* WITH_READLINE */
1218
1219static void
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001220Tkinter_Cleanup ()
1221{
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001222/* This segfault with Tk 4.0 beta and seems unnecessary there as well */
1223#if TK_MAJOR_VERSION < 4
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001224 /* XXX rl_deprep_terminal is static, damned! */
1225 while (tkMainWindowList != 0)
1226 Tk_DestroyWindow (tkMainWindowList->win);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001227#endif
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001228}
1229
Guido van Rossum18468821994-06-20 07:49:28 +00001230void
Jack Jansenba0311e1995-10-23 14:34:14 +00001231PyInit__tkinter ()
Guido van Rossum18468821994-06-20 07:49:28 +00001232{
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001233 static inited = 0;
1234
Guido van Rossum18468821994-06-20 07:49:28 +00001235#ifdef WITH_READLINE
1236 extern int (*rl_event_hook) ();
1237#endif /* WITH_READLINE */
1238 PyObject *m, *d, *v;
1239
Jack Jansenba0311e1995-10-23 14:34:14 +00001240 m = Py_InitModule ("_tkinter", moduleMethods);
Guido van Rossum18468821994-06-20 07:49:28 +00001241
1242 d = PyModule_GetDict (m);
1243 Tkinter_TclError = Py_BuildValue ("s", "TclError");
1244 PyDict_SetItemString (d, "TclError", Tkinter_TclError);
1245
1246 v = Py_BuildValue ("i", TK_READABLE);
1247 PyDict_SetItemString (d, "READABLE", v);
1248 v = Py_BuildValue ("i", TK_WRITABLE);
1249 PyDict_SetItemString (d, "WRITABLE", v);
1250 v = Py_BuildValue ("i", TK_EXCEPTION);
1251 PyDict_SetItemString (d, "EXCEPTION", v);
Guido van Rossum062cfb01995-01-10 17:42:51 +00001252 v = Py_BuildValue ("i", TK_X_EVENTS);
1253 PyDict_SetItemString (d, "X_EVENTS", v);
1254 v = Py_BuildValue ("i", TK_FILE_EVENTS);
1255 PyDict_SetItemString (d, "FILE_EVENTS", v);
1256 v = Py_BuildValue ("i", TK_TIMER_EVENTS);
1257 PyDict_SetItemString (d, "TIMER_EVENTS", v);
1258 v = Py_BuildValue ("i", TK_IDLE_EVENTS);
1259 PyDict_SetItemString (d, "IDLE_EVENTS", v);
1260 v = Py_BuildValue ("i", TK_ALL_EVENTS);
1261 PyDict_SetItemString (d, "ALL_EVENTS", v);
1262 v = Py_BuildValue ("i", TK_DONT_WAIT);
1263 PyDict_SetItemString (d, "DONT_WAIT", v);
Guido van Rossuma3c3f2c1995-02-07 15:41:02 +00001264 v = Py_BuildValue ("s", TK_VERSION);
1265 PyDict_SetItemString (d, "TK_VERSION", v);
1266 v = Py_BuildValue ("s", TCL_VERSION);
1267 PyDict_SetItemString (d, "TCL_VERSION", v);
Guido van Rossum18468821994-06-20 07:49:28 +00001268
Guido van Rossum18468821994-06-20 07:49:28 +00001269#ifdef WITH_READLINE
1270 rl_event_hook = EventHook;
1271#endif /* WITH_READLINE */
1272
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001273 if (!inited)
1274 {
1275 inited = 1;
Guido van Rossume4485b01994-09-07 14:32:49 +00001276 if (Py_AtExit (Tkinter_Cleanup) != 0)
1277 fprintf(stderr,
1278 "Tkinter: warning: cleanup procedure not registered\n");
Jack Jansen40b546d1995-11-14 10:34:45 +00001279#ifdef __MWERKS__
1280 PyTk_InitGUSI();
1281#endif
Guido van Rossumd308e2b1994-07-07 09:25:12 +00001282 }
1283
Guido van Rossum18468821994-06-20 07:49:28 +00001284 if (PyErr_Occurred ())
Jack Jansenba0311e1995-10-23 14:34:14 +00001285 Py_FatalError ("can't initialize module _tkinter");
Jack Jansen34cc5c31995-10-31 16:15:12 +00001286#ifdef macintosh
1287 mac_addlibresources();
1288#endif
Guido van Rossum18468821994-06-20 07:49:28 +00001289}
Guido van Rossum9722ad81995-09-22 23:49:28 +00001290
1291#ifdef macintosh
1292void
1293panic(char * format, ...)
1294{
1295 va_list varg;
1296
1297 va_start(varg, format);
1298
1299 vfprintf(stderr, format, varg);
1300 (void) fflush(stderr);
1301
1302 va_end(varg);
1303
1304 Py_FatalError("Tcl/Tk panic");
1305}
Jack Jansen40b546d1995-11-14 10:34:45 +00001306#ifdef __MWERKS__
1307void
1308PyTk_InitGUSI()
1309{
1310 static int is_inited;
1311
1312 if ( is_inited ) return;
1313 GUSISetup(GUSIwithInternetSockets);
1314 GUSISetup(GUSIwithSIOUXSockets);
1315 is_inited = 1;
1316}
1317#endif /* __MWERKS__ */
1318
Guido van Rossum9722ad81995-09-22 23:49:28 +00001319
Jack Jansen34cc5c31995-10-31 16:15:12 +00001320/*
1321** If this module is dynamically loaded the following routine should
1322** be the init routine. It takes care of adding the shared library to
1323** the resource-file chain, so that the tk routines can find their
1324** resources.
1325*/
1326OSErr pascal
1327init_tkinter_shlib(InitBlockPtr data)
1328{
1329 if ( data == nil ) return noErr;
1330 if ( data->fragLocator.where == kOnDiskFlat ) {
1331 library_fss = *data->fragLocator.u.onDisk.fileSpec;
1332 loaded_from_shlib = 1;
1333 } else if ( data->fragLocator.where == kOnDiskSegmented ) {
1334 library_fss = *data->fragLocator.u.inSegs.fileSpec;
1335 loaded_from_shlib = 1;
1336 }
1337 return noErr;
1338}
1339
1340/*
1341** Insert the library resources into the search path. Put them after
1342** the resources from the application. Again, we ignore errors.
1343*/
1344void
1345mac_addlibresources()
1346{
1347 if ( !loaded_from_shlib )
1348 return;
1349 (void)FSpOpenResFile(&library_fss, fsRdPerm);
1350}
1351
1352
Guido van Rossum9722ad81995-09-22 23:49:28 +00001353#endif