summaryrefslogtreecommitdiff
path: root/Build/source/texk/gsftopk
diff options
context:
space:
mode:
authorPeter Breitenlohner <peb@mppmu.mpg.de>2010-02-26 13:06:11 +0000
committerPeter Breitenlohner <peb@mppmu.mpg.de>2010-02-26 13:06:11 +0000
commitc3b610214e8dd43782606fe3f16eafc2c790648b (patch)
treed5f6d7a7ba4ba13fd30620370f24e7137872e597 /Build/source/texk/gsftopk
parentb0128c9b4c5f886ebf14ec5c6ecf8c6cd0fbbf1b (diff)
gsftopk patches from Akira for MinGW
git-svn-id: svn://tug.org/texlive/trunk@17216 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/gsftopk')
-rw-r--r--Build/source/texk/gsftopk/ChangeLog6
-rw-r--r--Build/source/texk/gsftopk/gsftopk.c156
2 files changed, 128 insertions, 34 deletions
diff --git a/Build/source/texk/gsftopk/ChangeLog b/Build/source/texk/gsftopk/ChangeLog
index e3735b857a3..779a38fa204 100644
--- a/Build/source/texk/gsftopk/ChangeLog
+++ b/Build/source/texk/gsftopk/ChangeLog
@@ -1,5 +1,11 @@
2010-02-12 Peter Breitenlohner <peb@mppmu.mpg.de>
+ * gsftopk.c [WIN32]: Patches for MinGW32 build
+ from Akira Kakuto, 26 Feb 2010 11:00:34.
+ Avoid compiler warnings.
+
+2010-02-12 Peter Breitenlohner <peb@mppmu.mpg.de>
+
* gsftopk.c: Add '#if defined(KPSE_DEBUG)' to allow compilation
with '-DNO_DEBUG'.
diff --git a/Build/source/texk/gsftopk/gsftopk.c b/Build/source/texk/gsftopk/gsftopk.c
index 96a702d4415..799b9329f96 100644
--- a/Build/source/texk/gsftopk/gsftopk.c
+++ b/Build/source/texk/gsftopk/gsftopk.c
@@ -188,7 +188,7 @@ char *getenv();
#include <kpathsea/tex-file.h>
#include <kpathsea/tex-make.h>
#include <kpathsea/variable.h>
-# include <kpathsea/version.h>
+#include <kpathsea/version.h>
#include <c-auto.h>
#include <signal.h>
#include <fcntl.h>
@@ -230,12 +230,73 @@ char *getenv();
#if WIN32
-#include <win32lib.h>
-#include <gs32lib.h>
-#include <gsdll.h>
+/* code from Akira Kakuto */
+
+/* message values for callback */
+#define GSDLL_STDIN 1
+#define GSDLL_STDOUT 2
+#define GSDLL_DEVICE 3
+#define GSDLL_SYNC 4
+#define GSDLL_PAGE 5
+#define GSDLL_SIZE 6
+#define GSDLL_POLL 7
+/* return values from gsdll_init() */
+#define GSDLL_INIT_IN_USE 100
+#define GSDLL_INIT_QUIT 101
+
+#include <windows.h>
+
+HINSTANCE hgsdll = NULL;
+PROC pgsdll_init = NULL;
+PROC pgsdll_exit = NULL;
+PROC pgsdll_revision = NULL;
+
+#if 0 /* unused */
+static long revision_n = 0;
+static char product_str[128];
+static char copyright_str[128];
+static long revdate_n;
+#endif /* 0, unused */
+
+static void Win32Error(const char *s)
+{
+ fprintf(stderr, "%s\n", s);
+ exit(EXIT_FAILURE);
+}
+
+static HINSTANCE gs_locate(void)
+{
+ hgsdll = GetModuleHandle("GSDLL32.DLL");
+ if(hgsdll == NULL) {
+ hgsdll = LoadLibrary("GSDLL32.DLL");
+ }
+ return hgsdll;
+}
+
+static void gs_dll_release(void)
+{
+ FreeLibrary(hgsdll);
+}
+
+static void gs_dll_initialize(void)
+{
+ pgsdll_init = GetProcAddress(hgsdll, "gsdll_init");
+ pgsdll_exit = GetProcAddress(hgsdll, "gsdll_exit");
+ pgsdll_revision = GetProcAddress(hgsdll, "gsdll_revision");
+ if(pgsdll_init == NULL || pgsdll_exit == NULL ||
+ pgsdll_revision == NULL) {
+ fprintf(stderr, "Failed to get proc addresses in GSDLL32.\n");
+ gs_dll_release();
+ exit(100);
+ }
+}
+
+/* end of code from Akira Kakuto */
+
HANDLE hGsThread = NULL;
HANDLE hGsDataIn = 0, hGsDataOut = 0; /* Events to synchronize threads */
/* Arguments to gs dll */
+const
char *gs_argv[] = { "gswin32c.exe", /* 0, */
"-dNOGC", /* 1, */
"-dNODISPLAY", /* 2, */
@@ -484,7 +545,7 @@ exit_toto_too(void)
break;
case WAIT_FAILED:
fprintf(stderr, "WaitForSingleObject failed on Gs thread (Error code %d).\n",
- GetLastError());
+ (int)GetLastError());
break;
default:
break;
@@ -621,11 +682,9 @@ get_one_arg(const char *src)
* Signal handlers.
*/
-static Boolean got_sigchld = False;
-
#if WIN32
-BOOL WINAPI
+static BOOL WINAPI
handle_sigterm(DWORD dwCtrlType)
{
@@ -641,6 +700,11 @@ handle_sigterm(DWORD dwCtrlType)
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
fprintf(stderr, "...exiting\n");
+ if (hGsThread) {
+ if (TerminateThread(hGsThread, 1) == 0) {
+ fprintf(stderr, "... couldn't terminate gs thread\n");
+ }
+ }
exit_toto_too();
return FALSE;
default:
@@ -651,6 +715,8 @@ handle_sigterm(DWORD dwCtrlType)
#else /* not WIN32 */
+static Boolean got_sigchld = False;
+
/* ARGSUSED */
static RETSIGTYPE
handle_sigchild(int signo)
@@ -676,7 +742,7 @@ typedef int gsf_wait_t;
/* This is the callback function for gs. It is mainly used to read and
write data on gs stdin/stdout. Data exchanges happen through
buffers. */
-int __cdecl
+static int __cdecl
gsdll_callback(int message, char *str, unsigned long count)
{
int n;
@@ -701,6 +767,13 @@ gsdll_callback(int message, char *str, unsigned long count)
#endif
data_out = buffer;
+ if (str == (char *)NULL || count == 0) {
+ data_eof = True;
+ data_end = data_out;
+ /* Tell data_fillbuf() */
+ SetEvent(hGsDataIn);
+ return 0;
+ }
n = (count >= BUFSIZE ? BUFSIZE : count);
memcpy(data_out, str, n);
data_end = data_out + n;
@@ -735,9 +808,6 @@ gsdll_callback(int message, char *str, unsigned long count)
break;
case GSDLL_POLL:
-#if 0
- fprintf(stderr, "GS: Poll sent (%d)!\n", 0);
-#endif
return 0; /* no error ? */
default:
fprintf(stdout,"%s: gs callback: unknown message=%d\n",progname, message);
@@ -750,10 +820,15 @@ gsdll_callback(int message, char *str, unsigned long count)
This is the thread function that will load the gs dll and
send it the data.
*/
-DWORD WINAPI Win32GsSendData(LPVOID lpParam)
+static DWORD WINAPI Win32GsSendData(LPVOID lpParam)
{
int ret;
+ if (gs_locate() == NULL) {
+ fprintf(stderr, "Can't locate Ghostscript ! Exiting ...\n");
+ return EXIT_FAILURE;
+ }
+
gs_dll_initialize();
ret = (*pgsdll_init)(gsdll_callback,
@@ -761,23 +836,32 @@ DWORD WINAPI Win32GsSendData(LPVOID lpParam)
gs_argc,
gs_argv);
- switch (ret) {
- case 0:
+ if (ret == 0) {
/* Should not happen : gs should quit
right after being initialized. */
(*pgsdll_exit)();
/* FIXME: this is working, but we could expect something cleaner ! */
/* GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0); */
- break;
- case GSDLL_INIT_QUIT:
- break;
- default:
- (*pgsdll_exit)();
- break;
+ return EXIT_FAILURE;
}
+
+ if (ret == GSDLL_INIT_QUIT) {
+ gs_dll_release();
+ return 0;
+ }
+
+ if (ret == GSDLL_INIT_IN_USE) {
+ fprintf(stderr, "gsdll_init returned %d\n", ret);
+ gs_dll_release();
+ return EXIT_FAILURE;
+ }
+
+ (*pgsdll_exit)();
+
#if DEBUG
fprintf(stderr, "%s: gsdll_init returned %d\n", progname, ret);
#endif
+
WaitForSingleObject(hGsDataOut, INFINITE);
data_eof = True;
data_end = data_out;
@@ -1815,7 +1899,7 @@ pk_bm_cvt(void)
}
static void
-putshort(short w)
+putshort(int w)
{
putc(w >> 8, pk_file);
putc(w, pk_file);
@@ -1994,6 +2078,7 @@ main(int argc, char **argv)
#endif
#if WIN32
DWORD idGsThread;
+ SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
#else /* not WIN32 */
#if !_AMIGA
int std_out[2];
@@ -2163,10 +2248,19 @@ Author of gsftopk: Paul Vojta.");
opt_oops("no more than two arguments are allowed");
#ifdef KPATHSEA
+#ifdef WIN32
+ setmode(fileno(stdout), _O_BINARY);
+#endif
kpse_set_progname(argv[0]);
kpse_init_prog("GSFTOPK", (int) (dpi + 0.5), NULL, "cmr10");
if (!test)
xputenv_int("KPATHSEA_DPI", (int) (dpi + 0.5));
+
+#if defined(WIN32) && !defined(__MINGW32__)
+ /* TeXLive uses its own Ghostscript */
+ texlive_gs_init();
+#endif /* WIN32 && !__MINGW32__ */
+
#endif
#if _AMIGA
@@ -2311,10 +2405,10 @@ Author of gsftopk: Paul Vojta.");
*p = '\0';
#ifdef KPATHSEA
searchpath = kpse_find_file(q, kpse_tex_ps_header_format,true);
-#ifdef WIN32
+#ifdef __MINGW32__
/* Be safe for Ghostscript's sake */
dostounix_filename(searchpath);
-#endif /* WIN32 */
+#endif /* __MINGW32__ */
f = searchpath ? fopen(searchpath, FOPEN_R_MODE) : NULL;
#else
f = search(config_file_header_path, "DVIPSHEADERS", q);
@@ -2563,16 +2657,10 @@ Author of gsftopk: Paul Vojta.");
close(std_in[1]);
#else /* WIN32 */
-
- if (gs_locate() == NULL) {
- fprintf(stderr, "\nCan't locate Ghostscript ! Exiting ...\n");
- return EXIT_FAILURE;
- }
-
SetConsoleCtrlHandler(handle_sigterm, TRUE);
- hGsDataIn = CreateEvent(NULL, FALSE, FALSE, "gsDataIn");
- hGsDataOut = CreateEvent(NULL, FALSE, FALSE, "gsDataOut");
+ hGsDataIn = CreateEvent(&sa, FALSE, FALSE, "gsDataIn");
+ hGsDataOut = CreateEvent(&sa, FALSE, FALSE, "gsDataOut");
gs_argv[3] = substarg;
gs_argv[6] = searchpath;
@@ -2583,7 +2671,7 @@ Author of gsftopk: Paul Vojta.");
buffer_stdin = concat(designstr, charlist);
- if ((hGsThread = CreateThread(NULL, /* security attributes */
+ if ((hGsThread = CreateThread(&sa, /* security attributes */
0, /* default stack size */
Win32GsSendData, /* start address of thread */
0, /* parameter */
@@ -2687,7 +2775,7 @@ Author of gsftopk: Paul Vojta.");
break;
case WAIT_FAILED:
fprintf(stderr, "WaitForSingleObject failed on Gs thread (Error code %d).\n",
- GetLastError());
+ (int)GetLastError());
break;
default:
break;