OSDN Git Service

Initial revision
[pf3gnuchains/sourceware.git] / tk / macosx / tkMacOSXAppInit.c
1 /* 
2  * tkAppInit.c --
3  *
4  *        Provides a default version of the Tcl_AppInit procedure for
5  *        use in wish and similar Tk-based applications.
6  *
7  * Copyright (c) 1993 The Regents of the University of California.
8  * Copyright (c) 1994-1997 Sun Microsystems, Inc.
9  * Copyright 2001, Apple Computer, Inc.
10  *
11  * See the file "license.terms" for information on usage and redistribution
12  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13  *
14  * RCS: @(#) $Id$
15  */
16 #include <pthread.h>
17 #include "tk.h"
18 #include "tclInt.h"
19 #include "locale.h"
20
21 #include <Carbon/Carbon.h>
22 #include "tkMacOSX.h"
23 #include "tkMacOSXEvent.h"
24
25 #ifndef MAX_PATH_LEN
26     #define MAX_PATH_LEN 1024
27 #endif
28
29 /*
30  * If the App is in an App package, then we want to add the Scripts
31  * directory to the auto_path.  But we have to wait till after the
32  * Tcl_Init is run, or it gets blown away.  This stores what we
33  * figured out in main.
34  */
35  
36 char scriptPath[MAX_PATH_LEN + 1];
37
38 extern Tcl_Interp *gStdoutInterp;
39
40 #ifdef TK_TEST
41 extern int                Tktest_Init _ANSI_ARGS_((Tcl_Interp *interp));
42 #endif /* TK_TEST */
43
44 /*
45  *----------------------------------------------------------------------
46  *
47  * main --
48  *
49  *        This is the main program for the application.
50  *
51  * Results:
52  *        None: Tk_Main never returns here, so this procedure never
53  *        returns either.
54  *
55  * Side effects:
56  *        Whatever the application does.
57  *
58  *----------------------------------------------------------------------
59  */
60
61 int
62 main(argc, argv)
63     int argc;                        /* Number of command-line arguments. */
64     char **argv;                /* Values of command-line arguments. */
65 {
66     int textEncoding; /* 
67                        * Variable used to take care of
68                        * lazy font initialization
69                        */
70     CFBundleRef bundleRef;
71
72     /*
73      * The following #if block allows you to change the AppInit
74      * function by using a #define of TCL_LOCAL_APPINIT instead
75      * of rewriting this entire file.  The #if checks for that
76      * #define and uses Tcl_AppInit if it doesn't exist.
77      */
78     
79 #ifndef TK_LOCAL_APPINIT
80 #define TK_LOCAL_APPINIT Tcl_AppInit    
81 #endif
82     extern int TK_LOCAL_APPINIT _ANSI_ARGS_((Tcl_Interp *interp));
83
84     scriptPath[0] = '\0';
85
86     /*
87      * The following #if block allows you to change how Tcl finds the startup
88      * script, prime the library or encoding paths, fiddle with the argv,
89      * etc., without needing to rewrite Tk_Main().  Note, if you use this
90      * hook, then I won't do the CFBundle lookup, since if you are messing
91      * around at this level, you probably don't want me to do this for you...
92      */
93     
94 #ifdef TK_LOCAL_MAIN_HOOK
95     extern int TK_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv));
96     TK_LOCAL_MAIN_HOOK(&argc, &argv);
97 #else
98
99     /*
100      * On MacOS X, we look for a file in the Resources/Scripts directory
101      * called AppMain.tcl and if found, we set argv[1] to that, so that
102      * the rest of the code will find it, and add the Scripts folder to
103      * the auto_path.  If we don't find the startup script, we just bag
104      * it, assuming the user is starting up some other way.
105      */
106     
107     bundleRef = CFBundleGetMainBundle();
108     
109     if (bundleRef != NULL) {
110         CFURLRef appMainURL;
111         appMainURL = CFBundleCopyResourceURL(bundleRef, 
112                 CFSTR("AppMain"), 
113                 CFSTR("tcl"), 
114                 CFSTR("Scripts"));
115
116         if (appMainURL != NULL) {
117             CFURLRef scriptFldrURL;
118             char *startupScript = malloc(MAX_PATH_LEN + 1);
119                             
120             if (CFURLGetFileSystemRepresentation (appMainURL, true,
121                     startupScript, MAX_PATH_LEN)) {
122                 TclSetStartupScriptFileName(startupScript);
123                 scriptFldrURL = CFBundleCopyResourceURL(bundleRef,
124                         CFSTR("Scripts"),
125                         NULL,
126                         NULL);
127                 CFURLGetFileSystemRepresentation(scriptFldrURL, 
128                         true, scriptPath, MAX_PATH_LEN);
129                 CFRelease(scriptFldrURL);
130             } else {
131                 free(startupScript);
132             }
133             CFRelease(appMainURL);
134         }
135     }
136
137 #endif
138     textEncoding=GetApplicationTextEncoding();
139     
140     /*
141      * Now add the scripts folder to the auto_path.
142      */
143      
144     Tk_Main(argc,argv,TK_LOCAL_APPINIT);
145     return 0;                        /* Needed only to prevent compiler warning. */
146 }
147
148 /*
149  *----------------------------------------------------------------------
150  *
151  * Tcl_AppInit --
152  *
153  *        This procedure performs application-specific initialization.
154  *        Most applications, especially those that incorporate additional
155  *        packages, will have their own version of this procedure.
156  *
157  * Results:
158  *        Returns a standard Tcl completion code, and leaves an error
159  *        message in the interp's result if an error occurs.
160  *
161  * Side effects:
162  *        Depends on the startup script.
163  *
164  *----------------------------------------------------------------------
165  */
166
167 int
168 Tcl_AppInit(interp)
169     Tcl_Interp *interp;                /* Interpreter for application. */
170 {        
171     if (Tcl_Init(interp) == TCL_ERROR) {
172         return TCL_ERROR;
173     }    
174     if (Tk_Init(interp) == TCL_ERROR) {
175         return TCL_ERROR;
176     }
177     Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);
178
179     if (scriptPath[0] != '\0') {
180         Tcl_SetVar(interp, "auto_path", scriptPath,
181                 TCL_GLOBAL_ONLY|TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
182     }
183     
184 #ifdef TK_TEST
185     if (Tktest_Init(interp) == TCL_ERROR) {
186         return TCL_ERROR;
187     }
188     Tcl_StaticPackage(interp, "Tktest", Tktest_Init,
189             (Tcl_PackageInitProc *) NULL);
190 #endif /* TK_TEST */
191
192     /*
193      * If we don't have a TTY, then use the Tk based console
194      * interpreter instead.
195      */
196
197     if (ttyname(0) == NULL) {
198         Tk_InitConsoleChannels(interp);
199         Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDIN));
200         Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDOUT));
201         Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDERR));
202         if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {
203             goto error;
204         }
205         /* Only show the console if we don't have a startup script */
206         if (TclGetStartupScriptPath() == NULL) {
207             Tcl_Eval(interp, "console show");
208         }
209     }
210     
211     /*
212      * Call the init procedures for included packages.  Each call should
213      * look like this:
214      *
215      * if (Mod_Init(interp) == TCL_ERROR) {
216      *     return TCL_ERROR;
217      * }
218      *
219      * where "Mod" is the name of the module.
220      */
221
222     /*
223      * Call Tcl_CreateCommand for application-specific commands, if
224      * they weren't already created by the init procedures called above.
225      */
226
227     
228     /*
229      * Specify a user-specific startup file to invoke if the application
230      * is run interactively.  Typically the startup file is "~/.apprc"
231      * where "app" is the name of the application.  If this line is deleted
232      * then no user-specific startup file will be run under any conditions.
233      */
234      
235     Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY);
236
237     return TCL_OK;
238
239     error:
240     return TCL_ERROR;
241 }