xref: /plan9/sys/src/cmd/gs/doc/DLL.htm (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
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
56overview</a>.
57
58<p>
59<b>WARNING: The API described in this document is obsolete and will
60be removed in the future.</b>
61The current Ghostscript Interpreter API
62is 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>
75For the OS/2, Win16 and Win32 platforms, Ghostscript is built as a dynamic
76link library (DLL), and to provide the interface described in the <a
77href="Use.htm">usage documentation</a>, a smaller independent executable
78(<b><tt>.EXE</tt></b>) loads this DLL, which provides all the interaction
79with the windowing system, including image windows and, if necessary, a
80text window.  This document describes the DLL interface, which consists of
81eight main functions, <a href="#functions">seven platform-independent
82ones</a> provided by the DLL and one, <a href="#Callback">the callback
83function</a>, provided by the caller.  The DLL provides some other
84platform-specific functions for display devices.
85
86<p>
87The 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
91MULTIPLE NONSHARED data segments and can be called by multiple programs
92simultaneously.
93
94<li>The <a href="#Win_device">Win32 DLL <b><tt>GSDLL32.DLL</tt></b></a> has
95MULTIPLE NONSHARED data segments.  Under Win32s it can be used by only one
96program at a time, but under Windows 95/98 or Windows NT it can be called by
97multiple programs simultaneously.
98
99<li>The <a href="#Win16">Win16 DLL <b><tt>GSDLL16.DLL</tt></b></a> is a
100large-memory model DLL with far static data.  Due to the limitations of
10116-bit MS Windows -- Windows 3.n -- the DLL can be used by only one program
102at a time.
103</ul>
104
105<p>
106The 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
108how to use the DLL.
109
110<hr>
111
112<h2><a name="Common_functions"></a>Platform-independent DLL functions</h2>
113
114<p>
115The 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>
126where <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>
133and 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>
143This function returns the revision numbers and strings of the Ghostscript
144DLL; you should call it before <b><tt>gsdll_init()</tt></b> to make sure
145that the correct version of the Ghostscript DLL has been loaded.  For
146example
147
148<blockquote>
149<pre>char *product;
150char *copyright;
151long revision;
152long revisiondate;
153gsdll_revision(&amp;product, &amp;copyright, &amp;revision, &amp;revisiondate);
154</pre></blockquote>
155
156<p>
157You may use <b><tt>NULL</tt></b> pointers if you do not want a particular
158value.
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
165before executing any Ghostscript commands.  The arguments are the address
166of the callback function, a parent window handle, the count of arguments
167and an array of pointers to the arguments.  For example
168
169<blockquote>
170<pre>char *argv[5];
171argv[0] = "gswin.exe";
172argv[1] = "-Ic:\\gs;c:\gs\\fonts";
173argv[2] = "-dNOPAUSE",
174argv[3] = "-sDEVICE=djet500",
175argv[4] = NULL;
176argc = 4;
177
178code = 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
183created by Ghostscript.  <b><tt>hwnd</tt></b> may be <b><tt>NULL</tt></b>
184if the caller has no windows, but if it is <b><tt>NULL</tt></b>, you should
185avoid using devices which may open windows.
186
187<p>
188A 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
190the return value is non-zero then <b><tt>gsdll_exit()</tt></b> must not be
191called.
192
193<p>
194A return value of <b><tt>GSDLL_INIT_QUIT</tt></b> indicates that one of the
195command line files or arguments called "<b><tt>quit</tt></b>", or that
196Ghostscript was reading stdin and reached end-of-file.  This is not an
197error.  <b><tt>gsdll_exit()</tt></b> must not be called.
198
199<p>
200A return value of <b><tt>GSDLL_INIT_IN_USE</tt></b> indicates that the DLL
201is in use by another application (Windows 3.1 only).  The DLL should be
202immediately 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>
209This 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>
216After successfully calling <b><tt>gsdll_init()</tt></b> and
217<b><tt>gsdll_execute_begin()</tt></b>, commands may be given to Ghostscript
218with <b><tt>gsdll_execute_cont()</tt></b>.  Examples are:
219
220<blockquote>
221<pre>char *command = "1 2 add == flush\n";
222code = gsdll_execute_cont(command, strlen(command));
223command = "qu"
224code = gsdll_execute_cont(command, strlen(command));
225command = "it\n"
226code = 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>
252does not flush stdio, so if you want to see output from Ghostscript you
253must do this explicitly as shown in the example above.
254
255<p>
256When 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>
259uses the callback.
260
261<p>
262Please note that there is a 64 KB length limit on the passed string.
263If you have more than 65535 bytes of input to process at a given time,
264it must be split into separate smaller buffers, each passed on a
265separate call.
266
267</blockquote>
268
269<h3><a name="execute_end"></a><b><tt>gsdll_execute_end()</tt></b></h3>
270
271<blockquote>
272If <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>
281Call gsdll_exit() to terminate the Ghostscript DLL.  It must be called if a
282fatal error has occurred; see the <a href="#cont_returns">return value
283of <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
288calling <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>
297Since the caller may be multithreaded, a lock is needed to control access
298to the display device, and <b><tt>gsdll_lock_device()</tt></b> provides that
299locking.
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>
322This function is typically used to lock the device while repainting a
323window or copying the device bitmap to the clipboard.  Ghostscript may draw
324into the device bitmap or update the palette entries while the device is
325locked by the caller, but locking the device prevents the Ghostscript DLL
326from closing the device or changing its size or depth.
327
328<p>
329Under OS/2, Windows 95/98 and Windows NT, this lock is implemented using a
330mutual exclusion semaphore (mutex).  The return value is the lock count,
331which is either 0 ("unlocked") or 1 ("locked").  The function blocks until
332the device is locked by the caller.
333
334<p>
335Under Win16 or Win32s, <b><tt>gsdll_lock_device()</tt></b> always returns
336immediately with a lock count as its return value.  A lock count of 2 or
337more is definite indication of an error, probably calling the function
338twice.  Access to the device should be controlled by checking the Windows
339message 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>
347As an argument to <a href="#init"><b><tt>gsdll_init()</tt></b></a> the
348caller must provide a callback function which the DLL invokes for stdio and
349to notify the caller about device events.  The function provided by the
350caller has this prototype:
351
352<blockquote><b><tt>
353int gsdll_callback(int&nbsp;message, char&nbsp;*str, unsigned&nbsp;long&nbsp;count);
354</tt></b></blockquote>
355
356<p>
357The Pascal calling convention is not used.  An example callback function
358is:
359
360<blockquote>
361<pre>int
362gsdll_callback(int message, char *str, unsigned long count)
363{
364char *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>
463The <b><tt>os2dll</tt></b> device is provided in the Ghostscript DLL for
464use by the caller.  No drawing facilities are provided by the DLL because
465the DLL may be loaded by a text-only (non-PM) application.  The caller is
466notified 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
470bitmap size changes (<b><tt>GSDLL_SIZE</tt></b>).
471Note 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
477format.  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>
486The caller can then display the bitmap however it likes, but should lock
487the bitmap with <b><tt>gsdll_lock_device()</tt></b> before painting from
488it, 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
490palette 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>
496The example here shows a minimal usage of the Ghostscript DLL under OS/2.
497The 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
505PFN_gsdll_init pgsdll_init;
506PFN_gsdll_execute_begin pgsdll_execute_begin;
507PFN_gsdll_execute_cont pgsdll_execute_cont;
508PFN_gsdll_execute_end pgsdll_execute_end;
509PFN_gsdll_exit pgsdll_exit;
510
511HMODULE hmodule_gsdll;
512char buf[256];
513
514int
515main(int argc, char *argv[])
516{
517int code;
518APIRET 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>
557The <b><tt>mswindll</tt></b> device is provided in the Ghostscript DLL for
558use 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
560is opened or closed (<b><tt>GSDLL_DEVICE</tt></b>), when the window should
561be redrawn (<b><tt>GSDLL_SYNC</tt></b> or <b><tt>GSDLL_PAGE</tt></b>) or
562when the bitmap size changes (<b><tt>GSDLL_SIZE</tt></b>).  Note that more
563than one <b><tt>mswindll</tt></b> device may be opened.
564
565<p>
566Four DLL functions are available to use the <b><tt>mswindll</tt></b>
567device.
568
569<h3><a name="Win_copydib"></a><b><tt>gsdll_copy_dib()</tt></b></h3>
570
571<blockquote>
572Copy 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>
584Copy 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>
596Display output from the <b><tt>mswindll</tt></b> device.  The caller should
597create 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>
599must 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>
614Get a BMP header, a palette, and a pointer to a row in the bitmap.  This
615function exists to allow the bitmap to be copied to a file or structured
616storage without the overhead of having two copies of the bitmap in memory
617at the same time.
618
619<p>
620Ghostscript can change the palette while the device is locked.  Do not call
621this 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>
640This platform has the most problems of the three.  Support for it may be
641dropped in future.
642
643<p>
644The Win16 DLL <b><tt>GSDLL16.DLL</tt></b> is a large-memory model DLL with
645far static data.  Due to the limitations of 16-bit MS Windows, the DLL can
646be used by only one program at a time.
647
648<p>
649However, <b><tt>GSDLL16</tt></b> is marked as having SINGLE SHARED data
650segments, allowing multiple applications to load it with no error
651indication.  (The DLL wouldn't load at all if MULTIPLE NONSHARED was used).
652Nonetheless, <b>it cannot be used by more than one application at a
653time</b>, so applications loading <b><tt>GSDLL16</tt></b> should check the
654return value of <b><tt>gsdll_init()</tt></b>: if this value is non-zero,
655then <b><tt>GSDLL16</tt></b> is already in use by another application and
656should <b><em>not</em></b> be used: <b><tt>GSDLL16</tt></b> should be
657unloaded immediately using <b><tt>FreeLibrary()</tt></b>, or the calling
658program should quit without attempting to use the library..
659
660<p>
661The segmented architecture of the Intel 80286 causes the usual amount of
662grief when using <b><tt>GSDLL16</tt></b>.  Because the callback is called
663from the DLL, which is using a different data segment, the callback must be
664declared 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>
671Instead 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
673a thunk created by <b><tt>MakeProcInstance</tt></b>.  This thunk changes
674the data segment back to that used by the caller:
675
676<blockquote>
677<pre>FARPROC lpfnCallback;
678lpfnCallback = (FARPROC)MakeProcInstance((FARPROC)gsdll_callback, hInstance);
679code = (*pgsdll_init)((GSDLL_CALLBACK)lpfnCallback, NULL, argc, argv);
680if (!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.
693All rights reserved.</small>
694
695<p>
696This software is provided AS-IS with no warranty, either express or
697implied.
698
699This software is distributed under license and may not be copied,
700modified or distributed except as expressly authorized under the terms
701of the license contained in the file LICENSE in this distribution.
702
703For more information about licensing, please refer to
704http://www.ghostscript.com/licensing/. For information on
705commercial licensing, go to http://www.artifex.com/licensing/ or
706contact Artifex Software, Inc., 101 Lucas Valley Road #110,
707San 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>
716