Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2
<html>
3
<head>
4
<title>How to use the Ghostscript Dynamic Link Library (DLL)</title>
5
<!-- $Id: DLL.htm,v 1.43 2005/10/20 19:46:23 ray Exp $ -->
6
<!-- Originally: dll.txt -->
7
<link rel="stylesheet" type="text/css" href="gs.css" title="Ghostscript Style">
8
</head>
9
 
10
<body>
11
<!-- [1.0 begin visible header] ============================================ -->
12
 
13
<!-- [1.1 begin headline] ================================================== -->
14
 
15
<h1>How to use the Ghostscript Dynamic Link Library (DLL)</h1>
16
 
17
<!-- [1.1 end headline] ==================================================== -->
18
 
19
<!-- [1.2 begin table of contents] ========================================= -->
20
 
21
<h2>Table of contents</h2>
22
 
23
<ul>
24
<li><a href="#DLL">What is the Ghostscript DLL?</a>
25
<li><a href="#Common_functions">Platform-independent DLL functions</a>
26
<ul>
27
<li><a href="#revision"><b><tt>gsdll_revision()</tt></b></a>
28
<li><a href="#init"><b><tt>gsdll_init()</tt></b></a>
29
<li><a href="#execute_begin"><b><tt>gsdll_execute_begin()</tt></b></a>
30
<li><a href="#execute_cont"><b><tt>gsdll_execute_cont()</tt></b></a>
31
<li><a href="#execute_end"><b><tt>gsdll_execute_end()</tt></b></a>
32
<li><a href="#exit"><b><tt>gsdll_exit()</tt></b></a>
33
<li><a href="#lock_device"><b><tt>gsdll_lock_device()</tt></b></a>
34
</ul>
35
<li><a href="#Callback">Callback function</a>
36
<li><a href="#OS2_device">Ghostscript DLL device for OS/2</a>
37
<ul>
38
<li><a href="#OS2_bmp"><b><tt>gsdll_get_bitmap()</tt></b></a>
39
<li><a href="#OS2_example">Example DLL usage for OS/2</a>
40
</ul>
41
<li><a href="#Win_device">Ghostscript DLL device for MS Windows</a>
42
<ul>
43
<li><a href="#Win_copydib"><b><tt>gsdll_copy_dib()</tt></b></a>
44
<li><a href="#Win_copypalette"><b><tt>gsdll_copy_palette()</tt></b></a>
45
<li><a href="#Win_draw"><b><tt>gsdll_draw()</tt></b></a>
46
<li><a href="#Win_get_row"><b><tt>gsdll_get_bitmap_row()</tt></b></a>
47
</ul>
48
<li><a href="#Win16">Ghostscript DLL Device for 16-bit MS Windows</a>
49
</ul>
50
 
51
<!-- [1.2 end table of contents] =========================================== -->
52
 
53
<!-- [1.3 begin hint] ====================================================== -->
54
 
55
<p>For other information, see the <a href="Readme.htm">Ghostscript
56
overview</a>.
57
 
58
<p>
59
<b>WARNING: The API described in this document is obsolete and will
60
be removed in the future.</b> 
61
The current Ghostscript Interpreter API 
62
is described in <a href="API.htm">API.htm</a>.
63
 
64
<!-- [1.3 end hint] ======================================================== -->
65
 
66
<hr>
67
 
68
<!-- [1.0 end visible header] ============================================== -->
69
 
70
<!-- [2.0 begin contents] ================================================== -->
71
 
72
<h2><a name="DLL"></a>What is the Ghostscript DLL?</h2>
73
 
74
<p>
75
For the OS/2, Win16 and Win32 platforms, Ghostscript is built as a dynamic
76
link library (DLL), and to provide the interface described in the <a
77
href="Use.htm">usage documentation</a>, a smaller independent executable
78
(<b><tt>.EXE</tt></b>) loads this DLL, which provides all the interaction
79
with the windowing system, including image windows and, if necessary, a
80
text window.  This document describes the DLL interface, which consists of
81
eight main functions, <a href="#functions">seven platform-independent
82
ones</a> provided by the DLL and one, <a href="#Callback">the callback
83
function</a>, provided by the caller.  The DLL provides some other
84
platform-specific functions for display devices.
85
 
86
<p>
87
The DLL's name and characteristics differ among the three platforms:
88
 
