summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--win/tkWinInit.c24
-rw-r--r--win/winMain.c82
3 files changed, 75 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index f527e47..61d0045 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,10 @@
2010-11-24 Jan Nijtmans <nijtmans@users.sf.net>
* win/tkWinDialog.c: [Bug #3071836]: Crash/Tcl_Panic on WinXP saving file to C:\
+ * win/tkWinInit.c: re-wrote TkpDisplayWarning such that it does not use
+ an Tcl API calls any more, so it works even with an ill-initialized Tcl.
+ * win/winMain.c: Teach WishPanic how to thread UTF-8 in it's messagebox.
+ Both of those changes backported from Tcl 8.6. No change in functionality.
2010-11-19 Jan Nijtmans <nijtmans@users.sf.net>
diff --git a/win/tkWinInit.c b/win/tkWinInit.c
index 1a7f2be..b149996 100644
--- a/win/tkWinInit.c
+++ b/win/tkWinInit.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWinInit.c,v 1.14 2007/12/13 15:28:55 dgp Exp $
+ * RCS: @(#) $Id: tkWinInit.c,v 1.14.2.1 2010/11/24 15:15:25 nijtmans Exp $
*/
#include "tkWinInt.h"
@@ -118,27 +118,21 @@ TkpDisplayWarning(
CONST char *msg, /* Message to be displayed. */
CONST char *title) /* Title of warning. */
{
- Tcl_DString msgString, titleString;
- Tcl_Encoding unicodeEncoding = TkWinGetUnicodeEncoding();
+#define TK_MAX_WARN_LEN 1024
+ WCHAR msgString[TK_MAX_WARN_LEN + 5];
+ WCHAR titleString[TK_MAX_WARN_LEN + 1];
+ MultiByteToWideChar(CP_UTF8, 0, msg, -1, msgString, TK_MAX_WARN_LEN);
+ MultiByteToWideChar(CP_UTF8, 0, title, -1, titleString, TK_MAX_WARN_LEN);
/*
* Truncate MessageBox string if it is too long to not overflow the screen
* and cause possible oversized window error.
*/
-
-#define TK_MAX_WARN_LEN (1024 * sizeof(WCHAR))
- Tcl_UtfToExternalDString(unicodeEncoding, msg, -1, &msgString);
- Tcl_UtfToExternalDString(unicodeEncoding, title, -1, &titleString);
- if (Tcl_DStringLength(&msgString) > TK_MAX_WARN_LEN) {
- Tcl_DStringSetLength(&msgString, TK_MAX_WARN_LEN);
- Tcl_DStringAppend(&msgString, (char *) L" ...", 4 * sizeof(WCHAR));
- }
- MessageBoxW(NULL, (WCHAR *) Tcl_DStringValue(&msgString),
- (WCHAR *) Tcl_DStringValue(&titleString),
+ memcpy(msgString + TK_MAX_WARN_LEN, L" ...", 5 * sizeof(WCHAR));
+ titleString[TK_MAX_WARN_LEN] = L'\0';
+ MessageBoxW(NULL, msgString, titleString,
MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL
| MB_SETFOREGROUND | MB_TOPMOST);
- Tcl_DStringFree(&msgString);
- Tcl_DStringFree(&titleString);
}
/*
diff --git a/win/winMain.c b/win/winMain.c
index 273cf0f..57979f3 100644
--- a/win/winMain.c
+++ b/win/winMain.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: winMain.c,v 1.26.2.1 2010/05/31 13:47:33 nijtmans Exp $
+ * RCS: @(#) $Id: winMain.c,v 1.26.2.2 2010/11/24 15:15:25 nijtmans Exp $
*/
#include "tkInt.h"
@@ -23,15 +23,21 @@
* 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 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);
@@ -156,6 +162,9 @@ int
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;
}
@@ -175,20 +184,15 @@ Tcl_AppInit(
}
}
#if defined(STATIC_BUILD) && 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 (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
@@ -198,12 +202,43 @@ Tcl_AppInit(
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);
@@ -235,13 +270,20 @@ WishPanic(
CONST char *format, ...)
{
va_list argList;
- char buf[1024];
+ 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();