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