89
<ul>
90
<li>The <a href="#OS2_device">OS/2 DLL <b><tt>GSDLL2.DLL</tt></b></a> has
91
MULTIPLE NONSHARED data segments and can be called by multiple programs
92
simultaneously.
93
 
94
<li>The <a href="#Win_device">Win32 DLL <b><tt>GSDLL32.DLL</tt></b></a> has
95
MULTIPLE NONSHARED data segments.  Under Win32s it can be used by only one
96
program at a time, but under Windows 95/98 or Windows NT it can be called by
97
multiple programs simultaneously.
98
 
99
<li>The <a href="#Win16">Win16 DLL <b><tt>GSDLL16.DLL</tt></b></a> is a
100
large-memory model DLL with far static data.  Due to the limitations of
101
16-bit MS Windows -- Windows 3.n -- the DLL can be used by only one program
102
at a time.
103
</ul>
104
 
105
<p>
106
The source for the executable is in <b><tt>dp</tt></b>*.* (OS/2) and
107
<b><tt>dw</tt></b>*.* (Windows).  See these source files for examples of
108
how to use the DLL.
109
 
110
<hr>
111
 
112
<h2><a name="Common_functions"></a>Platform-independent DLL functions</h2>
113
 
114
<p>
115
The seven functions provided by the DLL are
116
<ul>
117
<li><b><tt>int GSDLLAPI <a href="#revision">gsdll_revision</a>(char **product, char **copyright, long *gs_revision, long *gs_revisiondate)</tt></b>
118
<li><b><tt>int GSDLLAPI <a href="#init">gsdll_init</a>(GSDLL_CALLBACK callback, HWND hwnd, int argc, char *argv[]);</tt></b>
119
<li><b><tt>int GSDLLAPI <a href="#execute_begin">gsdll_execute_begin</a>(void);</tt></b>
120
<li><b><tt>int GSDLLAPI <a href="#execute_cont">gsdll_execute_cont</a>(const char *str, int len);</tt></b>
121
<li><b><tt>int GSDLLAPI <a href="#execute_end">gsdll_execute_end</a>(void);</tt></b>
122
<li><b><tt>int GSDLLAPI <a href="#exit">gsdll_exit</a>(void);</tt></b>
123
<li><b><tt>int GSDLLAPI <a href="#lock_device">gsdll_lock_device</a>(unsigned char *device, int flag);</tt></b>
124
 
125
<p>
126
where <b><tt>GSDLLAPI</tt></b> is defined under OS/2 as
127
 
128
<blockquote><b><tt>
129
#define GSDLLAPI
130
</tt></b></blockquote>
131
 
132
<p>
133
and under MS Windows as
134
 
135
<blockquote><b><tt>
136
#define GSDLLAPI CALLBACK _export
137
</tt></b></blockquote>
138
</ul>
139
 
140
<h3><a name="revision"></a><b><tt>gsdll_revision()</tt></b></h3>
141
 
142
<blockquote>
143
This function returns the revision numbers and strings of the Ghostscript
144
DLL; you should call it before <b><tt>gsdll_init()</tt></b> to make sure
145
that the correct version of the Ghostscript DLL has been loaded.  For
146
example
147
 
148
<blockquote>
149
<pre>char *product;
150
char *copyright;
151
long revision;
152
long revisiondate;
153
gsdll_revision(&amp;product, &amp;copyright, &amp;revision, &amp;revisiondate);
154
</pre></blockquote>
155
 
156
<p>
157
You may use <b><tt>NULL</tt></b> pointers if you do not want a particular
158
value.
159
</blockquote>
160
 
161
<h3><a name="init"></a><b><tt>gsdll_init()</tt></b></h3>
162
 
163
<blockquote>
164
<b><tt>gsdll_init()</tt></b> must be called after loading the DLL and
165
before executing any Ghostscript commands.  The arguments are the address
166
of the callback function, a parent window handle, the count of arguments
167
and an array of pointers to the arguments.  For example
168
 
169
<blockquote>
170
<pre>char *argv[5];
171
argv[0] = "gswin.exe";
172
argv[1] = "-Ic:\\gs;c:\gs\\fonts";
173
argv[2] = "-dNOPAUSE",
174
argv[3] = "-sDEVICE=djet500",
175
argv[4] = NULL;
176
argc = 4;
177
 
