Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises.  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: gp_msio.c,v 1.6 2002/06/16 05:48:55 lpd Exp $ */
18
/*
19
 * Streams for Windows text window
20
 *
21
 * Original version by Russell Lang and Maurice Castro with help from
22
 * Programming Windows, 2nd Ed., Charles Petzold, Microsoft Press;
23
 * initially created from gp_dosfb.c and gp_itbc.c 5th June 1992.
24
 */
25
 
26
/* Modified for Win32 & Microsoft C/C++ 8.0 32-Bit, 26.Okt.1994 */
27
/* by Friedrich Nowak                                           */
28
 
29
/* Factored out from gp_mswin.c by JD 6/25/97 */
30
 
31
/*
32
 * The MSVC compiler, when invoked with the /MD switch, considers that the
33
 * dllimport qualifier on fprintf in stdio.h and the dllexport qualifier
34
 * on the definition of fprintf in this file are incompatible.
35
 * We use a hack (similar to the one in stdpre.h to deal with sys/types.h)
36
 * to work around this.
37
 */
38
#define fprintf UNDEFINE_fprintf
39
#include "stdio_.h"
40
#undef fprintf
41
 
42
#include <stdlib.h>
43
#include "gx.h"
44
#include "gp.h"
45
#include "windows_.h"
46
#include <shellapi.h>
47
#ifdef __WIN32__
48
#include <winspool.h>
49
#endif
50
#include "gp_mswin.h"
51
#include "gsdll.h"
52
 
53
#include "stream.h"
54
#include "gxiodev.h"		/* must come after stream.h */
55
 
56
/* Imported from gp_msdos.c */
57
int gp_file_is_console(FILE *);
58
 
59
 
60
/* ====== Substitute for stdio ====== */
61
 
62
/* Forward references */
63
private void win_std_init(void);
64
private stream_proc_process(win_std_read_process);
65
private stream_proc_process(win_std_write_process);
66
private stream_proc_available(win_std_available);
67
 
68
/* Use a pseudo IODevice to get win_stdio_init called at the right time. */
69
/* This is bad architecture; we'll fix it later. */
70
private iodev_proc_init(win_stdio_init);
71
const gx_io_device gs_iodev_wstdio = {
72
    /* The name is null to keep this from showing up as a resource. */
73
    0, "Special",
74
    {win_stdio_init, iodev_no_open_device,
75
     iodev_no_open_file, iodev_no_fopen, iodev_no_fclose,
76
     iodev_no_delete_file, iodev_no_rename_file,
77
     iodev_no_file_status, iodev_no_enumerate_files
78
    }
79
};
80
 
81
/* Do one-time initialization */
82
private int
83
win_stdio_init(gx_io_device * iodev, gs_memory_t * mem)
84
{
85
    win_std_init();		/* redefine stdin/out/err to our window routines */
86
    return 0;
87
}
88
 
89
/* Define alternate 'open' routines for our stdin/out/err streams. */
90
 
91
extern const gx_io_device gs_iodev_stdin;
92
private int
93
win_stdin_open(gx_io_device * iodev, const char *access, stream ** ps,
94
	       gs_memory_t * mem)
95
{
96
    int code = gs_iodev_stdin.procs.open_device(iodev, access, ps, mem);
97
    stream *s = *ps;
98
 
99
    if (code != 1)
100
	return code;
101
    s->procs.process = win_std_read_process;
102
    s->procs.available = win_std_available;
103
    s->file = NULL;
104
    return 0;
105
}
106
 
107
extern const gx_io_device gs_iodev_stdout;
108
private int
109
win_stdout_open(gx_io_device * iodev, const char *access, stream ** ps,
110
		gs_memory_t * mem)
