summaryrefslogtreecommitdiff
path: root/gs/src/dwmain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gs/src/dwmain.cpp')
-rw-r--r--gs/src/dwmain.cpp412
1 files changed, 412 insertions, 0 deletions
diff --git a/gs/src/dwmain.cpp b/gs/src/dwmain.cpp
new file mode 100644
index 000000000..75d573e2e
--- /dev/null
+++ b/gs/src/dwmain.cpp
@@ -0,0 +1,412 @@
+/* Copyright (C) 1996, 1997, Russell Lang. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+*/
+
+
+// dwmain.cpp
+// Ghostscript DLL loader for Windows
+
+#define STRICT
+#include <windows.h>
+#include <shellapi.h>
+#ifndef __WIN32__
+#include <toolhelp.h>
+static BOOL dllfix(void);
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <dos.h>
+extern "C" {
+#include "gscdefs.h"
+#define GSREVISION gs_revision
+#include "gsdll.h"
+}
+#include "dwmain.h"
+#include "dwdll.h"
+#include "dwtext.h"
+#include "dwimg.h"
+
+#if defined(_MSC_VER) && defined(__WIN32__)
+#define _export
+#endif
+
+/* public handles */
+HINSTANCE ghInstance;
+
+/* redirected stdio */
+TextWindow tw;
+
+const LPSTR szAppName = "Ghostscript";
+
+#ifdef __WIN32__
+const LPSTR szIniName = "GSWIN32.INI";
+const char *szDllName = "GSDLL32.DLL";
+#else
+const LPSTR szIniName = "GSWIN.INI";
+const char *szDllName = "GSDLL16.DLL";
+#endif
+const LPSTR szIniSection = "Text";
+
+int dll_exit_status;
+
+int FAR _export gsdll_callback(int message, char FAR *str, unsigned long count);
+
+// the Ghostscript DLL class
+gsdll_class gsdll;
+
+char start_string[] = "systemdict /start get exec\n";
+
+// program really starts at WinMain
+int
+new_main(int argc, char *argv[])
+{
+typedef char FAR * FARARGV_PTR;
+FARARGV_PTR *far_argv;
+int rc;
+
+ // load DLL
+ if (gsdll.load(ghInstance, szDllName, GSREVISION)) {
+ char buf[256];
+ gsdll.get_last_error(buf, sizeof(buf));
+ tw.puts(buf);
+ return 1;
+ }
+
+
+#ifdef __WIN32__
+ far_argv = argv;
+#else
+ far_argv = new FARARGV_PTR[argc+1];
+ if (!far_argv)
+ return 1;
+ for (int i = 0; i<argc; i++)
+ far_argv[i] = argv[i]; // convert from near to far pointers
+ far_argv[i+1] = NULL;
+#endif
+
+ // initialize the interpreter
+ rc = gsdll.init(gsdll_callback, tw.get_handle(), argc, far_argv);
+ if (rc == GSDLL_INIT_QUIT) {
+ gsdll.unload();
+ return 0;
+ }
+ if (rc) {
+ char buf[256];
+ gsdll.get_last_error(buf, sizeof(buf));
+ tw.puts(buf);
+ gsdll.unload();
+#ifndef __WIN32__
+ if (rc == GSDLL_INIT_IN_USE)
+ dllfix(); // offer option to unload NASTY!
+#endif
+ return rc;
+ }
+
+ // if (!batch)
+ gsdll.execute(start_string, strlen(start_string));
+
+#ifdef UNUSED
+ int len;
+ char line[256];
+ do {
+ len = tw.read_line(line, sizeof(line));
+ } while ( len && !gsdll.execute(line, len) );
+#endif
+
+ gsdll.unload();
+
+ return 0;
+}
+
+
+/* our exit handler */
+/* also called from Text Window WM_CLOSE */
+void win_exit(void)
+{
+ if (dll_exit_status) {
+ /* display message box so error messages in text window can be read */
+ char buf[80];
+ if (IsIconic(tw.get_handle()))
+ ShowWindow(tw.get_handle(), SW_SHOWNORMAL);
+ BringWindowToTop(tw.get_handle()); /* make text window visible */
+ sprintf(buf, "Exit code %d\nSee text window for details",dll_exit_status);
+ MessageBox((HWND)NULL, buf, szAppName, MB_OK | MB_ICONSTOP);
+ }
+}
+
+void
+set_font(void)
+{
+ int fontsize;
+ char fontname[256];
+ char buf[32];
+
+ // read ini file
+ GetPrivateProfileString(szIniSection, "FontName", "Courier New", fontname, sizeof(fontname), szIniName);
+ fontsize = GetPrivateProfileInt(szIniSection, "FontSize", 10, szIniName);
+
+ // set font
+ tw.font(fontname, fontsize);
+
+ // write ini file
+ WritePrivateProfileString(szIniSection, "FontName", fontname, szIniName);
+ sprintf(buf, "%d", fontsize);
+ WritePrivateProfileString(szIniSection, "FontSize", buf, szIniName);
+}
+
+int PASCAL
+WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int cmdShow)
+{
+#if defined(_MSC_VER) /* MSC doesn't give us _argc and _argv[] so ... */
+#define MAXCMDTOKENS 128
+ int _argc=0;
+ LPSTR _argv[MAXCMDTOKENS];
+ LPSTR p, q;
+#ifdef __WIN32__
+ _argv[_argc] = "gswin32.exe";
+#else
+ _argv[_argc] = "gswin.exe";
+#endif
+ // Parse command line handling quotes.
+ p = lpszCmdLine;
+ while (*p) {
+ // for each argument
+ while ((*p) && (*p == ' '))
+ p++; // skip over leading spaces
+ if (*p == '\042') {
+ p++; // skip "
+ q = p;
+ // scan to end of argument
+ // doesn't handle embedded quotes
+ while ((*p) && (*p != '\042'))
+ p++;
+ _argv[++_argc] = q;
+ if (*p)
+ *p++ = '\0';
+ }
+ else if (*p) {
+ // delimited by spaces
+ q = p;
+ while ((*p) && (*p != ' '))
+ p++;
+ _argv[++_argc] = q;
+ if (*p)
+ *p++ = '\0';
+ }
+ }
+ _argv[++_argc] = (LPSTR)NULL;
+#endif
+
+ if (hPrevInstance) {
+ MessageBox((HWND)NULL,"Can't run twice", szAppName, MB_ICONHAND | MB_OK);
+ return FALSE;
+ }
+
+ /* copy the hInstance into a variable so it can be used */
+ ghInstance = hInstance;
+
+
+ /* start up the text window */
+ if (!hPrevInstance) {
+ HICON hicon = LoadIcon(hInstance, (LPSTR)MAKEINTRESOURCE(GSTEXT_ICON));
+ tw.register_class(hInstance, hicon);
+ }
+ set_font();
+ tw.size(80, 80);
+ tw.drag("(", ") run\r");
+
+ // create the text window
+ if (tw.create(szAppName, cmdShow))
+ exit(1);
+
+ // initialize for image windows
+ ImageWindow::hwndtext = tw.get_handle();
+ ImageWindow::hInstance = hInstance;
+
+ dll_exit_status = new_main(_argc, _argv);
+
+ win_exit();
+
+ tw.destroy();
+
+ return dll_exit_status;
+}
+
+
+int FAR _export
+gsdll_callback(int message, char FAR *str, unsigned long count)
+{
+char buf[256];
+ImageWindow *iw;
+ switch (message) {
+ case GSDLL_POLL:
+ {
+ MSG msg;
+ while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ // If text window closed then abort Ghostscript
+ if (!IsWindow(tw.get_handle()))
+ return -1;
+ break;
+ case GSDLL_STDIN:
+ return tw.read_line(str, count);
+ case GSDLL_STDOUT:
+ if (str != (char *)NULL)
+ tw.write_buf(str, count);
+ return count;
+ case GSDLL_DEVICE:
+#ifdef DEBUG
+ sprintf(buf,"Callback: DEVICE %p %s\n", (char *)str,
+ count ? "open" : "close");
+ tw.puts(buf);
+#endif
+ if (count) {
+ iw = new ImageWindow;
+ iw->open(str);
+ }
+ else {
+ iw = FindImageWindow(str);
+ iw->close();
+ }
+ break;
+ case GSDLL_SYNC:
+#ifdef DEBUG
+ sprintf(buf,"Callback: SYNC %p\n", (char *)str);
+ tw.puts(buf);
+#endif
+ iw = FindImageWindow(str);
+ iw->sync();
+ break;
+ case GSDLL_PAGE:
+#ifdef DEBUG
+ sprintf(buf,"Callback: PAGE %p\n", (char *)str);
+ tw.puts(buf);
+#endif
+ iw = FindImageWindow(str);
+ iw->page();
+ break;
+ case GSDLL_SIZE:
+#ifdef DEBUG
+ sprintf(buf,"Callback: SIZE %p width=%d height=%d\n", (char *)str,
+ (int)(count & 0xffff), (int)((count>>16) & 0xffff) );
+ tw.puts(buf);
+#endif
+ iw = FindImageWindow(str);
+ iw->size( (int)(count & 0xffff), (int)((count>>16) & 0xffff) );
+ break;
+ default:
+ sprintf(buf,"Callback: Unknown message=%d\n",message);
+ tw.puts(buf);
+ break;
+ }
+ return 0;
+}
+
+
+#ifndef __WIN32__
+// This is a hack to cope with a GPF occuring in either Ghostscript
+// or a driver loaded by Ghostscript. If a GPF occurs, gswin16.exe
+// is unloaded, but not gsdll16.dll.
+// Attempts to reload gswin16.exe will fail because gsdll16.dll
+// is already in use. If this occurs, this code will unload
+// gsdll16.dll, EVEN IF SOMEONE ELSE IS USING IT.
+
+// The DLL module name as it appears in the module definition file
+#define GSDLLNAME "GSDLL16"
+// These are the names of EXE modules that are known users
+// of the Ghostscript DLL.
+// If one of these is running, it is not safe to unload the DLL.
+#define GSEXE "GSWIN16"
+
+typedef HMODULE (WINAPI *TOOLMFN)(MODULEENTRY FAR *, LPCSTR);
+
+static BOOL
+dllfix(void)
+{
+HMODULE hdll; // module handle of DLL
+HMODULE hgswin16; // module handle of Ghostscript
+MODULEENTRY me_dll; // to contain details about DLL module
+MODULEENTRY me_gswin16; // details about Ghostscript
+HINSTANCE htool; // module handle of TOOLHELP.DLL
+TOOLMFN lpfnModuleFindName = NULL;
+char buf[256];
+BOOL err = FALSE;
+
+ // load TOOLHELP.DLL
+ htool = LoadLibrary("TOOLHELP.DLL");
+ if ( htool <= HINSTANCE_ERROR )
+ err = TRUE;
+
+ // get address of toolhelp function
+ if (!err) {
+ lpfnModuleFindName = (TOOLMFN)GetProcAddress(htool, "ModuleFindName");
+ err = !lpfnModuleFindName;
+ }
+
+ // find handle for DLL
+ if (!err) {
+ memset(&me_dll, 0, sizeof(me_dll));
+ me_dll.dwSize = sizeof(me_dll);
+ hdll = lpfnModuleFindName(&me_dll, GSDLLNAME);
+ }
+
+ // look for Ghostscript EXE module
+ // This should be found because we are it
+ if (!err) {
+ memset(&me_gswin16, 0, sizeof(me_gswin16));
+ me_gswin16.dwSize = sizeof(me_gswin16);
+ hgswin16 = lpfnModuleFindName(&me_gswin16, GSEXE);
+ }
+
+#ifdef DEBUG
+ // for debugging, show what we have found
+ if (hdll) {
+ wsprintf(buf, "Found %s\nModule Handle=%d\nModule Usage=%d\nModule Path=%s",
+ me_dll.szModule, me_dll.hModule, me_dll.wcUsage, me_dll.szExePath);
+ MessageBox((HWND)NULL, buf, szAppName, MB_OK);
+ }
+ if (hgswin16) {
+ wsprintf(buf, "Found %s\nModule Handle=%d\nModule Usage=%d\nModule Path=%s",
+ me_gswin16.szModule, me_gswin16.hModule, me_gswin16.wcUsage,
+ me_gswin16.szExePath);
+ MessageBox((HWND)NULL, buf, szAppName, MB_OK);
+ }
+#endif
+
+ // if DLL loaded and Ghostscript is not running...
+ if (!err &&
+ hdll && // Ghostscript DLL loaded
+ (hgswin16 && me_gswin16.wcUsage == 1) // Only one copy of Ghostscript EXE
+ ) {
+ wsprintf(buf, "%s is loaded but does not appear to be in use by Ghostscript. Unload it?", GSDLLNAME);
+ if (MessageBox((HWND)NULL, buf, szAppName, MB_YESNO | MB_ICONHAND) == IDYES)
+ // If DLL is really in use, we about to cause a disaster
+ while (GetModuleUsage(hdll))
+ FreeLibrary(hdll);
+ }
+
+ if (htool)
+ FreeLibrary(htool);
+ return err;
+}
+#endif
+