/* * winMain.c -- * * Provides a default version of the main program and Tcl_AppInit * procedure for wish and other Tk-based applications. * * Copyright © 1993 The Regents of the University of California. * Copyright © 1994-1997 Sun Microsystems, Inc. * Copyright © 1998-1999 Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ /* * Explanation on following undef USE_TCL_STUBS by JN 2023-12-19 on the core list: * What's going on is related to TIP #596: * Stubs support for Embedding Tcl in other applications * * If an application using Tcl_Main() is compiled with USE_TCL_STUBS, * Tcl_Main() will be replaced by a stub function, which loads * libtcl9.1.so/tcl91.dll and then calls its Tcl_MainEx(). If * libtcl9.1.so/tcl91.dll is not present (at runtime), a crash is what happens. * * So ... tkAppInit.c should not be compiled with USE_TCL_STUBS * (unless you want to use the TIP #596 functionality) * * The proper solution is to make sure that Makefile.in doesn't use * TCL_USE_STUBS when compiling tkAppInit.c. But that's a * quite big re-organization just before a b1 release. Simpler * is just to #undef'ine USE_TCL_STUBS, it has the same effect. */ #undef USE_TCL_STUBS #include "tk.h" #define WIN32_LEAN_AND_MEAN #include #undef WIN32_LEAN_AND_MEAN #include #include #include #if (TCL_MAJOR_VERSION < 9) # define Tcl_LibraryInitProc Tcl_PackageInitProc # define Tcl_StaticLibrary Tcl_StaticPackage #endif #if defined(__GNUC__) int _CRT_glob = 0; #endif /* __GNUC__ */ #ifdef __cplusplus extern "C" { #endif #ifdef TK_TEST extern Tcl_LibraryInitProc Tktest_Init; #endif /* TK_TEST */ #if !defined(TCL_USE_STATIC_PACKAGES) # if TCL_MAJOR_VERSION > 8 # define TCL_USE_STATIC_PACKAGES 1 # else # define TCL_USE_STATIC_PACKAGES 0 # endif #endif #if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES extern Tcl_LibraryInitProc Registry_Init; extern Tcl_LibraryInitProc Dde_Init; extern Tcl_LibraryInitProc Dde_SafeInit; #endif #ifdef __cplusplus } #endif /* * Forward declarations for procedures defined later in this file: */ static BOOL consoleRequired = TRUE; /* * The following #if block allows you to change the AppInit function by using * a #define of TCL_LOCAL_APPINIT instead of rewriting this entire file. The * #if checks for that #define and uses Tcl_AppInit if it doesn't exist. */ #ifndef TK_LOCAL_APPINIT #define TK_LOCAL_APPINIT Tcl_AppInit #endif #ifndef MODULE_SCOPE # ifdef __cplusplus # define MODULE_SCOPE extern "C" # else # define MODULE_SCOPE extern # endif #endif MODULE_SCOPE int TK_LOCAL_APPINIT(Tcl_Interp *interp); /* * The following #if block allows you to change how Tcl finds the startup * script, prime the library or encoding paths, fiddle with the argv, etc., * without needing to rewrite Tk_Main() */ #ifdef TK_LOCAL_MAIN_HOOK MODULE_SCOPE int TK_LOCAL_MAIN_HOOK(int *argc, TCHAR ***argv); #endif /* Make sure the stubbed variants of those are never used. */ #undef Tcl_ObjSetVar2 #undef Tcl_NewStringObj /* *---------------------------------------------------------------------- * * _tWinMain -- * * Main entry point from Windows. * * Results: * Returns false if initialization fails, otherwise it never returns. * * Side effects: * Just about anything, since from here we call arbitrary Tcl code. * *---------------------------------------------------------------------- */ int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpszCmdLine, int nCmdShow) { TCHAR **argv; int argc; TCHAR *p; (void)hInstance; (void)hPrevInstance; (void)lpszCmdLine; (void)nCmdShow; /* * Create the console channels and install them as the standard channels. * All I/O will be discarded until Tk_CreateConsoleWindow is called to * attach the console to a text widget. */ consoleRequired = TRUE; /* * Set up the default locale to be standard "C" locale so parsing is * performed correctly. */ setlocale(LC_ALL, "C"); /* * Get our args from the c-runtime. Ignore lpszCmdLine. */ argc = __argc; argv = __targv; /* * Forward slashes substituted for backslashes. */ for (p = argv[0]; *p != '\0'; p++) { if (*p == '\\') { *p = '/'; } } #ifdef TK_LOCAL_MAIN_HOOK TK_LOCAL_MAIN_HOOK(&argc, &argv); #elif defined(UNICODE) && (TCL_MAJOR_VERSION > 8) /* This doesn't work on Windows without UNICODE, neither does it work with Tcl 8.6 */ TclZipfs_AppHook(&argc, &argv); #endif Tk_Main(argc, argv, TK_LOCAL_APPINIT); return 0; /* Needed only to prevent compiler warning. */ } /* *---------------------------------------------------------------------- * * Tcl_AppInit -- * * This procedure performs application-specific initialization. Most * applications, especially those that incorporate additional packages, * will have their own version of this procedure. * * Results: * Returns a standard Tcl completion code, and leaves an error message in * the interp's result if an error occurs. * * Side effects: * Depends on the startup script. * *---------------------------------------------------------------------- */ int Tcl_AppInit( Tcl_Interp *interp) /* Interpreter for application. */ { if ((Tcl_Init)(interp) == TCL_ERROR) { return TCL_ERROR; } #if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES if (Registry_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticLibrary(interp, "Registry", Registry_Init, 0); if (Dde_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticLibrary(interp, "Dde", Dde_Init, Dde_SafeInit); #endif if (Tk_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticLibrary(interp, "Tk", Tk_Init, Tk_SafeInit); /* * Initialize the console only if we are running as an interactive * application. */ if (consoleRequired) { if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) { return TCL_ERROR; } } #ifdef TK_TEST if (Tktest_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticLibrary(interp, "Tktest", Tktest_Init, 0); #endif /* TK_TEST */ /* * Call the init procedures for included packages. Each call should look * like this: * * if (Mod_Init(interp) == TCL_ERROR) { * return TCL_ERROR; * } * * where "Mod" is the name of the module. (Dynamically-loadable packages * should have the same entry-point name.) */ /* * Call Tcl_CreateObjCommand for application-specific commands, if they * weren't already created by the init procedures called above. */ /* * Specify a user-specific startup file to invoke if the application is * run interactively. Typically the startup file is "~/.apprc" where "app" * is the name of the application. If this line is deleted then no * user-specific startup file will be run under any conditions. */ (void) Tcl_EvalEx(interp, "set tcl_rcFileName [file tildeexpand ~/wishrc.tcl]", -1, TCL_EVAL_GLOBAL); return TCL_OK; } #if defined(TK_TEST) /* *---------------------------------------------------------------------- * * _tmain -- * * Main entry point from the console. * * Results: * None: Tk_Main never returns here, so this procedure never returns * either. * * Side effects: * Whatever the applications does. * *---------------------------------------------------------------------- */ int _tmain( int argc, TCHAR **argv) { /* * Set up the default locale to be standard "C" locale so parsing is * performed correctly. */ setlocale(LC_ALL, "C"); /* * Console emulation widget not required as this entry is from the * console subsystem, thus stdin,out,err already have end-points. */ consoleRequired = FALSE; #ifdef TK_LOCAL_MAIN_HOOK TK_LOCAL_MAIN_HOOK(&argc, &argv); #endif Tk_Main(argc, argv, Tcl_AppInit); return 0; } #endif /* !__GNUC__ || TK_TEST */ /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */