4 * Provides a default version of the Tcl_AppInit procedure for
5 * use in wish and similar Tk-based applications.
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.
11 * See the file "license.terms" for information on usage and redistribution
12 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
21 #include <Carbon/Carbon.h>
23 #include "tkMacOSXEvent.h"
26 #define MAX_PATH_LEN 1024
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.
36 char scriptPath[MAX_PATH_LEN + 1];
38 extern Tcl_Interp *gStdoutInterp;
41 extern int Tktest_Init _ANSI_ARGS_((Tcl_Interp *interp));
45 *----------------------------------------------------------------------
49 * This is the main program for the application.
52 * None: Tk_Main never returns here, so this procedure never
56 * Whatever the application does.
58 *----------------------------------------------------------------------
63 int argc; /* Number of command-line arguments. */
64 char **argv; /* Values of command-line arguments. */
67 * Variable used to take care of
68 * lazy font initialization
70 CFBundleRef bundleRef;
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.
79 #ifndef TK_LOCAL_APPINIT
80 #define TK_LOCAL_APPINIT Tcl_AppInit
82 extern int TK_LOCAL_APPINIT _ANSI_ARGS_((Tcl_Interp *interp));
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...
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);
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.
107 bundleRef = CFBundleGetMainBundle();
109 if (bundleRef != NULL) {
111 appMainURL = CFBundleCopyResourceURL(bundleRef,
116 if (appMainURL != NULL) {
117 CFURLRef scriptFldrURL;
118 char *startupScript = malloc(MAX_PATH_LEN + 1);
120 if (CFURLGetFileSystemRepresentation (appMainURL, true,
121 startupScript, MAX_PATH_LEN)) {
122 TclSetStartupScriptFileName(startupScript);
123 scriptFldrURL = CFBundleCopyResourceURL(bundleRef,
127 CFURLGetFileSystemRepresentation(scriptFldrURL,
128 true, scriptPath, MAX_PATH_LEN);
129 CFRelease(scriptFldrURL);
133 CFRelease(appMainURL);
138 textEncoding=GetApplicationTextEncoding();
141 * Now add the scripts folder to the auto_path.
144 Tk_Main(argc,argv,TK_LOCAL_APPINIT);
145 return 0; /* Needed only to prevent compiler warning. */
149 *----------------------------------------------------------------------
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.
158 * Returns a standard Tcl completion code, and leaves an error
159 * message in the interp's result if an error occurs.
162 * Depends on the startup script.
164 *----------------------------------------------------------------------
169 Tcl_Interp *interp; /* Interpreter for application. */
171 if (Tcl_Init(interp) == TCL_ERROR) {
174 if (Tk_Init(interp) == TCL_ERROR) {
177 Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);
179 if (scriptPath[0] != '\0') {
180 Tcl_SetVar(interp, "auto_path", scriptPath,
181 TCL_GLOBAL_ONLY|TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
185 if (Tktest_Init(interp) == TCL_ERROR) {
188 Tcl_StaticPackage(interp, "Tktest", Tktest_Init,
189 (Tcl_PackageInitProc *) NULL);
193 * If we don't have a TTY, then use the Tk based console
194 * interpreter instead.
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) {
205 /* Only show the console if we don't have a startup script */
206 if (TclGetStartupScriptPath() == NULL) {
207 Tcl_Eval(interp, "console show");
212 * Call the init procedures for included packages. Each call should
215 * if (Mod_Init(interp) == TCL_ERROR) {
219 * where "Mod" is the name of the module.
223 * Call Tcl_CreateCommand for application-specific commands, if
224 * they weren't already created by the init procedures called above.
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.
235 Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY);