summaryrefslogtreecommitdiff
path: root/Master/xemtex/doc/ghostscript/DLL.htm
diff options
context:
space:
mode:
Diffstat (limited to 'Master/xemtex/doc/ghostscript/DLL.htm')
-rw-r--r--Master/xemtex/doc/ghostscript/DLL.htm703
1 files changed, 703 insertions, 0 deletions
diff --git a/Master/xemtex/doc/ghostscript/DLL.htm b/Master/xemtex/doc/ghostscript/DLL.htm
new file mode 100644
index 00000000000..180d4218349
--- /dev/null
+++ b/Master/xemtex/doc/ghostscript/DLL.htm
@@ -0,0 +1,703 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<title>How to use the Ghostscript Dynamic Link Library (DLL)</title>
+<!-- $Id: DLL.htm,v 1.15.2.11.2.5 2003/05/17 14:38:59 giles Exp $ -->
+<!-- Originally: dll.txt -->
+<link rel="stylesheet" type="text/css" href="gs.css" title="Ghostscript Style">
+</head>
+
+<body>
+<!-- [1.0 begin visible header] ============================================ -->
+
+<!-- [1.1 begin headline] ================================================== -->
+
+<h1>How to use the Ghostscript Dynamic Link Library (DLL)</h1>
+
+<!-- [1.1 end headline] ==================================================== -->
+
+<!-- [1.2 begin table of contents] ========================================= -->
+
+<h2>Table of contents</h2>
+
+<ul>
+<li><a href="#DLL">What is the Ghostscript DLL?</a>
+<li><a href="#Common_functions">Platform-independent DLL functions</a>
+<ul>
+<li><a href="#revision"><b><tt>gsdll_revision()</tt></b></a>
+<li><a href="#init"><b><tt>gsdll_init()</tt></b></a>
+<li><a href="#execute_begin"><b><tt>gsdll_execute_begin()</tt></b></a>
+<li><a href="#execute_cont"><b><tt>gsdll_execute_cont()</tt></b></a>
+<li><a href="#execute_end"><b><tt>gsdll_execute_end()</tt></b></a>
+<li><a href="#exit"><b><tt>gsdll_exit()</tt></b></a>
+<li><a href="#lock_device"><b><tt>gsdll_lock_device()</tt></b></a>
+</ul>
+<li><a href="#Callback">Callback function</a>
+<li><a href="#OS2_device">Ghostscript DLL device for OS/2</a>
+<ul>
+<li><a href="#OS2_bmp"><b><tt>gsdll_get_bitmap()</tt></b></a>
+<li><a href="#OS2_example">Example DLL usage for OS/2</a>
+</ul>
+<li><a href="#Win_device">Ghostscript DLL device for MS Windows</a>
+<ul>
+<li><a href="#Win_copydib"><b><tt>gsdll_copy_dib()</tt></b></a>
+<li><a href="#Win_copypalette"><b><tt>gsdll_copy_palette()</tt></b></a>
+<li><a href="#Win_draw"><b><tt>gsdll_draw()</tt></b></a>
+<li><a href="#Win_get_row"><b><tt>gsdll_get_bitmap_row()</tt></b></a>
+</ul>
+<li><a href="#Win16">Ghostscript DLL Device for 16-bit MS Windows</a>
+</ul>
+
+<!-- [1.2 end table of contents] =========================================== -->
+
+<!-- [1.3 begin hint] ====================================================== -->
+
+<p>For other information, see the <a href="Readme.htm">Ghostscript
+overview</a>.
+
+<p>
+<b>WARNING: The API described in this document is obsolete and will
+be removed in the future.</b>
+The current Ghostscript Interpreter API
+is described in <a href="API.htm">API.htm</a>.
+
+<!-- [1.3 end hint] ======================================================== -->
+
+<hr>
+
+<!-- [1.0 end visible header] ============================================== -->
+
+<!-- [2.0 begin contents] ================================================== -->
+
+<h2><a name="DLL"></a>What is the Ghostscript DLL?</h2>
+
+<p>
+For the OS/2, Win16 and Win32 platforms, Ghostscript is built as a dynamic
+link library (DLL), and to provide the interface described in the <a
+href="Use.htm">usage documentation</a>, a smaller independent executable
+(<b><tt>.EXE</tt></b>) loads this DLL, which provides all the interaction
+with the windowing system, including image windows and, if necessary, a
+text window. This document describes the DLL interface, which consists of
+eight main functions, <a href="#functions">seven platform-independent
+ones</a> provided by the DLL and one, <a href="#Callback">the callback
+function</a>, provided by the caller. The DLL provides some other
+platform-specific functions for display devices.
+
+<p>
+The DLL's name and characteristics differ among the three platforms:
+
+<ul>
+<li>The <a href="#OS2_device">OS/2 DLL <b><tt>GSDLL2.DLL</tt></b></a> has
+MULTIPLE NONSHARED data segments and can be called by multiple programs
+simultaneously.
+
+<li>The <a href="#Win_device">Win32 DLL <b><tt>GSDLL32.DLL</tt></b></a> has
+MULTIPLE NONSHARED data segments. Under Win32s it can be used by only one
+program at a time, but under Windows 95/98 or Windows NT it can be called by
+multiple programs simultaneously.
+
+<li>The <a href="#Win16">Win16 DLL <b><tt>GSDLL16.DLL</tt></b></a> is a
+large-memory model DLL with far static data. Due to the limitations of
+16-bit MS Windows -- Windows 3.n -- the DLL can be used by only one program
+at a time.
+</ul>
+
+<p>
+The source for the executable is in <b><tt>dp</tt></b>*.* (OS/2) and
+<b><tt>dw</tt></b>*.* (Windows). See these source files for examples of
+how to use the DLL.
+
+<hr>
+
+<h2><a name="Common_functions"></a>Platform-independent DLL functions</h2>
+
+<p>
+The seven functions provided by the DLL are
+<ul>
+<li><b><tt>int GSDLLAPI <a href="#revision">gsdll_revision</a>(char **product, char **copyright, long *gs_revision, long *gs_revisiondate)</tt></b>
+<li><b><tt>int GSDLLAPI <a href="#init">gsdll_init</a>(GSDLL_CALLBACK callback, HWND hwnd, int argc, char *argv[]);</tt></b>
+<li><b><tt>int GSDLLAPI <a href="#execute_begin">gsdll_execute_begin</a>(void);</tt></b>
+<li><b><tt>int GSDLLAPI <a href="#execute_cont">gsdll_execute_cont</a>(const char *str, int len);</tt></b>
+<li><b><tt>int GSDLLAPI <a href="#execute_end">gsdll_execute_end</a>(void);</tt></b>
+<li><b><tt>int GSDLLAPI <a href="#exit">gsdll_exit</a>(void);</tt></b>
+<li><b><tt>int GSDLLAPI <a href="#lock_device">gsdll_lock_device</a>(unsigned char *device, int flag);</tt></b>
+
+<p>
+where <b><tt>GSDLLAPI</tt></b> is defined under OS/2 as
+
+<blockquote><b><tt>
+#define GSDLLAPI
+</tt></b></blockquote>
+
+<p>
+and under MS Windows as
+
+<blockquote><b><tt>
+#define GSDLLAPI CALLBACK _export
+</tt></b></blockquote>
+</ul>
+
+<h3><a name="revision"></a><b><tt>gsdll_revision()</tt></b></h3>
+
+<blockquote>
+This function returns the revision numbers and strings of the Ghostscript
+DLL; you should call it before <b><tt>gsdll_init()</tt></b> to make sure
+that the correct version of the Ghostscript DLL has been loaded. For
+example
+
+<blockquote>
+<pre>char *product;
+char *copyright;
+long revision;
+long revisiondate;
+gsdll_revision(&amp;product, &amp;copyright, &amp;revision, &amp;revisiondate);
+</pre></blockquote>
+
+<p>
+You may use <b><tt>NULL</tt></b> pointers if you do not want a particular
+value.
+</blockquote>
+
+<h3><a name="init"></a><b><tt>gsdll_init()</tt></b></h3>
+
+<blockquote>
+<b><tt>gsdll_init()</tt></b> must be called after loading the DLL and
+before executing any Ghostscript commands. The arguments are the address
+of the callback function, a parent window handle, the count of arguments
+and an array of pointers to the arguments. For example
+
+<blockquote>
+<pre>char *argv[5];
+argv[0] = "gswin.exe";
+argv[1] = "-Ic:\\gs;c:\gs\\fonts";
+argv[2] = "-dNOPAUSE",
+argv[3] = "-sDEVICE=djet500",
+argv[4] = NULL;
+argc = 4;
+
+code = gsdll_init(gsdll_callback, hwnd, argc, argv);
+</pre></blockquote>
+
+<p>
+<b><tt>hwnd</tt></b> is used as the parent window handle for any windows
+created by Ghostscript. <b><tt>hwnd</tt></b> may be <b><tt>NULL</tt></b>
+if the caller has no windows, but if it is <b><tt>NULL</tt></b>, you should
+avoid using devices which may open windows.
+
+<p>
+A return code of 0 (zero) indicates no errors, and the code may now call
+<b><tt>gsdll_execute_begin()</tt></b> or <b><tt>gsdll_exit()</tt></b>. If
+the return value is non-zero then <b><tt>gsdll_exit()</tt></b> must not be
+called.
+
+<p>
+A return value of <b><tt>GSDLL_INIT_QUIT</tt></b> indicates that one of the
+command line files or arguments called "<b><tt>quit</tt></b>", or that
+Ghostscript was reading stdin and reached end-of-file. This is not an
+error. <b><tt>gsdll_exit()</tt></b> must not be called.
+
+<p>
+A return value of <b><tt>GSDLL_INIT_IN_USE</tt></b> indicates that the DLL
+is in use by another application (Windows 3.1 only). The DLL should be
+immediately unloaded (or the caller terminated).
+<b><tt>gsdll_exit()</tt></b> must not be called.
+</blockquote>
+
+<h3><a name="execute_begin"></a><b><tt>gsdll_execute_begin()</tt></b></h3>
+
+<blockquote>
+This must be called after <b><tt>gsdll_init()</tt></b> and before
+<b><tt>gsdll_execute_cont()</tt></b>.
+</blockquote>
+
+<h3><a name="execute_cont"></a><b><tt>gsdll_execute_cont()</tt></b></h3>
+
+<blockquote>
+After successfully calling <b><tt>gsdll_init()</tt></b> and
+<b><tt>gsdll_execute_begin()</tt></b>, commands may be given to Ghostscript
+with <b><tt>gsdll_execute_cont()</tt></b>. Examples are:
+
+<blockquote>
+<pre>char *command = "1 2 add == flush\n";
+code = gsdll_execute_cont(command, strlen(command));
+command = "qu"
+code = gsdll_execute_cont(command, strlen(command));
+command = "it\n"
+code = gsdll_execute_cont(command, strlen(command));
+</pre>
+
+<a name="cont_returns"></a>
+<table cellpadding=0 cellspacing=0>
+<tr><th colspan=3 bgcolor="#CCCC00"><hr><font size="+1">Return codes from <b><tt>gsdll_execute_cont()</tt></b></font><hr>
+<tr valign=bottom>
+ <th align=left>Code
+ <td>&nbsp;&nbsp;&nbsp;&nbsp;
+ <th align=left>Status
+<tr> <td colspan=3><hr>
+<tr valign=top> <td align=left>0
+ <td>&nbsp;
+ <td>No errors
+<tr valign=top> <td align=left>&lt; 0
+ <td>&nbsp;
+ <td>Error
+<tr valign=top> <td align=left>&lt;= -100
+ <td>&nbsp;
+ <td>"<b><tt>quit</tt></b>" has been executed, or fatal error.
+<b><tt>gsdll_exit()</tt></b> must then be called: do not call
+<b><tt>gsdll_execute_end()</tt></b>.
+</table>
+</blockquote>
+
+<b><tt>gsdll_execute_cont()</tt></b>
+does not flush stdio, so if you want to see output from Ghostscript you
+must do this explicitly as shown in the example above.
+
+<p>
+When executing a string with <b><tt>gsdll_execute_cont()</tt></b>,
+<b><tt>currentfile</tt></b> is the input from
+<b><tt>gsdll_execute_cont()</tt></b>. Reading from <b><tt>%stdin</tt></b>
+uses the callback.
+
+</blockquote>
+
+<h3><a name="execute_end"></a><b><tt>gsdll_execute_end()</tt></b></h3>
+
+<blockquote>
+If <b><tt>gsdll_execute_cont()</tt></b> did not return an error, then
+<b><tt>gsdll_execute_end()</tt></b> must be called after
+<b><tt>gsdll_execute_cont()</tt></b> and before
+<b><tt>gsdll_exit()</tt></b>.
+</blockquote>
+
+<h3><a name="exit"></a><b><tt>gsdll_exit()</tt></b></h3>
+
+<blockquote>
+Call gsdll_exit() to terminate the Ghostscript DLL. It must be called if a
+fatal error has occurred; see the <a href="#cont_returns">return value
+of <b><tt>gsdll_execute_cont()</tt></b></a>. After calling
+<b><tt>gsdll_exit()</tt></b>, there are two options:
+
+<ul>
+<li>Unload the DLL, either by terminating the application or by
+calling <b><tt>DosFreeModule</tt></b> (OS/2) or <b><tt>FreeLibrary</tt></b> (MS Windows).
+
+<li>Call <b><tt>gsdll_init()</tt></b> again to restart Ghostscript.
+</ul>
+</blockquote>
+
+<h3><a name="lock_device"></a><b><tt>gsdll_lock_device()</tt></b></h3>
+
+<blockquote>
+Since the caller may be multithreaded, a lock is needed to control access
+to the display device, and <b><tt>gsdll_lock_device()</tt></b> provides that
+locking.
+
+<blockquote>
+<pre>int gsdll_lock_device(unsigned char *device, int flag);
+ /* Lock the device if flag = TRUE */
+ /* Unlock the device if flag = FALSE */
+ /* device is a pointer to Ghostscript os2dll or mswindll device */
+ /* from GSDLL_DEVICE message. */
+ /* Return value is the lock count. */
+</pre>
+
+<table cellpadding=0 cellspacing=0>
+<tr><th colspan=3 bgcolor="#CCCC00"><hr><font size="+1">Locking and unlocking devices</font><hr>
+<tr valign=top> <td>To lock a device
+ <td>&nbsp;&nbsp;&nbsp;&nbsp;
+ <td><b><tt>gsdll_lock_device(device, 1)</tt></b>;
+<tr valign=top> <td>To unlock a device
+ <td>&nbsp;
+ <td><b><tt>gsdll_lock_device(device, 0)</tt></b>;
+</table>
+</blockquote>
+
+<p>
+This function is typically used to lock the device while repainting a
+window or copying the device bitmap to the clipboard. Ghostscript may draw
+into the device bitmap or update the palette entries while the device is
+locked by the caller, but locking the device prevents the Ghostscript DLL
+from closing the device or changing its size or depth.
+
+<p>
+Under OS/2, Windows 95/98 and Windows NT, this lock is implemented using a
+mutual exclusion semaphore (mutex). The return value is the lock count,
+which is either 0 ("unlocked") or 1 ("locked"). The function blocks until
+the device is locked by the caller.
+
+<p>
+Under Win16 or Win32s, <b><tt>gsdll_lock_device()</tt></b> always returns
+immediately with a lock count as its return value. A lock count of 2 or
+more is definite indication of an error, probably calling the function
+twice. Access to the device should be controlled by checking the Windows
+message queue only when the bitmap is not being accessed.
+</blockquote>
+
+<hr>
+
+<h2><a name="Callback"></a>Callback function</h2>
+
+<blockquote>
+As an argument to <a href="#init"><b><tt>gsdll_init()</tt></b></a> the
+caller must provide a callback function which the DLL invokes for stdio and
+to notify the caller about device events. The function provided by the
+caller has this prototype:
+
+<blockquote><b><tt>
+int gsdll_callback(int&nbsp;message, char&nbsp;*str, unsigned&nbsp;long&nbsp;count);
+</tt></b></blockquote>
+
+<p>
+The Pascal calling convention is not used. An example callback function
+is:
+
+<blockquote>
+<pre>int
+gsdll_callback(int message, char *str, unsigned long count)
+{
+char *p;
+ switch (message) {
+ case GSDLL_STDIN:
+ p = fgets(str, count, stdin);
+ if (p)
+ return strlen(str);
+ else
+ return 0;
+ case GSDLL_STDOUT:
+ if (str != (char *)NULL)
+ fwrite(str, 1, count, stdout);
+ return count;
+ case GSDLL_DEVICE:
+ fprintf(stdout,"Callback: DEVICE %p %s\n", str,
+ count ? "open" : "close");
+ break;
+ case GSDLL_SYNC:
+ fprintf(stdout,"Callback: SYNC %p\n", str);
+ break;
+ case GSDLL_PAGE:
+ fprintf(stdout,"Callback: PAGE %p\n", str);
+ break;
+ case GSDLL_SIZE:
+ fprintf(stdout,"Callback: SIZE %p width=%d height=%d\n", str,
+ (int)(count &amp; 0xffff), (int)((count&gt;&gt;16) &amp; 0xffff) );
+ break;
+ case GSDLL_POLL:
+ return 0; /* no error */
+ default:
+ fprintf(stdout,"Callback: Unknown message=%d\n",message);
+ break;
+ }
+ return 0;
+}
+</pre>
+
+<table cellpadding=0 cellspacing=0>
+<tr><th colspan=5 bgcolor="#CCCC00"><hr><font size="+1">Messages used by callback</font><hr>
+<tr valign=bottom>
+ <th align=left>Symbol
+ <td>&nbsp;&nbsp;
+ <th align=left>
+ <td>&nbsp;&nbsp;
+ <th align=left>Use
+<tr> <td colspan=5><hr>
+<tr valign=top> <td><b><tt>GSDLL_STDIN</tt></b>
+ <td>&nbsp;
+ <td>1
+ <td>&nbsp;
+ <td>get <b><tt>count</tt></b> characters to <b><tt>str</tt></b> from stdin, return number of characters read
+<tr valign=top> <td><b><tt>GSDLL_STDOUT</tt></b>
+ <td>&nbsp;
+ <td>2
+ <td>&nbsp;
+ <td>put <b><tt>count</tt></b> characters from <b><tt>str</tt></b>
+ to stdout, return number of characters written
+<tr valign=top> <td><b><tt>GSDLL_DEVICE</tt></b>
+ <td>&nbsp;
+ <td>3
+ <td>&nbsp;
+ <td>device <b><tt>str</tt></b> has been opened if
+ <b><tt>count</tt></b>&nbsp;=&nbsp;1, closed if
+ <b><tt>count</tt></b>&nbsp;=&nbsp;0
+<tr valign=top> <td><b><tt>GSDLL_SYNC</tt></b>
+ <td>&nbsp;
+ <td>4
+ <td>&nbsp;
+ <td>sync_output for device <b><tt>str</tt></b>
+<tr valign=top> <td><b><tt>GSDLL_PAGE</tt></b>
+ <td>&nbsp;
+ <td>5
+ <td>&nbsp;
+ <td>output_page for device <b><tt>str</tt></b>
+<tr valign=top> <td><b><tt>GSDLL_SIZE</tt></b>
+ <td>&nbsp;
+ <td>6
+ <td>&nbsp;
+ <td>resize for device <b><tt>str</tt></b>:
+ LOWORD(<b><tt>count</tt></b>) is new <b><tt>xsize</tt></b>,
+ HIWORD(<b><tt>count</tt></b>) is new <b><tt>ysize</tt></b>
+<tr valign=top> <td><b><tt>GSDLL_POLL</tt></b>
+ <td>&nbsp;
+ <td>7
+ <td>&nbsp;
+ <td>Called from <b><tt>gp_check_interrupt()</tt></b><br>
+ Can be used by the caller to poll the message queue.
+ Normally returns 0. To abort
+ <b><tt>gsdll_execute_cont()</tt></b>, return a non-zero
+ error code until <b><tt>gsdll_execute_cont()</tt></b>
+ returns.
+</table>
+</blockquote>
+</blockquote>
+
+<hr>
+
+<h2><a name="OS2_device"></a>Ghostscript DLL device for OS/2</h2>
+
+<p>
+The <b><tt>os2dll</tt></b> device is provided in the Ghostscript DLL for
+use by the caller. No drawing facilities are provided by the DLL because
+the DLL may be loaded by a text-only (non-PM) application. The caller is
+notified via the <b><tt>gsdll_callback()</tt></b> when a new
+<b><tt>os2dll</tt></b> device is opened or closed
+(<b><tt>GSDLL_DEVICE</tt></b>), when the window should be redrawn
+(<b><tt>GSDLL_SYNC</tt></b> or <b><tt>GSDLL_PAGE</tt></b>) or when the
+bitmap size changes (<b><tt>GSDLL_SIZE</tt></b>).
+Note that more than one <b><tt>os2dll</tt></b> device may be opened.
+
+<h3><a name="OS2_bmp"></a><b><tt>gsdll_get_bitmap()</tt></b></h3>
+
+<blockquote>
+<b><tt>gsdll_get_bitmap()</tt></b> returns a pointer to a bitmap in BMP
+format. The <b><tt>os2dll</tt></b> device draws into this bitmap.
+
+<blockquote>
+<pre>unsigned long gsdll_get_bitmap(unsigned char *device, unsigned char **pbitmap);
+ /* return in pbitmap the address of the bitmap */
+ /* device is a pointer to Ghostscript os2dll device from GSDLL_DEVICE message */
+</pre></blockquote>
+
+<p>
+The caller can then display the bitmap however it likes, but should lock
+the bitmap with <b><tt>gsdll_lock_device()</tt></b> before painting from
+it, and unlock it afterwards. The bitmap address does not change until the
+<b><tt>os2dll</tt></b> device is closed; however the bitmap size and
+palette may change whenever the bitmap is not locked.
+</blockquote>
+
+<h3><a name="OS2_example"></a>Example DLL usage for OS/2</h3>
+
+<p>
+The example here shows a minimal usage of the Ghostscript DLL under OS/2.
+The sample callback function above is needed.
+
+<blockquote>
+<pre>#define INCL_DOS
+#include &lt;os2.h&gt;
+#include &lt;stdio.h&gt;
+#include "gsdll.h"
+
+PFN_gsdll_init pgsdll_init;
+PFN_gsdll_execute_begin pgsdll_execute_begin;
+PFN_gsdll_execute_cont pgsdll_execute_cont;
+PFN_gsdll_execute_end pgsdll_execute_end;
+PFN_gsdll_exit pgsdll_exit;
+
+HMODULE hmodule_gsdll;
+char buf[256];
+
+int
+main(int argc, char *argv[])
+{
+int code;
+APIRET rc;
+ if (!DosLoadModule(buf, sizeof(buf), "GSDLL2", &amp;hmodule_gsdll)) {
+ fprintf(stderr, "Loaded GSDLL2\n");
+ DosQueryProcAddr(hmodule_gsdll, 0, "gsdll_init", (PFN *)(&amp;pgsdll_init));
+ DosQueryProcAddr(hmodule_gsdll, 0, "gsdll_execute_begin", (PFN *)(&amp;pgsdll_execute_begin));
+ DosQueryProcAddr(hmodule_gsdll, 0, "gsdll_execute_cont", (PFN *)(&amp;pgsdll_execute_cont));
+ DosQueryProcAddr(hmodule_gsdll, 0, "gsdll_execute_end", (PFN *)(&amp;pgsdll_execute_end));
+ DosQueryProcAddr(hmodule_gsdll, 0, "gsdll_exit", (PFN *)(&amp;pgsdll_exit));
+ }
+ else {
+ fprintf(stderr, "Can't load GSDLL2\n");
+ }
+
+ code = (*pgsdll_init)(gsdll_callback, NULL, argc, argv);
+ fprintf(stdout,"gsdll_init returns %d\n", code);
+ code = (*pgsdll_execute_begin)();
+ if (code==0) {
+ while (fgets(buf, sizeof(buf), stdin)) {
+ code = (*pgsdll_execute_cont)(buf, strlen(buf));
+ fprintf(stdout,"gsdll_execute returns %d\n", code);
+ if (code &lt; 0)
+ break;
+ }
+ if (!code)
+ code = (*pgsdll_execute_end)();
+ code = (*pgsdll_exit)();
+ fprintf(stdout,"gsdll_exit returns %d\n", code);
+ }
+ rc = DosFreeModule(hmodule_gsdll);
+ fprintf(stdout,"DosFreeModule returns %d\n", rc);
+ return 0;
+}
+</pre></blockquote>
+
+<hr>
+
+<h2><a name="Win_device"></a>Ghostscript DLL device for MS Windows</h2>
+
+<p>
+The <b><tt>mswindll</tt></b> device is provided in the Ghostscript DLL for
+use by the caller. The caller is notified via the
+<b><tt>gsdll_callback()</tt></b> when a new <b><tt>mswindll</tt></b> device
+is opened or closed (<b><tt>GSDLL_DEVICE</tt></b>), when the window should
+be redrawn (<b><tt>GSDLL_SYNC</tt></b> or <b><tt>GSDLL_PAGE</tt></b>) or
+when the bitmap size changes (<b><tt>GSDLL_SIZE</tt></b>). Note that more
+than one <b><tt>mswindll</tt></b> device may be opened.
+
+<p>
+Four DLL functions are available to use the <b><tt>mswindll</tt></b>
+device.
+
+<h3><a name="Win_copydib"></a><b><tt>gsdll_copy_dib()</tt></b></h3>
+
+<blockquote>
+Copy the <b><tt>mswindll</tt></b> bitmap to the clipboard.
+
+<blockquote>
+<pre>HGLOBAL GSDLLAPI gsdll_copy_dib(unsigned char *device);
+ /* make a copy of the device bitmap and return shared memory handle to it */
+ /* device is a pointer to Ghostscript device from GSDLL_DEVICE message */
+</pre></blockquote>
+</blockquote>
+
+<h3><a name="Win_copypalette"></a><b><tt>gsdll_copy_palette()</tt></b></h3>
+
+<blockquote>
+Copy the <b><tt>mswindll</tt></b> palette to the clipboard.
+
+<blockquote>
+<pre>HPALETTE GSDLLAPI gsdll_copy_palette(unsigned char *device);
+/* make a copy of the device palette and return a handle to it */
+/* device is a pointer to Ghostscript device from GSDLL_DEVICE message */
+</pre></blockquote>
+</blockquote>
+
+<h3><a name="Win_draw"></a><b><tt>gsdll_draw()</tt></b></h3>
+
+<blockquote>
+Display output from the <b><tt>mswindll</tt></b> device. The caller should
+create a window and call <b><tt>gsdll_draw()</tt></b> in response to the
+<b><tt>WM_PAINT</tt></b> message. The device context <b><tt>hdc</tt></b>
+must be for a device because <b><tt>SetDIBitsToDevice()</tt></b> is used.
+
+<blockquote>
+<pre>void GSDLLAPI gsdll_draw(unsigned char *device, HDC hdc,
+ LPRECT dest, LPRECT src);
+/* copy the rectangle src from the device bitmap */
+/* to the rectangle dest on the device given by hdc */
+/* hdc must be a device context for a device (NOT a bitmap) */
+/* device is a pointer to Ghostscript device from GSDLL_DEVICE message */
+</pre></blockquote>
+</blockquote>
+
+<h3><a name="Win_get_row"></a><b><tt>gsdll_get_bitmap_row()</tt></b></h3>
+
+<blockquote>
+Get a BMP header, a palette, and a pointer to a row in the bitmap. This
+function exists to allow the bitmap to be copied to a file or structured
+storage without the overhead of having two copies of the bitmap in memory
+at the same time.
+
+<p>
+Ghostscript can change the palette while the device is locked. Do not call
+this function while Ghostscript is busy.
+
+<blockquote>
+<pre>int GSDLLAPI gsdll_get_bitmap_row(unsigned char *device, LPBITMAPINFOHEADER pbmih,
+ LPRGBQUAD prgbquad, LPBYTE *ppbyte, unsigned int row)
+/* If pbmih nonzero, copy the BITMAPINFOHEADER.
+ * If prgbquad nonzero, copy the palette.
+ * number of entries copied is given by pbmih-&gt;biClrUsed
+ * If ppbyte nonzero, return pointer to row.
+ * pointer is only valid while device is locked
+ */
+</pre></blockquote>
+</blockquote>
+
+<hr>
+
+<h2><a name="Win16"></a>Ghostscript DLL Device for 16-bit MS Windows</h2>
+
+<p>
+This platform has the most problems of the three. Support for it may be
+dropped in future.
+
+<p>
+The Win16 DLL <b><tt>GSDLL16.DLL</tt></b> is a large-memory model DLL with
+far static data. Due to the limitations of 16-bit MS Windows, the DLL can
+be used by only one program at a time.
+
+<p>
+However, <b><tt>GSDLL16</tt></b> is marked as having SINGLE SHARED data
+segments, allowing multiple applications to load it with no error
+indication. (The DLL wouldn't load at all if MULTIPLE NONSHARED was used).
+Nonetheless, <b>it cannot be used by more than one application at a
+time</b>, so applications loading <b><tt>GSDLL16</tt></b> should check the
+return value of <b><tt>gsdll_init()</tt></b>: if this value is non-zero,
+then <b><tt>GSDLL16</tt></b> is already in use by another application and
+should <b><em>not</em></b> be used: <b><tt>GSDLL16</tt></b> should be
+unloaded immediately using <b><tt>FreeLibrary()</tt></b>, or the calling
+program should quit without attempting to use the library..
+
+<p>
+The segmented architecture of the Intel 80286 causes the usual amount of
+grief when using <b><tt>GSDLL16</tt></b>. Because the callback is called
+from the DLL, which is using a different data segment, the callback must be
+declared as <b><tt>_far&nbsp;_export</tt></b>:
+
+<blockquote>
+<pre>int _far _export gsdll_callback(int message, char *str, unsigned long count);
+</pre></blockquote>
+
+<p>
+Instead of giving <b><tt>gsdll_init()</tt></b> the address of
+<b><tt>gsdll_callback()</tt></b>, it should instead be given the address of
+a thunk created by <b><tt>MakeProcInstance</tt></b>. This thunk changes
+the data segment back to that used by the caller:
+
+<blockquote>
+<pre>FARPROC lpfnCallback;
+lpfnCallback = (FARPROC)MakeProcInstance((FARPROC)gsdll_callback, hInstance);
+code = (*pgsdll_init)((GSDLL_CALLBACK)lpfnCallback, NULL, argc, argv);
+if (!code) {
+ fprintf(stderr, "GSDLL16 is already in use\n");
+ return -1;
+}
+</pre></blockquote>
+
+<!-- [2.0 end contents] ==================================================== -->
+
+<!-- [3.0 begin visible trailer] =========================================== -->
+<hr>
+
+<p>
+<small>Copyright &copy; 1996, 1997, 1998 Aladdin Enterprises.
+All rights reserved.</small>
+
+<p>
+This software is provided AS-IS with no warranty, either express or
+implied.
+
+This software is distributed under license and may not be copied,
+modified or distributed except as expressly authorized under the terms
+of the license contained in the file LICENSE in this distribution.
+
+<p>
+<small>Ghostscript version 7.07, 17 May 2003
+
+<!-- [3.0 end visible trailer] ============================================= -->
+
+</body>
+</html>