178
code = gsdll_init(gsdll_callback, hwnd, argc, argv);
179
</pre></blockquote>
180
 
181
<p>
182
<b><tt>hwnd</tt></b> is used as the parent window handle for any windows
183
created by Ghostscript.  <b><tt>hwnd</tt></b> may be <b><tt>NULL</tt></b>
184
if the caller has no windows, but if it is <b><tt>NULL</tt></b>, you should
185
avoid using devices which may open windows.
186
 
187
<p>
188
A return code of 0 (zero) indicates no errors, and the code may now call
189
<b><tt>gsdll_execute_begin()</tt></b> or <b><tt>gsdll_exit()</tt></b>.  If
190
the return value is non-zero then <b><tt>gsdll_exit()</tt></b> must not be
191
called.
192
 
193
<p>
194
A return value of <b><tt>GSDLL_INIT_QUIT</tt></b> indicates that one of the
195
command line files or arguments called "<b><tt>quit</tt></b>", or that
196
Ghostscript was reading stdin and reached end-of-file.  This is not an
197
error.  <b><tt>gsdll_exit()</tt></b> must not be called.
198
 
199
<p>
200
A return value of <b><tt>GSDLL_INIT_IN_USE</tt></b> indicates that the DLL
201
is in use by another application (Windows 3.1 only).  The DLL should be
202
immediately unloaded (or the caller terminated).
203
<b><tt>gsdll_exit()</tt></b> must not be called.
204
</blockquote>
205
 
206
<h3><a name="execute_begin"></a><b><tt>gsdll_execute_begin()</tt></b></h3>
207
 
208
<blockquote>
209
This must be called after <b><tt>gsdll_init()</tt></b> and before
210
<b><tt>gsdll_execute_cont()</tt></b>.
211
</blockquote>
212
 
213
<h3><a name="execute_cont"></a><b><tt>gsdll_execute_cont()</tt></b></h3>
214
 
215
<blockquote>
216
After successfully calling <b><tt>gsdll_init()</tt></b> and
217
<b><tt>gsdll_execute_begin()</tt></b>, commands may be given to Ghostscript
218
with <b><tt>gsdll_execute_cont()</tt></b>.  Examples are:
219
 
220
<blockquote>
221
<pre>char *command = "1 2 add == flush\n";
222
code = gsdll_execute_cont(command, strlen(command));
223
command = "qu"
224
code = gsdll_execute_cont(command, strlen(command));
225
command = "it\n"
226
code = gsdll_execute_cont(command, strlen(command));
227
</pre>
228
 
229
<a name="cont_returns"></a>
230
<table cellpadding=0 cellspacing=0>
231
<tr><th colspan=3 bgcolor="#CCCC00"><hr><font size="+1">Return codes from <b><tt>gsdll_execute_cont()</tt></b></font><hr>
232
<tr valign=bottom>
233
	<th align=left>Code
234
	<td>&nbsp;&nbsp;&nbsp;&nbsp;
235
	<th align=left>Status
236
<tr>	<td colspan=3><hr>
237
<tr valign=top>	<td align=left>0
238
	<td>&nbsp;
239
	<td>No errors
240
<tr valign=top>	<td align=left>&lt; 0
241
	<td>&nbsp;
242
	<td>Error
243
<tr valign=top>	<td align=left>&lt;= -100
244
	<td>&nbsp;
245
	<td>"<b><tt>quit</tt></b>" has been executed, or fatal error.
246
<b><tt>gsdll_exit()</tt></b> must then be called: do not call
247
<b><tt>gsdll_execute_end()</tt></b>.
248
</table>
249
</blockquote>
250
 
251
<b><tt>gsdll_execute_cont()</tt></b>
252
does not flush stdio, so if you want to see output from Ghostscript you
253
must do this explicitly as shown in the example above.
254
 
255
<p>
256
When executing a string with <b><tt>gsdll_execute_cont()</tt></b>,
257
<b><tt>currentfile</tt></b> is the input from
258
<b><tt>gsdll_execute_cont()</tt></b>.  Reading from <b><tt>%stdin</tt></b>
259
uses the callback.
260
 
261
<p>
262
Please note that there is a 64 KB length limit on the passed string.
263
If you have more than 65535 bytes of input to process at a given time,
264
it must be split into separate smaller buffers, each passed on a 
265
separate call.
266
 
