Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/planix-v0/sys/src/cmd/gs/src/dwmainc.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1996-2004 Ghostgum Software Pty Ltd.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: dwmainc.c,v 1.24 2004/09/15 19:41:01 ray Exp $ */
18
/* dwmainc.c */
19
 
20
#include "windows_.h"
21
#include <stdio.h>
22
#include <stdlib.h>
23
#include <io.h>
24
#include <fcntl.h>
25
#include <process.h>
26
#include "ierrors.h"
27
#include "iapi.h"
28
#include "vdtrace.h"
29
#include "gdevdsp.h"
30
#include "dwdll.h"
31
#include "dwimg.h"
32
#include "dwtrace.h"
33
 
34
/* Patch by Rod Webster (rodw) */
35
/* Added conditional below to allow Borland Compilation (Tested on 5.5) */
36
/* It would be better to place this code in an include file but no dwmainc.h exists */
37
#ifdef __BORLANDC__
38
#define _isatty isatty
39
#define _setmode setmode
40
#endif
41
 
42
GSDLL gsdll;
43
void *instance;
44
BOOL quitnow = FALSE;
45
HANDLE hthread;
46
DWORD thread_id;
47
HWND hwndtext = NULL;	/* for dwimg.c, but not used */
48
HWND hwndforeground;	/* our best guess for our console window handle */
49
 
50
char start_string[] = "systemdict /start get exec\n";
51
 
52
/*********************************************************************/
53
/* stdio functions */
54
 
55
static int GSDLLCALL
56
gsdll_stdin(void *instance, char *buf, int len)
57
{
58
    return _read(fileno(stdin), buf, len);
59
}
60
 
61
static int GSDLLCALL
62
gsdll_stdout(void *instance, const char *str, int len)
63
{
64
    fwrite(str, 1, len, stdout);
65
    fflush(stdout);
66
    return len;
67
}
68
 
69
static int GSDLLCALL
70
gsdll_stderr(void *instance, const char *str, int len)
71
{
72
    fwrite(str, 1, len, stderr);
73
    fflush(stderr);
74
    return len;
75
}
76
 
77
/*********************************************************************/
78
/* dll device */
79
 
80
/* We must run windows from another thread, since main thread */
81
/* is running Ghostscript and blocks on stdin. */
82
 
83
/* We notify second thread of events using PostThreadMessage()
84
 * with the following messages. Apparently Japanese Windows sends
85
 * WM_USER+1 with lParam == 0 and crashes. So we use WM_USER+101.
86
 * Fix from Akira Kakuto
87
 */
88
#define DISPLAY_OPEN WM_USER+101
89
#define DISPLAY_CLOSE WM_USER+102
90
#define DISPLAY_SIZE WM_USER+103
91
#define DISPLAY_SYNC WM_USER+104
92
#define DISPLAY_PAGE WM_USER+105
93
#define DISPLAY_UPDATE WM_USER+106
94
 
95
/*
96
#define DISPLAY_DEBUG
97
*/
98
 
99
/* The second thread is the message loop */
100
static void winthread(void *arg)
101
{
102
    MSG msg;
103
    thread_id = GetCurrentThreadId();
104
    hthread = GetCurrentThread();
105
 
106
    while (!quitnow && GetMessage(&msg, (HWND)NULL, 0, 0)) {
107
	switch (msg.message) {
108
	    case DISPLAY_OPEN:
109
		image_open((IMAGE *)msg.lParam);
110
		break;
111
	    case DISPLAY_CLOSE:
112
		{
113
		    IMAGE *img = (IMAGE *)msg.lParam; 
114
		    HANDLE hmutex = img->hmutex;
115
		    image_close(img);
116
		    CloseHandle(hmutex);
117
		}
118
		break;
119
	    case DISPLAY_SIZE:
120
		image_updatesize((IMAGE *)msg.lParam);
121
		break;
122
	    case DISPLAY_SYNC:
123
		image_sync((IMAGE *)msg.lParam);
124
		break;
125
	    case DISPLAY_PAGE:
126
		image_page((IMAGE *)msg.lParam);
127
		break;
128
	    case DISPLAY_UPDATE:
129
		image_poll((IMAGE *)msg.lParam);
130
		break;
131
	    default:
132
		TranslateMessage(&msg);
133
		DispatchMessage(&msg);
134
	}
135
    }
136
}
137
 
