summaryrefslogtreecommitdiffstats
path: root/win/tclWin16.c
diff options
context:
space:
mode:
Diffstat (limited to 'win/tclWin16.c')
-rw-r--r--win/tclWin16.c347
1 files changed, 347 insertions, 0 deletions
diff --git a/win/tclWin16.c b/win/tclWin16.c
new file mode 100644
index 0000000..d8ea801
--- /dev/null
+++ b/win/tclWin16.c
@@ -0,0 +1,347 @@
+/*
+ * tclWin16.c --
+ *
+ * This file contains code for a 16-bit DLL to handle 32-to-16 bit
+ * thunking. This is necessary for the Win32s SynchSpawn() call.
+ *
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * SCCS: @(#) tclWin16.c 1.18 97/05/23 13:13:32
+ */
+
+#define STRICT
+
+#include <windows.h>
+#include <toolhelp.h>
+
+#include <stdio.h>
+#include <string.h>
+
+static int WinSpawn(char *command);
+static int DosSpawn(char *command, char *fromFileName,
+ char *toFileName);
+static int WaitForExit(int inst);
+
+/*
+ * The following data is used to construct a .pif file that wraps the
+ * .bat file that runs the 16-bit application (that Jack built).
+ * The .pif file causes the .bat file to run in an iconified window.
+ * Otherwise, when we try to exec something, a DOS box pops up,
+ * obscuring everything, and then almost immediately flickers out of
+ * existence, which is rather disconcerting.
+ */
+
+static char pifData[545] = {
+'\000', '\013', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\200', '\000', '\200', '\000', '\103', '\117', '\115', '\115',
+'\101', '\116', '\104', '\056', '\103', '\117', '\115', '\000',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\020', '\000', '\000', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\177', '\001', '\000',
+'\377', '\031', '\120', '\000', '\000', '\007', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\340',
+'\040', '\115', '\111', '\103', '\122', '\117', '\123', '\117',
+'\106', '\124', '\040', '\120', '\111', '\106', '\105', '\130',
+'\000', '\207', '\001', '\000', '\000', '\161', '\001', '\127',
+'\111', '\116', '\104', '\117', '\127', '\123', '\040', '\063',
+'\070', '\066', '\040', '\063', '\056', '\060', '\000', '\005',
+'\002', '\235', '\001', '\150', '\000', '\200', '\002', '\200',
+'\000', '\144', '\000', '\062', '\000', '\000', '\004', '\000',
+'\000', '\000', '\004', '\000', '\000', '\002', '\020', '\002',
+'\000', '\037', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\057', '\143', '\040',
+'\146', '\157', '\157', '\056', '\142', '\141', '\164', '\000',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\127', '\111', '\116',
+'\104', '\117', '\127', '\123', '\040', '\062', '\070', '\066',
+'\040', '\063', '\056', '\060', '\000', '\377', '\377', '\033',
+'\002', '\006', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000'
+};
+
+static HINSTANCE hInstance;
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * LibMain --
+ *
+ * 16-bit DLL entry point.
+ *
+ * Results:
+ * Returns 1.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int CALLBACK
+LibMain(
+ HINSTANCE hinst,
+ WORD wDS,
+ WORD cbHeap,
+ LPSTR unused)
+{
+ hInstance = hinst;
+ wDS = wDS; /* lint. */
+ cbHeap = cbHeap; /* lint. */
+ unused = unused; /* lint. */
+
+ return TRUE;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UTProc --
+ *
+ * Universal Thunk dispatch routine. Executes a 16-bit DOS
+ * application or a 16-bit or 32-bit Windows application and
+ * waits for it to complete.
+ *
+ * Results:
+ * 1 if the application could be run, 0 or -1 on failure.
+ *
+ * Side effects:
+ * Executes 16-bit code.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int WINAPI
+UTProc(buf, func)
+ void *buf;
+ DWORD func;
+{
+ char **args;
+
+ args = (char **) buf;
+ if (func == 0) {
+ return DosSpawn(args[0], args[1], args[2]);
+ } else {
+ return WinSpawn(args[0]);
+ }
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * WinSpawn --
+ *
+ * Start a 16-bit or 32-bit Windows application with optional
+ * command line arguments and wait for it to finish. Windows
+ * applications do not handle input/output redirection.
+ *
+ * Results:
+ * The return value is 1 if the application could be run, 0 otherwise.
+ *
+ * Side effects:
+ * Whatever the application does.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+WinSpawn(command)
+ char *command; /* The command line, consisting of the name
+ * of the executable to run followed by any
+ * number of arguments to the executable. */
+{
+ return WaitForExit(WinExec(command, SW_SHOW));
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DosSpawn --
+ *
+ * Start a 16-bit DOS program with optional command line arguments
+ * and wait for it to finish. Input and output can be redirected
+ * from the specified files, but there is no such thing as stderr
+ * under Win32s.
+ *
+ * This procedure to constructs a temporary .pif file that wraps a
+ * temporary .bat file that runs the 16-bit application. The .bat
+ * file is necessary to get the redirection symbols '<' and '>' to
+ * work, because WinExec() doesn't accept them. The .pif file is
+ * necessary to cause the .bat file to run in an iconified window,
+ * to avoid having a large DOS box pop up, obscuring everything, and
+ * then almost immediately flicker out of existence, which is rather
+ * disconcerting.
+ *
+ * Results:
+ * The return value is 1 if the application could be run, 0 otherwise.
+ *
+ * Side effects:
+ * Whatever the application does.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+DosSpawn(command, fromFileName, toFileName)
+ char *command; /* The name of the program, plus any
+ * arguments, to be run. */
+ char *fromFileName; /* Standard input for the program is to be
+ * redirected from this file, or NULL for no
+ * standard input. */
+ char *toFileName; /* Standard output for the program is to be
+ * redirected to this file, or NULL to
+ * discard standard output. */
+{
+ int result;
+ HFILE batFile, pifFile;
+ char batFileName[144], pifFileName[144];
+
+ GetTempFileName(0, "tcl", 0, batFileName);
+ unlink(batFileName);
+ strcpy(strrchr(batFileName, '.'), ".bat");
+ batFile = _lcreat(batFileName, 0);
+
+ GetTempFileName(0, "tcl", 0, pifFileName);
+ unlink(pifFileName);
+ strcpy(strrchr(pifFileName, '.'), ".pif");
+ pifFile = _lcreat(pifFileName, 0);
+
+ _lwrite(batFile, command, strlen(command));
+ if (fromFileName == NULL) {
+ _lwrite(batFile, " < nul", 6);
+ } else {
+ _lwrite(batFile, " < ", 3);
+ _lwrite(batFile, fromFileName, strlen(fromFileName));
+ }
+ if (toFileName == NULL) {
+ _lwrite(batFile, " > nul", 6);
+ } else {
+ _lwrite(batFile, " > ", 3);
+ _lwrite(batFile, toFileName, strlen(toFileName));
+ }
+ _lwrite(batFile, "\r\n\032", 3);
+ _lclose(batFile);
+
+ strcpy(pifData + 0x1c8, batFileName);
+ _lwrite(pifFile, pifData, sizeof(pifData));
+ _lclose(pifFile);
+
+ result = WaitForExit(WinExec(pifFileName, SW_MINIMIZE));
+
+ unlink(pifFileName);
+ unlink(batFileName);
+
+ return result;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * WaitForExit --
+ *
+ * Wait until the application with the given instance handle has
+ * finished. PeekMessage() is used to yield the processor;
+ * otherwise, nothing else could execute on the system.
+ *
+ * Results:
+ * The return value is 1 if the process exited successfully,
+ * or 0 otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+WaitForExit(inst)
+ int inst; /* Identifies the instance handle of the
+ * process to wait for. */
+{
+ TASKENTRY te;
+ MSG msg;
+ UINT timer;
+
+ if (inst < 32) {
+ return 0;
+ }
+
+ te.dwSize = sizeof(te);
+ te.hInst = 0;
+ TaskFirst(&te);
+ do {
+ if (te.hInst == (HINSTANCE) inst) {
+ break;
+ }
+ } while (TaskNext(&te) != FALSE);
+
+ if (te.hInst != (HINSTANCE) inst) {
+ return 0;
+ }
+
+ timer = SetTimer(NULL, 0, 0, NULL);
+ while (1) {
+ if (GetMessage(&msg, NULL, 0, 0) != 0) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ TaskFirst(&te);
+ do {
+ if (te.hInst == (HINSTANCE) inst) {
+ break;
+ }
+ } while (TaskNext(&te) != FALSE);
+
+ if (te.hInst != (HINSTANCE) inst) {
+ KillTimer(NULL, timer);
+ return 1;
+ }
+ }
+}