267
</blockquote>
268
 
269
<h3><a name="execute_end"></a><b><tt>gsdll_execute_end()</tt></b></h3>
270
 
271
<blockquote>
272
If <b><tt>gsdll_execute_cont()</tt></b> did not return an error, then
273
<b><tt>gsdll_execute_end()</tt></b> must be called after
274
<b><tt>gsdll_execute_cont()</tt></b> and before
275
<b><tt>gsdll_exit()</tt></b>.
276
</blockquote>
277
 
278
<h3><a name="exit"></a><b><tt>gsdll_exit()</tt></b></h3>
279
 
280
<blockquote>
281
Call gsdll_exit() to terminate the Ghostscript DLL.  It must be called if a
282
fatal error has occurred; see the <a href="#cont_returns">return value
283
of <b><tt>gsdll_execute_cont()</tt></b></a>.  After calling
284
<b><tt>gsdll_exit()</tt></b>, there are two options:
285
 
286
<ul>
287
<li>Unload the DLL, either by terminating the application or by
288
calling <b><tt>DosFreeModule</tt></b> (OS/2) or <b><tt>FreeLibrary</tt></b> (MS Windows).
289
 
290
<li>Call <b><tt>gsdll_init()</tt></b> again to restart Ghostscript.
291
</ul>
292
</blockquote>
293
 
294
<h3><a name="lock_device"></a><b><tt>gsdll_lock_device()</tt></b></h3>
295
 
296
<blockquote>
297
Since the caller may be multithreaded, a lock is needed to control access
298
to the display device, and <b><tt>gsdll_lock_device()</tt></b> provides that
299
locking.
300
 
301
<blockquote>
302
<pre>int gsdll_lock_device(unsigned char *device, int flag);
303
 /* Lock the device if flag = TRUE */
304
 /* Unlock the device if flag = FALSE */
305
 /* device is a pointer to Ghostscript os2dll or mswindll device */
306
 /* from GSDLL_DEVICE message. */
307
 /* Return value is the lock count. */
308
</pre>
309
 
310
<table cellpadding=0 cellspacing=0>
311
<tr><th colspan=3 bgcolor="#CCCC00"><hr><font size="+1">Locking and unlocking devices</font><hr>
312
<tr valign=top>	<td>To lock a device
313
	<td>&nbsp;&nbsp;&nbsp;&nbsp;
314
	<td><b><tt>gsdll_lock_device(device, 1)</tt></b>;
315
<tr valign=top>	<td>To unlock a device
316
	<td>&nbsp;
317
	<td><b><tt>gsdll_lock_device(device, 0)</tt></b>;
318
</table>
319
</blockquote>
320
 
321
<p>
322
This function is typically used to lock the device while repainting a
323
window or copying the device bitmap to the clipboard.  Ghostscript may draw
324
into the device bitmap or update the palette entries while the device is
325
locked by the caller, but locking the device prevents the Ghostscript DLL
326
from closing the device or changing its size or depth.
327
 
328
<p>
329
Under OS/2, Windows 95/98 and Windows NT, this lock is implemented using a
330
mutual exclusion semaphore (mutex).  The return value is the lock count,
331
which is either 0 ("unlocked") or 1 ("locked").  The function blocks until
332
the device is locked by the caller.
333
 
334
<p>
335
Under Win16 or Win32s, <b><tt>gsdll_lock_device()</tt></b> always returns
336
immediately with a lock count as its return value.  A lock count of 2 or
337
more is definite indication of an error, probably calling the function
338
twice.  Access to the device should be controlled by checking the Windows
339
message queue only when the bitmap is not being accessed.
340
</blockquote>
341
 
342
<hr>
343
 
344
<h2><a name="Callback"></a>Callback function</h2>
345
 
346
<blockquote>
347
As an argument to <a href="#init"><b><tt>gsdll_init()</tt></b></a> the
348
caller must provide a callback function which the DLL invokes for stdio and
349
to notify the caller about device events.  The function provided by the
350
caller has this prototype:
351
 
352
<blockquote><b><tt>
353
int gsdll_callback(int&nbsp;message, char&nbsp;*str, unsigned&nbsp;long&nbsp;count);
354
</tt></b></blockquote>
355
 
356
<p>
357
The Pascal calling convention is not used.  An example callback function
358
is:
359
 