138
 
139
/* New device has been opened */
140
/* Tell user to use another device */
141
int display_open(void *handle, void *device)
142
{
143
    IMAGE *img;
144
#ifdef DISPLAY_DEBUG
145
    fprintf(stdout, "display_open(0x%x, 0x%x)\n", handle, device);
146
#endif
147
    img = image_new(handle, device);	/* create and add to list */
148
    img->hmutex = CreateMutex(NULL, FALSE, NULL);
149
    if (img)
150
	PostThreadMessage(thread_id, DISPLAY_OPEN, 0, (LPARAM)img);
151
    return 0;
152
}
153
 
154
int display_preclose(void *handle, void *device)
155
{
156
    IMAGE *img;
157
#ifdef DISPLAY_DEBUG
158
    fprintf(stdout, "display_preclose(0x%x, 0x%x)\n", handle, device);
159
#endif
160
    img = image_find(handle, device);
161
    if (img) {
162
	/* grab mutex to stop other thread using bitmap */
163
	WaitForSingleObject(img->hmutex, 120000);
164
    }
165
    return 0;
166
}
167
 
168
int display_close(void *handle, void *device)
169
{
170
    IMAGE *img;
171
#ifdef DISPLAY_DEBUG
172
    fprintf(stdout, "display_close(0x%x, 0x%x)\n", handle, device);
173
#endif
174
    img = image_find(handle, device);
175
    if (img) {
176
	/* This is a hack to pass focus from image window to console */
177
	if (GetForegroundWindow() == img->hwnd)
178
	    SetForegroundWindow(hwndforeground);
179
 
180
	image_delete(img);	/* remove from list, but don't free */
181
	PostThreadMessage(thread_id, DISPLAY_CLOSE, 0, (LPARAM)img);
182
    }
183
    return 0;
184
}
185
 
186
int display_presize(void *handle, void *device, int width, int height, 
187
	int raster, unsigned int format)
188
{
189
    IMAGE *img;
190
#ifdef DISPLAY_DEBUG
191
    fprintf(stdout, "display_presize(0x%x 0x%x, %d, %d, %d, %d, %ld)\n",
192
	handle, device, width, height, raster, format);
193
#endif
194
    img = image_find(handle, device);
195
    if (img) {
196
	/* grab mutex to stop other thread using bitmap */
197
	WaitForSingleObject(img->hmutex, 120000);
198
    }
199
    return 0;
200
}
201
 
202
int display_size(void *handle, void *device, int width, int height, 
203
	int raster, unsigned int format, unsigned char *pimage)
204
{
205
    IMAGE *img;
206
#ifdef DISPLAY_DEBUG
207
    fprintf(stdout, "display_size(0x%x 0x%x, %d, %d, %d, %d, %ld, 0x%x)\n",
208
	handle, device, width, height, raster, format, pimage);
209
#endif
210
    img = image_find(handle, device);
211
    if (img) {
212
	image_size(img, width, height, raster, format, pimage);
213
	/* release mutex to allow other thread to use bitmap */
214
	ReleaseMutex(img->hmutex);
215
	PostThreadMessage(thread_id, DISPLAY_SIZE, 0, (LPARAM)img);
216
    }
217
    return 0;
218
}
219
 
220
int display_sync(void *handle, void *device)
221
{
222
    IMAGE *img;
223
#ifdef DISPLAY_DEBUG
224
    fprintf(stdout, "display_sync(0x%x, 0x%x)\n", handle, device);
225
#endif
226
    img = image_find(handle, device);
227
    if (img && !img->pending_sync) {
228
	img->pending_sync = 1;
229
	PostThreadMessage(thread_id, DISPLAY_SYNC, 0, (LPARAM)img);
230
    }
231
    return 0;
232
}
233
 