111
{
112
    int code = gs_iodev_stdout.procs.open_device(iodev, access, ps, mem);
113
    stream *s = *ps;
114
 
115
    if (code != 1)
116
	return code;
117
    s->procs.process = win_std_write_process;
118
    s->procs.available = win_std_available;
119
    s->procs.flush = s_std_write_flush;
120
    s->file = NULL;
121
    return 0;
122
}
123
 
124
extern const gx_io_device gs_iodev_stderr;
125
private int
126
win_stderr_open(gx_io_device * iodev, const char *access, stream ** ps,
127
		gs_memory_t * mem)
128
{
129
    int code = gs_iodev_stderr.procs.open_device(iodev, access, ps, mem);
130
    stream *s = *ps;
131
 
132
    if (code != 1)
133
	return code;
134
    s->procs.process = win_std_write_process;
135
    s->procs.available = win_std_available;
136
    s->procs.flush = s_std_write_flush;
137
    s->file = NULL;
138
    return 0;
139
}
140
 
141
/* Patch stdin/out/err to use our windows. */
142
private void
143
win_std_init(void)
144
{
145
    /* If stdxxx is the console, replace the 'open' routines, */
146
    /* which haven't gotten called yet. */
147
 
148
    if (gp_file_is_console(gs_stdin))
149
	gs_findiodevice((const byte *)"%stdin", 6)->procs.open_device =
150
	    win_stdin_open;
151
 
152
    if (gp_file_is_console(gs_stdout))
153
	gs_findiodevice((const byte *)"%stdout", 7)->procs.open_device =
154
	    win_stdout_open;
155
 
156
    if (gp_file_is_console(gs_stderr))
157
	gs_findiodevice((const byte *)"%stderr", 7)->procs.open_device =
158
	    win_stderr_open;
159
}
160
 
161
private int
162
win_std_read_process(stream_state * st, stream_cursor_read * ignore_pr,
163
		     stream_cursor_write * pw, bool last)
164
{
165
    int count = pw->limit - pw->ptr;
166
 
167
    if (count == 0)		/* empty buffer */
168
	return 1;
169
 
170
/* callback to get more input */
171
    count = (*pgsdll_callback) (GSDLL_STDIN, pw->ptr + 1, count);
172
    if (count == 0) {
173
	/* EOF */
174
	/* what should we do? */
175
	return EOFC;
176
    }
177
    pw->ptr += count;
178
    return 1;
179
}
180
 
181
private int
182
win_std_available(register stream * s, long *pl)
183
{
184
    *pl = -1;		// EOF, since we can't do it
185
    return 0;		// OK
186
}
187
 
188
 
189
private int
190
win_std_write_process(stream_state * st, stream_cursor_read * pr,
191
		      stream_cursor_write * ignore_pw, bool last)
192
{
193
    uint count = pr->limit - pr->ptr;
194
 
195
    (*pgsdll_callback) (GSDLL_STDOUT, (char *)(pr->ptr + 1), count);
196
    pr->ptr = pr->limit;
197
    return 0;
198
}
199
 
200
/* This is used instead of the stdio version. */
201
/* The declaration must be identical to that in <stdio.h>. */
202
#if defined(_WIN32) && (defined(_MSC_VER) || defined(_WATCOM_))
203
#if defined(_CRTAPI2)
204
int _CRTAPI2
205
fprintf(FILE * file, const char *fmt,...)
206
#else
207
_CRTIMP int __cdecl
208
fprintf(FILE * file, const char *fmt,...)
209
#endif
210
#else
211
int _Cdecl _FARFUNC
212
fprintf(FILE _FAR * file, const char *fmt,...)
213
#endif
214
{
215
    int count;
216
    va_list args;
217
 
218
    va_start(args, fmt);
219
    if (gp_file_is_console(file)) {
220
	char buf[1024];
221
 
222
	count = vsprintf(buf, fmt, args);
223
	(*pgsdll_callback) (GSDLL_STDOUT, buf, count);
224
    } else
225
	count = vfprintf(file, fmt, args);
226
    va_end(args);
227
    return count;
228
}