360
<blockquote>
361
<pre>int
362
gsdll_callback(int message, char *str, unsigned long count)
363
{
364
char *p;
365
    switch (message) {
366
        case GSDLL_STDIN:
367
            p = fgets(str, count, stdin);
368
            if (p)
369
                return strlen(str);
370
            else
371
                return 0;
372
        case GSDLL_STDOUT:
373
            if (str != (char *)NULL)
374
                fwrite(str, 1, count, stdout);
375
            return count;
376
        case GSDLL_DEVICE:
377
            fprintf(stdout,"Callback: DEVICE %p %s\n", str,
378
                count ? "open" : "close");
379
            break;
380
        case GSDLL_SYNC:
381
            fprintf(stdout,"Callback: SYNC %p\n", str);
382
            break;
383
        case GSDLL_PAGE:
384
            fprintf(stdout,"Callback: PAGE %p\n", str);
385
            break;
386
        case GSDLL_SIZE:
387
            fprintf(stdout,"Callback: SIZE %p width=%d height=%d\n", str,
388
                (int)(count &amp; 0xffff), (int)((count&gt;&gt;16) &amp; 0xffff) );
389
            break;
390
        case GSDLL_POLL:
391
            return 0; /* no error */
392
        default:
393
            fprintf(stdout,"Callback: Unknown message=%d\n",message);
394
            break;
395
    }
396
    return 0;
397
}
398
</pre>
399
 
400
<table cellpadding=0 cellspacing=0>
401
<tr><th colspan=5 bgcolor="#CCCC00"><hr><font size="+1">Messages used by callback</font><hr>
402
<tr valign=bottom>
403
	<th align=left>Symbol
404
	<td>&nbsp;&nbsp;
405
	<th align=left>
406
	<td>&nbsp;&nbsp;
407
	<th align=left>Use
408
<tr>	<td colspan=5><hr>
409
<tr valign=top>	<td><b><tt>GSDLL_STDIN</tt></b>
410
	<td>&nbsp;
411
	<td>1
412
	<td>&nbsp;
413
	<td>get <b><tt>count</tt></b> characters to <b><tt>str</tt></b> from stdin, return number of characters read
414
<tr valign=top>	<td><b><tt>GSDLL_STDOUT</tt></b>
415
	<td>&nbsp;
416
	<td>2
417
	<td>&nbsp;
418
	<td>put <b><tt>count</tt></b> characters from <b><tt>str</tt></b>
419
		to stdout, return number of characters written
420
<tr valign=top>	<td><b><tt>GSDLL_DEVICE</tt></b>
421
	<td>&nbsp;
422
	<td>3
423
	<td>&nbsp;
424
	<td>device <b><tt>str</tt></b> has been opened if
425
		<b><tt>count</tt></b>&nbsp;=&nbsp;1, closed if
426
		<b><tt>count</tt></b>&nbsp;=&nbsp;0
427
<tr valign=top>	<td><b><tt>GSDLL_SYNC</tt></b>
428
	<td>&nbsp;
429
	<td>4
430
	<td>&nbsp;
431
	<td>sync_output for device <b><tt>str</tt></b>
432
<tr valign=top>	<td><b><tt>GSDLL_PAGE</tt></b>
433
	<td>&nbsp;
434
	<td>5
435
	<td>&nbsp;
436
	<td>output_page for device <b><tt>str</tt></b>
437
<tr valign=top>	<td><b><tt>GSDLL_SIZE</tt></b>
438
	<td>&nbsp;
439
	<td>6
440
	<td>&nbsp;
441
	<td>resize for device <b><tt>str</tt></b>:
442
		LOWORD(<b><tt>count</tt></b>) is new <b><tt>xsize</tt></b>,
443
		HIWORD(<b><tt>count</tt></b>) is new <b><tt>ysize</tt></b>
444
<tr valign=top>	<td><b><tt>GSDLL_POLL</tt></b>
445
	<td>&nbsp;
446
	<td>7
447
	<td>&nbsp;
448
	<td>Called from <b><tt>gp_check_interrupt()</tt></b><br>
449
		Can be used by the caller to poll the message queue.
450
		Normally returns 0.  To abort
451
		<b><tt>gsdll_execute_cont()</tt></b>, return a non-zero
452
		error code until <b><tt>gsdll_execute_cont()</tt></b>
