1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
7
This software is distributed under license and may not be copied, modified
8
or distributed except as expressly authorized under the terms of that
9
license. Refer to licensing information at http://www.artifex.com/
10
or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11
San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
13
/* $Id: dwmain.c 8022 2007-06-05 22:23:38Z giles $ */
14
/* Ghostscript DLL loader for Windows */
22
#define GSREVISION gs_revision
38
/* redirected stdio */
41
static const LPSTR szAppName = "Ghostscript";
43
const LPSTR szIniName = "gswin32.ini";
44
const char *szDllName = "gsdll32.dll";
45
const LPSTR szIniSection = "Text";
52
char start_string[] = "systemdict /start get exec\n";
57
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
58
TranslateMessage(&msg);
59
DispatchMessage(&msg);
61
/* If text window closing then abort Ghostscript */
67
/*********************************************************************/
70
gsdll_stdin(void *instance, char *buf, int len)
72
return text_read_line(tw, buf, len);
76
gsdll_stdout(void *instance, const char *str, int len)
78
text_write_buf(tw, str, len);
83
gsdll_stderr(void *instance, const char *str, int len)
85
text_write_buf(tw, str, len);
89
/* Poll the caller for cooperative multitasking. */
90
/* If this function is NULL, polling is not needed */
91
static int GSDLLCALL gsdll_poll(void *handle)
95
/*********************************************************************/
97
/* new dll display device */
102
/* New device has been opened */
103
/* This is the first event from this device. */
104
static int display_open(void *handle, void *device)
109
sprintf(buf, "display_open(0x%x, 0x%x)\n", handle, device);
112
img = image_new(handle, device); /* create and add to list */
118
/* Device is about to be closed. */
119
/* Device will not be closed until this function returns. */
120
static int display_preclose(void *handle, void *device)
124
sprintf(buf, "display_preclose(0x%x, 0x$x)\n", handle, device);
127
/* do nothing - no thread synchonisation needed */
131
/* Device has been closed. */
132
/* This is the last event from this device. */
133
static int display_close(void *handle, void *device)
138
sprintf(buf, "display_close(0x%x, 0x$x)\n", handle, device);
141
img = image_find(handle, device);
143
image_delete(img); /* remove from list but don't free */
149
/* Device is about to be resized. */
150
/* Resize will only occur if this function returns 0. */
151
static int display_presize(void *handle, void *device, int width, int height,
152
int raster, unsigned int format)
156
sprintf(buf, "display_presize(0x%x, 0x%x, width=%d height=%d raster=%d\n\
158
handle, device, width, height, raster, format);
164
/* Device has been resized. */
165
/* New pointer to raster returned in pimage */
166
static int display_size(void *handle, void *device, int width, int height,
167
int raster, unsigned int format, unsigned char *pimage)
172
sprintf(buf, "display_size(0x%x, 0x%x, width=%d height=%d raster=%d\n\
173
format=%d image=0x%x)\n",
174
handle, device, width, height, raster, format, pimage);
177
img = image_find(handle, device);
178
image_size(img, width, height, raster, format, pimage);
179
image_updatesize(img);
184
static int display_sync(void *handle, void *device)
189
sprintf(buf, "display_sync(0x%x, 0x%x)\n", handle, device);
192
img = image_find(handle, device);
198
/* If you want to pause on showpage, then don't return immediately */
199
static int display_page(void *handle, void *device, int copies, int flush)
204
sprintf(buf, "display_page(0x%x, 0x%x, copies=%d flush=%d)\n",
205
handle, device, copies, flush);
208
img = image_find(handle, device);
213
/* Poll the caller for cooperative multitasking. */
214
/* If this function is NULL, polling is not needed */
215
static int display_update(void *handle, void *device,
216
int x, int y, int w, int h)
219
img = image_find(handle, device);
220
image_poll(img); /* redraw the window periodically */
224
int display_separation(void *handle, void *device,
225
int comp_num, const char *name,
226
unsigned short c, unsigned short m,
227
unsigned short y, unsigned short k)
231
fprintf(stdout, "display_separation(0x%x, 0x%x, %d '%s' %d,%d,%d,%d)\n",
232
handle, device, comp_num, name, (int)c, (int)m, (int)y, (int)k);
234
img = image_find(handle, device);
236
image_separation(img, comp_num, name, c, m, y, k);
240
display_callback display = {
241
sizeof(display_callback),
242
DISPLAY_VERSION_MAJOR,
243
DISPLAY_VERSION_MINOR,
258
/*********************************************************************/
260
/* program really starts at WinMain */
261
int new_main(int argc, char *argv[])
272
memset(buf, 0, sizeof(buf));
273
if (load_dll(&gsdll, buf, sizeof(buf))) {
274
text_puts(tw, "Can't load Ghostscript DLL\n");
280
if (gsdll.new_instance(&instance, NULL) < 0) {
281
text_puts(tw, "Can't create Ghostscript instance\n");
286
visual_tracer_init();
287
gsdll.set_visual_tracer(&visual_tracer);
290
gsdll.set_stdio(instance, gsdll_stdin, gsdll_stdout, gsdll_stderr);
291
gsdll.set_poll(instance, gsdll_poll);
292
gsdll.set_display_callback(instance, &display);
294
/* insert display device defaults as first arguments */
295
{ int format = DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE |
296
DISPLAY_DEPTH_1 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST;
297
HDC hdc = GetDC(NULL); /* get hdc for desktop */
298
int depth = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
299
sprintf(ddpi, "-dDisplayResolution=%d", GetDeviceCaps(hdc, LOGPIXELSY));
300
ReleaseDC(NULL, hdc);
302
format = DISPLAY_COLORS_RGB | DISPLAY_UNUSED_LAST |
303
DISPLAY_DEPTH_8 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST;
304
else if (depth == 16)
305
format = DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE |
306
DISPLAY_DEPTH_16 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST |
309
format = DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE |
310
DISPLAY_DEPTH_8 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST;
312
format = DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE |
313
DISPLAY_DEPTH_8 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST;
315
format = DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE |
316
DISPLAY_DEPTH_4 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST;
317
sprintf(dformat, "-dDisplayFormat=%d", format);
320
nargv = (char **)malloc((nargc + 1) * sizeof(char *));
324
memcpy(&nargv[3], &argv[1], argc * sizeof(char *));
326
#if defined(_MSC_VER) || defined(__BORLANDC__)
329
code = gsdll.init_with_args(instance, nargc, nargv);
331
code = gsdll.run_string(instance, start_string, 0, &exit_code);
332
code1 = gsdll.exit(instance);
333
if (code == 0 || (code == e_Quit && code1 != 0))
335
#if defined(_MSC_VER) || defined(__BORLANDC__)
336
} __except(exception_code() == EXCEPTION_STACK_OVERFLOW) {
338
text_puts(tw, "*** C stack overflow. Quiting...\n");
342
gsdll.delete_instance(instance);
345
visual_tracer_close();
378
GetPrivateProfileString(szIniSection, "FontName", "Courier New", fontname, sizeof(fontname), szIniName);
379
fontsize = GetPrivateProfileInt(szIniSection, "FontSize", 10, szIniName);
382
text_font(tw, fontname, fontsize);
385
WritePrivateProfileString(szIniSection, "FontName", fontname, szIniName);
386
sprintf(buf, "%d", fontsize);
387
WritePrivateProfileString(szIniSection, "FontSize", buf, szIniName);
391
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int cmdShow)
394
#define MAXCMDTOKENS 128
395
/* BC++ 4.5 will give us _argc and _argv[], but they will be */
396
/* incorrect if there is a space in the program name. */
397
/* Provide our own parsing code to create argc and argv[]. */
399
LPSTR argv[MAXCMDTOKENS];
405
int len = sizeof(winposbuf);
408
/* copy the hInstance into a variable so it can be used */
409
ghInstance = hInstance;
412
MessageBox((HWND)NULL,"Can't run twice", szAppName,
413
MB_ICONHAND | MB_OK);
417
/* If called with "gswin32c.exe arg1 arg2"
418
* lpszCmdLine returns:
419
* "arg1 arg2" if called with CreateProcess(NULL, command, ...)
420
* "arg2" if called with CreateProcess(command, args, ...)
421
* GetCommandLine() returns
422
* ""gswin32c.exe" arg1 arg2"
423
* if called with CreateProcess(NULL, command, ...)
425
* if called with CreateProcess(command, args, ...)
426
* Consequently we must use GetCommandLine()
428
p = GetCommandLine();
431
args = (char *)malloc(lstrlen(p)+1);
432
if (args == (char *)NULL) {
433
fprintf(stdout, "Insufficient memory in WinMain()\n");
437
/* Parse command line handling quotes. */
440
/* for each argument */
442
if (argc >= MAXCMDTOKENS - 1)
446
while ((*p) && (*p != ' ')) {
448
/* Remove quotes, skipping over embedded spaces. */
449
/* Doesn't handle embedded quotes. */
451
while ((*p) && (*p != '\042'))
462
while ((*p) && (*p == ' '))
463
p++; /* Skip over trailing spaces */
467
if (strlen(argv[0]) == 0) {
468
GetModuleFileName(hInstance, command, sizeof(command)-1);
475
MessageBox((HWND)NULL, "Can't create text window",
476
szAppName, MB_OK | MB_ICONSTOP);
480
/* start up the text window */
481
if (!hPrevInstance) {
482
HICON hicon = LoadIcon(hInstance, (LPSTR)MAKEINTRESOURCE(GSTEXT_ICON));
483
text_register_class(tw, hicon);
486
text_size(tw, 80, 80);
487
text_drag(tw, "(", ") run\r");
488
if (win_get_reg_value("Text", winposbuf, &len) == 0) {
489
if (sscanf(winposbuf, "%d %d %d %d", &x, &y, &cx, &cy) == 4)
490
text_setpos(tw, x, y, cx, cy);
493
/* create the text window */
494
if (text_create(tw, szAppName, cmdShow))
497
hwndtext = text_get_handle(tw);
499
dll_exit_status = new_main(argc, argv);
501
if (dll_exit_status && !tw->quitnow) {
502
/* display error message in text window */
504
text_puts(tw, "\nClose this window with the close button on the title bar or the system menu.\n");
505
if (IsIconic(text_get_handle(tw)))
506
ShowWindow(text_get_handle(tw), SW_SHOWNORMAL);
507
BringWindowToTop(text_get_handle(tw)); /* make text window visible */
508
FlashWindow(text_get_handle(tw), TRUE);
509
/* Wait until error message is read */
510
while (!tw->quitnow && GetMessage(&msg, (HWND)NULL, 0, 0)) {
511
TranslateMessage(&msg);
512
DispatchMessage(&msg);
516
/* Save the text window size */
517
if (text_getpos(tw, &x, &y, &cx, &cy) == 0) {
518
sprintf(winposbuf, "%d %d %d %d", x, y, cx, cy);
519
win_set_reg_value("Text", winposbuf);
525
return dll_exit_status;