--- mtcltk.0.m	2007-01-10 10:32:26.000000000 +0100
+++ mtcltk.m	2007-01-16 23:14:41.386086400 +0100
@@ -14,7 +14,7 @@
 %
 % See the file "HOWTO" for instructions on how to link with this library.
 %
-%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------% 
 %-----------------------------------------------------------------------------%
 
 :- module mtcltk.
@@ -128,6 +128,9 @@
 :- pragma foreign_decl("C", "
     extern MR_Word mtcltk_mercury_initializer;
     extern char *mtcltk_strdup(const char *str);
+    void mtcltk_MainEx(int argc, char **argv,
+		       Tcl_AppInitProc *appInitProc,
+		       Tcl_Interp *interp);
 ").
 
 :- pragma foreign_code("C", "
@@ -162,10 +165,92 @@
 
     mtcltk_mercury_initializer = Closure;
 
-    Tk_Main(argc, argv, Tcl_AppInit);
+    mtcltk_MainEx(argc, argv, Tcl_AppInit, Tcl_CreateInterp());
     IO = IO0;
 }").
 
+
+:- pragma foreign_code("C", "
+void
+mtcltk_MainEx(int argc, char **argv,
+	      Tcl_AppInitProc *appInitProc,
+	      Tcl_Interp *interp)
+{
+    Tcl_Obj *argvPtr;
+    size_t length;
+    Tcl_DString appName;
+
+    /*
+    ** Ensure that we are getting the matching version of Tcl.  This is
+    ** really only an issue when Tk is loaded dynamically.
+    */
+    if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) {
+	abort();
+    }
+
+    Tcl_FindExecutable(argv[0]);
+    Tcl_Preserve((ClientData) interp);
+
+#if (defined(__WIN32__) || defined(MAC_TCL))
+    Tk_InitConsoleChannels(interp);
+#endif
+
+#ifdef MAC_OSX_TK
+    if (TclGetStartupScriptFileName() == NULL) {
+        TkMacOSXDefaultStartupScript();
+    }
+#endif
+    
+#ifdef TCL_MEM_DEBUG
+    Tcl_InitMemory(interp);
+#endif
+
+    /*
+    ** Make command-line arguments available in the Tcl variables ""argc""
+    ** and ""argv"".
+    */
+    if (TclGetStartupScriptFileName() == NULL) {
+	Tcl_ExternalToUtfDString(NULL, argv[0], -1, &appName);
+    } else {
+	TclSetStartupScriptFileName(Tcl_ExternalToUtfDString(NULL,
+		TclGetStartupScriptFileName(), -1, &appName));
+    }
+    Tcl_SetVar(interp, ""argv0"", Tcl_DStringValue(&appName), TCL_GLOBAL_ONLY);
+    Tcl_DStringFree(&appName);
+    argc--;
+    argv++;
+
+    Tcl_SetVar2Ex(interp, ""argc"", NULL, Tcl_NewIntObj(argc), TCL_GLOBAL_ONLY);
+
+    argvPtr = Tcl_NewListObj(0, NULL);
+    while (argc--) {
+	Tcl_DString ds;
+	Tcl_ExternalToUtfDString(NULL, *argv++, -1, &ds);
+	Tcl_ListObjAppendElement(NULL, argvPtr, Tcl_NewStringObj(
+		Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)));
+	Tcl_DStringFree(&ds);
+    }
+    Tcl_SetVar2Ex(interp, ""argv"", NULL, argvPtr, TCL_GLOBAL_ONLY);
+
+    /*
+    ** Invoke application-specific initialization.
+    */
+    if ((*appInitProc)(interp) != TCL_OK) {
+	TkpDisplayWarning(Tcl_GetStringResult(interp),
+		""Application initialization failed"");
+    }
+
+    /*
+    ** Loop infinitely, waiting for commands to execute.  When there
+    ** are no windows left, Tk_MainLoop returns and we exit.
+    */
+    Tk_MainLoop();
+    Tcl_DeleteInterp(interp);
+    Tcl_Release((ClientData) interp);
+    Tcl_Exit(0);
+}
+").
+
 :- pragma export(call_mercury_initializer(pred(in, di, uo) is det, in, di, uo),
     "mtcltk_call_mercury_initializer").
 :- pred call_mercury_initializer(