453
		returns.
454
</table>
455
</blockquote>
456
</blockquote>
457
 
458
<hr>
459
 
460
<h2><a name="OS2_device"></a>Ghostscript DLL device for OS/2</h2>
461
 
462
<p>
463
The <b><tt>os2dll</tt></b> device is provided in the Ghostscript DLL for
464
use by the caller.  No drawing facilities are provided by the DLL because
465
the DLL may be loaded by a text-only (non-PM) application.  The caller is
466
notified via the <b><tt>gsdll_callback()</tt></b> when a new
467
<b><tt>os2dll</tt></b> device is opened or closed
468
(<b><tt>GSDLL_DEVICE</tt></b>), when the window should be redrawn
469
(<b><tt>GSDLL_SYNC</tt></b> or <b><tt>GSDLL_PAGE</tt></b>) or when the
470
bitmap size changes (<b><tt>GSDLL_SIZE</tt></b>).
471
Note that more than one <b><tt>os2dll</tt></b> device may be opened.
472
 
473
<h3><a name="OS2_bmp"></a><b><tt>gsdll_get_bitmap()</tt></b></h3>
474
 
475
<blockquote>
476
<b><tt>gsdll_get_bitmap()</tt></b> returns a pointer to a bitmap in BMP
477
format.  The <b><tt>os2dll</tt></b> device draws into this bitmap.
478
 
479
<blockquote>
480
<pre>unsigned long gsdll_get_bitmap(unsigned char *device, unsigned char **pbitmap);
481
 /* return in pbitmap the address of the bitmap */
482
 /* device is a pointer to Ghostscript os2dll device from GSDLL_DEVICE message */
483
</pre></blockquote>
484
 
485
<p>
486
The caller can then display the bitmap however it likes, but should lock
487
the bitmap with <b><tt>gsdll_lock_device()</tt></b> before painting from
488
it, and unlock it afterwards.  The bitmap address does not change until the
489
<b><tt>os2dll</tt></b> device is closed; however the bitmap size and
490
palette may change whenever the bitmap is not locked.
491
</blockquote>
492
 
493
<h3><a name="OS2_example"></a>Example DLL usage for OS/2</h3>
494
 
495
<p>
496
The example here shows a minimal usage of the Ghostscript DLL under OS/2.
497
The sample callback function above is needed.
498
 
499
<blockquote>
500
<pre>#define INCL_DOS
501
#include &lt;os2.h&gt;
502
#include &lt;stdio.h&gt;
503
#include "gsdll.h"
504
 
505
PFN_gsdll_init pgsdll_init;
506
PFN_gsdll_execute_begin pgsdll_execute_begin;
507
PFN_gsdll_execute_cont pgsdll_execute_cont;
508
PFN_gsdll_execute_end pgsdll_execute_end;
509
PFN_gsdll_exit pgsdll_exit;
510
 
511
HMODULE hmodule_gsdll;
512
char buf[256];
513
 
514
int
515
main(int argc, char *argv[])
516
{
517
int code;
518
APIRET rc;
519
    if (!DosLoadModule(buf, sizeof(buf), "GSDLL2", &amp;hmodule_gsdll)) {
520
        fprintf(stderr, "Loaded GSDLL2\n");
521
        DosQueryProcAddr(hmodule_gsdll, 0, "gsdll_init", (PFN *)(&amp;pgsdll_init));
522
        DosQueryProcAddr(hmodule_gsdll, 0, "gsdll_execute_begin", (PFN *)(&amp;pgsdll_execute_begin));
523
        DosQueryProcAddr(hmodule_gsdll, 0, "gsdll_execute_cont", (PFN *)(&amp;pgsdll_execute_cont));
524
        DosQueryProcAddr(hmodule_gsdll, 0, "gsdll_execute_end", (PFN *)(&amp;pgsdll_execute_end));
525
        DosQueryProcAddr(hmodule_gsdll, 0, "gsdll_exit", (PFN *)(&amp;pgsdll_exit));
526
    }
527
    else {
528
        fprintf(stderr, "Can't load GSDLL2\n");
529
    }
530
 
531
    code = (*pgsdll_init)(gsdll_callback, NULL, argc, argv);
532
    fprintf(stdout,"gsdll_init returns %d\n", code);
533
    code = (*pgsdll_execute_begin)();
534
    if (code==0) {
535
        while (fgets(buf, sizeof(buf), stdin)) {
536
            code = (*pgsdll_execute_cont)(buf, strlen(buf));
537
            fprintf(stdout,"gsdll_execute returns %d\n", code);
538
            if (code &lt; 0)
539
               break;
540
        }
541
        if (!code)
542
            code = (*pgsdll_execute_end)();
543
        code = (*pgsdll_exit)();
544
        fprintf(stdout,"gsdll_exit returns %d\n", code);
545
    }
546
    rc = DosFreeModule(hmodule_gsdll);
547
    fprintf(stdout,"DosFreeModule returns %d\n", rc);
548
    return 0;
549
}
550
</pre></blockquote>
551
 