234
int display_page(void *handle, void *device, int copies, int flush)
235
{
236
    IMAGE *img;
237
#ifdef DISPLAY_DEBUG
238
    fprintf(stdout, "display_page(0x%x, 0x%x, copies=%d, flush=%d)\n", 
239
	handle, device, copies, flush);
240
#endif
241
    img = image_find(handle, device);
242
    if (img)
243
	PostThreadMessage(thread_id, DISPLAY_PAGE, 0, (LPARAM)img);
244
    return 0;
245
}
246
 
247
int display_update(void *handle, void *device, 
248
    int x, int y, int w, int h)
249
{
250
    IMAGE *img;
251
    img = image_find(handle, device);
252
    if (img && !img->pending_update && !img->pending_sync) {
253
	img->pending_update = 1;
254
	PostThreadMessage(thread_id, DISPLAY_UPDATE, 0, (LPARAM)img);
255
    }
256
    return 0;
257
}
258
 
259
/*
260
#define DISPLAY_DEBUG_USE_ALLOC
261
*/
262
#ifdef DISPLAY_DEBUG_USE_ALLOC
263
/* This code isn't used, but shows how to use this function */
264
void *display_memalloc(void *handle, void *device, unsigned long size)
265
{
266
    void *mem;
267
#ifdef DISPLAY_DEBUG
268
    fprintf(stdout, "display_memalloc(0x%x 0x%x %d)\n", 
269
	handle, device, size);
270
#endif
271
    mem = malloc(size);
272
#ifdef DISPLAY_DEBUG
273
    fprintf(stdout, "  returning 0x%x\n", (int)mem);
274
#endif
275
    return mem;
276
}
277
 
278
int display_memfree(void *handle, void *device, void *mem)
279
{
280
#ifdef DISPLAY_DEBUG
281
    fprintf(stdout, "display_memfree(0x%x, 0x%x, 0x%x)\n", 
282
	handle, device, mem);
283
#endif
284
    free(mem);
285
    return 0;
286
}
287
#endif
288
 
289
int display_separation(void *handle, void *device, 
290
   int comp_num, const char *name,
291
   unsigned short c, unsigned short m,
292
   unsigned short y, unsigned short k)
293
{
294
    IMAGE *img;
295
#ifdef DISPLAY_DEBUG
296
    fprintf(stdout, "display_separation(0x%x, 0x%x, %d '%s' %d,%d,%d,%d)\n", 
297
	handle, device, comp_num, name, (int)c, (int)m, (int)y, (int)k);
298
#endif
299
    img = image_find(handle, device);
300
    if (img)
301
        image_separation(img, comp_num, name, c, m, y, k);
302
    return 0;
303
}
304
 
305
 
306
display_callback display = { 
307
    sizeof(display_callback),
308
    DISPLAY_VERSION_MAJOR,
309
    DISPLAY_VERSION_MINOR,
310
    display_open,
311
    display_preclose,
312
    display_close,
313
    display_presize,
314
    display_size,
315
    display_sync,
316
    display_page,
317
    display_update,
318
#ifdef DISPLAY_DEBUG_USE_ALLOC
319
    display_memalloc,	/* memalloc */
320
    display_memfree,	/* memfree */
321
#else
322
    NULL,	/* memalloc */
323
    NULL,	/* memfree */
324
#endif
325
    display_separation
326
};
327
 
328
 
329
/*********************************************************************/
330
 
