summaryrefslogtreecommitdiffstats
path: root/win/winMain.c
diff options
context:
space:
mode:
Diffstat (limited to 'win/winMain.c')
-rw-r--r--win/winMain.c330
1 files changed, 195 insertions, 135 deletions
diff --git a/win/winMain.c b/win/winMain.c
index b4e11f7..2883ad7 100644
--- a/win/winMain.c
+++ b/win/winMain.c
@@ -1,4 +1,4 @@
-/*
+/*
* winMain.c --
*
* Main entry point for wish and other Tk-based applications.
@@ -6,60 +6,63 @@
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
* Copyright (c) 1998-1999 by Scriptics Corporation.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include <tk.h>
+#include "tkInt.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
-#include <malloc.h>
#include <locale.h>
-#include "tkInt.h"
/*
- * The following declarations refer to internal Tk routines. These
- * interfaces are available for use, but are not supported.
+ * The following declarations refer to internal Tk routines. These interfaces
+ * are available for use, but are not supported.
*/
+#ifdef TK_TEST
+extern Tcl_PackageInitProc Tktest_Init;
+#endif /* TK_TEST */
+#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES
+extern Tcl_PackageInitProc Registry_Init;
+extern Tcl_PackageInitProc Dde_Init;
+extern Tcl_PackageInitProc Dde_SafeInit;
+#endif
/*
* Forward declarations for procedures defined later in this file:
*/
-static void setargv _ANSI_ARGS_((int *argcPtr, char ***argvPtr));
-static Tcl_PanicProc WishPanic;
+static void WishPanic(CONST char *format, ...);
-#ifdef TK_TEST
-extern int Tktest_Init(Tcl_Interp *interp);
-#endif /* TK_TEST */
+#if defined(__CYGWIN__)
+static void setargv(int *argcPtr, char ***argvPtr);
+#endif /* __CYGWIN__ */
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.
+ * 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
+#define TK_LOCAL_APPINIT Tcl_AppInit
#endif
-extern int TK_LOCAL_APPINIT _ANSI_ARGS_((Tcl_Interp *interp));
-
+extern 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()
+ * script, prime the library or encoding paths, fiddle with the argv, etc.,
+ * without needing to rewrite Tk_Main()
*/
#ifdef TK_LOCAL_MAIN_HOOK
-extern int TK_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv));
+extern int TK_LOCAL_MAIN_HOOK(int *argc, char ***argv);
#endif
-
/*
*----------------------------------------------------------------------
@@ -69,8 +72,7 @@ extern int TK_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv));
* Main entry point from Windows.
*
* Results:
- * Returns false if initialization fails, otherwise it never
- * returns.
+ * Returns false if initialization fails, otherwise it never returns.
*
* Side effects:
* Just about anything, since from here we call arbitrary Tcl code.
@@ -79,43 +81,49 @@ extern int TK_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv));
*/
int APIENTRY
-WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
- HINSTANCE hInstance;
- HINSTANCE hPrevInstance;
- LPSTR lpszCmdLine;
- int nCmdShow;
+WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpszCmdLine,
+ int nCmdShow)
{
char **argv;
int argc;
- char buffer[MAX_PATH+1];
char *p;
Tcl_SetPanicProc(WishPanic);
/*
- * 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.
+ * 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.
+ * 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.
+ */
+
+#if defined(__CYGWIN__)
setargv(&argc, &argv);
+#else
+ argc = __argc;
+ argv = __argv;
+#endif
/*
- * Replace argv[0] with full pathname of executable, and forward
- * slashes substituted for backslashes.
+ * Forward slashes substituted for backslashes.
*/
- GetModuleFileName(NULL, buffer, sizeof(buffer));
- argv[0] = buffer;
- for (p = buffer; *p != '\0'; p++) {
+ for (p = argv[0]; *p != '\0'; p++) {
if (*p == '\\') {
*p = '/';
}
@@ -128,20 +136,19 @@ WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
Tk_Main(argc, argv, TK_LOCAL_APPINIT);
return 1;
}
-
/*
*----------------------------------------------------------------------
*
* Tcl_AppInit --
*
- * This procedure performs application-specific initialization.
- * Most applications, especially those that incorporate additional
- * packages, will have their own version of this procedure.
+ * 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.
+ * 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.
@@ -150,9 +157,12 @@ WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
*/
int
-Tcl_AppInit(interp)
- Tcl_Interp *interp; /* Interpreter for application. */
+Tcl_AppInit(
+ Tcl_Interp *interp) /* Interpreter for application. */
{
+#define TK_MAX_WARN_LEN 1024
+ WCHAR msgString[TK_MAX_WARN_LEN + 5];
+
if (Tcl_Init(interp) == TCL_ERROR) {
goto error;
}
@@ -171,40 +181,69 @@ Tcl_AppInit(interp)
goto error;
}
}
-#if defined(STATIC_BUILD) && defined(TCL_USE_STATIC_PACKAGES)
- {
- extern Tcl_PackageInitProc Registry_Init;
- extern Tcl_PackageInitProc Dde_Init;
-
- if (Registry_Init(interp) == TCL_ERROR) {
- return TCL_ERROR;
- }
- Tcl_StaticPackage(interp, "registry", Registry_Init, NULL);
+#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES
+ if (Registry_Init(interp) == TCL_ERROR) {
+ goto error;
+ }
+ Tcl_StaticPackage(interp, "registry", Registry_Init, NULL);
- if (Dde_Init(interp) == TCL_ERROR) {
- return TCL_ERROR;
- }
- Tcl_StaticPackage(interp, "dde", Dde_Init, NULL);
- }
+ if (Dde_Init(interp) == TCL_ERROR) {
+ goto error;
+ }
+ Tcl_StaticPackage(interp, "dde", Dde_Init, NULL);
#endif
#ifdef TK_TEST
if (Tktest_Init(interp) == TCL_ERROR) {
goto error;
}
- Tcl_StaticPackage(interp, "Tktest", Tktest_Init,
- (Tcl_PackageInitProc *) NULL);
+ Tcl_StaticPackage(interp, "Tktest", Tktest_Init, NULL);
#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_CreateCommand 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.
+ */
+
Tcl_SetVar(interp, "tcl_rcFileName", "~/wishrc.tcl", TCL_GLOBAL_ONLY);
return TCL_OK;
error:
+ MultiByteToWideChar(CP_UTF8, 0, Tcl_GetStringResult(interp), -1,
+ msgString, TK_MAX_WARN_LEN);
+ /*
+ * Truncate MessageBox string if it is too long to not overflow the screen
+ * and cause possible oversized window error.
+ */
+ memcpy(msgString + TK_MAX_WARN_LEN, L" ...", 5 * sizeof(WCHAR));
MessageBeep(MB_ICONEXCLAMATION);
- MessageBox(NULL, Tcl_GetStringResult(interp), "Error in Wish",
+ MessageBoxW(NULL, msgString, L"Error in Wish",
MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
ExitProcess(1);
- /* we won't reach this, but we need the return */
+
+ /*
+ * We won't reach this, but we need the return.
+ */
+
return TCL_ERROR;
}
@@ -225,32 +264,85 @@ error:
*/
void
-WishPanic TCL_VARARGS_DEF(CONST char *,arg1)
+WishPanic(
+ CONST char *format, ...)
{
va_list argList;
- char buf[1024];
- CONST char *format;
-
- format = TCL_VARARGS_START(CONST char *,arg1,argList);
+ char buf[TK_MAX_WARN_LEN];
+ WCHAR msgString[TK_MAX_WARN_LEN + 5];
+
+ va_start(argList, format);
vsprintf(buf, format, argList);
+ MultiByteToWideChar(CP_UTF8, 0, buf, -1, msgString, TK_MAX_WARN_LEN);
+ /*
+ * Truncate MessageBox string if it is too long to not overflow the screen
+ * and cause possible oversized window error.
+ */
+ memcpy(msgString + TK_MAX_WARN_LEN, L" ...", 5 * sizeof(WCHAR));
MessageBeep(MB_ICONEXCLAMATION);
- MessageBox(NULL, buf, "Fatal Error in Wish",
+ MessageBoxW(NULL, msgString, L"Fatal Error in Wish",
MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
#ifdef _MSC_VER
DebugBreak();
#endif
ExitProcess(1);
}
+
+#if !defined(__GNUC__) || defined(TK_TEST)
+/*
+ *----------------------------------------------------------------------
+ *
+ * main --
+ *
+ * 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
+main(
+ int argc,
+ char **argv)
+{
+ Tcl_SetPanicProc(WishPanic);
+
+ /*
+ * 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;
+
+ Tk_Main(argc, argv, Tcl_AppInit);
+ return 0;
+}
+#endif /* !__GNUC__ || TK_TEST */
+
+
/*
*-------------------------------------------------------------------------
*
* setargv --
*
- * Parse the Windows command line string into argc/argv. Done here
- * because we don't trust the builtin argument parser in crt0.
- * Windows applications are responsible for breaking their command
- * line into arguments.
+ * Parse the Windows command line string into argc/argv. Done here
+ * because we don't trust the builtin argument parser in crt0. Windows
+ * applications are responsible for breaking their command line into
+ * arguments.
*
* 2N backslashes + quote -> N backslashes + begin quoted string
* 2N + 1 backslashes + quote -> literal
@@ -260,8 +352,8 @@ WishPanic TCL_VARARGS_DEF(CONST char *,arg1)
* quote -> begin quoted string
*
* Results:
- * Fills argcPtr with the number of arguments and argvPtr with the
- * array of arguments.
+ * Fills argcPtr with the number of arguments and argvPtr with the array
+ * of arguments.
*
* Side effects:
* Memory allocated.
@@ -269,20 +361,21 @@ WishPanic TCL_VARARGS_DEF(CONST char *,arg1)
*--------------------------------------------------------------------------
*/
+#if defined(__CYGWIN__)
static void
-setargv(argcPtr, argvPtr)
- int *argcPtr; /* Filled with number of argument strings. */
- char ***argvPtr; /* Filled with argument strings (malloc'd). */
+setargv(
+ int *argcPtr, /* Filled with number of argument strings. */
+ char ***argvPtr) /* Filled with argument strings (malloc'd). */
{
char *cmdLine, *p, *arg, *argSpace;
char **argv;
int argc, size, inquote, copy, slashes;
-
+
cmdLine = GetCommandLine(); /* INTL: BUG */
/*
- * Precompute an overly pessimistic guess at the number of arguments
- * in the command line by counting non-space spans.
+ * Precompute an overly pessimistic guess at the number of arguments in
+ * the command line by counting non-space spans.
*/
size = 2;
@@ -297,7 +390,7 @@ setargv(argcPtr, argvPtr)
}
}
}
- argSpace = (char *) Tcl_Alloc(
+ argSpace = (char *) ckalloc(
(unsigned) (size * sizeof(char *) + strlen(cmdLine) + 1));
argv = (char **) argSpace;
argSpace += size * sizeof(char *);
@@ -330,18 +423,18 @@ setargv(argcPtr, argvPtr)
} else {
inquote = !inquote;
}
- }
- slashes >>= 1;
- }
+ }
+ slashes >>= 1;
+ }
- while (slashes) {
+ while (slashes) {
*arg = '\\';
arg++;
slashes--;
}
- if ((*p == '\0')
- || (!inquote && ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */
+ if ((*p == '\0') || (!inquote &&
+ ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */
break;
}
if (copy != 0) {
@@ -349,7 +442,7 @@ setargv(argcPtr, argvPtr)
arg++;
}
p++;
- }
+ }
*arg = '\0';
argSpace = arg + 1;
}
@@ -358,45 +451,12 @@ setargv(argcPtr, argvPtr)
*argcPtr = argc;
*argvPtr = argv;
}
-
-#if !defined(__GNUC__) || defined(TK_TEST)
+#endif /* __CYGWIN__ */
+
/*
- *----------------------------------------------------------------------
- *
- * main --
- *
- * 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.
- *
- *----------------------------------------------------------------------
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
*/
-
-int main(int argc, char **argv)
-{
- Tcl_SetPanicProc(WishPanic);
-
- /*
- * Set up the default locale to be standard "C" locale so parsing
- * is performed correctly.
- */
-
- setlocale(LC_ALL, "C");
-
- /*
- * 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 = FALSE;
-
- Tk_Main(argc, argv, Tcl_AppInit);
- return 0;
-}
-#endif /* !__GNUC__ || TK_TEST */