552
<hr>
553
 
554
<h2><a name="Win_device"></a>Ghostscript DLL device for MS Windows</h2>
555
 
556
<p>
557
The <b><tt>mswindll</tt></b> device is provided in the Ghostscript DLL for
558
use by the caller.  The caller is notified via the
559
<b><tt>gsdll_callback()</tt></b> when a new <b><tt>mswindll</tt></b> device
560
is opened or closed (<b><tt>GSDLL_DEVICE</tt></b>), when the window should
561
be redrawn (<b><tt>GSDLL_SYNC</tt></b> or <b><tt>GSDLL_PAGE</tt></b>) or
562
when the bitmap size changes (<b><tt>GSDLL_SIZE</tt></b>).  Note that more
563
than one <b><tt>mswindll</tt></b> device may be opened.
564
 
565
<p>
566
Four DLL functions are available to use the <b><tt>mswindll</tt></b>
567
device.
568
 
569
<h3><a name="Win_copydib"></a><b><tt>gsdll_copy_dib()</tt></b></h3>
570
 
571
<blockquote>
572
Copy the <b><tt>mswindll</tt></b> bitmap to the clipboard.
573
 
574
<blockquote>
575
<pre>HGLOBAL GSDLLAPI gsdll_copy_dib(unsigned char *device);
576
 /* make a copy of the device bitmap and return shared memory handle to it */
577
 /* device is a pointer to Ghostscript device from GSDLL_DEVICE message */
578
</pre></blockquote>
579
</blockquote>
580
 
581
<h3><a name="Win_copypalette"></a><b><tt>gsdll_copy_palette()</tt></b></h3>
582
 
583
<blockquote>
584
Copy the <b><tt>mswindll</tt></b> palette to the clipboard.
585
 
586
<blockquote>
587
<pre>HPALETTE GSDLLAPI gsdll_copy_palette(unsigned char *device);
588
/* make a copy of the device palette and return a handle to it */
589
/* device is a pointer to Ghostscript device from GSDLL_DEVICE message */
590
</pre></blockquote>
591
</blockquote>
592
 
593
<h3><a name="Win_draw"></a><b><tt>gsdll_draw()</tt></b></h3>
594
 
595
<blockquote>
596
Display output from the <b><tt>mswindll</tt></b> device.  The caller should
597
create a window and call <b><tt>gsdll_draw()</tt></b> in response to the
598
<b><tt>WM_PAINT</tt></b> message.  The device context <b><tt>hdc</tt></b>
599
must be for a device because <b><tt>SetDIBitsToDevice()</tt></b> is used.
600
 
601
<blockquote>
602
<pre>void GSDLLAPI gsdll_draw(unsigned char *device, HDC hdc,
603
                                  LPRECT dest, LPRECT src);
604
/* copy the rectangle src from the device bitmap */
605
/* to the rectangle dest on the device given by hdc */
606
/* hdc must be a device context for a device (NOT a bitmap) */
607
/* device is a pointer to Ghostscript device from GSDLL_DEVICE message */
608
</pre></blockquote>
609
</blockquote>
610
 
611
<h3><a name="Win_get_row"></a><b><tt>gsdll_get_bitmap_row()</tt></b></h3>
612
 
613
<blockquote>
614
Get a BMP header, a palette, and a pointer to a row in the bitmap.  This
615
function exists to allow the bitmap to be copied to a file or structured
616
storage without the overhead of having two copies of the bitmap in memory
617
at the same time.
618
 
619
<p>
620
Ghostscript can change the palette while the device is locked.  Do not call
621
this function while Ghostscript is busy.
622
 