331
int main(int argc, char *argv[])
332
{
333
    int code, code1;
334
    int exit_code;
335
    int exit_status;
336
    int nargc;
337
    char **nargv;
338
    char buf[256];
339
    char dformat[64];
340
    char ddpi[64];
341
 
342
    if (!_isatty(fileno(stdin)))
343
        _setmode(fileno(stdin), _O_BINARY);
344
    _setmode(fileno(stdout), _O_BINARY);
345
    _setmode(fileno(stderr), _O_BINARY);
346
 
347
    hwndforeground = GetForegroundWindow();	/* assume this is ours */
348
    memset(buf, 0, sizeof(buf));
349
    if (load_dll(&gsdll, buf, sizeof(buf))) {
350
	fprintf(stderr, "Can't load Ghostscript DLL\n");
351
	fprintf(stderr, "%s\n", buf);
352
	return 1;
353
    }
354
 
355
    if (gsdll.new_instance(&instance, NULL) < 0) {
356
	fprintf(stderr, "Can't create Ghostscript instance\n");
357
	return 1;
358
    }
359
 
360
#ifdef DEBUG
361
    visual_tracer_init();
362
    gsdll.set_visual_tracer(&visual_tracer);
363
#endif
364
 
365
    if (_beginthread(winthread, 65535, NULL) == -1) {
366
	fprintf(stderr, "GUI thread creation failed\n");
367
    }
368
    else {
369
	int n = 30;
370
	/* wait for thread to start */
371
	Sleep(0);
372
	while (n && (hthread == INVALID_HANDLE_VALUE)) {
373
	    n--;
374
	    Sleep(100);
375
        }
376
	while (n && (PostThreadMessage(thread_id, WM_USER, 0, 0) == 0)) {
377
	    n--;
378
	    Sleep(100);
379
	}
380
	if (n == 0)
381
	    fprintf(stderr, "Can't post message to GUI thread\n");
382
    }
383
 
384
    gsdll.set_stdio(instance, gsdll_stdin, gsdll_stdout, gsdll_stderr);
385
    gsdll.set_display_callback(instance, &display);
386
 
387
    {   int format = DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | 
388
		DISPLAY_DEPTH_1 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST;
389
	HDC hdc = GetDC(NULL);	/* get hdc for desktop */
390
	int depth = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
391
	sprintf(ddpi, "-dDisplayResolution=%d", GetDeviceCaps(hdc, LOGPIXELSY));
392
        ReleaseDC(NULL, hdc);
393
	if (depth == 32)
394
 	    format = DISPLAY_COLORS_RGB | DISPLAY_UNUSED_LAST | 
395
		DISPLAY_DEPTH_8 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST;
396
	else if (depth == 16)
397
 	    format = DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | 
398
		DISPLAY_DEPTH_16 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST |
399
		DISPLAY_NATIVE_555;
400
	else if (depth > 8)
401
 	    format = DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | 
402
		DISPLAY_DEPTH_8 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST;
403
	else if (depth >= 8)
404
 	    format = DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | 
405
		DISPLAY_DEPTH_8 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST;
406
	else if (depth >= 4)
407
 	    format = DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | 
408
		DISPLAY_DEPTH_4 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST;
409
        sprintf(dformat, "-dDisplayFormat=%d", format);
410
    }
411
    nargc = argc + 2;
412
    nargv = (char **)malloc((nargc + 1) * sizeof(char *));
413
    nargv[0] = argv[0];
414
    nargv[1] = dformat;
415
    nargv[2] = ddpi;
416
    memcpy(&nargv[3], &argv[1], argc * sizeof(char *));
417
 
418
#if defined(_MSC_VER) || defined(__BORLANDC__)
419
    __try {
420
#endif
421
    code = gsdll.init_with_args(instance, nargc, nargv);
422
    if (code == 0)
423
	code = gsdll.run_string(instance, start_string, 0, &exit_code);
424
    code1 = gsdll.exit(instance);
425
    if (code == 0 || (code == e_Quit && code1 != 0))
426
	code = code1;
427
#if defined(_MSC_VER) || defined(__BORLANDC__)
428
    } __except(exception_code() == EXCEPTION_STACK_OVERFLOW) {
429
        code = e_Fatal;
430
        fprintf(stderr, "*** C stack overflow. Quiting...\n");
431
    }
432
#endif
433
 
434
    gsdll.delete_instance(instance);
435
 
436
#ifdef DEBUG
437
    visual_tracer_close();
438
#endif
439
 
440
    unload_dll(&gsdll);
441
 
442
    free(nargv);
443
 
444
    /* close other thread */
445
    quitnow = TRUE; 
446
    PostThreadMessage(thread_id, WM_QUIT, 0, (LPARAM)0);
447
    Sleep(0);
448
 
449
    exit_status = 0;
450
    switch (code) {
451
	case 0:
452
	case e_Info:
453
	case e_Quit:
454
	    break;
455
	case e_Fatal:
456
	    exit_status = 1;
457
	    break;
458
	default:
459
	    exit_status = 255;
460
    }
461
 
462
 
463
    return exit_status;
464
}
465