623
<blockquote>
624
<pre>int GSDLLAPI gsdll_get_bitmap_row(unsigned char *device, LPBITMAPINFOHEADER pbmih,
625
    LPRGBQUAD prgbquad, LPBYTE *ppbyte, unsigned int row)
626
/* If pbmih nonzero, copy the BITMAPINFOHEADER.
627
 * If prgbquad nonzero, copy the palette.
628
 *   number of entries copied is given by pbmih-&gt;biClrUsed
629
 * If ppbyte nonzero, return pointer to row.
630
 *   pointer is only valid while device is locked
631
 */
632
</pre></blockquote>
633
</blockquote>
634
 
635
<hr>
636
 
637
<h2><a name="Win16"></a>Ghostscript DLL Device for 16-bit MS Windows</h2>
638
 
639
<p>
640
This platform has the most problems of the three.  Support for it may be
641
dropped in future.
642
 
643
<p>
644
The Win16 DLL <b><tt>GSDLL16.DLL</tt></b> is a large-memory model DLL with
645
far static data.  Due to the limitations of 16-bit MS Windows, the DLL can
646
be used by only one program at a time.
647
 
648
<p>
649
However, <b><tt>GSDLL16</tt></b> is marked as having SINGLE SHARED data
650
segments, allowing multiple applications to load it with no error
651
indication.  (The DLL wouldn't load at all if MULTIPLE NONSHARED was used).
652
Nonetheless, <b>it cannot be used by more than one application at a
653
time</b>, so applications loading <b><tt>GSDLL16</tt></b> should check the
654
return value of <b><tt>gsdll_init()</tt></b>: if this value is non-zero,
655
then <b><tt>GSDLL16</tt></b> is already in use by another application and
656
should <b><em>not</em></b> be used: <b><tt>GSDLL16</tt></b> should be
657
unloaded immediately using <b><tt>FreeLibrary()</tt></b>, or the calling
658
program should quit without attempting to use the library..
659
 
660
<p>
661
The segmented architecture of the Intel 80286 causes the usual amount of
662
grief when using <b><tt>GSDLL16</tt></b>.  Because the callback is called
663
from the DLL, which is using a different data segment, the callback must be
664
declared as <b><tt>_far&nbsp;_export</tt></b>:
665
 
666
<blockquote>
667
<pre>int _far _export gsdll_callback(int message, char *str, unsigned long count);
668
</pre></blockquote>
669
 
670
<p>
671
Instead of giving <b><tt>gsdll_init()</tt></b> the address of
672
<b><tt>gsdll_callback()</tt></b>, it should instead be given the address of
673
a thunk created by <b><tt>MakeProcInstance</tt></b>.  This thunk changes
674
the data segment back to that used by the caller:
675
 
676
<blockquote>
677
<pre>FARPROC lpfnCallback;
678
lpfnCallback = (FARPROC)MakeProcInstance((FARPROC)gsdll_callback, hInstance);
679
code = (*pgsdll_init)((GSDLL_CALLBACK)lpfnCallback, NULL, argc, argv);
680
if (!code) {
681
    fprintf(stderr, "GSDLL16 is already in use\n");
682
    return -1;
683
}
684
</pre></blockquote>
685
 
686
<!-- [2.0 end contents] ==================================================== -->
687
 
688
<!-- [3.0 begin visible trailer] =========================================== -->
689
<hr>
690
 
691
<p>
692
<small>Copyright &copy; 1996, 1997, 1998 Aladdin Enterprises.
693
All rights reserved.</small>
694
 
695
<p>
696
This software is provided AS-IS with no warranty, either express or
697
implied.
698
 
699
This software is distributed under license and may not be copied,
700
modified or distributed except as expressly authorized under the terms
701
of the license contained in the file LICENSE in this distribution.
702
 
703
For more information about licensing, please refer to
704
http://www.ghostscript.com/licensing/. For information on
705
commercial licensing, go to http://www.artifex.com/licensing/ or
706
contact Artifex Software, Inc., 101 Lucas Valley Road #110,
707
San Rafael, CA  94903, U.S.A., +1(415)492-9861.
708
 
709
<p>
710
<small>Ghostscript version 8.53, 20 October 2005
711
 
712
<!-- [3.0 end visible trailer] ============================================= -->
713
 
714
</body>
715
</html>