]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - doc/spm.shtml
Load cups into easysw/current.
[thirdparty/cups.git] / doc / spm.shtml
diff --git a/doc/spm.shtml b/doc/spm.shtml
deleted file mode 100644 (file)
index a63ad39..0000000
+++ /dev/null
@@ -1,10202 +0,0 @@
-<HTML>
-<HEAD>
-       <META NAME="COPYRIGHT" CONTENT="Copyright 1997-2003, All Rights Reserved">
-       <META NAME="DOCNUMBER" CONTENT="CUPS-SPM-1.2.0">
-       <META NAME="Author" CONTENT="Easy Software Products">
-       <TITLE>CUPS Software Programmers Manual</TITLE>
-</HEAD>
-<BODY>
-
-<H1 ALIGN="RIGHT">Preface</H1>
-
-<P>This software programmers manual provides software
-programming information for the Common UNIX Printing System
-("CUPS") Version 1.2.0.
-
-<EMBED SRC="system-overview.shtml">
-
-<!-- NEED 2in -->
-<H2>Document Overview</H2>
-
-<P>This software programmers manual is organized into the following sections:
-
-<UL>
-       <LI><A HREF="#OVERVIEW">1 - Printing System Overview</A>
-       <LI><A HREF="#CUPS_API">2 - The CUPS API</A>
-       <LI><A HREF="#WRITING_FILTERS">3 - Writing Filters</A>
-       <LI><A HREF="#WRITING_DRIVERS">4 - Writing Printer Drivers</A>
-       <LI><A HREF="#WRITING_BACKENDS">5 - Writing Backends</A>
-       <LI><A HREF="#LICENSE">A - Software License Agreement</A>
-       <LI><A HREF="#CONSTANTS">B - Constants</A>
-       <LI><A HREF="#STRUCTURES">C - Structures</A>
-       <LI><A HREF="#FUNCTIONS">D - Functions</A>
-</UL>
-
-<H2>Notation Conventions</H2>
-
-<P>Various font and syntax conventions are used in this guide. Examples and
-their meanings and uses are explained below:
-
-<CENTER><TABLE WIDTH="80%">
-<TR>
-       <TH>Example</TH>
-       <TD>&nbsp;&nbsp;&nbsp;</TD>
-       <TH>Description</TH>
-</TR>
-<TR><TD>&nbsp;</TD></TR>
-<TR VALIGN="TOP">
-       <TD><CODE>lpstat</CODE><BR>
-       <CODE>lpstat(1)</CODE></TD>
-
-       <TD>&nbsp;&nbsp;&nbsp;</TD>
-
-       <TD>The names of commands; the first mention of a command or
-       function in a chapter is followed by a manual page section
-       number.</TD>
-</TR>
-<TR><TD>&nbsp;</TD></TR>
-<TR VALIGN="TOP">
-       <TD><VAR>/var</VAR><BR>
-       <VAR>/usr/share/cups/data/testprint.ps</VAR></TD>
-
-       <TD>&nbsp;&nbsp;&nbsp;</TD>
-
-       <TD>File and directory names.</TD>
-</TR>
-<TR><TD>&nbsp;</TD></TR>
-<TR VALIGN="TOP">
-       <TD NOWRAP><TT>Request ID is Printer-123</TT></TD>
-
-       <TD>&nbsp;&nbsp;&nbsp;</TD>
-
-       <TD>Screen output.</TD>
-</TR>
-<TR><TD>&nbsp;</TD></TR>
-<TR VALIGN="TOP">
-       <TD NOWRAP><KBD>lp -d printer filename ENTER</KBD></TD>
-
-       <TD>&nbsp;&nbsp;&nbsp;</TD>
-
-       <TD>Literal user input; special keys like <KBD>ENTER</KBD> are
-       in ALL CAPS.</TD>
-</TR>
-<TR><TD>&nbsp;</TD></TR>
-<TR VALIGN="TOP">
-       <TD>12.3</TD>
-
-       <TD>&nbsp;&nbsp;&nbsp;</TD>
-
-       <TD>Numbers in the text are written using the period (.) to indicate
-       the decimal point.</TD>
-</TR>
-</TABLE></CENTER>
-
-<!-- NEED 3in -->
-<H2>Abbreviations</H2>
-
-The following abbreviations are used throughout this manual:
-
-<UL>
-<DL>
-
-       <DT>kb
-       <DD>Kilobytes, or 1024 bytes<BR>&nbsp;
-
-       <DT>Mb
-       <DD>Megabytes, or 1048576 bytes<BR>&nbsp;
-
-       <DT>Gb
-       <DD>Gigabytes, or 1073741824 bytes<BR>&nbsp;
-
-</DL>
-</UL>
-
-<H2>Other References</H2>
-
-<UL>
-<DL>
-
-       <DT>CUPS Software Administrators Manual
-
-       <DD>An administration guide for the CUPS software.<BR>&nbsp;
-
-       <DT>CUPS Software Users Manual
-
-       <DD>An end-user guide for using the CUPS software.<BR>&nbsp;
-
-</DL>
-</UL>
-
-
-<EMBED SRC="printing-overview.shtml">
-
-
-<H1 ALIGN="RIGHT"><A NAME="CUPS_API">2 - The CUPS API</A></H1>
-
-<P>This chapter describes the CUPS Application Programmers Interface ("API").
-
-<H2>The CUPS API Library</H2>
-
-<P>The CUPS library provides a whole collection of interfaces needed to
-support the internal needs of the CUPS software as well as the needs of
-applications, filters, printer drivers, and backends.
-
-<P>Unlike the rest of CUPS, the CUPS API library is provided under the
-GNU Library General Public License. This means that you can use the
-CUPS API library in both proprietary and open-source programs.
-
-<P>Programs that use the CUPS API library typically will include the
-<CODE>&lt;cups/cups.h&gt;</CODE> header file:
-
-<UL><PRE>
-#include &lt;cups/cups.h&gt;
-
-...
-
-jobid = cupsPrintFile("myprinter", "filename.ps", "title",
-                      num_options, options);
-</PRE></UL>
-
-<P>Use the <CODE>-lcups</CODE> compiler option when linking to the CUPS API
-library:
-
-<UL><PRE>
-<B>cc -o program program.c -lcups ENTER</B>
-</PRE></UL>
-
-<P>Additional options and libraries may be required depending on the
-operating system and the location of the CUPS API library.
-
-<H3>Detecting the CUPS API Library in GNU Autoconf</H3>
-
-<P>GNU autoconf is a popular configuration tool used by many programs.
-Add the following lines to your <VAR>configure.in</VAR> file to check
-for the CUPS API library in your configuration script:
-
-<UL><PRE>
-AC_CHECK_LIB(socket,socket,
-if test "$uname" != "IRIX"; then
-       LIBS="-lsocket $LIBS"
-else
-       echo "Not using -lsocket since you are running IRIX."
-fi)
-AC_CHECK_LIB(nsl,gethostbyaddr,
-if test "$uname" != "IRIX"; then
-       LIBS="-lnsl $LIBS"
-else
-       echo "Not using -lnsl since you are running IRIX."
-fi)
-
-AC_CHECK_LIB(cups,httpConnect)
-</PRE></UL>
-
-<H2>Printing Services</H2>
-
-<P>The CUPS API library provides some basic printing services for applications
-that need to print files.
-
-<H3>Include Files</H3>
-
-<P>The include file used by all of these functions is
-<CODE>&lt;cups/cups.h&gt;</CODE>:
-
-<UL><PRE>
-#include &lt;cups/cups.h&gt;
-</PRE></UL>
-
-<H3>Printing a File</H3>
-
-<P>The CUPS API provides two functions for printing files. The first is
-<CODE>cupsPrintFile</CODE> which prints a single named file:
-
-<UL><PRE>
-#include &lt;cups/cups.h&gt;
-
-...
-
-int jobid;
-
-...
-
-jobid = cupsPrintFile("<I>name</I>", "<I>filename</I>", "<I>title</I>", 0, NULL);
-</PRE></UL>
-
-<P>The <CODE>name</CODE> string is the name of the printer or class to
-print to. The <CODE>filename</CODE> string is the name of the file to
-print. The <CODE>title</CODE> string is the name of the print job, e.g.
-"Acme Word Document".
-
-<P>The return value is a unique ID number for the print job or 0 if there
-was an error.
-
-<H3>Printing Multiple Files</H3>
-
-<P>The second printing function is <CODE>cupsPrintFiles</CODE>:
-
-<UL><PRE>
-#include &lt;cups/cups.h&gt;
-
-...
-
-int        jobid;
-int        num_files;
-const char *files[100];
-...
-
-jobid = cupsPrintFiles("name", <I>num_files</I>, <I>files</I>, "title", 0, NULL);
-</PRE></UL>
-
-<P>Instead of passing a filename string as with <CODE>cupsPrintFile()</CODE>
-you pass a file count (<CODE>num_files</CODE>) and filename pointer array
-(<CODE>files</CODE>) for each file that you want to print.
-
-<P>As with <CODE>cupsPrintFile()</CODE> the return value is a unique ID for
-the print job.
-
-<H3>Cancelling Jobs</H3>
-
-<P>The <CODE>cupsCancelJob()</CODE> function cancels a queued print job:
-
-<UL><PRE>
-#include &lt;cups/cups.h&gt;
-
-...
-
-int jobid;
-int status;
-...
-
-status = cupsCancelJob("<I>name</I>", <I>jobid</I>);
-</PRE></UL>
-
-<P>The <CODE>name</CODE> string specifies the destination and is used
-to determine the server to send the request to. The <CODE>jobid</CODE>
-value is the integer returned from a previous <CODE>cupsPrintFile()</CODE>
-or <CODE>cupsPrintFiles()</CODE> call.
-
-<P><CODE>cupsCancelJob()</CODE> returns <CODE>1</CODE> if the job was
-successfully cancelled and <CODE>0</CODE> if there was an error.
-
-<H3>Getting the Available Printers and Classes</H3>
-
-<P>The <CODE>cupsGetDests()</CODE> function can be used to get a list
-of the available printers, classes, and instances that a user has defined:
-
-<UL><PRE>
-#include &lt;cups/cups.h&gt;
-
-...
-
-int         num_dests;
-cups_dest_t *dests;
-
-...
-
-num_dests = cupsGetDests(&amp;dests);
-</PRE></UL>
-
-<P>Each destination is stored in a <CODE>cups_dest_t</CODE> structure which
-defines the printer or class name, the instance name (if any), if it is the
-default destination, and the default options the user has defined for the
-destination:
-
-<UL><PRE>
-typedef struct               /**** Destination ****/
-{
-  char          *name,       /* Printer or class name */
-                *instance;   /* Local instance name or NULL */
-  int           is_default;  /* Is this printer the default? */
-  int           num_options; /* Number of options */
-  cups_option_t *options;    /* Options */
-} cups_dest_t;
-</PRE></UL>
-
-<P>The destinations are sorted by name and instance for your convenience.
-Once you have the list of available destinations, you can lookup a specific
-destination using the <CODE>cupsGetDest()</CODE> function:
-
-<UL><PRE>
-#include &lt;cups/cups.h&gt;
-
-...
-
-int         num_dests;
-cups_dest_t *dests;
-cups_dest_t *mydest;
-
-...
-
-mydest = cupsGetDest("<I>name</I>", "<I>instance</I>", num_dests, dests);
-</PRE></UL>
-
-<P>The <CODE>name</CODE> string is the printer or class name. You can pass
-a value of <CODE>NULL</CODE> to get the default destination.
-
-<P>The <CODE>instance</CODE> string is the user-defined instance name. Pass
-<CODE>NULL</CODE> to select the default instance, e.g. "name" instead of
-"name/instance".
-
-<H3>Printing with Options</H3>
-
-<P>All of the previous printing examples have passed <CODE>0</CODE> and
-<CODE>NULL</CODE> for the last two arguments to the <CODE>cupsPrintFile()</CODE>
-and <CODE>cupsPrintFiles()</CODE> functions. These last two arguments are the
-number of options and a pointer to the option array:
-
-<UL><PRE>
-int cupsPrintFile(const char *name, const char *filename, const char *title,
-                  int num_options, cups_option_t *options);
-int cupsPrintFiles(const char *name, int num_files, const char **files,
-                   const char *title, int num_options,
-                  cups_option_t *options);
-</PRE></UL>
-
-<P>The <CODE>cups_option_t</CODE> structure holds each option and its value.
-These are converted as needed and passed to the CUPS server when printing a
-file.
-
-<P>The simplest way of handling options is to use the <CODE>num_options</CODE>
-and <CODE>options</CODE> members of the <CODE>cups_dest_t</CODE>
-structure described earlier:
-
-<UL><PRE>
-#include &lt;cups/cups.h&gt;
-
-...
-
-int         jobid;
-int         num_dests;
-cups_dest_t *dests;
-cups_dest_t *mydest;
-
-...
-
-mydest = cupsGetDest("<I>name</I>", "<I>instance</I>", num_dests, dests);
-
-jobid  = cupsPrintFile(mydest-&gt;name, "filename", "title",
-                       mydest-&gt;num_options, mydest-&gt;options);
-</PRE></UL>
-
-<P>This effectively uses the options a user has previous selected without a
-lot of code.
-
-<H3>Setting Printer Options</H3>
-
-<P>Options can also be set by your program using the <CODE>cupsAddOption()</CODE>
-function:
-
-<UL><PRE>
-#include &lt;cups/cups.h&gt;
-
-...
-
-int           num_options;
-cups_option_t *options;
-
-...
-
-num_options = 0;
-options     = NULL;
-
-...
-
-num_options = cupsAddOption("<I>name</I>", "<I>value</I>", num_options, &amp;options);
-num_options = cupsAddOption("<I>name</I>", "<I>value</I>", num_options, &amp;options);
-num_options = cupsAddOption("<I>name</I>", "<I>value</I>", num_options, &amp;options);
-num_options = cupsAddOption("<I>name</I>", "<I>value</I>", num_options, &amp;options);
-</PRE></UL>
-
-<P>The <CODE>name</CODE> string is the name of the option, and the
-<CODE>value</CODE> string is the value for that option.
-
-<P>Each call to <CODE>cupsAddOption()</CODE> returns the new number of
-options. Since adding two options with the same name overwrites the
-first value with the second, do not assume that calling
-<CODE>cupsAddOptions()</CODE> 20 times will result in 20 options.
-
-<P>Call <CODE>cupsFreeOptions</CODE> once you are done using the options:
-
-<UL><PRE>
-#include &lt;cups/cups.h&gt;
-
-...
-
-int           num_options;
-cups_option_t *options;
-
-...
-
-cupsFreeOptions(num_options, options);
-</PRE></UL>
-
-<H3>Getting Errors</H3>
-
-<P>If any of the CUPS API printing functions returns an error, the reason for
-that error can be found by calling <CODE>cupsLastError()</CODE> and
-<CODE>cupsErrorString()</CODE>. <CODE>cupsLastError()</CODE> returns the
-last IPP error code that was encountered. <CODE>cupsErrorString()</CODE>
-converts the error code to a localized message string suitable for
-presentation to the user:
-
-<UL><PRE>
-#include &lt;cups/cups.h&gt;
-
-...
-
-int jobid;
-
-...
-
-if (jobid == 0)
-  puts(cupsErrorString(cupsLastError()));
-</PRE></UL>
-
-<H3>Passwords and Authentication</H3>
-
-<P>CUPS supports authentication of any request, including
-submission of print jobs. The default mechanism for getting the
-username and password is to use the login user and a password
-from the console.
-
-<P>To support other types of applications, in particular
-Graphical User Interfaces ("GUIs"), the CUPS API provides
-functions to set the default username and to register a callback
-function that returns a password string.
-
-<P>The <A HREF="#cupsSetPasswordCB"><CODE>cupsSetPasswordCB()</CODE></A>
-function is used to set a password callback in your program. Only one
-function can be used at any time.
-
-<P>The <A HREF="#cupsSetUser"><CODE>cupsSetUser()</CODE></A> function sets
-the current username for authentication. This function can be called by
-your password callback function to change the current username as needed.
-
-<P>The following example shows a simple password callback that gets a
-username and password from the user:
-
-<UL><PRE>
-#include &lt;cups/cups.h&gt;
-
-const char *
-my_password_cb(const char *prompt)
-{
-  char user[65];
-
-
-  puts(prompt);
-
- /* Get a username from the user */
-  printf("Username: ");
-  if (fgets(user, sizeof(user), stdin) == NULL)
-    return (NULL);
-
- /* Strip the newline from the string and set the user */
-  user[strlen(user) - 1] = '\0';
-
-  cupsSetUser(user);
-
- /* Use getpass() to ask for the password... */
-  return (getpass("Password: "));
-}
-
-...
-
-cupsSetPasswordCB(my_password_cb);
-</PRE></UL>
-
-<P>Similarly, a GUI interface could display the prompt string in a
-window with input fields for the username and password. The username
-should probably default to the value of
-<A HREF="#cupsUser"><CODE>cupsUser()</CODE></A> to make things easier
-on the user.
-
-<H2>PPD Services</H2>
-
-<P>CUPS includes functions to access and manipulate PostScript Printer
-Description ("PPD") files that are used with the printer drivers in CUPS.
-
-<P>Each PPD file enumerates the available features provided by a
-printer, including conflict information for specific options (e.g.
-can't duplex output on envelopes.)
-
-<H3>Include Files</H3>
-
-<P>Include the <CODE>&lt;cups/ppd.h&gt;</CODE> header file to use the PPD
-functions:
-
-<UL><PRE>
-#include &lt;cups/ppd.h&gt;
-</PRE></UL>
-
-<P>This header file is also included by the
-<CODE>&lt;cups/cups.h&gt;</CODE> header file.
-
-<H3>Getting a PPD File for a Printer</H3>
-
-<P>The <CODE>cupsGetPPD()</CODE> function retrieves the PPD file for the
-named printer or class:
-
-<UL><PRE>
-#include &lt;cups/cups.h&gt;
-
-...
-
-const char *filename;
-
-filename = cupsGetPPD("<I>name</I>");
-</PRE></UL>
-
-<P>The <CODE>name</CODE> string is the name of the printer or class, including
-the remote server name as appropriate (e.g. "printer@server".)
-
-<P>The return value is a pointer to a filename in static storage; this value
-is overwritten with each call to <CODE>cupsGetPPD()</CODE>. If the printer
-or class does not exist, a <CODE>NULL</CODE> pointer will be returned.
-
-<H3>Loading a PPD File</H3>
-
-<P>The <CODE>ppdOpenFile()</CODE> function "opens" a PPD file and loads it
-into memory:
-
-<UL><PRE>
-#include &lt;cups/ppd.h&gt;
-
-...
-
-ppd_file_t *ppd;
-
-ppd = ppdOpenFile("<I>filename</I>");
-</PRE></UL>
-
-<P>The <CODE>filename</CODE> string is the name of the file to load, such as
-the value returned by the <CODE>cupsGetPPD()</CODE> function.
-
-<P>The return value is a pointer to a structure describing the contents of the
-PPD file or NULL if the PPD file could not be read.
-
-<H3>Freeing PPD File Information</H3>
-
-<P>Once you are done using a PPD file, call the <CODE>ppdClose()</CODE> function
-to free all memory that has been used:
-
-<UL><PRE>
-#include &lt;cups/ppd.h&gt;
-
-...
-
-ppd_file_t *ppd;
-
-...
-
-ppdClose(ppd);
-</PRE></UL>
-
-<H3>The PPD File Structure</H3>
-
-<P>Each PPD file contains a number of capability attributes, printer options,
-and conflict definitions. The page size options also include the physical
-margins for the printer and the minimum and maximum sizes for the printer.
-All of this information is stored in the <CODE>ppd_file_t</CODE> structure.
-
-<H4>Capabilities</H4>
-
-<P>Each PPD file contains a number of informational attributes that
-describe the capabilities of the printer. These are provided in the
-<CODE>ppd_file_t</CODE> structure in the following members:
-
-<CENTER><TABLE WIDTH="80%" BORDER="1">
-<TR>
-       <TH>Member</TH>
-       <TH>Type</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD><CODE>accurate_screens</CODE></TD>
-       <TD><CODE>int</CODE></TD>
-       <TD>1 = supports accurate screens</TD>
-</TR>
-<TR>
-       <TD><CODE>color_device</CODE></TD>
-       <TD><CODE>int</CODE></TD>
-       <TD>1 = color device</TD>
-</TR>
-<TR>
-       <TD><CODE>colorspace</CODE></TD>
-       <TD><CODE>ppd_cs_t</CODE></TD>
-       <TD>Default colorspace: PPD_CS_CMYK, PPD_CS_CMY, PPD_CS_GRAY,
-       PPD_CS_RGB, PPD_CS_RGBK, PPD_CS_N</TD>
-</TR>
-<TR>
-       <TD><CODE>contone_only</CODE></TD>
-       <TD><CODE>int</CODE></TD>
-       <TD>1 = printer is continuous tone only</TD>
-</TR>
-<TR>
-       <TD><CODE>num_emulations<BR>
-       emulations</CODE></TD>
-       <TD><CODE>int<BR>
-       ppd_emul_t *</CODE></TD>
-       <TD>Emulations supported by the printer</TD>
-</TR>
-<TR>
-       <TD><CODE>flip_duplex</CODE></TD>
-       <TD><CODE>int</CODE></TD>
-       <TD>1 = need to flip odd pages when duplexing</TD>
-</TR>
-<TR>
-       <TD><CODE>num_fonts<BR>
-       fonts</CODE></TD>
-       <TD><CODE>int<BR>
-       char **</CODE></TD>
-       <TD>The fonts available on the printer.</TD>
-</TR>
-<TR>
-       <TD><CODE>jcl_begin<BR>
-       jcl_ps<BR>
-       jcl_end</CODE></TD>
-       <TD><CODE>char *</CODE></TD>
-       <TD>Job Control Language commands for PostScript output</TD>
-</TR>
-<TR>
-       <TD><CODE>landscape</CODE></TD>
-       <TD><CODE>int</CODE></TD>
-       <TD>Landscape orientation, -90 or 90 degrees</TD>
-</TR>
-<TR>
-       <TD><CODE>lang_encoding</CODE></TD>
-       <TD><CODE>char *</CODE></TD>
-       <TD>The character used for the option strings</TD>
-</TR>
-<TR>
-       <TD><CODE>lang_version</CODE></TD>
-       <TD><CODE>char *</CODE></TD>
-       <TD>The language used for the options strings (English, French, etc.)</TD>
-</TR>
-<TR>
-       <TD><CODE>language_level</CODE></TD>
-       <TD><CODE>int</CODE></TD>
-       <TD>PostScript language level, 1 to 3</TD>
-</TR>
-<TR>
-       <TD><CODE>manual_copies</CODE></TD>
-       <TD><CODE>int</CODE></TD>
-       <TD>1 = Copies are done manually</TD>
-</TR>
-<TR>
-       <TD><CODE>model_number</CODE></TD>
-       <TD><CODE>int</CODE></TD>
-       <TD>Driver-specific model number.</TD>
-</TR>
-<TR>
-       <TD><CODE>patches</CODE></TD>
-       <TD><CODE>char *</CODE></TD>
-       <TD>Patch commands to send to the printer</TD>
-</TR>
-<TR>
-       <TD><CODE>manufacturer</CODE></TD>
-       <TD><CODE>char *</CODE></TD>
-       <TD>The Manufacturer attribute from the PPD file, if any</TD>
-</TR>
-<TR>
-       <TD><CODE>modelname</CODE></TD>
-       <TD><CODE>char *</CODE></TD>
-       <TD>The ModelName attribute from the PPD file</TD>
-</TR>
-<TR>
-       <TD><CODE>nickname</CODE></TD>
-       <TD><CODE>char *</CODE></TD>
-       <TD>The NickName attribute from the PPD file, if any</TD>
-</TR>
-<TR>
-       <TD><CODE>product</CODE></TD>
-       <TD><CODE>char *</CODE></TD>
-       <TD>The Product attribute from the PPD file, if any</TD>
-</TR>
-<TR>
-       <TD><CODE>shortnickname</CODE></TD>
-       <TD><CODE>char *</CODE></TD>
-       <TD>The ShortNickName attribute from the PPD file, if any</TD>
-</TR>
-<TR>
-       <TD><CODE>throughput</CODE></TD>
-       <TD><CODE>int</CODE></TD>
-       <TD>Number of pages per minute</TD>
-</TR>
-<TR>
-       <TD><CODE>ttrasterizer</CODE></TD>
-       <TD><CODE>char *</CODE></TD>
-       <TD>The TruType font rasterizer (Type42)</TD>
-</TR>
-<TR>
-       <TD><CODE>variable_sizes</CODE></TD>
-       <TD><CODE>int</CODE></TD>
-       <TD>1 = supports variable sizes</TD>
-</TR>
-</TABLE></CENTER>
-
-<H4>Options and Groups</H4>
-
-<P>PPD files support multiple options, which are stored in
-<CODE>ppd_option_t</CODE> and <CODE>ppd_choice_t</CODE> structures by
-the PPD functions.
-
-<P>Each option in turn is associated with a group
-stored in the <CODE>ppd_group_t</CODE> structure. Groups can be
-specified in the PPD file; if an option is not associated with a group
-then it is put in a "General" or "Extra" group depending on the option.
-
-<P>Groups can also have sub-groups; CUPS currently limits the depth of
-sub-groups to 1 level to reduce programming complexity.
-
-<H4>Conflicts</H4>
-
-<P>PPD files support specification of conflict conditions between
-different options. Conflicts are stored in <CODE>ppd_conflict_t</CODE>
-structures which specify the options that conflict with each other.
-
-<H4>Page Sizes</H4>
-
-<P>PPD files specify all of the available pages sizes and the physical
-margins associated with them. These sizes are stored in
-<CODE>ppd_size_t</CODE> structures and are available in the
-<CODE>num_sizes</CODE> and <CODE>sizes</CODE> members of the
-<CODE>ppd_file_t</CODE> structure. You can lookup a particular page size
-with the <CODE>ppdPageWidth()</CODE>, <CODE>ppdPageLength()</CODE>, and
-<CODE>ppdPageSize()</CODE> functions:
-
-<UL><PRE>
-#include &lt;cups/ppd.h&gt;
-
-...
-
-ppd_file_t *ppd;
-ppd_size_t *size;
-float      width;
-float      length;
-
-...
-
-size   = ppdPageSize(ppd, "<I>size</I>");
-width  = ppdPageWidth(ppd, "<I>size</I>");
-length = ppdPageLength(ppd, "<I>size</I>");
-</PRE></UL>
-
-<P>The <CODE>size</CODE> string is the named page size option. The
-width and length are in points; there are 72 points per inch. The
-<CODE>ppd_size_t</CODE> structure contains the width, length, and
-margin information:
-
-<UL><PRE>
-typedef struct    /**** Page Sizes ****/
-{
-  int   marked;   /* Page size selected? */
-  char  name[41]; /* Media size option */
-  float width,    /* Width of media in points */
-        length,   /* Length of media in points */
-        left,     /* Left printable margin in points */
-        bottom,   /* Bottom printable margin in points */
-        right,    /* Right printable margin in points */
-        top;      /* Top printable margin in points */
-} ppd_size_t;
-</PRE></UL>
-
-<H4>Custom Page Sizes</H4>
-
-<P>Besides the standard page sizes listed in a PPD file, some printers
-support variable or custom page sizes. If <CODE>variables_sizes</CODE>
-is non-zero, the <CODE>custom_min</CODE>, <CODE>custom_max</CODE>, and
-<CODE>custom_margins</CODE> members of the <CODE>ppd_file_t</CODE>
-structure define the limits of the variable sizes.
-
-<P>To get the resulting media size, use a page size string of
-<CODE>Custom.<I>width</I>x<I>length</I></CODE>, where <CODE>width</CODE>
-and <CODE>length</CODE> are integer values in points:
-
-<UL><PRE>
-Custom.612x792   [8.5 inches wide, 11 inches long]
-Custom.1224x792  [17 inches wide, 11 inches long]
-</PRE></UL>
-
-<H3>Marking Options</H3>
-
-<P>Before marking any user-defined options, call the <CODE>ppdMarkDefaults()</CODE>
-function to mark the default options from the PPD file:
-
-<UL><PRE>
-#include &lt;cups/ppd.h&gt;
-
-...
-
-ppd_file_t *ppd;
-
-...
-
-ppdMarkDefaults(ppd);
-</PRE></UL>
-
-<P>Then call the <CODE>ppdMarkOption()</CODE> function to mark individual
-options:
-
-<UL><PRE>
-#include &lt;cups/ppd.h&gt;
-
-...
-
-ppd_file_t *ppd;
-int        conflicts;
-
-...
-
-conflicts = ppdMarkOption(ppd, "<I>name</I>", "<I>value</I>");
-</PRE></UL>
-
-<P>The <CODE>name</CODE> and <CODE>value</CODE> strings choose a
-particular option and choice, respectively. The return value is 0
-if there are not conflicts created by the selection.
-
-<P>CUPS also provides a convenience function for marking all options
-in the <CODE>cups_option_t</CODE> structure:
-
-<UL><PRE>
-#include &lt;cups/cups.h&gt;
-
-...
-
-ppd_file_t    *ppd;
-int           num_options;
-cups_option_t *options;
-int           conflicts;
-
-...
-
-conflicts = cupsMarkOptions(ppd, num_options, options);
-</PRE></UL>
-
-<P>The <CODE>cupsMarkOptions()</CODE> function also handles mapping the
-IPP job template attributes to PPD options. The return value is the number
-of conflicts present.
-
-<H3>Checking for Conflicts</H3>
-
-<P>The <CODE>ppdMarkOption()</CODE> and <CODE>cupsMarkOptions()</CODE>
-functions return the number of conflicts with the currently marked options.
-
-<P>Call the <CODE>ppdConflicts()</CODE> function to get the number of
-conflicts after you have marked all of the options:
-
-<UL><PRE>
-#include &lt;cups/cups.h&gt;
-
-...
-
-ppd_file_t *ppd;
-int        conflicts;
-
-...
-
-conflicts = ppdConflicts(ppd);
-</PRE></UL>
-
-<P>The return value is the number of conflicting options, or 0 if there
-are no conflicts.
-
-
-<H1 ALIGN="RIGHT"><A NAME="WRITING_FILTERS">3 - Writing Filters</A></H1>
-
-<P>This chapter describes how to write a file filter for CUPS.
-
-<H2>Overview</H2>
-
-<P>File filters are programs that convert from one or more MIME types to
-another type. Filters use a common command-line and environment interface
-that allows them to be joined as needed to print files to any type of
-printer.
-
-<H3>Security Considerations</H3>
-
-<P>Filters are normally run as a non-priviledged user, so the major
-security consideration is resource utilization - filters should not
-depend on unlimited amounts of memory and disk space.
-
-<H3>Users and Groups</H3>
-
-<P>The default CUPS configuration runs filters as user "lp" and group "other".
-
-<H3>Temporary Files</H3>
-
-<P>Temporary files should be created in the directory specified by the
-"TMPDIR" environment variable. The
-<A HREF="#cupsTempFile"><CODE>cupsTempFile()</CODE></A> function can be
-used to safely choose temporary files in this directory.
-
-<H3>Sending Messages to the User</H3>
-
-<P>The CUPS scheduler collects messages sent to the standard error file
-by the filter. These messages are relayed to the user based upon the
-scheduler <CODE>LogLevel</CODE> directive.
-
-<P>The type of message is determined by an initial prefix sent on each
-line:
-
-<UL>
-
-       <LI><CODE>DEBUG:</CODE> - a debug message
-
-       <LI><CODE>INFO:</CODE> - an informational message
-
-       <LI><CODE>WARNING:</CODE> - a warning message
-
-       <LI><CODE>ERROR:</CODE> - an error message
-
-       <LI><CODE>PAGE:</CODE> - a page accounting message
-
-</UL>
-
-<P>If the line of text does not begin with any of the above prefixes, it
-is treated as a debug message. Text following the prefix is copied to the
-<CODE>printer-state-message</CODE> attribute for the printer, and also
-added to the <VAR>error_log</VAR> unless it is an informational or page
-accounting message.
-
-<H3>Page Accounting</H3>
-
-<P>Page accounting messages are used to inform the server when one or more
-pages are printed. Each line has the form:
-
-<UL><PRE>
-PAGE: page-number copy-count
-</PRE></UL>
-
-<P>The <I>page-number</I> field is the current page number, starting at 1.
-The <I>copy-count</I> field specifies the number of copies of that page
-that was produced.
-
-<P>Page account messages are added to the <VAR>page_log</VAR> file and
-cause the <CODE>job-sheets-completed</CODE> attribute to be updated for
-the job.
-
-<H3>Command-Line Arguments</H3>
-
-<P>Every filter accepts exactly 6 or 7 command-line arguments:
-
-<UL><PRE>
-printer job user title copies options [filename]
-</PRE>
-
-       <LI><CODE>printer</CODE> - The name of the printer queue (normally
-       this is the name of the program being run)
-
-       <LI><CODE>job</CODE> - The numeric job ID for the job being
-       printed
-
-       <LI><CODE>user</CODE> - The string from the
-       <CODE>originating-user-name</CODE> attribute
-
-       <LI><CODE>title</CODE> - The string from the
-       <CODE>job-name</CODE> attribute
-
-       <LI><CODE>copies</CODE> - The numeric value from the
-       <CODE>number-copies</CODE> attribute
-
-       <LI><CODE>options</CODE> - String representations of the
-       job template attributes, separated by spaces. Boolean attributes
-       are provided as "name" for true values and "noname" for false
-       values. All other attributes are provided as "name=value" for
-       single-valued attributes and "name=value1,value2,...,valueN" for
-       set attributes
-
-       <LI><CODE>filename</CODE> - The request file
-
-</UL>
-
-<P>The <I>filename</I> argument is only provided to the first filter in the
-chain; all filters <B>must</B> be prepared to read the print file from
-the standard input if the <I>filename</I> argument is omitted.
-
-<H3>Copy Generation</H3>
-
-<P>The <I>copies</I> argument specifies the number of copies to produce
-of the input file. In general, you should only generate copies if the
-<I>filename</I> argument is supplied. The only exception to this are
-filters that produce device-independent PostScript output (without any
-printer commands from the printer's PPD file), since the PostScript
-filter <CODE>pstops</CODE> is responsible for copy generation.
-
-<H3>Environment Variables</H3>
-
-<P>Every filter receives a fixed set of environment variables that can
-be used by the filter:
-
-<UL>
-
-       <LI><CODE>CHARSET</CODE> - The character set used by the client for
-       this print file
-
-       <LI><CODE>CONTENT_TYPE</CODE> - The original document type, such as
-       "application/postscript"
-
-       <LI><CODE>CUPS_DATADIR</CODE> - The location of CUPS data files
-
-       <LI><CODE>CUPS_SERVERROOT</CODE> - The location of CUPS configuration
-       files
-
-       <LI><CODE>DEVICE_URI</CODE> - The output device URI
-
-       <LI><CODE>LANG</CODE> - The language used by the client for
-       this print file
-
-       <LI><CODE>PATH</CODE> - The execution path exported to the filter
-
-       <LI><CODE>PPD</CODE> - The full filename of the printer's PPD file
-
-       <LI><CODE>PRINTER</CODE> - The name of the printer queue
-
-       <LI><CODE>RIP_CACHE</CODE> - The maximum amount of memory each filter
-       should use
-
-       <LI><CODE>SOFTWARE</CODE> - The name of the CUPS software, typically
-       "CUPS/1.1"
-
-       <LI><CODE>TZ</CODE> - The local timezone
-
-       <LI><CODE>USER</CODE> - The name of the current user
-
-</UL>
-
-<H2>Dissecting the HP-GL/2 Filter</H2>
-
-<P>The HP-GL/2 filter (<CODE>hpgltops</CODE>) provided with CUPS is a
-complex program that converts HP-GL/2 files into device-independent PostScript
-output. Since it produces device-independent PostScript output, it does not
-need to handle copy generation or writing printer options from the printer's
-PPD file.
-
-<H3>Initializing the Filter</H3>
-
-<P>The first task of any filter is to ensure that the correct number of
-command-line arguments are present:
-
-<UL><PRE>
-if (argc &lt; 6 || argc > 7)
-{
-  fputs("ERROR: hpgltops job-id user title copies options [file]\n", stderr);
-  return (1);
-}
-</PRE></UL>
-
-<P>After this you open the print file or read from the standard input
-as needed:
-
-<UL><PRE>
-FILE *fp;
-
-/*
- * If we have 7 arguments, print the file named on the command-line.
- * Otherwise, send stdin instead...
- */
-
-if (argc == 6)
-  fp = stdin;
-else
-{
- /*
-  * Try to open the print file...
-  */
-
-  if ((fp = fopen(argv[6], "rb")) == NULL)
-  {
-    perror("ERROR: unable to open print file - ");
-    return (1);
-  }
-}
-</PRE></UL>
-
-<P>Once the print file has been opened, options can be processed using
-the <A HREF="#cupsParseOptions"><CODE>cupsParseOptions()</CODE></A> and
-<A HREF="#cupsGetOption"><CODE>cupsGetOption()</CODE></A> functions:
-
-<UL><PRE>
-int           num_options;
-cups_option_t *options;
-const char    *val;
-
-/*
- * Process command-line options and write the prolog...
- */
-
-options     = NULL;
-num_options = cupsParseOptions(argv[5], 0, &options);
-
-if ((val = cupsGetOption("blackplot", num_options, options)) != NULL)
-  shading = 0;
-
-if ((val = cupsGetOption("fitplot", num_options, options)) != NULL)
-  FitPlot = 1;
-
-if ((val = cupsGetOption("penwidth", num_options, options)) != NULL)
-  PenWidth = (float)atoi(val) * 0.001f;
-</PRE></UL>
-
-<P>After the options have been processed, the filter writes PostScript code
-to the standard output based on the print file, closes the print file (as
-needed), and returns 0 to the scheduler.
-
-<H2>PostScript Output</H2>
-
-<P>Filters that produce PostScript output must generate output conforming
-to the Adobe Document Structuring Conventions, 3.0. In general this means
-the beginning of each file must begin with:
-
-<UL><PRE>
-%!PS-Adobe-3.0
-%%BoundingBox: left bottom right top
-%%Pages: (atend)
-%%EndComments
-</PRE></UL>
-
-<P>The <I>left</I>, <I>bottom</I>, <I>right</I>, and <I>top</I> values
-are integers in points from the lower-lefthand corner of the page.
-
-<P>Pages must be surrounded by:
-
-<UL><PRE>
-%%Page: number number
-gsave
-...
-grestore
-showpage
-</PRE></UL>
-
-<P>And the end of each file must contain:
-
-<UL><PRE>
-%%Trailer
-%%Pages: number-pages
-%%EOF
-</PRE></UL>
-
-<P>These comments allow the PostScript filter to correctly perform page
-accounting, copy generation, N-up printing, and so forth.
-
-<H1 ALIGN="RIGHT"><A NAME="WRITING_DRIVERS">4 - Writing Printer Drivers</A></H1>
-
-<P>This chapter discusses how to write a printer driver, which is a
-special filter program that converts CUPS raster data into the
-appropriate commands and data required for a printer.
-
-<H2>Overview</H2>
-
-<P>Raster printers utilitize PPD files that specify one or more
-device-specific filters that handle converting print files for the
-printer. The simplest raster printer drivers provide a single filter
-that converts CUPS raster data to the printer's native format.
-
-<H3>CUPS Raster Data</H3>
-
-<P>CUPS raster data (<CODE>application/vnd.cups-raster</CODE>) consists of
-a stream of raster page descriptions produced by one of the RIP filters,
-such as <CODE>pstoraster</CODE> or <CODE>imagetoraster</CODE>.
-
-<P>Each page of data begins with a page dictionary structure called
-<A HREF="#cups_raster_header_t"><CODE>cups_raster_header_t</CODE></A>. This
-structure contains the colorspace, bits per color, media size, media type,
-hardware resolution, and so forth.
-
-<P>After the page dictionary comes the page data which is a full-resolution,
-uncompressed bitmap representing the page in the printer's output colorspace.
-
-<H3>Page Accounting</H3>
-
-<P>Printer drivers must handle all page accounting. This means they must
-send "PAGE:" messages to the standard error file for each page (and in many
-cases, copy) sent to the printer.
-
-<H3>Color Management</H3>
-
-<P>Printer drivers can implement their color management via the
-<CODE>cupsColorProfile</CODE> attributes in the PPD file or internally
-in the driver from a device-independent colorspace. In general, color
-management performed by the RIP filters is more efficient than that
-performed inside printer drivers.
-
-<P>For example, the <CODE>pstoraster</CODE> filter often only has to
-perform a color conversion once each time the color is used for
-multiple output pixels, while the raster filter must convert every
-pixel on the page.
-
-<H3>Device and Bitmap Variables</H3>
-
-<P>Besides the standard PostScript page device dictionary variables defined
-in the Adobe PostScript Level 3 reference manual, the CUPS filters support
-additional variables that are passed in the page device dictionary header for
-the page and in some cases control the type of raster data that is generated:
-
-<CENTER><TABLE WIDTH="90%" BORDER="1">
-<TR>
-       <TH>Variable</TH>
-       <TH>Type</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>cupsWidth</TD>
-       <TD>read-only integer</TD>
-       <TD>Width of bitmap in pixels</TD>
-</TR>
-<TR>
-       <TD>cupsHeight</TD>
-       <TD>read-only integer </TD>
-       <TD>Height of bitmap in pixels</TD>
-</TR>
-<TR>
-       <TD>cupsMediaType</TD>
-       <TD>read-write integer</TD>
-       <TD>Device-specific media type code</TD>
-</TR>
-<TR>
-       <TD>cupsBitsPerColor</TD>
-       <TD>read-write integer</TD>
-       <TD>Number of bits per color; 1, 2, 4, and 8 are currently
-       supported</TD>
-</TR>
-<TR>
-       <TD>cupsBitsPerPixel</TD>
-       <TD>read-only integer </TD>
-       <TD>Number of bits per pixel; 1 to 32</TD>
-</TR>
-<TR>
-       <TD>cupsBytesPerLine</TD>
-       <TD>read-only integer</TD>
-       <TD>Number of bytes per line of raster graphics</TD>
-</TR>
-<TR>
-       <TD>cupsColorOrder</TD>
-       <TD>read-write enum</TD>
-       <TD>The order of color values in the bitmap:
-       <UL>
-               <LI><CODE>CUPS_ORDER_CHUNKED</CODE> - CMYK&nbsp;CMYK&nbsp;CMYK
-               <LI><CODE>CUPS_ORDER_BANDED</CODE> - CCC&nbsp;MMM&nbsp;YYY&nbsp;KKK
-               <LI><CODE>CUPS_ORDER_PLANAR</CODE> - CCC&nbsp;...&nbsp;MMM&nbsp;...&nbsp;YYY&nbsp;...&nbsp;KKK&nbsp;...
-       </UL>
-       </TD>
-</TR>
-<TR>
-       <TD>cupsColorSpace</TD>
-       <TD>read-write enum</TD>
-       <TD>The colorspace of the bitmap:
-       <UL>
-               <LI><CODE>CUPS_CSPACE_W</CODE> - White (luminance)
-               <LI><CODE>CUPS_CSPACE_RGB</CODE> - Red, green, blue
-               <LI><CODE>CUPS_CSPACE_RGBA</CODE> - Red, green, blue, alpha
-               <LI><CODE>CUPS_CSPACE_K</CODE> - Black
-               <LI><CODE>CUPS_CSPACE_CMY</CODE> - Cyan, magenta, yellow
-               <LI><CODE>CUPS_CSPACE_YMC</CODE> - Yellow, magenta, cyan
-               <LI><CODE>CUPS_CSPACE_CMYK</CODE> - Cyan, magenta, yellow, black
-               <LI><CODE>CUPS_CSPACE_YMCK</CODE> - Yellow, magenta, cyan, black
-               <LI><CODE>CUPS_CSPACE_KCMY</CODE> - Black, cyan, magenta, yellow
-               <LI><CODE>CUPS_CSPACE_KCMYcm</CODE> - Black, cyan, magenta, yellow,
-               light cyan, light magenta
-               <LI><CODE>CUPS_CSPACE_GMCK</CODE> - Metallic yellow (gold), metallic magenta,
-               metallic cyan, black
-               <LI><CODE>CUPS_CSPACE_GMCS</CODE> - Metallic yellow (gold), metallic magenta,
-               metallic cyan, metallic grey (silver)
-               <LI><CODE>CUPS_CSPACE_WHITE</CODE> - White pigment (black as white pigment)
-               <LI><CODE>CUPS_CSPACE_GOLD</CODE> - Gold foil (black as gold foil)
-               <LI><CODE>CUPS_CSPACE_SILVER</CODE> - Silver foil (black as silver foil)
-       </UL>
-       </TD>
-</TR>
-<TR>
-       <TD>cupsCompression</TD>
-       <TD>read-write integer</TD>
-       <TD>Device-specific compression type code</TD>
-</TR>
-<TR>
-       <TD>cupsRowCount</TD>
-       <TD>read-write integer</TD>
-       <TD>Device-specific row count value</TD>
-</TR>
-<TR>
-       <TD>cupsRowFeed</TD>
-       <TD>read-write integer</TD>
-       <TD>Device-specific row feed value</TD>
-</TR>
-<TR>
-       <TD>cupsRowStep</TD>
-       <TD>read-write integer</TD>
-       <TD>Device-specific row step value</TD>
-</TR>
-</TABLE></CENTER>
-
-<P>Bitmaps with a colorspace of CUPS_CSPACE_KCMYcm and more than 1 bit per
-color are transmitted to the raster driver in KCMY colorspace; the driver
-is responsible for producing the correct separation of normal and light
-cyan and magenta inks.
-
-<H2>Dissecting the HP-PCL Driver</H2>
-
-<P>The HP-PCL driver provided with CUPS (<CODE>rastertohp</CODE>) converts
-bitmap data from the raster filters into HP-PCL commands for most
-PCL-compatible printers. The actual format of the raster data is controlled
-by the PPD file being used - <VAR>deskjet.ppd</VAR> or <VAR>laserjet.ppd</VAR>.
-
-<H3>PPD Files</H3>
-
-<P>PPD files play an important part of all raster printer drivers. Options
-defined in the PPD file contain PostScript commands that control the raster
-data that is sent to the printer driver.
-
-<P>A typical CUPS printer driver will include <CODE>ColorModel</CODE>,
-<CODE>InputSlot</CODE>, <CODE>PageSize</CODE>, <CODE>PageRegion</CODE>,
-and <CODE>Resolution</CODE> options. Each option is shown using the
-standard PPD format:
-
-<UL><PRE>
-*OpenUI *PageSize/Media Size: PickOne
-*OrderDependency: 10 AnySetup *PageSize
-*DefaultPageSize: Letter
-*PageSize Letter/US Letter: "&lt;&lt;
-/PageSize [612 792]
-/ImagingBBox null
->> setpagedevice"
-*End
-*PageSize Legal/US Legal: "&lt;&lt;
-/PageSize [612 1008]
-/ImagingBBox null
->> setpagedevice"
-*End
-*PageSize A4/A4: "&lt;&lt;
-/PageSize [595 842]
-/ImagingBBox null
->> setpagedevice"
-*End
-*CloseUI: *PageSize
-</PRE></UL>
-
-<P>The <CODE>OpenUI</CODE> keyword specifies the new option. The first
-name is the option with an asterisk (*) in front of it. The first name is
-usually followed by a slash (/) and a human-readable version of the
-option name.
-
-<P>Every option <B>must</B> have a default value, specified using the
-<CODE>Default<I>Option</I></CODE> keyword.
-
-<P>Each option begins with the option name followed by the computer and
-human-readable values. The PostScript commands follow these inside double
-quotes. PostScript commands can be provided on a single line:
-
-<UL><PRE>
-*PageSize A4/A4: "&lt;&lt;/PageSize[595 842]/ImagingBBox null>> setpagedevice"
-</PRE></UL>
-
-<P>or broken down on separate lines using the <CODE>End</CODE> keyword to
-terminate them:
-
-<UL><PRE>
-*PageSize A4/A4: "&lt;&lt;
-/PageSize [595 842]
-/ImagingBBox null
->> setpagedevice"
-*End
-</PRE></UL>
-
-<P>The choice of the two formats is usually esthetic. However, each line in
-a PPD file must not exceed 255 characters, so if your PostScript commands are
-long you may need to break them up on separate lines.
-
-<H3>Reading Raster Data</H3>
-
-<P>As with any filter, your printer driver should handle raster data from
-a filename specified on the command-line or from the standard input. The
-<A HREF="#cupsRasterOpen"><CODE>cupsRasterOpen()</CODE></A> function opens
-a raster stream for printing:
-
-<UL><PRE>
-int           fd;   /* File descriptor */
-cups_raster_t *ras; /* Raster stream for printing */
-
-
-/*
- * Check for valid arguments...
- */
-
-if (argc &lt; 6 || argc > 7)
-{
- /*
-  * We don't have the correct number of arguments; write an error message
-  * and return.
-  */
-
-  fputs("ERROR: rastertopcl job-id user title copies options [file]\n", stderr);
-  return (1);
-}
-
-/*
- * Open the page stream...
- */
-
-if (argc == 7)
-{
-  if ((fd = open(argv[6], O_RDONLY)) == -1)
-  {
-    perror("ERROR: Unable to open raster file - ");
-    sleep(1);
-    return (1);
-  }
-}
-else
-  fd = 0;
-
-ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
-</PRE></UL>
-
-<P>Once you have opened the raster stream you just need to read each
-page and print it:
-
-<UL><PRE>
-cups_raster_header_t header;
-int                  y;
-unsigned char        data[8192];
-
-while (cupsRasterReadHeader(ras, &amp;header))
-{
-  ... initialize the printer ...
-  for (y = header.cupsHeight; y > 0; y ++)
-  {
-    cupsRasterReadPixels(ras, data, header.cupsBytesPerLine);
-    ... send raster line to printer ...
-  }
-}
-</PRE></UL>
-
-<P>After you have processed all pages, close the raster stream and
-return:
-
-<UL><PRE>
-cupsRasterClose(ras);
-
-return (0);
-</PRE></UL>
-
-<H1 ALIGN="RIGHT"><A NAME="WRITING_BACKENDS">5 - Writing Backends</A></H1>
-
-<P>This chapter describes how to write a backend for CUPS.  Backends
-communicate directly with printers and allow printer drivers and
-filters to send data using any type of connection transparently.
-
-<H2>Overview</H2>
-
-<P>Backends are special filters that communicate with printers directly.
-They are treated slightly differently than filters, however, and have some
-unique requirements.
-
-<H3>Security Considerations</H3>
-
-<P>Backends are run as the root user, so special care must be taken to
-avoid potential security violations. In particular, remember that a backend
-will be able to manipulate disk files, devices, and other resources that
-potentially could damage a system or printer.
-
-<H3>Command-Line Arguments</H3>
-
-<P>Besides the standard filter arguments, backends are also run with no
-arguments to get a list of available devices. This discovery process is
-described later in this chapter.
-
-<H3>Copy Generation</H3>
-
-<P>Like filters, backends should send multiple copies of the print file only
-if a filename is supplied on the command-line.  Otherwise the backend should
-assume that the upstream filter has already added the necessary commands or
-data to produce the multiple copies.
-
-<H3>Page Accounting</H3>
-
-<P>Backend filters generally do not do page accounting, however they should
-at a minimum produce a single page message for each copy that is produced
-when a filename is present on the command-line. This is because the user
-selected "raw" printing and no other accounting information is possible.
-
-<H3>Exclusive Access</H3>
-
-<P>Backends that talk to local character or block devices should open the
-device file in exclusive mode (<CODE>O_EXCL</CODE>) to cooperate with other
-printers defined for the same device.
-
-<H3>Retries</H3>
-
-<P>All backends <B>must</B> retry connections to the device. This
-includes backends that talk to local character or block devices, as the
-user may define more than one printer queue pointing at the same
-physical device.
-
-<P>To prevent excess CPU utilitization, the backend should go to sleep
-for an amount of time between retries; the CUPS-supplied backends retry
-once every 30 seconds.
-
-<H2>Dissecting the Serial Port Backend</H2>
-
-<P>The serial port backend provides support for serial printers. Since
-it does everything a good backend needs to do, it provides an excellent
-example of what to do.
-
-<H3>Supporting Device Discovery</H3>
-
-<P>As previously noted, backends are special filter programs that talk
-to printer devices. Another task a backend must perform is to list the
-available devices it supports. The backend lists the available devices
-when no additioanl arguments are supplied on the command-line (i.e.
-just the command name...)
-
-<P>The serial backend lists devices by looking at serial port files in the
-<VAR>/dev</VAR> directory, by consulting a hardware inventory (IRIX), and
-in some cases by trying to open the ports to see if they actually exist.
-
-<P>Once it finds a serial port it writes a single line for each port to
-the standard error file. Each line looks like this:
-
-<UL><PRE>
-serial serial:/dev/ttyS0?baud=115200 "Unknown" "Serial Port 1"
-</PRE></UL>
-
-<P>The first word "serial" is the <I>device class</I>; this identifies the
-class of device which can be used to categorize it in user interfaces. CUPS
-currently recognizes the following classes:
-
-<UL>
-
-       <LI>"file" - a disk file.
-
-       <LI>"direct" - a parallel or fixed-rate serial data port,
-       currently used for Centronics, IEEE-1284, and USB printer
-       ports.
-
-       <LI>"serial" - a variable-rate serial port.
-
-       <LI>"network" - a network connection, typically via AppSocket,
-       HTTP, IPP, LPD, or SMB/CIFS protocols.
-
-</UL>
-
-<P>After the device class is the <I>device URI</I>, in this case
-"serial:/dev/ttyS0?baud=115200". This is the URI that should be used by
-the user to select this port. For serial ports, the "baud=115200"
-specifies the maximum baud rate supported by the port - the actual
-value will vary based on the speed the user selects for the printer.
-
-<P>The last two strings are the model and description for the port. The
-"Unknown" string means that the printer model is unknown - some devices
-are able to provide a make and model such as "HP DeskJet" that allows
-users and software to choose an appropriate printer driver more easily.
-Both the model and description must be enclosed inside double quotes.
-
-<H3>Opening the Serial Port</H3>
-
-<P>As noted previously, all backends should open device files in exclusive
-mode, and retry as needed until the port is available. The serial port does
-this using a <CODE>do-while</CODE> loop:
-
-<UL><PRE>
-do
-{
-  if ((fd = open(resource, O_WRONLY | O_NOCTTY | O_EXCL)) == -1)
-  {
-    if (errno == EBUSY)
-    {
-      fputs("INFO: Serial port busy; will retry in 30 seconds...\n", stderr);
-      sleep(30);
-    }
-    else
-    {
-      perror("ERROR: Unable to open serial port device file");
-      return (1);
-    }
-  }
-}
-while (fd &lt; 0);
-</PRE></UL>
-
-<P>If the port is busy or in use by another process, the backend will
-go to sleep for 30 seconds and try again. If another error is detected
-a message is sent to the user and the backend aborts the print job
-until the problem can be corrected.
-
-<H3>Writing Data to the Port</H3>
-
-<P>Network and character devices pose an interesting problem when writing
-data to the port - they may not be able to write all of the bytes in your
-buffer before returning. To work around this problem you must loop until
-all bytes have been written:
-
-<UL><PRE>
-while (nbytes > 0)
-{
-  if ((wbytes = write(fd, bufptr, nbytes)) &lt; 0)
-    if (errno == ENOTTY)
-      wbytes = write(fd, bufptr, nbytes);
-
-  if (wbytes &lt; 0)
-  {
-    perror("ERROR: Unable to send print file to printer");
-    break;
-  }
-
-  nbytes -= wbytes;
-  bufptr += wbytes;
-}
-</PRE></UL>
-
-<P>The check for the <CODE>ENOTTY</CODE> error is needed on some platforms
-to clear an error from a previous <CODE>ioctl()</CODE> call.
-
-<H3>Finishing Up</H3>
-
-<P>Once you have sent the print file, return 0 if the file printed
-successfully or 1 if it did not. This will allow the scheduler to stop
-the print job if there is a device error, preserving the print job for
-later printing once the problem has been corrected.
-
-<H1 ALIGN="RIGHT"><A NAME="LICENSE">A - Software License Agreement</A></H1>
-
-<EMBED SRC="../LICENSE.html">
-
-
-<H1 ALIGN="RIGHT"><A NAME="CONSTANTS">B - Constants</A></H1>
-
-<P>This appendix lists all of the constants that are defined by the CUPS
-API.
-
-<H2>CUPS Constants</H2>
-
-<H3>Version Number</H3>
-
-<P>The <CODE>CUPS_VERSION</CODE> constant is a floating-point number
-representing the API version number. The current version number is
-1.0100 which represents CUPS version 1.1.0.
-
-<H3>Printer Capabilities</H3>
-
-<P>The <CODE>CUPS_PRINTER</CODE> constants represent capability bits for
-printers and classes:
-
-<UL>
-
-       <LI><CODE>CUPS_PRINTER_LOCAL</CODE> - Is a local printer or class.
-
-       <LI><CODE>CUPS_PRINTER_REMOTE</CODE> - Is a remote printer or class.
-
-       <LI><CODE>CUPS_PRINTER_CLASS</CODE> - Is a class.
-
-       <LI><CODE>CUPS_PRINTER_BW</CODE> - Printer prints in black and white.
-
-       <LI><CODE>CUPS_PRINTER_COLOR</CODE> - Printer prints in color.
-
-       <LI><CODE>CUPS_PRINTER_DUPLEX</CODE> - Printer can print double-sided.
-
-       <LI><CODE>CUPS_PRINTER_STAPLE</CODE> - Printer can staple output.
-
-       <LI><CODE>CUPS_PRINTER_COPIES</CODE> - Printer can produce multiple
-       copies on its own.
-
-       <LI><CODE>CUPS_PRINTER_COLLATE</CODE> - Printer can collate copies.
-
-       <LI><CODE>CUPS_PRINTER_PUNCH</CODE> - Printer can punch holes in output.
-
-       <LI><CODE>CUPS_PRINTER_COVER</CODE> - Printer can put covers on output.
-
-       <LI><CODE>CUPS_PRINTER_BIND</CODE> - Printer can bind output.
-
-       <LI><CODE>CUPS_PRINTER_SORT</CODE> - Printer can sort output.
-
-       <LI><CODE>CUPS_PRINTER_SMALL</CODE> - Printer can print on media up
-       to 9x14 inches.
-
-       <LI><CODE>CUPS_PRINTER_MEDIUM</CODE> - Printer can print on media
-       from 9x14 to 18x24 inches.
-
-       <LI><CODE>CUPS_PRINTER_LARGE</CODE> - Printer can print on media
-       larger than 18x24 inches.
-
-       <LI><CODE>CUPS_PRINTER_VARIABLE</CODE> - Printer can print on
-       variable or custom media sizes.
-
-       <LI><CODE>CUPS_PRINTER_IMPLICIT</CODE> - Is an implicit class.
-
-       <LI><CODE>CUPS_PRINTER_OPTIONS</CODE> - All of the printer capability
-       and option bits.
-
-</UL>
-
-<H3>Encodings</H3>
-
-<P>CUPS defines the following character set encoding constants:
-
-<UL>
-
-       <LI><CODE>CUPS_US_ASCII</CODE> - US ASCII character set.
-
-       <LI><CODE>CUPS_UTF_8</CODE> - UTF-8 encoding of Unicode.
-
-       <LI><CODE>CUPS_ISO8859_1</CODE> - ISO-8859-1 character set.
-
-       <LI><CODE>CUPS_ISO8859_2</CODE> - ISO-8859-2 character set.
-
-       <LI><CODE>CUPS_ISO8859_3</CODE> - ISO-8859-3 character set.
-
-       <LI><CODE>CUPS_ISO8859_4</CODE> - ISO-8859-4 character set.
-
-       <LI><CODE>CUPS_ISO8859_5</CODE> - ISO-8859-5 character set.
-
-       <LI><CODE>CUPS_ISO8859_6</CODE> - ISO-8859-6 character set.
-
-       <LI><CODE>CUPS_ISO8859_7</CODE> - ISO-8859-7 character set.
-
-       <LI><CODE>CUPS_ISO8859_8</CODE> - ISO-8859-8 character set.
-
-       <LI><CODE>CUPS_ISO8859_9</CODE> - ISO-8859-9 character set.
-
-       <LI><CODE>CUPS_ISO8859_10</CODE> - ISO-8859-10 character set.
-
-       <LI><CODE>CUPS_ISO8859_13</CODE> - ISO-8859-13 character set.
-
-       <LI><CODE>CUPS_ISO8859_14</CODE> - ISO-8859-14 character set.
-
-       <LI><CODE>CUPS_ISO8859_15</CODE> - ISO-8859-15 character set.
-
-       <LI><CODE>CUPS_WINDOWS_874</CODE> - Windows code page 874.
-
-       <LI><CODE>CUPS_WINDOWS_1250</CODE> - Windows code page 1250.
-
-       <LI><CODE>CUPS_WINDOWS_1251</CODE> - Windows code page 1251.
-
-       <LI><CODE>CUPS_WINDOWS_1252</CODE> - Windows code page 1252.
-
-       <LI><CODE>CUPS_WINDOWS_1253</CODE> - Windows code page 1253.
-
-       <LI><CODE>CUPS_WINDOWS_1254</CODE> - Windows code page 1254.
-
-       <LI><CODE>CUPS_WINDOWS_1255</CODE> - Windows code page 1255.
-
-       <LI><CODE>CUPS_WINDOWS_1256</CODE> - Windows code page 1256.
-
-       <LI><CODE>CUPS_WINDOWS_1257</CODE> - Windows code page 1257.
-
-       <LI><CODE>CUPS_WINDOWS_1258</CODE> - Windows code page 1258.
-
-       <LI><CODE>CUPS_KOI8_R</CODE> - Russian code page koi8-r.
-
-       <LI><CODE>CUPS_KOI8_U</CODE> - Ukrainian code page koi8-r.
-
-</UL>
-
-<H2>HTTP Constants</H2>
-
-<H3>Limits</H3>
-
-<P>The following constants define the limits for strings:
-
-<UL>
-
-       <LI><CODE>HTTP_MAX_BUFFER</CODE> - Size of socket buffer.
-
-       <LI><CODE>HTTP_MAX_HOST</CODE> - Maximum length of hostname.
-
-       <LI><CODE>HTTP_MAX_URI</CODE> - Maximum length of URI.
-
-       <LI><CODE>HTTP_MAX_VALUE</CODE> - Maximum length of field values.
-
-</UL>
-
-<H3>Status Codes</H3>
-
-<P>The following status codes can be returned by <CODE>httpUpdate()</CODE>:
-
-<UL>
-
-       <LI><CODE>HTTP_ERROR</CODE> - A network error occurred
-
-       <LI><CODE>HTTP_CONTINUE</CODE> - Continue response from HTTP proxy
-
-       <LI><CODE>HTTP_OK</CODE> - OPTIONS/GET/HEAD/POST/TRACE command was successful
-
-       <LI><CODE>HTTP_CREATED</CODE> - PUT command was successful
-
-       <LI><CODE>HTTP_ACCEPTED</CODE> - DELETE command was successful
-
-       <LI><CODE>HTTP_NOT_AUTHORITATIVE</CODE> - Information isn't authoritative
-
-       <LI><CODE>HTTP_NO_CONTENT</CODE> - Successful command
-
-       <LI><CODE>HTTP_RESET_CONTENT</CODE> - Content was reset/recreated
-
-       <LI><CODE>HTTP_PARTIAL_CONTENT</CODE> - Only a partial file was recieved/sent
-
-       <LI><CODE>HTTP_MULTIPLE_CHOICES</CODE> - Multiple files match request
-
-       <LI><CODE>HTTP_MOVED_PERMANENTLY</CODE> - Document has moved permanently
-
-       <LI><CODE>HTTP_MOVED_TEMPORARILY</CODE> - Document has moved temporarily
-
-       <LI><CODE>HTTP_SEE_OTHER</CODE> - See this other link...
-
-       <LI><CODE>HTTP_NOT_MODIFIED</CODE> - File not modified
-
-       <LI><CODE>HTTP_USE_PROXY</CODE> - Must use a proxy to access this URI
-
-       <LI><CODE>HTTP_BAD_REQUEST</CODE> - Bad request
-
-       <LI><CODE>HTTP_UNAUTHORIZED</CODE> - Unauthorized to access host
-
-       <LI><CODE>HTTP_PAYMENT_REQUIRED</CODE> - Payment required
-
-       <LI><CODE>HTTP_FORBIDDEN</CODE> - Forbidden to access this URI
-
-       <LI><CODE>HTTP_NOT_FOUND</CODE> - URI was not found
-
-       <LI><CODE>HTTP_METHOD_NOT_ALLOWED</CODE> - Method is not allowed
-
-       <LI><CODE>HTTP_NOT_ACCEPTABLE</CODE> - Not Acceptable
-
-       <LI><CODE>HTTP_PROXY_AUTHENTICATION</CODE> - Proxy Authentication is Required
-
-       <LI><CODE>HTTP_REQUEST_TIMEOUT</CODE> - Request timed out
-
-       <LI><CODE>HTTP_CONFLICT</CODE> - Request is self-conflicting
-
-       <LI><CODE>HTTP_GONE</CODE> - Server has gone away
-
-       <LI><CODE>HTTP_LENGTH_REQUIRED</CODE> - A content length or encoding is required
-
-       <LI><CODE>HTTP_PRECONDITION</CODE> - Precondition failed
-
-       <LI><CODE>HTTP_REQUEST_TOO_LARGE</CODE> - Request entity too large
-
-       <LI><CODE>HTTP_URI_TOO_LONG</CODE> - URI too long
-
-       <LI><CODE>HTTP_UNSUPPORTED_MEDIATYPE</CODE> - The requested media type is unsupported
-
-       <LI><CODE>HTTP_SERVER_ERROR</CODE> - Internal server error
-
-       <LI><CODE>HTTP_NOT_IMPLEMENTED</CODE> - Feature not implemented
-
-       <LI><CODE>HTTP_BAD_GATEWAY</CODE> - Bad gateway
-
-       <LI><CODE>HTTP_SERVICE_UNAVAILABLE</CODE> - Service is unavailable
-
-       <LI><CODE>HTTP_GATEWAY_TIMEOUT</CODE> - Gateway connection timed out
-
-       <LI><CODE>HTTP_NOT_SUPPORTED</CODE> - HTTP version not supported
-
-</UL>
-
-<H3>Fields</H3>
-
-<P>The following fields are indices for each of the standard HTTP fields in
-HTTP 1/1:
-
-<UL>
-
-       <LI><CODE>HTTP_FIELD_ACCEPT_LANGUAGE</CODE> - Accept-Language
-
-       <LI><CODE>HTTP_FIELD_ACCEPT_RANGES</CODE> - Accept-Ranges
-
-       <LI><CODE>HTTP_FIELD_AUTHORIZATION</CODE> - Authorization
-
-       <LI><CODE>HTTP_FIELD_CONNECTION</CODE> - Connection
-
-       <LI><CODE>HTTP_FIELD_CONTENT_ENCODING</CODE> - Content-Encoding
-
-       <LI><CODE>HTTP_FIELD_CONTENT_LANGUAGE</CODE> - Content-Language
-
-       <LI><CODE>HTTP_FIELD_CONTENT_LENGTH</CODE> - Content-Length
-
-       <LI><CODE>HTTP_FIELD_CONTENT_LOCATION</CODE> - Content-Location
-
-       <LI><CODE>HTTP_FIELD_CONTENT_MD5</CODE> - Content-MD5
-
-       <LI><CODE>HTTP_FIELD_CONTENT_RANGE</CODE> - Content-Range
-
-       <LI><CODE>HTTP_FIELD_CONTENT_TYPE</CODE> - Content-Type
-
-       <LI><CODE>HTTP_FIELD_CONTENT_VERSION</CODE> - Content-Version
-
-       <LI><CODE>HTTP_FIELD_DATE</CODE> - Date
-
-       <LI><CODE>HTTP_FIELD_HOST</CODE> - Host
-
-       <LI><CODE>HTTP_FIELD_IF_MODIFIED_SINCE</CODE> - If-Modified-Since
-
-       <LI><CODE>HTTP_FIELD_IF_UNMODIFIED_SINCE</CODE> - If-Unmodified-Since
-
-       <LI><CODE>HTTP_FIELD_KEEP_ALIVE</CODE> - Keep-Alive
-
-       <LI><CODE>HTTP_FIELD_LAST_MODIFIED</CODE> - Last-Modified
-
-       <LI><CODE>HTTP_FIELD_LINK</CODE> - Link
-
-       <LI><CODE>HTTP_FIELD_LOCATION</CODE> - Location
-
-       <LI><CODE>HTTP_FIELD_RANGE</CODE> - Range
-
-       <LI><CODE>HTTP_FIELD_REFERER</CODE> - Referer
-
-       <LI><CODE>HTTP_FIELD_RETRY_AFTER</CODE> - Retry-After
-
-       <LI><CODE>HTTP_FIELD_TRANSFER_ENCODING</CODE> - Transfer-Encoding
-
-       <LI><CODE>HTTP_FIELD_UPGRADE</CODE> - Upgrade
-
-       <LI><CODE>HTTP_FIELD_USER_AGENT</CODE> - User-Agent
-
-       <LI><CODE>HTTP_FIELD_WWW_AUTHENTICATE</CODE> - WWW-Authenticate
-
-
-</UL>
-
-<H2>IPP Constants</H2>
-
-<H3>Limits</H3>
-
-<P>The following constants define array limits for IPP data:
-
-<UL>
-
-       <LI><CODE>IPP_MAX_NAME</CODE> - Maximum length of an attribute name
-
-       <LI><CODE>IPP_MAX_VALUES</CODE> - Maximum number of set-of values
-       that can be read in a request.
-
-</UL>
-
-<H3>Tags</H3>
-
-<UL>
-
-       <LI><CODE>IPP_TAG_ZERO</CODE> - Wildcard tag value for searches; also
-       used to separate groups of attributes
-
-       <LI><CODE>IPP_TAG_OPERATION</CODE> - Tag for values of type operation
-
-       <LI><CODE>IPP_TAG_JOB</CODE> - Tag for values of type job
-
-       <LI><CODE>IPP_TAG_END</CODE> - Tag for values of type end
-
-       <LI><CODE>IPP_TAG_PRINTER</CODE> - Tag for values of type printer
-
-       <LI><CODE>IPP_TAG_UNSUPPORTED_GROUP</CODE> - Tag for values of type unsupported_group
-
-       <LI><CODE>IPP_TAG_UNSUPPORTED_VALUE</CODE> - Tag for values of type unsupported_value
-
-       <LI><CODE>IPP_TAG_DEFAULT</CODE> - Tag for values of type default
-
-       <LI><CODE>IPP_TAG_UNKNOWN</CODE> - Tag for values of type unknown
-
-       <LI><CODE>IPP_TAG_NOVALUE</CODE> - Tag for values of type novalue
-
-       <LI><CODE>IPP_TAG_NOTSETTABLE</CODE> - Tag for values of type notsettable
-
-       <LI><CODE>IPP_TAG_DELETEATTR</CODE> - Tag for values of type deleteattr
-
-       <LI><CODE>IPP_TAG_ANYVALUE</CODE> - Tag for values of type anyvalue
-
-       <LI><CODE>IPP_TAG_INTEGER</CODE> - Tag for values of type integer
-
-       <LI><CODE>IPP_TAG_BOOLEAN</CODE> - Tag for values of type boolean
-
-       <LI><CODE>IPP_TAG_ENUM</CODE> - Tag for values of type enum
-
-       <LI><CODE>IPP_TAG_STRING</CODE> - Tag for values of type string
-
-       <LI><CODE>IPP_TAG_DATE</CODE> - Tag for values of type date
-
-       <LI><CODE>IPP_TAG_RESOLUTION</CODE> - Tag for values of type resolution
-
-       <LI><CODE>IPP_TAG_RANGE</CODE> - Tag for values of type range
-
-       <LI><CODE>IPP_TAG_COLLECTION</CODE> - Tag for values of type collection
-
-       <LI><CODE>IPP_TAG_TEXTLANG</CODE> - Tag for values of type textlang
-
-       <LI><CODE>IPP_TAG_NAMELANG</CODE> - Tag for values of type namelang
-
-       <LI><CODE>IPP_TAG_TEXT</CODE> - Tag for values of type text
-
-       <LI><CODE>IPP_TAG_NAME</CODE> - Tag for values of type name
-
-       <LI><CODE>IPP_TAG_KEYWORD</CODE> - Tag for values of type keyword
-
-       <LI><CODE>IPP_TAG_URI</CODE> - Tag for values of type uri
-
-       <LI><CODE>IPP_TAG_URISCHEME</CODE> - Tag for values of type urischeme
-
-       <LI><CODE>IPP_TAG_CHARSET</CODE> - Tag for values of type charset
-
-       <LI><CODE>IPP_TAG_LANGUAGE</CODE> - Tag for values of type language
-
-       <LI><CODE>IPP_TAG_MIMETYPE</CODE> - Tag for values of type mimetype
-
-</UL>
-
-<H3>Resolution Units</H3>
-
-<P>The <CODE>IPP_RES_PER_INCH</CODE> and <CODE>IPP_RES_PER_CM</CODE> constants
-specify dots per inch and dots per centimeter, respectively.
-
-<H3>Finishings</H3>
-
-<P>The finishing values specify special finishing operations to be
-performed on the job.
-
-<UL>
-
-       <LI><CODE>IPP_FINISH_NONE</CODE> - Do no finishing
-
-       <LI><CODE>IPP_FINISH_STAPLE</CODE> - Staple the job
-
-       <LI><CODE>IPP_FINISH_PUNCH</CODE> - Punch the job
-
-       <LI><CODE>IPP_FINISH_COVER</CODE> - Cover the job
-
-       <LI><CODE>IPP_FINISH_BIND</CODE> - Bind the job
-
-</UL>
-
-<H3>Orientations</H3>
-
-<P>The orientation values specify the orientation of the job.
-
-<UL>
-
-       <LI><CODE>IPP_PORTRAIT</CODE> - No rotation
-
-       <LI><CODE>IPP_LANDSCAPE</CODE> - 90 degrees counter-clockwise
-
-       <LI><CODE>IPP_REVERSE_LANDSCAPE</CODE> - 90 degrees clockwise
-
-       <LI><CODE>IPP_REVERSE_PORTRAIT</CODE> - 180 degrees
-
-</UL>
-
-<H3>Qualities</H3>
-
-<P>The quality values specify the desired quality of the print.
-<UL>
-
-       <LI><CODE>IPP_QUALITY_DRAFT</CODE> - Draft quality
-
-       <LI><CODE>IPP_QUALITY_NORMAL</CODE> - Normal quality
-
-       <LI><CODE>IPP_QUALITY_HIGH</CODE> - High quality
-
-</UL>
-
-<H3>Job States</H3>
-
-<P>The job state values are used to represent the current job state.
-
-<UL>
-
-       <LI><CODE>IPP_JOB_PENDING</CODE> - Job is pending
-
-       <LI><CODE>IPP_JOB_HELD</CODE> - Job is held
-
-       <LI><CODE>IPP_JOB_PROCESSING</CODE> - Job is processing
-
-       <LI><CODE>IPP_JOB_STOPPED</CODE> - Job is stopped
-
-       <LI><CODE>IPP_JOB_CANCELLED</CODE> - Job is cancelled
-
-       <LI><CODE>IPP_JOB_ABORTED</CODE> - Job is aborted
-
-       <LI><CODE>IPP_JOB_COMPLETED</CODE> - Job is completed
-
-</UL>
-
-<H3>Printer States</H3>
-
-<P>The printer state values are used to represent the current printer
-state.
-
-<UL>
-
-       <LI><CODE>IPP_PRINTER_IDLE</CODE> - Printer is idle
-
-       <LI><CODE>IPP_PRINTER_PROCESSING</CODE> - Printer is processing
-
-       <LI><CODE>IPP_PRINTER_STOPPED</CODE> - Printer is stopped
-
-</UL>
-
-<H3>Operations</H3>
-
-<P>The operation values represent the available IPP operations.
-
-<UL>
-
-       <LI><CODE>IPP_PRINT_JOB</CODE> - Print a file
-
-       <LI><CODE>IPP_PRINT_URI</CODE> - Print a URI
-
-       <LI><CODE>IPP_VALIDATE_JOB</CODE> - Validate job attributes
-
-       <LI><CODE>IPP_CREATE_JOB</CODE> - Create a new job
-
-       <LI><CODE>IPP_SEND_DOCUMENT</CODE> - Send a document to a job
-
-       <LI><CODE>IPP_SEND_URI</CODE> - Send a URI to a job
-
-       <LI><CODE>IPP_CANCEL_JOB</CODE> - Cancel a job
-
-       <LI><CODE>IPP_GET_JOB_ATTRIBUTES</CODE> - Get job attributes
-
-       <LI><CODE>IPP_GET_JOBS</CODE> - Get a list of all jobs
-
-       <LI><CODE>IPP_GET_PRINTER_ATTRIBUTES</CODE> - Get printer attributes
-
-       <LI><CODE>IPP_HOLD_JOB</CODE> - Hold a pending job
-
-       <LI><CODE>IPP_RELEASE_JOB</CODE> - Release a held job
-
-       <LI><CODE>IPP_RESTART_JOB</CODE> - Restart a completed job
-
-       <LI><CODE>IPP_PAUSE_PRINTER</CODE> - Pause a printer
-
-       <LI><CODE>IPP_RESUME_PRINTER</CODE> - Restart a paused printer
-
-       <LI><CODE>IPP_PURGE_JOBS</CODE> - Purge jobs from the queue
-
-       <LI><CODE>IPP_SET_PRINTER_ATTRIBUTES</CODE> - Set printer attributes
-
-       <LI><CODE>IPP_SET_JOB_ATTRIBUTES</CODE> - Set job attributes
-
-       <LI><CODE>IPP_GET_PRINTER_SUPPORTED_VALUES</CODE> - Get printer supported values
-
-       <LI><CODE>CUPS_GET_DEFAULT</CODE> - Get the default destination
-
-       <LI><CODE>CUPS_GET_PRINTERS</CODE> - Get a list of all printers
-
-       <LI><CODE>CUPS_ADD_PRINTER</CODE> - Add or modify a printer
-
-       <LI><CODE>CUPS_DELETE_PRINTER</CODE> - Delete a printer
-
-       <LI><CODE>CUPS_GET_CLASSES</CODE> - Get a list of all classes
-
-       <LI><CODE>CUPS_ADD_CLASS</CODE> - Add or modify a class
-
-       <LI><CODE>CUPS_DELETE_CLASS</CODE> - Delete a class
-
-       <LI><CODE>CUPS_ACCEPT_JOBS</CODE> - Accept jobs on a printer or class
-
-       <LI><CODE>CUPS_REJECT_JOBS</CODE> - Reject jobs on a printer or class
-
-       <LI><CODE>CUPS_SET_DEFAULT</CODE> - Set the default destination
-
-       <LI><CODE>CUPS_GET_DEVICES</CODE> - Get a list of all devices
-
-       <LI><CODE>CUPS_GET_PPDS</CODE> - Get a list of all PPDs
-
-       <LI><CODE>CUPS_MOVE_JOB</CODE> - Move a job to a new destination
-
-</UL>
-
-<H3>Status Codes</H3>
-
-<P>Status codes are returned by all IPP requests.
-
-<UL>
-
-       <LI><CODE>IPP_OK</CODE> - Request completed with no errors
-
-       <LI><CODE>IPP_OK_SUBST</CODE> - Request completed but some attribute
-       values were substituted
-
-       <LI><CODE>IPP_OK_CONFLICT</CODE> - Request completed but some attributes
-       conflicted
-
-       <LI><CODE>IPP_BAD_REQUEST</CODE> - The request was bad
-
-       <LI><CODE>IPP_FORBIDDEN</CODE> - You don't have access to the resource
-
-       <LI><CODE>IPP_NOT_AUTHENTICATED</CODE> - You are not authenticated for
-       the resource
-
-       <LI><CODE>IPP_NOT_AUTHORIZED</CODE> - You not authorized to access
-       the resource
-
-       <LI><CODE>IPP_NOT_POSSIBLE</CODE> - The requested operation cannot be
-       completed
-
-       <LI><CODE>IPP_TIMEOUT</CODE> - A timeout occurred
-
-       <LI><CODE>IPP_NOT_FOUND</CODE> - The resource was not found
-
-       <LI><CODE>IPP_GONE</CODE> - The resource has gone away
-
-       <LI><CODE>IPP_REQUEST_ENTITY</CODE> - The request was too large
-
-       <LI><CODE>IPP_REQUEST_VALUE</CODE> - The request contained a value
-       that was unknown to the server
-
-       <LI><CODE>IPP_DOCUMENT_FORMAT</CODE> - The document format is not
-       supported by the server
-
-       <LI><CODE>IPP_ATTRIBUTES</CODE> - Required attributes are missing
-
-       <LI><CODE>IPP_URI_SCHEME</CODE> - The URI scheme is not supported
-
-       <LI><CODE>IPP_CHARSET</CODE> - The charset is not supported
-
-       <LI><CODE>IPP_CONFLICT</CODE> - One or more attributes conflict
-
-       <LI><CODE>IPP_COMPRESSION_NOT_SUPPORTED</CODE> - The specified
-       compression is not supported
-
-       <LI><CODE>IPP_COMPRESSION_ERROR</CODE> - The compressed data
-       contained an error
-
-       <LI><CODE>IPP_DOCUMENT_FORMAT_ERROR</CODE> - The document data
-       contained an error in it
-
-       <LI><CODE>IPP_DOCUMENT_ACCESS_ERROR</CODE> - The remote document
-       could not be accessed
-
-       <LI><CODE>IPP_INTERNAL_ERROR</CODE> - The server encountered an
-       internal error
-
-       <LI><CODE>IPP_OPERATION_NOT_SUPPORTED</CODE> - The requested operation
-       is not supported
-
-       <LI><CODE>IPP_SERVICE_UNAVAILABLE</CODE> - The requested service
-       is unavailable
-
-       <LI><CODE>IPP_VERSION_NOT_SUPPORTED</CODE> - The IPP request
-       version is not supported
-
-       <LI><CODE>IPP_DEVICE_ERROR</CODE> - The output device encountered
-       an error
-
-       <LI><CODE>IPP_TEMPORARY_ERROR</CODE> - A temporary error occurred
-
-       <LI><CODE>IPP_NOT_ACCEPTING</CODE> - The destination is not accepting
-       jobs
-
-       <LI><CODE>IPP_PRINTER_BUSY</CODE> - The destination is busy
-
-       <LI><CODE>IPP_ERROR_JOB_CANCELLED</CODE> - The requested job has been
-       cancelled
-
-       <LI><CODE>IPP_MULTIPLE_JOBS_NOT_SUPPORTED</CODE> - The server
-       does not support multiple jobs
-
-</UL>
-
-<H2>PPD Constants</H2>
-
-<H3>PPD Format Version</H3>
-
-<P>The <CODE>PPD_VERSION</CODE> constant defines a floating point number
-representing the newest format version that is supported by CUPS, currently
-4.3.
-
-<H3>PPD User-Interface Types</H3>
-
-<P>Each printer option has a type associated with it:
-
-<UL>
-
-       <LI><CODE>PPD_UI_BOOLEAN</CODE> - The user can turn this option on or off
-
-       <LI><CODE>PPD_UI_PICKONE</CODE> - The user can choose one option value
-       to use.
-
-       <LI><CODE>PPD_UI_PICKMANY</CODE> - The user can choose zero or more
-       option values.
-
-</UL>
-
-<H3>PPD Sections</H3>
-
-<P>Some options must be output before others, or in different sections of
-the output document. The <CODE>ppd_section_t</CODE> enumeration defines
-which section the option must be output in:
-
-<UL>
-
-       <LI><CODE>PPD_ORDER_ANY</CODE> - The option can be output in any of
-       the document, page, or prolog sections of the document
-
-       <LI><CODE>PPD_ORDER_DOCUMENT</CODE> - The option must be output in
-       the DocumentSetup section of the document
-
-       <LI><CODE>PPD_ORDER_EXIT</CODE> - The option must be output before
-       the document
-
-       <LI><CODE>PPD_ORDER_JCL</CODE> - The option must be output in the
-       job control section of the document
-
-       <LI><CODE>PPD_ORDER_PAGE</CODE> - The option must be output in the
-       PageSetup section of the document
-
-       <LI><CODE>PPD_ORDER_PROLOG</CODE> - The option must be output in the
-       Prolog section of the document
-
-</UL>
-
-<H3>PPD Colorspaces</H3>
-
-<P>Each printer has a default colorspace:
-
-<UL>
-
-       <LI><CODE>PPD_CS_CMYK</CODE> - The printer uses CMYK colors by default
-
-       <LI><CODE>PPD_CS_CMY</CODE> - The printer uses CMY colors by default
-
-       <LI><CODE>PPD_CS_GRAY</CODE> - The printer uses grayscale by default
-
-       <LI><CODE>PPD_CS_RGB</CODE> - The printer uses RGB colors by default
-
-       <LI><CODE>PPD_CS_RGBK</CODE> - The printer uses RGBK colors by default
-
-       <LI><CODE>PPD_CS_N</CODE> - The printer uses a DeviceN colorspace
-       by default
-
-</UL>
-
-<H2>Raster Constants</H2>
-
-<H3>Raster Sync Words</H3>
-
-<P>The <CODE>CUPS_RASTER_SYNC</CODE> and <CODE>CUPS_RASTER_REVSYNC</CODE>
-constants define the standard sync words at the beginning of each CUPS
-raster file.
-
-<H3>Raster Stream Modes</H3>
-
-<P>The <CODE>CUPS_RASTER_READ</CODE> and <CODE>CUPS_RASTER_WRITE</CODE>
-constants are used with the
-<A HREF="#cupsRasterOpen"><CODE>cupsRasterOpen()</CODE></A> function to
-specify a stream for reading or writing.
-
-<H3>Raster Boolean Constants</H3>
-
-<P>The <CODE>CUPS_FALSE</CODE> and <CODE>CUPS_TRUE</CODE> constants
-represent boolean values in the page header.
-
-<H3>Raster Jog Values</H3>
-
-<P>The <CODE>cups_jog_t</CODE> enumeration defines constants for the
-Jog page device dictionary variable:
-
-<UL>
-
-       <LI><CODE>CUPS_JOG_NONE</CODE> - Do no jogging
-
-       <LI><CODE>CUPS_JOG_FILE</CODE> - Jog pages after each file
-
-       <LI><CODE>CUPS_JOG_JOB</CODE> - Jog pages after each job
-
-       <LI><CODE>CUPS_JOG_SET</CODE> - Jog pages after each set of jobs
-
-</UL>
-
-<H3>Raster Orientation Values</H3>
-
-<P>The <CODE>cups_orient_t</CODE> enumeration defines constants for the
-Orientation page device dictionary variable:
-
-<UL>
-
-       <LI><CODE>CUPS_ORIENT_0</CODE> - Portrait orientation
-
-       <LI><CODE>CUPS_ORIENT_90</CODE> - Landscape orientation
-
-       <LI><CODE>CUPS_ORIENT_180</CODE> - Reverse-portrait orientation
-
-       <LI><CODE>CUPS_ORIENT_270</CODE> - Reverse-landscape orientation
-
-</UL>
-
-<H3>Raster CutMedia Values</H3>
-
-<P>The <CODE>cups_cut_t</CODE> enumeration defines constants for the
-CutMedia page device dictionary variable:
-
-<UL>
-
-       <LI><CODE>CUPS_CUT_NONE</CODE> - Do no jogging
-
-       <LI><CODE>CUPS_CUT_FILE</CODE> - Cut pages after each file
-
-       <LI><CODE>CUPS_CUT_JOB</CODE> - Cut pages after each job
-
-       <LI><CODE>CUPS_CUT_SET</CODE> - Cut pages after each set of jobs
-
-       <LI><CODE>CUPS_CUT_PAGE</CODE> - Cut each page
-
-</UL>
-
-<H3>Raster AdvanceMedia Values</H3>
-
-<P>The <CODE>cups_advance_t</CODE> enumeration defines constants for the
-AdvanceMedia page device dictionary variable:
-
-<UL>
-
-       <LI><CODE>CUPS_ADVANCE_NONE</CODE> - Do no jogging
-
-       <LI><CODE>CUPS_ADVANCE_FILE</CODE> - Advance media after each file
-
-       <LI><CODE>CUPS_ADVANCE_JOB</CODE> - Advance media after each job
-
-       <LI><CODE>CUPS_ADVANCE_SET</CODE> - Advance media after each set of jobs
-
-       <LI><CODE>CUPS_ADVANCE_PAGE</CODE> - Advance media for each page
-
-</UL>
-
-<H3>Raster LeadingEdge Values</H3>
-
-<P>The <CODE>cups_edge_t</CODE> enumeration defines constants for the
-LeadingEdge page device dictionary variable:
-
-<UL>
-
-       <LI><CODE>CUPS_EDGE_TOP</CODE> - The top of the media is the leading
-       edge
-
-       <LI><CODE>CUPS_EDGE_RIGHT</CODE> - The right of the media is the leading
-       edge
-
-       <LI><CODE>CUPS_EDGE_BOTTOM</CODE> - The bottom of the media is the
-       leading edge
-
-       <LI><CODE>CUPS_EDGE_LEFT</CODE> - The left of the media is the leading
-       edge
-
-</UL>
-
-<H3>Raster Color Order Values</H3>
-
-<P>The <CODE>cups_order_t</CODE> enumeration defines the possible color
-value orderings:
-
-<UL>
-
-       <LI><CODE>CUPS_ORDER_CHUNKED</CODE> - CMYK&nbsp;CMYK&nbsp;CMYK
-
-       <LI><CODE>CUPS_ORDER_BANDED</CODE> - CCC&nbsp;MMM&nbsp;YYY&nbsp;KKK
-
-       <LI><CODE>CUPS_ORDER_PLANAR</CODE> - CCC&nbsp;...&nbsp;MMM&nbsp;...&nbsp;YYY&nbsp;...&nbsp;KKK&nbsp;...
-
-</UL>
-
-<H3>Raster Colorspace Values</H3>
-
-<P>The <CODE>cups_cspace_t</CODE> enumeration defines the possible colorspaces:
-
-<UL>
-
-       <LI><CODE>CUPS_CSPACE_W</CODE> - White (luminance)
-
-       <LI><CODE>CUPS_CSPACE_RGB</CODE> - Red, green, blue
-
-       <LI><CODE>CUPS_CSPACE_RGBA</CODE> - Red, green, blue, alpha
-
-       <LI><CODE>CUPS_CSPACE_K</CODE> - Black
-
-       <LI><CODE>CUPS_CSPACE_CMY</CODE> - Cyan, magenta, yellow
-
-       <LI><CODE>CUPS_CSPACE_YMC</CODE> - Yellow, magenta, cyan
-
-       <LI><CODE>CUPS_CSPACE_CMYK</CODE> - Cyan, magenta, yellow, black
-
-       <LI><CODE>CUPS_CSPACE_YMCK</CODE> - Yellow, magenta, cyan, black
-
-       <LI><CODE>CUPS_CSPACE_KCMY</CODE> - Black, cyan, magenta, yellow
-
-       <LI><CODE>CUPS_CSPACE_KCMYcm</CODE> - Black, cyan, magenta, yellow,
-       light cyan, light magenta
-
-       <LI><CODE>CUPS_CSPACE_GMCK</CODE> - Metallic yellow (gold), metallic magenta,
-       metallic cyan, black
-
-       <LI><CODE>CUPS_CSPACE_GMCS</CODE> - Metallic yellow (gold), metallic magenta,
-       metallic cyan, metallic grey (silver)
-
-       <LI><CODE>CUPS_CSPACE_WHITE</CODE> - White pigment (black as white pigment)
-
-       <LI><CODE>CUPS_CSPACE_GOLD</CODE> - Gold foil (black as gold foil)
-
-       <LI><CODE>CUPS_CSPACE_SILVER</CODE> - Silver foil (black as silver foil)
-
-</UL>
-
-<H1 ALIGN="RIGHT"><A NAME="STRUCTURES">C - Structures</A></H1>
-
-<P>This appendix describes all of the structures that are
-defined by the CUPS API.
-
-<H2>CUPS Structures</H2>
-
-<H3><A NAME="cups_dest_t">CUPS Destinations</A></H3>
-
-<P>The CUPS destination structure (<CODE>cups_dest_t</CODE>)
-contains information on a specific destination or instance:
-
-<CENTER><TABLE WIDTH="90%" BORDER="1">
-<TR>
-       <TH>Member</TH>
-       <TH>Type</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>char *</TD>
-       <TD>The name of the printer or class.</TD>
-</TR>
-<TR>
-       <TD>instance</TD>
-       <TD>char *</TD>
-       <TD>The instance of the printer or class; NULL for the primary
-       instance.</TD>
-</TR>
-<TR>
-       <TD>is_default</TD>
-       <TD>int</TD>
-       <TD>1 if the destination is set as the default, 0 otherwise.</TD>
-</TR>
-<TR>
-       <TD>num_options</TD>
-       <TD>int</TD>
-       <TD>The number of options associated with this destination.</TD>
-</TR>
-<TR>
-       <TD>options</TD>
-       <TD><A HREF="#cups_option_t">cups_option_t *</A></TD>
-       <TD>The options associated with this destination.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3><A NAME="cups_job_t">CUPS Jobs</A></H3>
-
-<P>The CUPS job structure (<CODE>cups_job_t</CODE>) contains
-information on a specific job:
-
-<CENTER><TABLE WIDTH="90%" BORDER="1">
-<TR>
-       <TH>Member</TH>
-       <TH>Type</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>id</TD>
-       <TD>int</TD>
-       <TD>The job ID for this job.</TD>
-</TR>
-<TR>
-       <TD>dest</TD>
-       <TD>char *</TD>
-       <TD>The destination for this job (printer or class name).</TD>
-</TR>
-<TR>
-       <TD>title</TD>
-       <TD>char *</TD>
-       <TD>The job-name for this job (title).</TD>
-</TR>
-<TR>
-       <TD>user</TD>
-       <TD>char *</TD>
-       <TD>The job-originating-user-name for this job (username).</TD>
-</TR>
-<TR>
-       <TD>format</TD>
-       <TD>char *</TD>
-       <TD>The document-format for this job (MIME type string).</TD>
-</TR>
-<TR>
-       <TD>state</TD>
-       <TD>ipp_jstate</TD>
-       <TD>The current state of the job.</TD>
-</TR>
-<TR>
-       <TD>size</TD>
-       <TD>int</TD>
-       <TD>The size of this job in kilobytes.</TD>
-</TR>
-<TR>
-       <TD>priority</TD>
-       <TD>int</TD>
-       <TD>The priority of this job from 1 to 100 (50 is normal).</TD>
-</TR>
-<TR>
-       <TD>completed_time</TD>
-       <TD>time_t</TD>
-       <TD>The time the job was completed, or 0 if not yet completed.</TD>
-</TR>
-<TR>
-       <TD>creation_time</TD>
-       <TD>time_t</TD>
-       <TD>The time the job was queued.</TD>
-</TR>
-<TR>
-       <TD>processing_time</TD>
-       <TD>time_t</TD>
-       <TD>The time the job started printing.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3><A NAME="cups_lang_t">CUPS Messages</A></H3>
-
-<P>The CUPS messages structure (<CODE>cups_lang_t</CODE>)
-contains the character set, locale name, and messages array:
-
-<CENTER><TABLE WIDTH="90%" BORDER="1">
-<TR>
-       <TH>Member</TH>
-       <TH>Type</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>next</TD>
-       <TD>cups_lang_t *</TD>
-       <TD>Pointer to the next messages structure in memory.</TD>
-</TR>
-<TR>
-       <TD>used</TD>
-       <TD>int</TD>
-       <TD>The number of active users of this messages structure.</TD>
-</TR>
-<TR>
-       <TD>encoding</TD>
-       <TD>cups_encoding_t</TD>
-       <TD>The character encoding of the message strings.</TD>
-</TR>
-<TR>
-       <TD>language</TD>
-       <TD>char [16]</TD>
-       <TD>The language/locale name.</TD>
-</TR>
-<TR>
-       <TD>messages</TD>
-       <TD>char *[]</TD>
-       <TD>The array of message strings.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3><A NAME="cups_option_t">CUPS Options</A></H3>
-
-<P>The CUPS option structure (<CODE>cups_option_t</CODE>)
-contains the option name and string value:
-
-<CENTER><TABLE WIDTH="90%" BORDER="1">
-<TR>
-       <TH>Member</TH>
-       <TH>Type</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>char *</TD>
-       <TD>The name of the option.</TD>
-</TR>
-<TR>
-       <TD>value</TD>
-       <TD>char *</TD>
-       <TD>The string value of the option.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H2>Networking Structures</H2>
-
-<H3><A NAME="http_t">HTTP State</A></H3>
-
-<P>The HTTP state structure (<CODE>http_t</CODE>) contains the
-current state of a HTTP request or response:
-
-<CENTER><TABLE WIDTH="90%" BORDER="1">
-<TR>
-       <TH>Member</TH>
-       <TH>Type</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>fd</TD>
-       <TD>int</TD>
-       <TD>The socket for the HTTP connection.</TD>
-</TR>
-<TR>
-       <TD>blocking</TD>
-       <TD>int</TD>
-       <TD>1 if the HTTP functions should block, 0 if not.</TD>
-</TR>
-<TR>
-       <TD>error</TD>
-       <TD>int</TD>
-       <TD>The last OS error that occurred on the socket.</TD>
-</TR>
-<TR>
-       <TD>activity</TD>
-       <TD>time_t</TD>
-       <TD>The last time the HTTP connection was used.</TD>
-</TR>
-<TR>
-       <TD>state</TD>
-       <TD>http_state_t</TD>
-       <TD>The current HTTP request/response state.</TD>
-</TR>
-<TR>
-       <TD>status</TD>
-       <TD>int</TD>
-       <TD>The last HTTP status seen.</TD>
-</TR>
-<TR>
-       <TD>version</TD>
-       <TD>http_version_t</TD>
-       <TD>The HTTP protocol version in use.</TD>
-</TR>
-<TR>
-       <TD>keep_alive</TD>
-       <TD>http_keep_alive_t</TD>
-       <TD>Whether or not to use Keep-Alive</TD>
-</TR>
-<TR>
-       <TD>hostaddr</TD>
-       <TD>struct sockaddr_in</TD>
-       <TD>The IPv4 address of the HTTP server.</TD>
-</TR>
-<TR>
-       <TD>hostname</TD>
-       <TD>char []</TD>
-       <TD>The hostname of the HTTP server.</TD>
-</TR>
-<TR>
-       <TD>fields</TD>
-       <TD>char [][]</TD>
-       <TD>The string values of all HTTP request/response
-       fields.</TD>
-</TR>
-<TR>
-       <TD>data</TD>
-       <TD>char *</TD>
-       <TD>Current byte in data buffer.</TD>
-</TR>
-<TR>
-       <TD>data_encoding</TD>
-       <TD>http_encoding_t</TD>
-       <TD>The transfer encoding for the request/response.</TD>
-</TR>
-<TR>
-       <TD>data_remaining</TD>
-       <TD>int</TD>
-       <TD>The number of bytes remaining in the current request,
-       response, or chunk.</TD>
-</TR>
-<TR>
-       <TD>used</TD>
-       <TD>int</TD>
-       <TD>The number of bytes that are used in the buffer.</TD>
-</TR>
-<TR>
-       <TD>buffer</TD>
-       <TD>char []</TD>
-       <TD>The read/write buffer.</TD>
-</TR>
-<TR>
-       <TD>auth_type</TD>
-       <TD>int</TD>
-       <TD>The type of authentication in use.</TD>
-</TR>
-<TR>
-       <TD>md5_state</TD>
-       <TD>md5_state_t</TD>
-       <TD>The current MD5 digest state.</TD>
-</TR>
-<TR>
-       <TD>nonce</TD>
-       <TD>char []</TD>
-       <TD>The nonce value for Digest authentication.</TD>
-</TR>
-<TR>
-       <TD>nonce_count</TD>
-       <TD>int</TD>
-       <TD>The nonce count value.</TD>
-</TR>
-<TR>
-       <TD>tls</TD>
-       <TD>void *</TD>
-       <TD>A pointer to private encryption data.</TD>
-</TR>
-<TR>
-       <TD>encryption</TD>
-       <TD>http_encryption_t</TD>
-       <TD>The current encryption mode.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3><A NAME="ipp_t">IPP State</A></H3>
-
-<P>The IPP state structure (<CODE>ipp_t</CODE>) contains the
-current state of a IPP request or response:
-
-<CENTER><TABLE WIDTH="90%" BORDER="1">
-<TR>
-       <TH>Member</TH>
-       <TH>Type</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD></TD>
-       <TD></TD>
-       <TD></TD>
-</TR>
-</TABLE></CENTER>
-
-<H2>Raster Structures</H2>
-
-<H3><A NAME="cups_raster_header_t">Raster Page Header</A></H3>
-
-<P>The raster page header (<CODE>cups_raster_header_t</CODE>)
-consists of the PostScript page device dictionary for the page:
-
-<CENTER><TABLE WIDTH="90%" BORDER="1">
-<TR>
-       <TH>Member</TH>
-       <TH>Type</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>MediaClass</TD>
-       <TD>char[64]</TD>
-       <TD>The media class name</TD>
-</TR>
-<TR>
-       <TD>MediaColor</TD>
-       <TD>char[64]</TD>
-       <TD>The media color name</TD>
-</TR>
-<TR>
-       <TD>MediaType</TD>
-       <TD>char[64]</TD>
-       <TD>The media type name</TD>
-</TR>
-<TR>
-       <TD>OutputType</TD>
-       <TD>char[64]</TD>
-       <TD>The output type name</TD>
-</TR>
-<TR>
-       <TD>AdvanceDistance</TD>
-       <TD>unsigned</TD>
-       <TD>The distance to advance the media in points</TD>
-</TR>
-<TR>
-       <TD>AdvanceMedia</TD>
-       <TD>cups_adv_t</TD>
-       <TD>When to advance the media</TD>
-</TR>
-<TR>
-       <TD>Collate</TD>
-       <TD>cups_bool_t</TD>
-       <TD>Whether or not to produce collated copies</TD>
-</TR>
-<TR>
-       <TD>CutMedia</TD>
-       <TD>cups_cut_t</TD>
-       <TD>When to cut the media</TD>
-</TR>
-<TR>
-       <TD>Duplex</TD>
-       <TD>cups_bool_t</TD>
-       <TD>Whether or not to print on both sides of the paper</TD>
-</TR>
-<TR>
-       <TD>HWResolution</TD>
-       <TD>unsigned[2]</TD>
-       <TD>The resolution of the page image in pixels per inch; the
-       HWResolution[0] represents the horizontal resolution and
-       HWResolution[1] represents the vertical resolution</TD>
-</TR>
-<TR>
-       <TD>ImagingBoundingBox</TD>
-       <TD>unsigned[4]</TD>
-       <TD>The bounding box for the page in points; the elements
-       represent the left, bottom, right, and top coordinates of the
-       imaged area (if 0 then the whole page is imaged)</TD>
-</TR>
-<TR>
-       <TD>InsertSheet</TD>
-       <TD>cups_bool_t</TD>
-       <TD>Whether or not to insert a sheet before this page</TD>
-</TR>
-<TR>
-       <TD>Jog</TD>
-       <TD>cups_jog_t</TD>
-       <TD>When to jog copies of the page</TD>
-</TR>
-<TR>
-       <TD>LeadingEdge</TD>
-       <TD>cups_edge_t</TD>
-       <TD>The leading edge of the page</TD>
-</TR>
-<TR>
-       <TD>Margins</TD>
-       <TD>unsigned[2]</TD>
-       <TD>The lower-lefthand margin of the page in points</TD>
-</TR>
-<TR>
-       <TD>ManualFeed</TD>
-       <TD>cups_bool_t</TD>
-       <TD>Whether or not to manually feed the page</TD>
-</TR>
-<TR>
-       <TD>MediaPosition</TD>
-       <TD>unsigned</TD>
-       <TD>The input slot number to use</TD>
-</TR>
-<TR>
-       <TD>MediaWeight</TD>
-       <TD>unsigned</TD>
-       <TD>The weight of the output media in grams/m<SUP>2</SUP></TD>
-</TR>
-<TR>
-       <TD>MirrorPrint</TD>
-       <TD>cups_bool_t</TD>
-       <TD>Whether or not to mirror the print</TD>
-</TR>
-<TR>
-       <TD>NegativePrint</TD>
-       <TD>cups_bool_t</TD>
-       <TD>Whether or not to invert the print</TD>
-</TR>
-<TR>
-       <TD>NumCopies</TD>
-       <TD>unsigned</TD>
-       <TD>The number of copies to produce</TD>
-</TR>
-<TR>
-       <TD>Orientation</TD>
-       <TD>cups_orient_t</TD>
-       <TD>The orientation of the page image</TD>
-</TR>
-<TR>
-       <TD>OutputFaceUp</TD>
-       <TD>cups_bool_t</TD>
-       <TD>Whether or not to output the page face up</TD>
-</TR>
-<TR>
-       <TD>PageSize</TD>
-       <TD>unsigned[2]</TD>
-       <TD>The width and height of the page in points</TD>
-</TR>
-<TR>
-       <TD>Separations</TD>
-       <TD>cups_bool_t</TD>
-       <TD>Whether or not to output separations</TD>
-</TR>
-<TR>
-       <TD>TraySwitch</TD>
-       <TD>cups_bool_t</TD>
-       <TD>Whether or not to automatically switch trays for the requested
-       media size/type</TD>
-</TR>
-<TR>
-       <TD>Tumble</TD>
-       <TD>cups_bool_t</TD>
-       <TD>Whether or not to rotate the back side of the page</TD>
-</TR>
-<TR>
-       <TD>cupsWidth</TD>
-       <TD>unsigned</TD>
-       <TD>The width of the page image in pixels</TD>
-</TR>
-<TR>
-       <TD>cupsHeight</TD>
-       <TD>unsigned</TD>
-       <TD>The height of the page image in pixels</TD>
-</TR>
-<TR>
-       <TD>cupsMediaType</TD>
-       <TD>unsigned</TD>
-       <TD>The device-specific media type code</TD>
-</TR>
-<TR>
-       <TD>cupsBitsPerColor</TD>
-       <TD>unsigned</TD>
-       <TD>The number of bits per color</TD>
-</TR>
-<TR>
-       <TD>cupsBitsPerPixel</TD>
-       <TD>unsigned</TD>
-       <TD>The number of bits per pixel</TD>
-</TR>
-<TR>
-       <TD>cupsBytesPerLine</TD>
-       <TD>unsigned</TD>
-       <TD>The number of bytes per line of image data</TD>
-</TR>
-<TR>
-       <TD>cupsColorOrder</TD>
-       <TD>cups_order_t</TD>
-       <TD>The order of color values</TD>
-</TR>
-<TR>
-       <TD>cupsColorSpace</TD>
-       <TD>cups_cspace_t</TD>
-       <TD>The type of color values</TD>
-</TR>
-<TR>
-       <TD>cupsCompression</TD>
-       <TD>unsigned</TD>
-       <TD>The device-specific compression code</TD>
-</TR>
-<TR>
-       <TD>cupsRowCount</TD>
-       <TD>unsigned</TD>
-       <TD>The device-specific row count</TD>
-</TR>
-<TR>
-       <TD>cupsRowFeed</TD>
-       <TD>unsigned</TD>
-       <TD>The device-specific row feed</TD>
-</TR>
-<TR>
-       <TD>cupsRowStep</TD>
-       <TD>unsigned</TD>
-       <TD>The device-specific row step</TD>
-</TR>
-</TABLE></CENTER>
-
-<H1 ALIGN="RIGHT"><A NAME="FUNCTIONS">D - Functions</A></H1>
-
-<P>This appendix provides a reference for all of the CUPS API functions.
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsAddDest">cupsAddDest()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-cupsAddDest(const char  *name,
-            const char  *instance,
-            int         num_dests,
-           cups_dest_t **dests);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of the destination.</TD>
-</TR>
-<TR>
-       <TD>instance</TD>
-       <TD>The instance of the destination, or NULL for the primary instance.</TD>
-</TR>
-<TR>
-       <TD>num_dests</TD>
-       <TD>The number of destinations in the array.</TD>
-</TR>
-<TR>
-       <TD>dest</TD>
-       <TD>A pointer to the destination array pointer.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The new number of destinations in the array.
-
-<H3>Description</H3>
-
-<P><CODE>cupsAddDest()</CODE> adds the named destination to the destination
-array if it does not already exist.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-int         num_dests;
-<A HREF="#cups_dest_t">cups_dest_t</A> *dests;
-
-
-num_dests = cupsAddDests("foo", "bar", num_dests, &amp;dests);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsFreeDests"><CODE>cupsFreeDests()</CODE></A>,
-<A HREF="#cupsGetDest"><CODE>cupsGetDest()</CODE></A>,
-<A HREF="#cupsGetDests"><CODE>cupsGetDests()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsAddOption">cupsAddOption()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-cupsAddOption(const char    *name,
-              const char    *value,
-              int           num_options,
-             cups_option_t **options);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of the option.</TD>
-</TR>
-<TR>
-       <TD>value</TD>
-       <TD>The value of the option.</TD>
-</TR>
-<TR>
-       <TD>num_options</TD>
-       <TD>Number of options currently in the array.</TD>
-</TR>
-<TR>
-       <TD>options</TD>
-       <TD>Pointer to the options array.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The new number of options.
-
-<H3>Description</H3>
-
-<P><CODE>cupsAddOption()</CODE> adds an option to the specified array.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups.h&gt;
-
-...
-
-/* Declare the options array */
-int           num_options;
-<A HREF="#cups_option_t">cups_option_t</A> *options;
-
-/* Initialize the options array */
-num_options = 0;
-options     = (cups_option_t *)0;
-
-/* Add options using cupsAddOption() */
-num_options = cupsAddOption("media", "letter", num_options, &amp;options);
-num_options = cupsAddOption("resolution", "300dpi", num_options, &amp;options);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#cupsEncodeOptions"><CODE>cupsEncodeOptions()</CODE></A>,
-<A HREF="#cupsFreeOptions"><CODE>cupsFreeOptions()</CODE></A>,
-<A HREF="#cupsGetOption"><CODE>cupsGetOption()</CODE></A>,
-<A HREF="#cupsParseOptions"><CODE>cupsParseOptions()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsCancelJob">cupsCancelJob()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-cupsCancelJob(const char *dest,
-              int        job);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>dest</TD>
-       <TD>Printer or class name</TD>
-</TR>
-<TR>
-       <TD>job</TD>
-       <TD>Job ID</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>1 on success, 0 on failure. On failure the error can be found by calling
-<A HREF="#cupsLastError"><CODE>cupsLastError()</CODE></A>.
-
-<H3>Description</H3>
-
-<P><CODE>cupsCancelJob()</CODE> cancels the specifies job.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups.h&gt;
-
-cupsCancelJob("LaserJet", 1);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsLastError"><CODE>cupsLastError()</CODE></A>,
-<A HREF="#cupsPrintFile"><CODE>cupsPrintFile()</CODE></A>,
-<A HREF="#cupsPrintFiles"><CODE>cupsPrintFiles()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsDoFileRequest">cupsDoFileRequest()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_t *
-cupsDoFileRequest(http_t     *http,
-                  ipp_t      *request,
-                  const char *resource,
-                 const char *filename);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>HTTP connection to server.</TD>
-</TR>
-<TR>
-       <TD>request</TD>
-       <TD>IPP request data.</TD>
-</TR>
-<TR>
-       <TD>resource</TD>
-       <TD>HTTP resource name for POST.</TD>
-</TR>
-<TR>
-       <TD>filename</TD>
-       <TD>File to send with POST request (<CODE>NULL</CODE> pointer if none.)</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>IPP response data or <CODE>NULL</CODE> if the request fails. On failure
-the error can be found by calling
-<A HREF="#cupsLastError"><CODE>cupsLastError()</CODE></A>.
-
-<H3>Description</H3>
-
-<P><CODE>cupsDoFileRequest()</CODE> does a HTTP POST request and provides the
-IPP request and optionally the contents of a file to the IPP server. It also
-handles resubmitting the request and performing password authentication as
-needed.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups.h&gt;
-
-<A HREF="#http_t">http_t</A>      *http;
-<A HREF="#cups_lang_t">cups_lang_t</A> *language;
-<A HREF="#ipp_t">ipp_t</A>       *request;
-ipp_t       *response;
-
-...
-
-/* Get the default language */
-language = <A HREF="#cupsLangDefault">cupsLangDefault()</A>;
-
-/* Create a new IPP request */
-request  = <A HREF="#ippNew">ippNew()</A>;
-
-request-&gt;request.op.operation_id = IPP_PRINT_FILE;
-request-&gt;request.op.request_id   = 1;
-
-/* Add required attributes */
-<A HREF="#ippAddString">ippAddString</A>(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-             "attributes-charset", NULL, <A HREF="#cupsLangEncoding">cupsLangEncoding</A>(language));
-
-ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
-             "attributes-natural-language", NULL,
-             language != NULL ? language-&gt;language : "C");
-
-ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
-             NULL, "ipp://hostname/resource");
-
-ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
-             NULL, <A HREF="#cupsUser">cupsUser()</A>);
-
-/* Do the request... */
-response = cupsDoFileRequest(http, request, "/resource", "filename.txt");
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsLangDefault"><CODE>cupsLangDefault()</CODE></A>,
-<A HREF="#cupsLangEncoding"><CODE>cupsLangEncoding()</CODE></A>,
-<A HREF="#cupsUser"><CODE>cupsUser()</CODE></A>,
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
-<A HREF="#ippNew"><CODE>ippNew()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsDoRequest">cupsDoRequest()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_t *
-cupsDoRequest(http_t *http,
-              ipp_t *request,
-              const char *resource);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>HTTP connection to server.</TD>
-</TR>
-<TR>
-       <TD>request</TD>
-       <TD>IPP request data.</TD>
-</TR>
-<TR>
-       <TD>resource</TD>
-       <TD>HTTP resource name for POST.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>IPP response data or <CODE>NULL</CODE> if the request fails. On failure
-the error can be found by calling
-<A HREF="#cupsLastError"><CODE>cupsLastError()</CODE></A>.
-
-<H3>Description</H3>
-
-<P><CODE>cupsDoRequest()</CODE> does a HTTP POST request and provides
-the IPP request to the IPP server. It also handles resubmitting the
-request and performing password authentication as needed.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups.h&gt;
-
-<A HREF="#http_t">http_t</A>      *http;
-<A HREF="#cups_lang_t">cups_lang_t</A> *language;
-<A HREF="#ipp_t">ipp_t</A>       *request;
-ipp_t       *response;
-
-...
-
-/* Get the default language */
-language = <A HREF="#cupsLangDefault">cupsLangDefault()</A>;
-
-/* Create a new IPP request */
-request  = <A HREF="#ippNew">ippNew()</A>;
-
-request-&gt;request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
-request-&gt;request.op.request_id   = 1;
-
-/* Add required attributes */
-<A HREF="#ippAddString">ippAddString</A>(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-             "attributes-charset", NULL, <A HREF="#cupsLangEncoding">cupsLangEncoding</A>(language));
-
-ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
-             "attributes-natural-language", NULL,
-             language != NULL ? language-&gt;language : "C");
-
-ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
-             NULL, "ipp://hostname/resource");
-
-/* Do the request... */
-response = cupsDoRequest(http, request, "/resource");
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsLangDefault"><CODE>cupsLangDefault()</CODE></A>,
-<A HREF="#cupsLangEncoding"><CODE>cupsLangEncoding()</CODE></A>,
-<A HREF="#cupsUser"><CODE>cupsUser()</CODE></A>,
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
-<A HREF="#ippNew"><CODE>ippNew()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsEncodeOptions">cupsEncodeOptions()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-cupsEncodeOptions(ipp_t         *ipp,
-                  int           num_options,
-                 cups_option_t *options);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request.</TD>
-</TR>
-<TR>
-       <TD>num_options</TD>
-       <TD>The number of options.</TD>
-</TR>
-<TR>
-       <TD>options</TD>
-       <TD>The options.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P><CODE>cupsEncodeOptions()</CODE> encodes all of the options
-in the specified array as IPP attributes and adds them to the
-IPP request.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-<A HREF="#ipp_t">ipp_t</A>         *ipp;
-int           num_options;
-<A HREF="#cups_option_t">cups_option_t</A> *options;
-
-
-cupsEncodeOptions(ipp, num_options, options);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsAddOption"><CODE>cupsAddOption()</CODE></A>,
-<A HREF="#cupsParseOptions"><CODE>cupsParseOptions()</CODE></A>,
-<A HREF="#ippNew"><CODE>ippNew()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsEncryption">cupsEncryption()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-http_encryption_t
-cupsEncryption(void);
-</PRE>
-
-<H3>Returns</H3>
-
-<P>The current encryption setting.
-
-<H3>Description</H3>
-
-<P><CODE>cupsEncryption()</CODE> returns the current encryption setting
-for IPP requests such as printing.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-<A HREF="#http_t">http_t</A> *http;
-
-printf("The current encryption setting is %d.\n", cupsEncryption());
-
-http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsServer"><CODE>cupsServer()</CODE></A>,
-<A HREF="#httpConnectEncrypt"><CODE>httpConnectEncrypt()</CODE></A>,
-<A HREF="#ippPort"><CODE>ippPort()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsFreeDests">cupsFreeDests()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-cupsFreeDests(int         num_dests,
-              cups_dest_t *dests);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>num_dests</TD>
-       <TD>The number of destinations in the array.</TD>
-</TR>
-<TR>
-       <TD>dests</TD>
-       <TD>The destination array.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P><CODE>cupsFreeDests()</CODE> frees a destination array that was
-created using <CODE>cupsGetDests()</CODE>.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-int         num_dests;
-<A HREF="#cups_dest_t">cups_dest_t</A> *dests;
-cups_dest_t *dest;
-
-num_dests = cupsGetDests(&amp;dests);
-dest      = cupsGetDest(NULL, NULL, num_dests, dests);
-
-if (dest)
-  printf("The default destination is %s\n", dest->name);
-else
-  puts("No default destination.");
-
-cupsFreeDests(num_dests, dests);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsGetDest"><CODE>cupsGetDest()</CODE></A>,
-<A HREF="#cupsGetDests"><CODE>cupsGetDests()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsFreeJobs">cupsFreeJobs()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-cupsFreeJobs(int        num_jobs,
-             cups_job_t *jobs);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>num_jobs</TD>
-       <TD>The number of jobs.</TD>
-</TR>
-<TR>
-       <TD>jobs</TD>
-       <TD>The job array.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P><CODE>cupsFreeJobs()</CODE> frees an array of print jobs created by
-the <CODE>cupsGetJobs()</CODE> function.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-int        i;
-int        num_jobs;
-<A HREF="#cups_job_t">cups_job_t</A> *jobs;
-
-
-num_jobs = cupsGetJobs(&amp;jobs, NULL, 0, 0);
-
-printf("%d active job(s):\n", num_jobs);
-for (i = 0; i &lt; num_jobs; i ++)
-  printf("%-16.16s %-6d %-12.12s %s (%s)\n", jobs[i].dest, jobs[i].id,
-         jobs[i].user, jobs[i].title,
-        jobs[i].state != IPP_JOB_PENDING ? "printing" : "pending");
-
-cupsFreeJobs(num_jobs, jobs);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsGetJobs"><CODE>cupsGetJobs()</CODE></A>,
-<A HREF="#cupsGetDests"><CODE>cupsGetDests()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsFreeOptions">cupsFreeOptions()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-cupsFreeOptions(int           num_options,
-                cups_option_t *options);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>num_options</TD>
-       <TD>Number of options in array.</TD>
-</TR>
-<TR>
-       <TD>options</TD>
-       <TD>Pointer to options array.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P><CODE>cupsFreeOptions()</CODE> frees all memory associated with the
-option array specified.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-int           num_options;
-<A HREF="#cups_option_t">cups_option_t</A> *options;
-
-...
-
-cupsFreeOptions(num_options, options);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsAddOption"><CODE>cupsAddOption()</CODE></A>,
-<A HREF="#cupsEncodeOptions"><CODE>cupsEncodeOptions()</CODE></A>,
-<A HREF="#cupsGetOption"><CODE>cupsGetOption()</CODE></A>,
-<A HREF="#cupsMarkOptions"><CODE>cupsMarkOptions()</CODE></A>,
-<A HREF="#cupsParseOptions"><CODE>cupsParseOptions()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsGetClasses">cupsGetClasses()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-cupsGetClasses(char ***classes);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>classes</TD>
-       <TD>Pointer to character pointer array.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The number of printer classes available.
-
-<H3>Description</H3>
-
-<P><CODE>cupsGetClasses()</CODE> gets a list of the available printer classes.
-The returned array should be freed using the <CODE>free()</CODE> when it is
-no longer needed.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-int  i;
-int  num_classes;
-char **classes;
-
-...
-
-num_classes = cupsGetClasses(&classes);
-
-...
-
-if (num_classes > 0)
-{
-  for (i = 0; i &lt; num_classes; i ++)
-    free(classes[i]);
-
-  free(classes);
-}
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsGetDefault"><CODE>cupsGetDefault()</CODE></A>,
-<A HREF="#cupsGetPrinters"><CODE>cupsGetPrinters()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsGetDefault">cupsGetDefault()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-const char *
-cupsGetDefault(void);
-</PRE>
-
-<H3>Returns</H3>
-
-<P>A pointer to the default destination.
-
-<H3>Description</H3>
-
-<P><CODE>cupsGetDefault()</CODE> gets the default destination printer or class.
-The default destination is stored in a static string and will be overwritten
-(usually with the same value) after each call.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-printf("The default destination is %s\n", cupsGetDefault());
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsGetClasses"><CODE>cupsGetClasses()</CODE></A>,
-<A HREF="#cupsGetPrinters"><CODE>cupsGetPrinters()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsGetDest">cupsGetDest()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-cups_dest_t *
-cupsGetDest(const char  *name,
-            const char  *instance,
-            int         num_dests,
-            cups_dest_t *dests);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of the destination, or NULL for the default destination.</TD>
-</TR>
-<TR>
-       <TD>instance</TD>
-       <TD>The instance of the destination, or NULL for the primary instance.</TD>
-</TR>
-<TR>
-       <TD>num_dests</TD>
-       <TD>The number of destinations.</TD>
-</TR>
-<TR>
-       <TD>dests</TD>
-       <TD>The destination array.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the specified destination, or NULL if none exists.
-
-<H3>Description</H3>
-
-<P><CODE>cupsGetDest()</CODE> finds the specified destination in the array
-of destinations created by the <CODE>cupsGetDests()</CODE> function.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-int         num_dests;
-<A HREF="#cups_dest_t">cups_dest_t</A> *dests;
-cups_dest_t *dest;
-
-num_dests = cupsGetDests(&amp;dests);
-dest      = cupsGetDest(NULL, NULL, num_dests, dests);
-
-if (dest)
-  printf("The default destination is %s\n", dest->name);
-else
-  puts("No default destination.");
-
-cupsFreeDests(num_dests, dests);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsGetDests"><CODE>cupsGetDests()</CODE></A>,
-<A HREF="#cupsGetJobs"><CODE>cupsGetJobs()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsGetDests">cupsGetDests()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-cupsGetDests(cups_dest_t **dests);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>dests</TD>
-       <TD>A pointer to a destination array pointer.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The number of available destinations.
-
-<H3>Description</H3>
-
-<P><CODE>cupsGetDests()</CODE> creates an array of available
-destinations that the user can print to. The array should be
-freed using the <CODE>cupsFreeDests()</CODE> function.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-int         num_dests;
-<A HREF="#cups_dest_t">cups_dest_t</A> *dests;
-cups_dest_t *dest;
-
-num_dests = cupsGetDests(&amp;dests);
-dest      = cupsGetDest(NULL, NULL, num_dests, dests);
-
-if (dest)
-  printf("The default destination is %s\n", dest->name);
-else
-  puts("No default destination.");
-
-cupsFreeDests(num_dests, dests);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsFreeDests"><CODE>cupsFreeDests()</CODE></A>,
-<A HREF="#cupsGetDest"><CODE>cupsGetDest()</CODE></A>,
-<A HREF="#cupsGetJobs"><CODE>cupsGetJobs()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsGetJobs">cupsGetJobs()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-cupsGetJobs(cups_job_t **jobs,
-            const char *dest,
-            int        myjobs,
-            int        completed);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>jobs</TD>
-       <TD>A pointer to the job array pointer.</TD>
-</TR>
-<TR>
-       <TD>dest</TD>
-       <TD>The destination name, or NULL if jobs for all destinations are requested.</TD>
-</TR>
-<TR>
-       <TD>myjobs</TD>
-       <TD>1 if only those jobs submitted by the current
-       <CODE>cupsUser()</CODE> should be returned, 0 for jobs
-       submitted by all users.</TD>
-</TR>
-<TR>
-       <TD>completed</TD>
-       <TD>1 if only completed jobs should be returned, 0 if only
-       pending/processing jobs should be returned.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The number of jobs.
-
-<H3>Description</H3>
-
-<P><CODE>cupsGetJobs()</CODE> creates an array of print jobs based on the
-arguments supplied in the function call. The returned array should be freed
-using the <CODE>cupsFreeJobs()</CODE> function.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-int        i;
-int        num_jobs;
-<A HREF="#cups_job_t">cups_job_t</A> *jobs;
-
-
-num_jobs = cupsGetJobs(&amp;jobs, NULL, 0, 0);
-
-printf("%d active job(s):\n", num_jobs);
-for (i = 0; i &lt; num_jobs; i ++)
-  printf("%-16.16s %-6d %-12.12s %s (%s)\n", jobs[i].dest, jobs[i].id,
-         jobs[i].user, jobs[i].title,
-        jobs[i].state != IPP_JOB_PENDING ? "printing" : "pending");
-
-cupsFreeJobs(num_jobs, jobs);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsFreeJobs"><CODE>cupsFreeJobs()</CODE></A>,
-<A HREF="#cupsGetDests"><CODE>cupsGetDests()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsGetOption">cupsGetOption()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-const char *
-cupsGetOption(const char    *name,
-              int           num_options,
-              cups_option_t *options);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of the option.</TD>
-</TR>
-<TR>
-       <TD>num_options</TD>
-       <TD>The number of options in the array.</TD>
-</TR>
-<TR>
-       <TD>options</TD>
-       <TD>The options array.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the option values or <CODE>NULL</CODE> if the option is
-not defined.
-
-<H3>Description</H3>
-
-<P><CODE>cupsGetOption()</CODE> returns the first occurrence of the
-named option. If the option is not included in the options array then a
-<CODE>NULL</CODE> pointer is returned.
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-int           num_options;
-cups_option_t *options;
-const char    *media;
-
-...
-
-media = cupsGetOption("media", num_options, options);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsAddOption"><CODE>cupsAddOption()</CODE></A>,
-<A HREF="#cupsEncodeOptions"><CODE>cupsEncodeOptions()</CODE></A>,
-<A HREF="#cupsFreeOptions"><CODE>cupsFreeOptions()</CODE></A>,
-<A HREF="#cupsMarkOptions"><CODE>cupsMarkOptions()</CODE></A>,
-<A HREF="#cupsParseOptions"><CODE>cupsParseOptions()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsGetPassword">cupsGetPassword()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-const char *
-cupsGetPassword(const char *prompt);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>prompt</TD>
-       <TD>The prompt to display to the user.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the password that was entered or <CODE>NULL</CODE> if no
-password was entered.
-
-<H3>Description</H3>
-
-<P><CODE>cupsGetPassword()</CODE> displays the prompt string and asks the user
-for a password. The password text is not echoed to the user.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-char *password;
-
-...
-
-password = cupsGetPassword("Please enter a password:");
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsServer"><CODE>cupsServer()</CODE></A>,
-<A HREF="#cupsSetPasswordCB"><CODE>cupsSetPasswordCB()</CODE></A>,
-<A HREF="#cupsSetServer"><CODE>cupsSetServer()</CODE></A>,
-<A HREF="#cupsSetUser"><CODE>cupsSetUser()</CODE></A>,
-<A HREF="#cupsUser"><CODE>cupsUser()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsGetPPD">cupsGetPPD()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-const char *
-cupsGetPPD(const char *printer);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>printer</TD>
-       <TD>The name of the printer.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The name of a temporary file containing the PPD file or <CODE>NULL</CODE>
-if the printer cannot be located or does not have a PPD file.
-
-<H3>Description</H3>
-
-<P><CODE>cupsGetPPD()</CODE> gets a copy of the PPD file for the named printer.
-The printer name can be of the form "printer" or "printer@hostname".
-
-<P>You should remove (unlink) the PPD file after you are done using it. The
-filename is stored in a static buffer and will be overwritten with each call
-to <CODE>cupsGetPPD()</CODE>.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-char *ppd;
-
-...
-
-ppd = cupsGetPPD("printer@hostname");
-
-...
-
-unlink(ppd);
-</PRE>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsGetPrinters">cupsGetPrinters()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-cupsGetPrinters(char ***printers);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>printers</TD>
-       <TD>Pointer to character pointer array.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The number of printer printers available.
-
-<H3>Description</H3>
-
-<P><CODE>cupsGetPrinters()</CODE> gets a list of the available printers.
-The returned array should be freed using the <CODE>free()</CODE> when it is
-no longer needed.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-int  i;
-int  num_printers;
-char **printers;
-
-...
-
-num_printers = cupsGetPrinters(&printers);
-
-...
-
-if (num_printers > 0)
-{
-  for (i = 0; i &lt; num_printers; i ++)
-    free(printers[i]);
-
-  free(printers);
-}
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsGetClasses"><CODE>cupsGetClasses()</CODE></A>
-<A HREF="#cupsGetDefault"><CODE>cupsGetDefault()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsLangDefault">cupsLangDefault()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-const char *
-cupsLangDefault(void);
-</PRE>
-
-<H3>Returns</H3>
-
-<P>A pointer to the default language structure.
-
-<H3>Description</H3>
-
-<P><CODE>cupsLangDefault()</CODE> returns a language structure for the default
-language. The default language is defined by the <CODE>LANG</CODE> environment
-variable. If the specified language cannot be located then the POSIX (English)
-locale is used.
-
-<P>Call <CODE>cupsLangFree()</CODE> to free any memory associated with the
-language structure when you are done.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/language.h&gt;
-
-<A HREF="#cups_lang_t">cups_lang_t</A> *language;
-...
-
-language = cupsLangDefault();
-
-...
-
-cupsLangFree(language);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsLangEncoding"><CODE>cupsLangEncoding()</CODE></A>,
-<A HREF="#cupsLangFlush"><CODE>cupsLangFlush()</CODE></A>,
-<A HREF="#cupsLangFree"><CODE>cupsLangFree()</CODE></A>,
-<A HREF="#cupsLangGet"><CODE>cupsLangGet()</CODE></A>,
-<A HREF="#cupsLangString"><CODE>cupsLangString()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsLangEncoding">cupsLangEncoding()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-char *
-cupsLangEncoding(cups_lang_t *language);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>language</TD>
-       <TD>The language structure.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the encoding string.
-
-<H3>Description</H3>
-
-<P><CODE>cupsLangEncoding()</CODE> returns the language encoding used for the
-specified language, e.g. "iso-8859-1", "utf-8", etc.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/language.h&gt;
-
-<A HREF="#cups_lang_t">cups_lang_t</A> *language;
-char        *encoding;
-...
-
-language = cupsLangDefault();
-encoding = cupsLangEncoding(language);
-...
-
-cupsLangFree(language);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsLangDefault"><CODE>cupsLangDefault()</CODE></A>,
-<A HREF="#cupsLangFlush"><CODE>cupsLangFlush()</CODE></A>,
-<A HREF="#cupsLangFree"><CODE>cupsLangFree()</CODE></A>,
-<A HREF="#cupsLangGet"><CODE>cupsLangGet()</CODE></A>,
-<A HREF="#cupsLangString"><CODE>cupsLangString()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsLangFlush">cupsLangFlush()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-cupsLangFlush(void);
-</PRE>
-
-<H3>Description</H3>
-
-<P><CODE>cupsLangFlush()</CODE> frees all language structures that have been
-allocated.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/language.h&gt;
-
-...
-
-cupsLangFlush();
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsLangDefault"><CODE>cupsLangDefault()</CODE></A>,
-<A HREF="#cupsLangEncoding"><CODE>cupsLangEncoding()</CODE></A>,
-<A HREF="#cupsLangFree"><CODE>cupsLangFree()</CODE></A>,
-<A HREF="#cupsLangGet"><CODE>cupsLangGet()</CODE></A>,
-<A HREF="#cupsLangString"><CODE>cupsLangString()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsLangFree">cupsLangFree()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-cupsLangFree(cups_lang_t *language);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>language</TD>
-       <TD>The language structure to free.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P><CODE>cupsLangFree()</CODE> frees the specified language structure.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/language.h&gt;
-
-<A HREF="#cups_lang_t">cups_lang_t</A> *language;
-...
-
-cupsLangFree(language);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsLangDefault"><CODE>cupsLangDefault()</CODE></A>,
-<A HREF="#cupsLangEncoding"><CODE>cupsLangEncoding()</CODE></A>,
-<A HREF="#cupsLangFlush"><CODE>cupsLangFlush()</CODE></A>,
-<A HREF="#cupsLangGet"><CODE>cupsLangGet()</CODE></A>,
-<A HREF="#cupsLangString"><CODE>cupsLangString()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsLangGet">cupsLangGet()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-cups_lang_t *
-cupsLangGet(const char *name);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of the locale.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to a language structure.
-
-<H3>Description</H3>
-
-<P><CODE>cupsLangGet()</CODE> returns a language structure for the specified
-locale. If the locale is not defined then the POSIX (English) locale is
-substituted.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/language.h&gt;
-
-<A HREF="#cups_lang_t">cups_lang_t</A> *language;
-
-...
-
-language = cupsLangGet("fr");
-
-...
-
-cupsLangFree(language);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsLangDefault"><CODE>cupsLangDefault()</CODE></A>,
-<A HREF="#cupsLangEncoding"><CODE>cupsLangEncoding()</CODE></A>,
-<A HREF="#cupsLangFlush"><CODE>cupsLangFlush()</CODE></A>,
-<A HREF="#cupsLangFree"><CODE>cupsLangFree()</CODE></A>,
-<A HREF="#cupsLangString"><CODE>cupsLangString()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsLangString">cupsLangString()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-char *
-cupsLangString(cups_lang_t *language,
-               int         message);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>language</TD>
-       <TD>The language to query.</TD>
-</TR>
-<TR>
-       <TD>message</TD>
-       <TD>The message number.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the message string or <CODE>NULL</CODE> if the message is
-not defined.
-
-<H3>Description</H3>
-
-<P><CODE>cupsLangString()</CODE> returns a pointer to the specified message
-string in the specified language.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/language.h&gt;
-
-<A HREF="#cups_lang_t">cups_lang_t</A> *language;
-char        *s;
-...
-
-language = cupsLangGet("fr");
-
-s = cupsLangString(language, CUPS_MSG_YES);
-
-...
-
-cupsLangFree(language);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsLangDefault"><CODE>cupsLangDefault()</CODE></A>,
-<A HREF="#cupsLangEncoding"><CODE>cupsLangEncoding()</CODE></A>,
-<A HREF="#cupsLangFlush"><CODE>cupsLangFlush()</CODE></A>,
-<A HREF="#cupsLangFree"><CODE>cupsLangFree()</CODE></A>,
-<A HREF="#cupsLangGet"><CODE>cupsLangGet()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsLastError">cupsLastError()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_status_t
-cupsLastError(void);
-</PRE>
-
-<H3>Returns</H3>
-
-<P>An enumeration containing the last IPP error.
-
-<H3>Description</H3>
-
-<P><CODE>cupsLastError()</CODE> returns the last IPP error that occurred.
-If no error occurred then it will return <CODE>IPP_OK</CODE> or
-<CODE>IPP_OK_CONFLICT</CODE>.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-ipp_status_t status;
-
-...
-
-status = cupsLastError();
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsCancelJob"><CODE>cupsCancelJob()</CODE></A>,
-<A HREF="#cupsPrintFile"><CODE>cupsPrintFile()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsMarkOptions">cupsMarkOptions()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-cupsMarkOptions(ppd_file_t    *ppd,
-                int           num_options,
-                cups_option_t *options);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ppd</TD>
-       <TD>The PPD file to mark.</TD>
-</TR>
-<TR>
-       <TD>num_options</TD>
-       <TD>The number of options in the options array.</TD>
-</TR>
-<TR>
-       <TD>options</TD>
-       <TD>A pointer to the options array.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The number of conflicts found.
-
-<H3>Description</H3>
-
-<P><CODE>cupsMarkOptions()</CODE> marks options in the PPD file. It also
-handles mapping of IPP option names and values to PPD option names.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-int           num_options;
-<A HREF="#cups_option_t">cups_option_t</A> *options;
-<A HREF="#ppd_file_t">ppd_file_t</A>    *ppd;
-
-...
-
-cupsMarkOptions(ppd, num_options, options);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsAddOption"><CODE>cupsAddOption()</CODE></A>,
-<A HREF="#cupsFreeOptions"><CODE>cupsFreeOptions()</CODE></A>,
-<A HREF="#cupsGetOption"><CODE>cupsGetOption()</CODE></A>,
-<A HREF="#cupsParseOptions"><CODE>cupsParseOptions()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsParseOptions">cupsParseOptions()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-cupsParseOptions(const char    *arg,
-                 int           num_options,
-                 cups_option_t **options);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>arg</TD>
-       <TD>The string containing one or more options.</TD>
-</TR>
-<TR>
-       <TD>num_options</TD>
-       <TD>The number of options in the options array.</TD>
-</TR>
-<TR>
-       <TD>options</TD>
-       <TD>A pointer to the options array pointer.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The new number of options in the array.
-
-<H3>Description</H3>
-
-<P><CODE>cupsParseOptions()</CODE> parses the specifies string for one
-or more options of the form "name=value", "name", or "noname". It can
-be called multiple times to combine the options from several strings.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-int           num_options;
-<A HREF="#cups_options_t">cups_option_t</A> *options;
-
-...
-
-num_options = 0;
-options     = (cups_option_t *)0;
-num_options = cupsParseOptions(argv[5], num_options, &amp;options);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsAddOption"><CODE>cupsAddOption()</CODE></A>,
-<A HREF="#cupsFreeOptions"><CODE>cupsFreeOptions()</CODE></A>,
-<A HREF="#cupsGetOption"><CODE>cupsGetOption()</CODE></A>,
-<A HREF="#cupsMarkOptions"><CODE>cupsMarkOptions()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsPrintFile">cupsPrintFile()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-cupsPrintFile(const char    *printer,
-              const char    *filename,
-              const char    *title,
-             int           num_options,
-             cups_option_t *options);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>printer</TD>
-       <TD>The printer or class to print to.</TD>
-</TR>
-<TR>
-       <TD>filename</TD>
-       <TD>The file to print.</TD>
-</TR>
-<TR>
-       <TD>title</TD>
-       <TD>The job title.</TD>
-</TR>
-<TR>
-       <TD>num_options</TD>
-       <TD>The number of options in the options array.</TD>
-</TR>
-<TR>
-       <TD>options</TD>
-       <TD>A pointer to the options array.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The new job ID number or 0 on error.
-
-<H3>Description</H3>
-
-<P><CODE>cupsPrintFile()</CODE> sends a file to the specified printer or
-class for printing. If the job cannot be printed the error code can be
-found by calling <CODE>cupsLastError()</CODE>.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-int           num_options;
-<A HREF="#cups_option_t">cups_option_t</A> *options;
-int           jobid;
-
-...
-
-jobid = cupsPrintFile("printer@hostname", "filename.ps", "Job Title",
-                      num_options, options);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsCancelJob"><CODE>cupsCancelJob()</CODE></A>,
-<A HREF="#cupsLastError"><CODE>cupsLastError()</CODE></A>,
-<A HREF="#cupsPrintFiles"><CODE>cupsPrintFiles()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsPrintFiles">cupsPrintFiles()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-cupsPrintFiles(const char    *printer,
-               int           num_files,
-               const char    **files,
-               const char    *title,
-              int           num_options,
-              cups_option_t *options);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>printer</TD>
-       <TD>The printer or class to print to.</TD>
-</TR>
-<TR>
-       <TD>num_files</TD>
-       <TD>The number of files to print.</TD>
-</TR>
-<TR>
-       <TD>files</TD>
-       <TD>The files to print.</TD>
-</TR>
-<TR>
-       <TD>title</TD>
-       <TD>The job title.</TD>
-</TR>
-<TR>
-       <TD>num_options</TD>
-       <TD>The number of options in the options array.</TD>
-</TR>
-<TR>
-       <TD>options</TD>
-       <TD>A pointer to the options array.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The new job ID number or 0 on error.
-
-<H3>Description</H3>
-
-<P><CODE>cupsPrintFiles()</CODE> sends multiple files to the specified
-printer or class for printing. If the job cannot be printed the error
-code can be found by calling <CODE>cupsLastError()</CODE>.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-int           num_files;
-const char    *files[100];
-int           num_options;
-<A HREF="#cups_option_t">cups_option_t</A> *options;
-int           jobid;
-
-...
-
-jobid = cupsPrintFiles("printer@hostname", num_files, files,
-                       "Job Title", num_options, options);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsCancelJob"><CODE>cupsCancelJob()</CODE></A>,
-<A HREF="#cupsLastError"><CODE>cupsLastError()</CODE></A>,
-<A HREF="#cupsPrintFile"><CODE>cupsPrintFile()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsRasterClose">cupsRasterClose()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-cupsRasterClose(cups_raster_t *ras);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ras</TD>
-       <TD>The raster stream to close.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P><CODE>cupsRasterClose()</CODE> closes the specified raster stream.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/raster.h&gt;
-
-<A HREF="#cups_raster_t">cups_raster_t</A> *ras;
-
-...
-
-cupsRasterClose(ras);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsRasterOpen"><CODE>cupsRasterOpen()</CODE></A>,
-<A HREF="#cupsRasterReadHeader"><CODE>cupsRasterReadHeader()</CODE></A>,
-<A HREF="#cupsRasterReadPixels"><CODE>cupsRasterReadPixels()</CODE></A>,
-<A HREF="#cupsRasterWriteHeader"><CODE>cupsRasterWriteHeader()</CODE></A>,
-<A HREF="#cupsRasterWritePixels"><CODE>cupsRasterWritePixels()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsRasterOpen">cupsRasterOpen()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-cups_raster_t *
-cupsRasterOpen(int         fd,
-               cups_mode_t mode);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>fd</TD>
-       <TD>The file descriptor to use.</TD>
-</TR>
-<TR>
-       <TD>mode</TD>
-       <TD>The mode to use; <CODE>CUPS_RASTER_READ</CODE> or
-       <CODE>CUPS_RASTER_WRITE</CODE>.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to a raster stream or <CODE>NULL</CODE> if there was an error.
-
-<H3>Description</H3>
-
-<P><CODE>cupsRasterOpen()</CODE> opens a raster stream for reading or writing.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/raster.h&gt;
-
-<A HREF="#cups_raster_t">cups_raster_t</A> *ras;
-
-...
-
-ras = cupsRasterOpen(0, CUPS_RASTER_READ);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsRasterClose"><CODE>cupsRasterClose()</CODE></A>,
-<A HREF="#cupsRasterReadHeader"><CODE>cupsRasterReadHeader()</CODE></A>,
-<A HREF="#cupsRasterReadPixels"><CODE>cupsRasterReadPixels()</CODE></A>,
-<A HREF="#cupsRasterWriteHeader"><CODE>cupsRasterWriteHeader()</CODE></A>,
-<A HREF="#cupsRasterWritePixels"><CODE>cupsRasterWritePixels()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsRasterReadHeader">cupsRasterReadHeader()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-unsigned
-cupsRasterReadHeader(cups_raster_t      *ras,
-                     cups_page_header_t *header);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ras</TD>
-       <TD>The raster stream to read from.</TD>
-</TR>
-<TR>
-       <TD>header</TD>
-       <TD>A pointer to a page header structure to read into.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>1 on success, 0 on EOF or error.
-
-<H3>Description</H3>
-
-<P><CODE>cupsRasterReadHeader()</CODE> reads a page header from the specified
-raster stream.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/raster.h&gt;
-
-int                  line;
-<A HREF="#cups_raster_t">cups_raster_t</A>        *ras;
-<A HREF="#cups_raster_header_t">cups_raster_header_t</A> header;
-unsigned char        pixels[8192];
-...
-
-while (cupsRasterReadHeader(ras, &amp;header))
-{
-  ...
-
-  for (line = 0; line &lt; header.cupsHeight; line ++)
-  {
-    cupsRasterReadPixels(ras, pixels, header.cupsBytesPerLine);
-
-    ...
-  }
-}
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsRasterClose"><CODE>cupsRasterClose()</CODE></A>,
-<A HREF="#cupsRasterOpen"><CODE>cupsRasterOpen()</CODE></A>,
-<A HREF="#cupsRasterReadPixels"><CODE>cupsRasterReadPixels()</CODE></A>,
-<A HREF="#cupsRasterWriteHeader"><CODE>cupsRasterWriteHeader()</CODE></A>,
-<A HREF="#cupsRasterWritePixels"><CODE>cupsRasterWritePixels()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsRasterReadPixels">cupsRasterReadPixels()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-unsigned
-cupsRasterReadPixels(cups_raster_t *ras,
-                     unsigned char *pixels,
-                    unsigned      length);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ras</TD>
-       <TD>The raster stream to read from.</TD>
-</TR>
-<TR>
-       <TD>pixels</TD>
-       <TD>The pointer to a pixel buffer.</TD>
-</TR>
-<TR>
-       <TD>length</TD>
-       <TD>The number of bytes of pixel data to read.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The number of bytes read or 0 on EOF or error.
-
-<H3>Description</H3>
-
-<P><CODE>cupsRasterReadPixels()</CODE> reads pixel data from the specified
-raster stream.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/raster.h&gt;
-
-int                  line;
-<A HREF="#cups_raster_t">cups_raster_t</A>        *ras;
-<A HREF="#cups_raster_header_t">cups_raster_header_t</A> header;
-unsigned char        pixels[8192];
-...
-
-while (cupsRasterReadHeader(ras, &amp;header))
-{
-  ...
-
-  for (line = 0; line &lt; header.cupsHeight; line ++)
-  {
-    cupsRasterReadPixels(ras, pixels, header.cupsBytesPerLine);
-
-    ...
-  }
-}
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsRasterClose"><CODE>cupsRasterClose()</CODE></A>,
-<A HREF="#cupsRasterOpen"><CODE>cupsRasterOpen()</CODE></A>,
-<A HREF="#cupsRasterReadHeader"><CODE>cupsRasterReadHeader()</CODE></A>,
-<A HREF="#cupsRasterWriteHeader"><CODE>cupsRasterWriteHeader()</CODE></A>,
-<A HREF="#cupsRasterWritePixels"><CODE>cupsRasterWritePixels()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsRasterWriteHeader">cupsRasterWriteHeader()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-unsigned
-cupsRasterWriteHeader(cups_raster_t      *ras,
-                      cups_page_header_t *header);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ras</TD>
-       <TD>The raster stream to write to.</TD>
-</TR>
-<TR>
-       <TD>header</TD>
-       <TD>A pointer to the page header to write.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>1 on success, 0 on error.
-
-<H3>Description</H3>
-
-<P><CODE>cupsRasterWriteHeader()</CODE> writes the specified page header to
-a raster stream.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/raster.h&gt;
-
-int                  line;
-<A HREF="#cups_raster_t">cups_raster_t</A>        *ras;
-<A HREF="#cups_raster_header_t">cups_raster_header_t</A> header;
-unsigned char        pixels[8192];
-...
-
-cupsRasterWriteHeader(ras, &amp;header);
-
-for (line = 0; line &lt; header.cupsHeight; line ++)
-{
-  ...
-
-  cupsRasterWritePixels(ras, pixels, header.cupsBytesPerLine);
-}
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsRasterClose"><CODE>cupsRasterClose()</CODE></A>,
-<A HREF="#cupsRasterOpen"><CODE>cupsRasterOpen()</CODE></A>,
-<A HREF="#cupsRasterReadHeader"><CODE>cupsRasterReadHeader()</CODE></A>,
-<A HREF="#cupsRasterReadPixels"><CODE>cupsRasterReadPixels()</CODE></A>,
-<A HREF="#cupsRasterWritePixels"><CODE>cupsRasterWritePixels()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsRasterWritePixels">cupsRasterWritePixels()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-unsigned
-cupsRasterWritePixels(cups_raster_t *ras,
-                      unsigned char *pixels,
-                     unsigned      length);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ras</TD>
-       <TD>The raster stream to write to.</TD>
-</TR>
-<TR>
-       <TD>pixels</TD>
-       <TD>The pixel data to write.</TD>
-</TR>
-<TR>
-       <TD>length</TD>
-       <TD>The number of bytes to write.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The number of bytes written.
-
-<H3>Description</H3>
-
-<P><CODE>cupsRasterWritePixels()</CODE> writes the specified pixel data to a
-raster stream.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/raster.h&gt;
-
-int                  line;
-<A HREF="#cups_raster_t">cups_raster_t</A>        *ras;
-<A HREF="#cups_raster_header_t">cups_raster_header_t</A> header;
-unsigned char        pixels[8192];
-...
-
-cupsRasterWriteHeader(ras, &amp;header);
-
-for (line = 0; line &lt; header.cupsHeight; line ++)
-{
-  ...
-
-  cupsRasterWritePixels(ras, pixels, header.cupsBytesPerLine);
-}
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsRasterClose"><CODE>cupsRasterClose()</CODE></A>,
-<A HREF="#cupsRasterOpen"><CODE>cupsRasterOpen()</CODE></A>,
-<A HREF="#cupsRasterReadHeader"><CODE>cupsRasterReadHeader()</CODE></A>,
-<A HREF="#cupsRasterReadPixels"><CODE>cupsRasterReadPixels()</CODE></A>,
-<A HREF="#cupsRasterWriteHeader"><CODE>cupsRasterWriteHeader()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsServer">cupsServer()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-const char *
-cupsServer(void);
-</PRE>
-
-<H3>Returns</H3>
-
-<P>A pointer to the default server name.
-
-<H3>Description</H3>
-
-<P><CODE>cupsServer()</CODE> returns a pointer to the default server name.
-The server name is stored in a static location and will be overwritten with
-every call to <CODE>cupsServer()</CODE>.
-
-<P>The default server is determined from the following locations:
-
-<OL>
-
-       <LI>The <CODE>CUPS_SERVER</CODE> environment variable,
-
-       <LI>The <CODE>ServerName</CODE> directive in the
-       <VAR>client.conf</VAR> file,
-
-       <LI>The default host, "localhost".
-
-</OL>
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-const char *server;
-
-server = cupsServer();
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsGetPassword"><CODE>cupsGetPassword()</CODE></A>,
-<A HREF="#cupsSetPasswordCB"><CODE>cupsSetPasswordCB()</CODE></A>,
-<A HREF="#cupsSetServer"><CODE>cupsSetServer()</CODE></A>,
-<A HREF="#cupsSetUser"><CODE>cupsSetUser()</CODE></A>,
-<A HREF="#cupsUser"><CODE>cupsUser()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsSetDests">cupsSetDests()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-cupsSetDests(int         num_dests,
-             cups_dest_t *dests);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>num_dests</TD>
-       <TD>Number of destinations.</TD>
-</TR>
-<TR>
-       <TD>dests</TD>
-       <TD>Array of destinations.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P><CODE>cupsSetDests()</CODE> saves the destination array to
-disk. If the current UID is 0, the destinations are saved in the
-<VAR>/etc/cups/lpoptions</VAR> file, otherwise they are saved
-in the <VAR>~/.lpoptions</VAR> file. This function is typically used
-to save the default options and instances that are set by the user.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-int         num_dests;
-<A HREF="#cups_dest_t">cups_dest_t</A> *dests;
-
-...
-
-cupsSetDests(num_dests, dests);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsGetDests"><CODE>cupsGetDests()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsSetEncryption">cupsSetEncryption()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-cupsSetEncryption(http_encryption_t encryption);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>encryption</TD>
-       <TD>The type of encryption to use.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P><CODE>cupsSetEncryption()</CODE> sets the default type of encryption to
-use when connecting with the print server.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsEncryption"><CODE>cupsEncryption()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsSetPasswordCB">cupsSetPasswordCB()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-cupsSetPasswordCB(const char *(*cb)(const char *prompt));
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>cb</TD>
-       <TD>The password callback function.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P><CODE>cupsSetPasswordCB()</CODE> sets the callback function to use when
-asking the user for a password. The callback function must accept a single
-character string pointer (the prompt string) and return <CODE>NULL</CODE>
-if the user did not enter a password string or a pointer to the password
-string otherwise.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-const char *
-my_password_cb(const char *prompt)
-{
-  return (getpass(prompt));
-}
-
-...
-
-char *password;
-
-...
-
-cupsSetPasswordCB(my_password_cb);
-password = cupsGetPassword("Please enter a password:");
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsServer"><CODE>cupsServer()</CODE></A>,
-<A HREF="#cupsSetServer"><CODE>cupsSetServer()</CODE></A>,
-<A HREF="#cupsSetUser"><CODE>cupsSetUser()</CODE></A>,
-<A HREF="#cupsUser"><CODE>cupsUser()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsSetServer">cupsSetServer()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-cupsSetServer(const char *server);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>server</TD>
-       <TD>The default server to use.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P><CODE>cupsSetServer()</CODE> sets the default server to use for
-the CUPS API. If the <CODE>server</CODE> argument is <CODE>NULL</CODE>,
-the default server is used.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-cupsSetServer("foo.bar.com");
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsServer"><CODE>cupsServer()</CODE></A>,
-<A HREF="#cupsSetPasswordCB"><CODE>cupsSetPasswordCB()</CODE></A>,
-<A HREF="#cupsSetUser"><CODE>cupsSetUser()</CODE></A>,
-<A HREF="#cupsUser"><CODE>cupsUser()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsSetUser">cupsSetUser()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-cupsSetUser(const char *user);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>user</TD>
-       <TD>The user name string to use.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P><CODE>cupsSetUser()</CODE> sets the default user name for authentication.
-If the <CODE>user</CODE> argument is <CODE>NULL</CODE> then the current
-login user is used.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-...
-
-cupsSetUser("root");
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsServer"><CODE>cupsServer()</CODE></A>,
-<A HREF="#cupsSetPasswordCB"><CODE>cupsSetPasswordCB()</CODE></A>,
-<A HREF="#cupsSetServer"><CODE>cupsSetServer()</CODE></A>,
-<A HREF="#cupsUser"><CODE>cupsUser()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsTempFd">cupsTempFd()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-cupsTempFd(char *filename,
-           int  length);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>filename</TD>
-       <TD>The character string to hold the temporary filename.</TD>
-</TR>
-<TR>
-       <TD>length</TD>
-       <TD>The size of the filename string in bytes.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A file descriptor open for reading and writing.
-
-<H3>Description</H3>
-
-<P><CODE>cupsTempFd()</CODE> create a temporary filename in the
-<VAR>/var/tmp</VAR> directory or the directory specified by the
-<CODE>TMPDIR</CODE> environment variable.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-int  fd;
-char filename[256];
-
-fd = cupsTempFd(filename, sizeof(filename));
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsTempFile"><CODE>cupsTempFile()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsTempFile">cupsTempFile()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-char *
-cupsTempFile(char *filename,
-             int  length);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>filename</TD>
-       <TD>The character string to hold the temporary filename.</TD>
-</TR>
-<TR>
-       <TD>length</TD>
-       <TD>The size of the filename string in bytes.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to <CODE>filename</CODE>.
-
-<H3>Description</H3>
-
-<P><CODE>cupsTempFile()</CODE> creates a temporary filename in the
-<VAR>/var/tmp</VAR> directory or the directory specified by the
-<CODE>TMPDIR</CODE> environment variable.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-char filename[256];
-
-cupsTempFile(filename, sizeof(filename));
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsTempFd"><CODE>cupsTempFd()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="cupsUser">cupsUser()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-const char *
-cupsUser(void);
-</PRE>
-
-<H3>Returns</H3>
-
-<P>A pointer to the current username or <CODE>NULL</CODE> if the user ID is
-undefined.
-
-<H3>Description</H3>
-
-<P><CODE>cupsUser()</CODE> returns the name associated with the current
-user ID as reported by the <CODE>getuid()</CODE> system call.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/cups.h&gt;
-
-const char *user;
-
-user = cupsUser();
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsGetPassword"><CODE>cupsGetPassword()</CODE></A>,
-<A HREF="#cupsServer"><CODE>cupsServer()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpBlocking">httpBlocking()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-httpBlocking(http_t *http,
-             int    blocking)
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-<TR>
-       <TD>blocking</TD>
-       <TD>0 if the connection should be non-blocking, 1 if it should
-       be blocking</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P>The <CODE>httpBlocking()</CODE> function sets the blocking mode for the
-HTTP connection. By default HTTP connections will block (stop) the client
-program until data is available or can be sent to the server.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-
-http = httpConnect("server", port);
-httpBlocking(http, 0);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpCheck"><CODE>httpCheck()</CODE></A>,
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpCheck">httpCheck()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-httpCheck(http_t *http);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>0 if there is no data pending, 1 otherwise.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpCheck()</CODE> function checks to see if there is any data
-pending on an HTTP connection.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-
-if (httpCheck(http))
-{
-  ... do something ...
-}
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpBlocking"><CODE>httpBlocking()</CODE></A>,
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpGets"><CODE>httpGets()</CODE></A>,
-<A HREF="#httpRead"><CODE>httpRead()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpClearFields">httpClearFields()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-httpClearFields(http_t *http)
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P>The <CODE>httpClearFields()</CODE> function clears all HTTP request fields
-for the HTTP connection.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-
-httpClearFields(http);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpGetField"><CODE>httpGetField()</CODE></A>,
-<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpClose">httpClose()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-httpClose(http_t *http);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P>The <CODE>httpClose()</CODE> function closes an active HTTP connection.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-
-httpClose(http);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpConnect">httpConnect()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-http_t *
-httpConnect(const char *hostname,
-            int        port);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>hostname</TD>
-       <TD>The name or IP address of the server to connect to</TD>
-</TR>
-<TR>
-       <TD>port</TD>
-       <TD>The port number to use</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to a HTTP connection structure or NULL if the connection could
-not be made.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpConnect()</CODE> function opens a HTTP connection to the
-specified server and port.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-<A HREF="#http_t">http_t</A> *http;
-
-http = httpConnect(cupsServer(), ippPort());
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpClose"><CODE>httpClose()</CODE></A>,
-<A HREF="#httpConnectEncrypt"><CODE>httpConnectEncrypt()</CODE></A>,
-<A HREF="#httpGet"><CODE>httpGet()</CODE></A>,
-<A HREF="#httpGets"><CODE>httpGets()</CODE></A>,
-<A HREF="#httpPost"><CODE>httpPost()</CODE></A>,
-<A HREF="#httpRead"><CODE>httpRead()</CODE></A>,
-<A HREF="#httpWrite"><CODE>httpWrite()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpConnectEncrypt">httpConnectEncrypt()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-http_t *
-httpConnectEncrypt(const char        *hostname,
-                   int               port,
-                   http_encryption_t encryption);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>hostname</TD>
-       <TD>The name or IP address of the server to connect to</TD>
-</TR>
-<TR>
-       <TD>port</TD>
-       <TD>The port number to use</TD>
-</TR>
-<TR>
-       <TD>encryption</TD>
-       <TD>The level of encryption to use</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to a HTTP connection structure or NULL if the connection could
-not be made.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpConnectEncrypt()</CODE> function opens a HTTP
-connection to the specified server, port, and encryption.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-<A HREF="#http_t">http_t</A> *http;
-
-http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpClose"><CODE>httpClose()</CODE></A>,
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpGet"><CODE>httpGet()</CODE></A>,
-<A HREF="#httpGets"><CODE>httpGets()</CODE></A>,
-<A HREF="#httpPost"><CODE>httpPost()</CODE></A>,
-<A HREF="#httpRead"><CODE>httpRead()</CODE></A>,
-<A HREF="#httpWrite"><CODE>httpWrite()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpDecode64">httpDecode64()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-char *
-httpDecode64(char       *out,
-             const char *in);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>out</TD>
-       <TD>The output string</TD>
-</TR>
-<TR>
-       <TD>in</TD>
-       <TD>The input string</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the decoded string.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpDecode64()</CODE> function decodes a base-64 encoded string
-to the original string.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-char encoded_string[255];
-char original_string[255];
-
-httpDecode64(original_string, encoded_string);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpEncode64"><CODE>httpEncode64()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpDelete">httpDelete()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-httpDelete(http_t     *http,
-           const char *uri);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-<TR>
-       <TD>uri</TD>
-       <TD>The URI to delete</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>0 on success, non-zero on failure.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpDelete()</CODE> function sends a HTTP DELETE request to
-the server.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-
-httpDelete(http, "/some/uri");
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>,
-<A HREF="#httpUpdate"><CODE>httpUpdate()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpEncode64">httpEncode64()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-char *
-httpEncode64(char       *out,
-             const char *in);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>out</TD>
-       <TD>The output string</TD>
-</TR>
-<TR>
-       <TD>in</TD>
-       <TD>The input string</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the encoded string.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpEncode64()</CODE> function decodes a base-64 encoded string
-to the original string.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-char encoded_string[255];
-char original_string[255];
-
-httpEncode64(encoded_string, original_string);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpDecode64"><CODE>httpDecode64()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpEncryption">httpEncryption()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-httpEncryption(http_t            *http,
-               http_encryption_t encryption);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection.</TD>
-</TR>
-<TR>
-       <TD>encryption</TD>
-       <TD>The desired level of encryption.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>0 on success, -1 on error.
-
-<H3>Description</H3>
-
-<P><CODE>httpEncryption()</CODE> sets the encryption level for the HTTP
-connection.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-<A HREF="#http_t">http_t</A> *http;
-
-...
-
-httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#httpConnectEncrypt"><CODE>httpConnectEncrypt()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpError">httpError()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-httpError(http_t *http);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The last error that occurred or 0 if no error has occurred.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpError()</CODE> function returns the last error that occurred
-on the HTTP connection.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-
-if (httpError(http))
-{
-  ... show an error message ...
-}
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpFlush">httpFlush()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-httpFlush(http_t *http);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P>The <CODE>httpFlush()</CODE> function flushes any remaining data left from
-a GET or POST operation.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-
-httpFlush(http);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-
-
-<!-- NEW PAGE --><H2><A NAME="httpGet">httpGet()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-httpGet(http_t     *http,
-        const char *uri);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-<TR>
-       <TD>uri</TD>
-       <TD>The URI to get</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>0 on success, non-zero on failure.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpGet()</CODE> function sends a HTTP GET request to the
-server.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-<A HREF="#http_t">http_t</A> *http;
-
-httpGet(http, "/some/uri");
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>,
-<A HREF="#httpUpdate"><CODE>httpUpdate()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpGets">httpGets()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-char *
-httpGets(char   *line,
-         int    length,
-         http_t *http)
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>line</TD>
-       <TD>The string to fill with a line from the HTTP connection</TD>
-</TR>
-<TR>
-       <TD>length</TD>
-       <TD>The maximum length of the string</TD>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the string or NULL if no line could be retrieved.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpGets()</CODE> function is used to read a request line from
-the HTTP connection. It is not normally used by a client program.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-<A HREF="#http_t">http_t</A> *http;
-char   line[1024];
-
-if (httpGets(line, sizeof(line), http))
-{
-  ... process the line ...
-}
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpUpdate"><CODE>httpUpdate()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpGetDateString">httpGetDateString()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-const char *
-httpGetDateString(time_t time)
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>time</TD>
-       <TD>The UNIX date/time value</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to a static string containing the HTTP date/time string for
-the specified UNIX time value.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpGetDateString()</CODE> function generates a date/time string
-suitable for HTTP requests from a UNIX time value.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-puts(httpGetDateString(time(NULL)));
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpGetDateTime"><CODE>httpGetDateTime()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpGetDateTime">httpGetDateTime()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-time_t
-httpGetDateTime(const char *date)
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>date</TD>
-       <TD>The HTTP date/time string</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A UNIX time value.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpGetDateTime()</CODE> function converts a HTTP
-date/time string to a UNIX time value.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-printf("%d\n", httpGetDateTime("Fri, 30 June 2000 12:34:56 GMT"));
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpGetDateString"><CODE>httpGetDateString()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpGetField">httpGetField()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-const char *
-httpGetField(http_t       *http,
-             http_field_t field);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-<TR>
-       <TD>field</TD>
-       <TD>The HTTP field</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the field value string.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpGetField()</CODE> function returns the current value for
-the specified HTTP field.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-<A HREF="#http_t">http_t</A> *http;
-
-httpGet(http, "/some/uri");
-while (httpUpdate(http) == HTTP_CONTINUE);
-
-puts(httpGetField(http, HTTP_FIELD_CONTENT_TYPE));
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpGetSubField"><CODE>httpGetSubField()</CODE></A>,
-<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpGetHostByName">httpGetHostByName()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-struct hostent *
-httpGetHostByName(const char *name);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>Name or IP address to lookup.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>NULL if the host could not be found or a pointer to a host entry
-containing one or more addresses.
-
-<H3>Description</H3>
-
-<P><CODE>httpGetHostByName()</CODE> is a portable wrapper around the
-<CODE>gethostbyname()</CODE> function which handles both hostnames
-and IP addresses.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-struct hostent *hostaddr;
-
-hostaddr = httpGetHostByName("foo.bar.com");
-</PRE>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpGetLength">httpGetLength()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-httpGetLength(http_t *http);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The content length of the response or MAX_INT if chunking is used.
-
-<H3>Description</H3>
-
-<P><CODE>httpGetLength()</CODE> returns the content length of a response.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-<A HREF="#http_t">http_t</A> *http;
-
-...
-
-printf("The length of the response is %d bytes.\n", httpGetLength(http));
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#httpGet"><CODE>httpGet()</CODE></A>,
-<A HREF="#httpPost"><CODE>httpPost()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpGetSubField">httpGetSubField()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-const char *
-httpGetSubField(http_t       *http,
-                http_field_t field,
-               const char   *name,
-               char         *value);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection.</TD>
-</TR>
-<TR>
-       <TD>field</TD>
-       <TD>The HTTP field.</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of the subfield.</TD>
-</TR>
-<TR>
-       <TD>value</TD>
-       <TD>The string to hold the subfield value.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the subfield value string or NULL if it does not exist.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpGetSubField()</CODE> function returns a subfield value
-from the specified HTTP field. The destination string buffer must be at
-least <CODE>HTTP_MAX_VALUE</CODE> bytes in length.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-<A HREF="#http_t">http_t</A> *http;
-char   value[HTTP_MAX_VALUE];
-
-httpGet(http, "/some/uri");
-while (httpUpdate(http) == HTTP_CONTINUE);
-
-puts(httpGetSubField(http, HTTP_FIELD_CONTENT_TYPE, "charset", value));
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpGetField"><CODE>httpGetField()</CODE></A>,
-<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpHead">httpHead()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-httpHead(http_t     *http,
-         const char *uri);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-<TR>
-       <TD>uri</TD>
-       <TD>The URI to head</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>0 on success, non-zero on failure.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpHead()</CODE> function sends a HTTP HEAD request to the
-server.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-
-httpHead(http, "/some/uri");
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>,
-<A HREF="#httpUpdate"><CODE>httpUpdate()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpInitialize">httpInitialize()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void httpInitialize(void);
-</PRE>
-
-<H3>Description</H3>
-
-<P>The <CODE>httpInitialize()</CODE> function initializes the networking
-code as needed by the underlying platform. It is called automatically by
-the <CODE>httpConnect()</CODE> function.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-httpInitialize();
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpMD5">httpMD5()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-char *
-httpMD5(const char *username,
-        const char *realm,
-        const char *passwd,
-        char       md5[33]);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>username</TD>
-       <TD>The authenticating user name.</TD>
-</TR>
-<TR>
-       <TD>realm</TD>
-       <TD>The authenticating realm name.</TD>
-</TR>
-<TR>
-       <TD>passwd</TD>
-       <TD>The authenticating password.</TD>
-</TR>
-<TR>
-       <TD>md5</TD>
-       <TD>The MD5 sum string.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the MD5 sum string.
-
-<H3>Description</H3>
-
-<P><CODE>httpMD5()</CODE> computes the MD5 hash of the username,
-realm, and password as required by the HTTP Digest specification.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-char md5[33];
-
-...
-
-httpMD5("user", "realm", "password", md5);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#httpMD5Final"><CODE>httpMD5Final()</CODE></A>,
-<A HREF="#httpMD5String"><CODE>httpMD5String()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpMD5Final">httpMD5Final()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-char *
-httpMD5Final(const char *nonce,
-             const char *method,
-             const char *resource,
-             char       md5[33]);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>nonce</TD>
-       <TD>The server nonce value.</TD>
-</TR>
-<TR>
-       <TD>method</TD>
-       <TD>The HTTP method (GET, POST, etc.)</TD>
-</TR>
-<TR>
-       <TD>resource</TD>
-       <TD>The resource path.</TD>
-</TR>
-<TR>
-       <TD>md5</TD>
-       <TD>The MD5 sum string.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The MD5 sum string.
-
-<H3>Description</H3>
-
-<P><CODE>httpMD5Final()</CODE> appends the nonce, method, and resource
-to the specified MD5 sum.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-char md5[33];
-
-...
-
-httpMD5Final("nonce", "GET", "/jobs", md5);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#httpMD5"><CODE>httpMD5()</CODE></A>,
-<A HREF="#httpMD5String"><CODE>httpMD5String()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpMD5String">httpMD5String()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-char *
-httpMD5String(const md5_byte_t *sum,
-              char             md5[33]);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>sum</TD>
-       <TD>The raw MD5 sum data.</TD>
-</TR>
-<TR>
-       <TD>md5</TD>
-       <TD>The MD5 sum string.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The MD5 sum string.
-
-<H3>Description</H3>
-
-<P><CODE>httpMD5String()</CODE> converts the raw MD5 sum value to a string.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-md5_byte_t sum[16];
-char       md5[33];
-
-...
-
-httpMD5String(sum, md5);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#httpMD5"><CODE>httpMD5()</CODE></A>,
-<A HREF="#httpMD5Final"><CODE>httpMD5Final()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpOptions">httpOptions()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-httpOptions(http_t     *http,
-            const char *uri);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-<TR>
-       <TD>uri</TD>
-       <TD>The URI to check for options</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>0 on success, non-zero on failure.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpOptions()</CODE> function sends a HTTP OPTIONS request to the
-server.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-
-httpOptions(http, "/some/uri");
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>,
-<A HREF="#httpUpdate"><CODE>httpUpdate()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpPost">httpPost()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-httpPost(http_t     *http,
-         const char *uri);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-<TR>
-       <TD>uri</TD>
-       <TD>The URI to post to</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>0 on success, non-zero on failure.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpPost()</CODE> function sends a HTTP POST request to the
-server.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-
-httpPost(http, "/some/uri");
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>,
-<A HREF="#httpUpdate"><CODE>httpUpdate()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpPrintf">httpPrintf()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-httpPrintf(http_t     *http,
-           const char *format,
-           ...);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-<TR>
-       <TD>format</TD>
-       <TD>A printf-style format string</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The number of bytes written.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpPrintf()</CODE> function sends a formatted string to the
-HTTP connection. It is normally only used by the CUPS API and scheduler.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-
-httpPrintf(http, "GET / HTTP/1.1 \r\n");
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpPut">httpPut()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-httpPut(http_t     *http,
-        const char *uri);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-<TR>
-       <TD>uri</TD>
-       <TD>The URI to put</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>0 on success, non-zero on failure.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpPut()</CODE> function sends a HTTP PUT request to the
-server.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-
-httpDelete(http, "/some/uri");
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>,
-<A HREF="#httpUpdate"><CODE>httpUpdate()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpRead">httpRead()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-httpRead(http_t *http,
-         char   *buffer,
-         int    length);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-<TR>
-       <TD>buffer</TD>
-       <TD>The buffer to read into</TD>
-</TR>
-<TR>
-       <TD>length</TD>
-       <TD>The number of bytes to read</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The number of bytes read or -1 on error.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpRead()</CODE> function reads data from the HTTP connection,
-possibly the result of a GET or POST request.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-char buffer[1024];
-int  bytes;
-
-httpGet(http, "/");
-while (httpUpdate(http) != HTTP_CONTINUE);
-while ((bytes = httpRead(http, buffer, sizeof(buffer) - 1)) > 0)
-{
-  buffer[bytes] = '\0';
-  fputs(buffer, stdout);
-}
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpWrite"><CODE>httpWrite()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpReconnect">httpReconnect()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-httpReconnect(http_t *http);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>0 on success, non-zero on failure.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpReconnect()</CODE> function reconnects to the HTTP server.
-This is usually done automatically if the HTTP functions detect that the
-server connection has terminated.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-
-httpReconnect(http);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpSeparate">httpSeparate()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-httpSeparate(const char *uri,
-             char       *method,
-             char       *username,
-             char       *host,
-             int        *port,
-             char       *resource);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>uri</TD>
-       <TD>The URI to separate</TD>
-</TR>
-<TR>
-       <TD>method</TD>
-       <TD>The method (scheme) of the URI</TD>
-</TR>
-<TR>
-       <TD>username</TD>
-       <TD>The username (and password) portion of the URI, if any</TD>
-</TR>
-<TR>
-       <TD>host</TD>
-       <TD>The hostname portion of the URI, if any</TD>
-</TR>
-<TR>
-       <TD>port</TD>
-       <TD>The port number for the URI, either as specified or as
-       default for the method/scheme</TD>
-</TR>
-<TR>
-       <TD>resource</TD>
-       <TD>The resource string, usually a filename on the server</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P>The <CODE>httpSeparate()</CODE> function separates the specified URI into
-its component parts. The method, username, hostname, and resource strings should
-be at least <CODE>HTTP_MAX_URI</CODE> characters long to avoid potential
-buffer overflow problems.
-
-<H3>Example</H3>
-
-<PRE>
-char uri[HTTP_MAX_URI];
-char method[HTTP_MAX_URI];
-char username[HTTP_MAX_URI];
-char host[HTTP_MAX_URI];
-char resource[HTTP_MAX_URI];
-int  port;
-
-...
-
-httpSeparate(uri, method, username, host, &amp;port, resource);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpSetField">httpSetField()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-httpSetField(http_t       *http,
-             http_field_t field,
-             const char   *value);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-<TR>
-       <TD>field</TD>
-       <TD>The HTTP field</TD>
-</TR>
-<TR>
-       <TD>value</TD>
-       <TD>The string value for the field</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P>The <CODE>httpSetField()</CODE> function sets the current value for
-the specified HTTP field.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-
-httpSetField(http, HTTP_FIELD_AUTHORIZATION, "Basic dfdr34453454325"));
-httpGet(http, "/some/uri");
-while (httpUpdate(http) == HTTP_CONTINUE);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpGetField"><CODE>httpGetField()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpStatus">httpStatus()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-const char *
-httpStatus(http_status_t status);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>status</TD>
-       <TD>The HTTP status code from the server.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The standard HTTP status text associated with the status code.
-
-<H3>Description</H3>
-
-<P><CODE>httpStatus()</CODE> returns the standard HTTP status text
-associated with the status code.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-<A HREF="#http_t">http_t</A> *http;
-
-...
-
-puts(httpStatus(http->status));
-</PRE>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpTrace">httpTrace()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-httpTrace(http_t     *http,
-          const char *uri);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-<TR>
-       <TD>uri</TD>
-       <TD>The URI to trace</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>0 on success, non-zero on failure.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpTrace()</CODE> function sends a HTTP TRACE request to the
-server.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-
-httpTrace(http, "/some/uri");
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>,
-<A HREF="#httpUpdate"><CODE>httpUpdate()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpUpdate">httpUpdate()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-http_status_t
-httpUpdate(http_t *http);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The HTTP status of the current request.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpUpdate()</CODE> function updates the current request status.
-It is used after any DELETE, GET, HEAD, OPTIONS, POST, PUT, or TRACE
-request to finalize the HTTP request and retrieve the request status.
-
-<P>Since proxies and the current blocking mode can cause the request to
-take longer, programs should continue calling <CODE>httpUpdate()<CODE>
-until the return status is not the constant value <CODE>HTTP_CONTINUE</CODE>.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-http_status_t status;
-
-httpGet(http, "/some/uri");
-while ((status = httpUpdate(http)) == HTTP_CONTINUE);
-printf("Request status is %d\n", status);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpDelete"><CODE>httpDelete()</CODE></A>,
-<A HREF="#httpGet"><CODE>httpGet()</CODE></A>,
-<A HREF="#httpHead"><CODE>httpHead()</CODE></A>,
-<A HREF="#httpOptions"><CODE>httpOptions()</CODE></A>,
-<A HREF="#httpPost"><CODE>httpPost()</CODE></A>,
-<A HREF="#httpPut"><CODE>httpPut()</CODE></A>,
-<A HREF="#httpTrace"><CODE>httpTrace()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="httpWrite">httpWrite()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-httpWrite(http_t *http,
-          char   *buffer,
-          int    length);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-<TR>
-       <TD>buffer</TD>
-       <TD>The buffer to read into</TD>
-</TR>
-<TR>
-       <TD>length</TD>
-       <TD>The number of bytes to read</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The number of bytes read or -1 on error.
-
-<H3>Description</H3>
-
-<P>The <CODE>httpWrite()</CODE> function reads data from the HTTP connection,
-possibly the result of a GET or POST request.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h&gt;
-
-http_t *http;
-FILE *fp;
-char buffer[1024];
-int  bytes;
-
-httpPost(http, "/");
-
-while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0)
-  httpWrite(http, buffer, bytes);
-
-while (httpUpdate(http) != HTTP_CONTINUE);
-
-while ((bytes = httpRead(http, buffer, sizeof(buffer) - 1)) > 0)
-{
-  buffer[bytes] = '\0';
-  fputs(buffer, stdout);
-}
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
-<A HREF="#httpRead"><CODE>httpRead()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippAddBoolean">ippAddBoolean()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_attribute_t *
-ippAddBoolean(ipp_t      *ipp,
-              ipp_tag_t  group,
-              const char *name,
-             char       value);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request</TD>
-</TR>
-<TR>
-       <TD>group</TD>
-       <TD>The IPP group</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of attribute</TD>
-</TR>
-<TR>
-       <TD>value</TD>
-       <TD>The boolean value</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the new attribute or NULL if the attribute could not be
-created.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippAddBoolean()</CODE> function adds a single boolean attribute
-value to the specified IPP request.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h>
-
-ipp_t *ipp;
-
-ippAddBoolean(ipp, IPP_TAG_OPERATION, "my-jobs", 1);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
-<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
-<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
-<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
-<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
-<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
-<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
-<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
-<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
-<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
-<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippAddBooleans">ippAddBooleans()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_attribute_t *
-ippAddBooleans(ipp_t      *ipp,
-               ipp_tag_t  group,
-               const char *name,
-               int        num_values,
-               const char *values);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request</TD>
-</TR>
-<TR>
-       <TD>group</TD>
-       <TD>The IPP group</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of attribute</TD>
-</TR>
-<TR>
-       <TD>num_values</TD>
-       <TD>The number of values</TD>
-</TR>
-<TR>
-       <TD>values</TD>
-       <TD>The boolean values</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the new attribute or NULL if the attribute could not be
-created.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippAddBooleans()</CODE> function adds one or more boolean
-attribute values to the specified IPP request. If the
-<CODE>values</CODE> pointer is <CODE>NULL</CODE> then an array of
-<CODE>num_values</CODE> false values is created.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h>
-
-ipp_t *ipp;
-char values[10];
-
-ippAddBooleans(ipp, IPP_TAG_OPERATION, "some-attribute", 10, values);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
-<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
-<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
-<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
-<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
-<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
-<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
-<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
-<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
-<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
-<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippAddDate">ippAddDate()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_attribute_t *
-ippAddDate(ipp_t       *ipp,
-           ipp_tag_t   group,
-           const char  *name,
-           ipp_uchar_t *value);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request</TD>
-</TR>
-<TR>
-       <TD>group</TD>
-       <TD>The IPP group</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of attribute</TD>
-</TR>
-<TR>
-       <TD>value</TD>
-       <TD>The date value</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the new attribute or NULL if the attribute could not be
-created.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippAddDate()</CODE> function adds a single date-time attribute
-value to the specified IPP request.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h>
-
-ipp_t *ipp;
-
-ippAddDate(ipp, IPP_TAG_OPERATION, "some-attribute", 
-           ippTimeToDate(time(NULL));
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
-<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
-<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
-<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
-<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
-<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
-<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
-<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
-<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
-<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
-<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>,
-<A HREF="#ippTimeToDate"><CODE>ippTimeToDate()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippAddInteger">ippAddInteger()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_attribute_t *
-ippAddInteger(ipp_t      *ipp,
-              ipp_tag_t  group,
-              ipp_tag_t  tag,
-              const char *name,
-              int        value);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request</TD>
-</TR>
-<TR>
-       <TD>group</TD>
-       <TD>The IPP group</TD>
-</TR>
-<TR>
-       <TD>tag</TD>
-       <TD>The type of integer value (IPP_TAG_INTEGER or IPP_TAG_ENUM)</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of attribute</TD>
-</TR>
-<TR>
-       <TD>value</TD>
-       <TD>The integer value</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the new attribute or NULL if the attribute could not be
-created.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippAddInteger()</CODE> function adds a single integer attribute
-value to the specified IPP request.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h>
-
-ipp_t *ipp;
-
-ippAddInteger(ipp, IPP_TAG_OPERATION, "limit", 100);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
-<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
-<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
-<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
-<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
-<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
-<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
-<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
-<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
-<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
-<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippAddIntegers">ippAddIntegers()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_attribute_t *
-ippAddIntegers(ipp_t      *ipp,
-               ipp_tag_t  group,
-               ipp_tag_t  tag,
-               const char *name,
-               int        num_values,
-               const int  *values);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request</TD>
-</TR>
-<TR>
-       <TD>group</TD>
-       <TD>The IPP group</TD>
-</TR>
-<TR>
-       <TD>tag</TD>
-       <TD>The type of integer value (IPP_TAG_INTEGER or IPP_TAG_ENUM)</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of attribute</TD>
-</TR>
-<TR>
-       <TD>num_values</TD>
-       <TD>The number of values</TD>
-</TR>
-<TR>
-       <TD>values</TD>
-       <TD>The integer values</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the new attribute or NULL if the attribute could not be
-created.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippAddIntegers()</CODE> function adds one or more integer
-attribute values to the specified IPP request.  If the
-<CODE>values</CODE> pointer is <CODE>NULL</CODE> then an array of
-<CODE>num_values</CODE> 0 values is created.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h>
-
-ipp_t *ipp;
-int values[100];
-
-ippAddIntegers(ipp, IPP_TAG_OPERATION, "some-attribute", 100, values);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
-<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
-<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
-<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
-<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
-<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
-<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
-<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
-<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
-<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
-<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippAddRange">ippAddRange()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_attribute_t *
-ippAddRange(ipp_t      *ipp,
-            ipp_tag_t  group,
-            const char *name,
-            int        low,
-            int        high);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request</TD>
-</TR>
-<TR>
-       <TD>group</TD>
-       <TD>The IPP group</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of attribute</TD>
-</TR>
-<TR>
-       <TD>low</TD>
-       <TD>The lower value</TD>
-</TR>
-<TR>
-       <TD>high</TD>
-       <TD>The higher value</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the new attribute or NULL if the attribute could not be
-created.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippAddRange()</CODE> function adds a single range attribute
-value to the specified IPP request.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h>
-
-ipp_t *ipp;
-
-ippAddRange(ipp, IPP_TAG_OPERATION, "page-ranges", 1, 10);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
-<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
-<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
-<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
-<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
-<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
-<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
-<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
-<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
-<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
-<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippAddRanges">ippAddRanges()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_attribute_t *
-ippAddRanges(ipp_t      *ipp,
-             ipp_tag_t  group,
-             const char *name,
-             int        num_values,
-             const int  *lows,
-             const int  *highs);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request</TD>
-</TR>
-<TR>
-       <TD>group</TD>
-       <TD>The IPP group</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of attribute</TD>
-</TR>
-<TR>
-       <TD>num_values</TD>
-       <TD>The number of range values</TD>
-</TR>
-<TR>
-       <TD>lows</TD>
-       <TD>The lower values</TD>
-</TR>
-<TR>
-       <TD>highs</TD>
-       <TD>The higher values</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the new attribute or NULL if the attribute could not be
-created.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippAddRanges()</CODE> function adds one or more range
-attribute values to the specified IPP request. If the
-<CODE>values</CODE> pointer is <CODE>NULL</CODE> then an array of
-<CODE>num_values</CODE> 0,0 ranges is created.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h>
-
-ipp_t *ipp;
-int lows[2];
-int highs[2];
-
-ippAddRanges(ipp, IPP_TAG_OPERATION, "page-ranges", 2, lows, highs);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
-<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
-<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
-<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
-<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
-<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
-<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
-<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
-<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
-<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
-<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippAddResolution">ippAddResolution()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_attribute_t *
-ippAddResolution(ipp_t      *ipp,
-                 ipp_tag_t  group,
-                 const char *name,
-                 int        xres,
-                 int        yres,
-                 ipp_res_t  units);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request</TD>
-</TR>
-<TR>
-       <TD>group</TD>
-       <TD>The IPP group</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of attribute</TD>
-</TR>
-<TR>
-       <TD>xres</TD>
-       <TD>The horizontal resolution</TD>
-</TR>
-<TR>
-       <TD>yres</TD>
-       <TD>The vertical resolution</TD>
-</TR>
-<TR>
-       <TD>units</TD>
-       <TD>The resolution units</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the new attribute or NULL if the attribute could not be
-created.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippAddResolution()</CODE> function adds a single resolution attribute
-value to the specified IPP request.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h>
-
-ipp_t *ipp;
-
-ippAddBoolean(ipp, IPP_TAG_OPERATION, "printer-resolution",
-              720, 720, IPP_RES_PER_INCH);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
-<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
-<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
-<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
-<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
-<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
-<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
-<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
-<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
-<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
-<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippAddResolutions">ippAddResolutions()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_attribute_t *
-ippAddResolutions(ipp_t           *ipp,
-                  ipp_tag_t       group,
-                  const char      *name,
-                  int             num_values,
-                  const int       *xres,
-                  const int       *yres,
-                  const ipp_res_t *units);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request</TD>
-</TR>
-<TR>
-       <TD>group</TD>
-       <TD>The IPP group</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of attribute</TD>
-</TR>
-<TR>
-       <TD>num_values</TD>
-       <TD>The number of resolution values</TD>
-</TR>
-<TR>
-       <TD>xres</TD>
-       <TD>The horizontal resolutions</TD>
-</TR>
-<TR>
-       <TD>yres</TD>
-       <TD>The vertical resolutions</TD>
-</TR>
-<TR>
-       <TD>units</TD>
-       <TD>The resolution units</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the new attribute or NULL if the attribute could not be
-created.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippAddResolutions()</CODE> function adds one or more
-resolution attribute values to the specified IPP request. If the
-<CODE>values</CODE> pointer is <CODE>NULL</CODE> then an array of
-<CODE>num_values</CODE> 0,0 resolutions is created.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h>
-
-ipp_t *ipp;
-int xres[5];
-int yres[5];
-ipp_res_t units[5];
-
-ippAddBoolean(ipp, IPP_TAG_OPERATION, "printer-resolutions-supported",
-              5, xres, yres, units);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
-<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
-<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
-<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
-<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
-<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
-<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
-<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
-<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
-<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
-<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippAddSeparator">ippAddSeparator()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_attribute_t *
-ippAddSeparator(ipp_t *ipp);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the new separator or NULL if the separator could not be
-created.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippAddSeparator()</CODE> function adds a group separator
-to the specified IPP request.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h>
-
-ipp_t *ipp;
-
-ippAddSeparator(ipp);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
-<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
-<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
-<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
-<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
-<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
-<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
-<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
-<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
-<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
-<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippAddString">ippAddString()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_attribute_t *
-ippAddString(ipp_t      *ipp,
-             ipp_tag_t  group,
-             ipp_tag_t  tag,
-             const char *name,
-             const char *charset,
-             const char *value);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request</TD>
-</TR>
-<TR>
-       <TD>group</TD>
-       <TD>The IPP group</TD>
-</TR>
-<TR>
-       <TD>tag</TD>
-       <TD>The type of string value</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of attribute</TD>
-</TR>
-<TR>
-       <TD>charset</TD>
-       <TD>The character set for the string</TD>
-</TR>
-<TR>
-       <TD>value</TD>
-       <TD>The string value</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the new attribute or NULL if the attribute could not be
-created.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippAddString()</CODE> function adds a single string attribute
-value to the specified IPP request. For <CODE>IPP_TAG_NAMELANG</CODE> and
-<CODE>IPP_TAG_TEXTLANG</CODE> strings, the charset value is provided with
-the string to identify the string encoding used. Otherwise the charset value
-is ignored.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h>
-
-ipp_t *ipp;
-
-ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
-             NULL, "abc123");
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
-<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
-<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
-<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
-<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
-<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
-<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
-<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
-<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
-<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
-<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippAddStrings">ippAddStrings()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_attribute_t *
-ippAddStrings(ipp_t      *ipp,
-              ipp_tag_t  group,
-              ipp_tag_t  tag,
-              const char *name,
-              int        num_values,
-              const char *charset,
-              const char **values);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request</TD>
-</TR>
-<TR>
-       <TD>group</TD>
-       <TD>The IPP group</TD>
-</TR>
-<TR>
-       <TD>tag</TD>
-       <TD>The type of string value</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of attribute</TD>
-</TR>
-<TR>
-       <TD>num_values</TD>
-       <TD>The number of strings</TD>
-</TR>
-<TR>
-       <TD>charset</TD>
-       <TD>The character set for the strings</TD>
-</TR>
-<TR>
-       <TD>values</TD>
-       <TD>The string values</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the new attribute or NULL if the attribute could not be
-created.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippAddStrings()</CODE> function adds one or more string
-attribute values to the specified IPP request. For
-<CODE>IPP_TAG_NAMELANG</CODE> and <CODE>IPP_TAG_TEXTLANG</CODE>
-strings, the charset value is provided with the strings to identify the
-string encoding used. Otherwise the charset value is ignored. If the
-<CODE>values</CODE> pointer is <CODE>NULL</CODE> then an array of
-<CODE>num_values</CODE> NULL strings is created.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h>
-
-ipp_t *ipp;
-char *values[2] = { "one", "two" };
-
-ippAddStrings(ipp, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "attr-name",
-              2, NULL, values);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
-<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
-<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
-<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
-<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
-<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
-<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
-<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
-<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
-<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
-<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippDateToTime">ippDateToTime()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-time_t
-ippDateToTime(const ipp_uchar_t date[11]);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>date</TD>
-       <TD>The IPP date-time value</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A UNIX time value.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippDateToTime()</CODE> function converts an IPP date-time value
-to a UNIX time value.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h>
-
-ipp_uchar_t date[11];
-
-printf("UNIX time is %d\n", ippDateToTime(date));
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippTimeToDate"><CODE>ippTimeToDate()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippDelete">ippDelete()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-ippDelete(ipp_t *ipp);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request or response</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P>The <CODE>ippDelete()</CODE> function deletes all memory used by an IPP
-request or response.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h>
-
-ipp_t *ipp;
-
-ippDelete(ipp);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippNew"><CODE>ippNew()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippErrorString">ippErrorString()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-const char *
-ippErrorString(ipp_status_t error);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>error</TD>
-       <TD>IPP error code.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The standard text representation of the IPP error code.
-
-<H3>Description</H3>
-
-<P><CODE>ippErrorString()</CODE> returns the standard text representation
-of the IPP error code.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h&gt;
-
-puts(ippErrorString(IPP_OK));
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#cupsLastError"><CODE>cupsLastError()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippFindAttribute">ippFindAttribute()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_attribute_t *
-ippFindAttribute(ipp_t      *ipp,
-                 const char *name,
-                 ipp_tag_t  tag);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request or response</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of the attribute</TD>
-</TR>
-<TR>
-       <TD>tag</TD>
-       <TD>The required value tag for the attribute or
-       <CODE>IPP_TAG_ZERO</CODE> for any type of value.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the first occurrence of the requested attribute, or
-<CODE>NULL</CODE> if it was not found.
-
-<H3>Description</H3>
-
-<P><CODE>ippFindAttribute()</CODE> finds the first occurrence of the named
-attribute. The <CODE>tag</CODE> parameter restricts the search to a specific
-value type - use <CODE>IPP_TAG_ZERO</CODE> to find any value with the name.
-
-<P>The value tags <CODE>IPP_TAG_NAME</CODE> and <CODE>IPP_TAG_TEXT</CODE>
-match the name/text values with or without the language code.
-
-<H3>Example</H3>
-
-<PRE>
-<A HREF="#ipp_attribute_t">ipp_attribute_t</A> *attr;
-
-attr = ippFindAttribute(response, "printer-state-message", IPP_TAG_TEXT);
-while (attr != NULL)
-{
-  puts(attr->values[0].string.text);
-
-  attr = ippFindNextAttribute(response, "printer-state-message", IPP_TAG_TEXT);
-}
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#cupsDoFileRequest"><CODE>cupsDoFileRequest()</CODE></A>,
-<A HREF="#cupsDoRequest"><CODE>cupsDoRequest()</CODE></A>,
-<A HREF="#ippDelete"><CODE>ippDelete()</CODE></A>,
-<A HREF="#ippFindNextAttribute"><CODE>ippFindNextAttribute()</CODE></A>,
-<A HREF="#ippNew"><CODE>ippNew()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippFindNextAttribute">ippFindNextAttribute()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_attribute_t *
-ippFindNextAttribute(ipp_t      *ipp,
-                     const char *name,
-                     ipp_tag_t  tag);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request or response</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of the attribute</TD>
-</TR>
-<TR>
-       <TD>tag</TD>
-       <TD>The required value tag for the attribute or
-       <CODE>IPP_TAG_ZERO</CODE> for any type of value.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the next occurrence of the requested attribute, or
-<CODE>NULL</CODE> if it was not found.
-
-<H3>Description</H3>
-
-<P><CODE>ippFindNextAttribute()</CODE> finds the next occurrence of the named
-attribute. The <CODE>tag</CODE> parameter restricts the search to a specific
-value type - use <CODE>IPP_TAG_ZERO</CODE> to find any value with the name.
-
-<P>The value tags <CODE>IPP_TAG_NAME</CODE> and <CODE>IPP_TAG_TEXT</CODE>
-match the name/text values with or without the language code.
-
-<H3>Example</H3>
-
-<PRE>
-<A HREF="#ipp_attribute_t">ipp_attribute_t</A> *attr;
-
-attr = ippFindAttribute(response, "printer-state-message", IPP_TAG_TEXT);
-while (attr != NULL)
-{
-  puts(attr->values[0].string.text);
-
-  attr = ippFindNextAttribute(response, "printer-state-message", IPP_TAG_TEXT);
-}
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#cupsDoFileRequest"><CODE>cupsDoFileRequest()</CODE></A>,
-<A HREF="#cupsDoRequest"><CODE>cupsDoRequest()</CODE></A>,
-<A HREF="#ippDelete"><CODE>ippDelete()</CODE></A>,
-<A HREF="#ippFindNextAttribute"><CODE>ippFindNextAttribute()</CODE></A>,
-<A HREF="#ippNew"><CODE>ippNew()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippLength">ippLength()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-ippLength(ipp_t *ipp);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request or response</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The total encoded length of the IPP request or response in bytes.
-
-<H3>Description</H3>
-
-<P><CODE>ippLength()</CODE> returns the length of the IPP request or
-response in bytes.
-
-<H3>Example</H3>
-
-<PRE>
-printf("The length of the response is %d bytes.\n", ippLength(response));
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippDelete"><CODE>ippDelete()</CODE></A>,
-<A HREF="#ippNew"><CODE>ippNew()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippNew">ippNew()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_t *
-ippNew(void);
-</PRE>
-
-<H3>Returns</H3>
-
-<P>A pointer to a new IPP request or response.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippNew()</CODE> function creates a new IPP request or response.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h>
-
-ipp_t *ipp;
-
-ipp = ippNew();
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippDelete"><CODE>ippDelete()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippPort">ippPort()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-ippPort(void);
-</PRE>
-
-<H3>Returns</H3>
-
-<P>The default TCP/IP port number for IPP requests.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippPort()</CODE> function returns the default IPP port number
-for requests.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h>
-#include &lt;cups/ipp.h>
-
-http_t *http;
-
-http = httpConnect(cupsServer(), ippPort());
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#cupsServer"><CODE>cupsServer()</CODE></A>,
-<A HREF="#ippSetPort"><CODE>ippSetPort()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippRead">ippRead()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_state_t
-ippRead(http_t *http,
-        ipp_t  *ipp);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request or response</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The current read state.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippRead()</CODE> function reads IPP attributes from the specified
-HTTP connection. Programs should continue calling <CODE>ippRead()</CODE> until
-<CODE>IPP_ERROR</CODE> or <CODE>IPP_DATA</CODE> is returned.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h>
-#include &lt;cups/ipp.h>
-
-http_t *http;
-ipp_t *ipp;
-ipp_state_t status;
-
-ipp = ippNew();
-
-while ((status = ippRead(http, ipp)) != IPP_ERROR)
-  if (status == IPP_DATA)
-    break;
-
-if (status == IPP_DATA)
-{
-  ... read additional non-IPP data using httpRead() ...
-}
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippWrite"><CODE>ippWrite()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippSetPort">ippSetPort()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-ippSetPort(int port);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>port</TD>
-       <TD>The port number to use</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P>The <CODE>ippSetPort()</CODE> function sets the default IPP port number
-for requests.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h>
-#include &lt;cups/ipp.h>
-
-...
-
-ippSetPort(8631);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippPort"><CODE>ippPort()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippTimeToDate">ippTimeToDate()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_uchar_t *
-ippTimeToDate(time_t time);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>time</TD>
-       <TD>The UNIX time value</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A static pointer to an IPP date-time value.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippTimeToDate()</CODE> function converts a UNIX time to an IPP
-date-time value.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ipp.h>
-
-ipp_uchar_t *date;
-
-date = ippTimeToDate(time(NULL));
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippDateToTime"><CODE>ippDateToTime()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ippWrite">ippWrite()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ipp_state_t
-ippWrite(http_t *http,
-         ipp_t  *ipp);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>http</TD>
-       <TD>The HTTP connection</TD>
-</TR>
-<TR>
-       <TD>ipp</TD>
-       <TD>The IPP request or response</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The current write state.
-
-<H3>Description</H3>
-
-<P>The <CODE>ippWrite()</CODE> function writes IPP attributes to the specified
-HTTP connection. Programs should continue calling <CODE>ippWrite()</CODE> until
-<CODE>IPP_ERROR</CODE> or <CODE>IPP_DATA</CODE> is returned.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/http.h>
-#include &lt;cups/ipp.h>
-
-http_t *http;
-ipp_t *ipp;
-ipp_state_t status;
-
-ipp = ippNew();
-... add attributes ...
-
-while ((status = ippWrite(http, ipp)) != IPP_ERROR)
-  if (status == IPP_DATA)
-    break;
-
-if (status == IPP_DATA)
-{
-  ... read additional non-IPP data using httpWrite() ...
-}
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ippRead"><CODE>ippRead()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdClose">ppdClose()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-ppdClose(ppd_file_t *ppd);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ppd</TD>
-       <TD>The PPD file</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P>The <CODE>ppdClose()</CODE> function frees all memory associated with the
-PPD file.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h>
-
-ppd_file_t *ppd;
-
-ppdClose(ppd);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ppdOpen"><CODE>ppdOpen()</CODE></A>,
-<A HREF="#ppdOpenFd"><CODE>ppdOpenFd()</CODE></A>,
-<A HREF="#ppdOpenFile"><CODE>ppdOpenFile()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdCollect">ppdCollect()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-ppdCollect(ppd_file_t    *ppd,
-           ppd_section_t section,
-           ppd_choice_t  ***choices);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ppd</TD>
-       <TD>The PPD file.</TD>
-</TR>
-<TR>
-       <TD>section</TD>
-       <TD>The document section to collect.</TD>
-</TR>
-<TR>
-       <TD>choices</TD>
-       <TD>The array of option choices that are marked.</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The number of options collected.
-
-<H3>Description</H3>
-
-<P><CODE>ppdCollect()</CODE> collects all of the marked options in the
-specified section, sorts them by their order dependency values, and
-returns an array that can be used to emit option commands in the proper
-order. It is normally used by the <CODE>ppdEmit*()</CODE> functions.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h&gt;
-
-<A HREF="#ppd_file_t">ppd_file_t</A>   *ppd;
-int          num_choices;
-<A HREF="#ppd_choice_t">ppd_choice_t</A> **choices;
-
-...
-
-num_choices = ppdCollect(ppd, PPD_ORDER_JCL, &amp;choices);
-</PRE>
-
-<H3>See Also</H3>
-
-<P>
-<A HREF="#ppdEmit"><CODE>ppdEmit()</CODE></A>,
-<A HREF="#ppdEmitFd"><CODE>ppdEmitFd()</CODE></A>,
-<A HREF="#ppdEmitJCL"><CODE>ppdEmitJCL()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdConflicts">ppdConflicts()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-ppdConflicts(ppd_file_t *ppd);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ppd</TD>
-       <TD>The PPD file</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The number of option conflicts in the file.
-
-<H3>Description</H3>
-
-<P>The <CODE>ppdConflicts()</CODE> function returns the number of conflicts
-with the currently selected options.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h>
-
-ppd_file_t *ppd;
-
-printf("%d conflicts\n", ppdConflicts(ppd));
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#cupsMarkOptions"><CODE>cupsMarkOptions()</CODE></A>,
-<A HREF="#ppdIsMarked"><CODE>ppdIsMarked()</CODE></A>,
-<A HREF="#ppdMarkDefaults"><CODE>ppdMarkDefaults()</CODE></A>,
-<A HREF="#ppdMarkOption"><CODE>ppdMarkOption()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdEmit">ppdEmit()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-ppdEmit(ppd_file_t    *ppd,
-        FILE          *file,
-        ppd_section_t section);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ppd</TD>
-       <TD>The PPD file</TD>
-</TR>
-<TR>
-       <TD>file</TD>
-       <TD>The file to write to</TD>
-</TR>
-<TR>
-       <TD>section</TD>
-       <TD>The option section to write</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>0 on success, -1 on error.
-
-<H3>Description</H3>
-
-<P>The <CODE>ppdEmit()</CODE> function sends printer-specific option
-commands to the specified file.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h>
-
-ppd_file_t *ppd;
-
-ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ppdEmitFd"><CODE>ppdEmitFd()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdEmitFd">ppdEmitFd()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-ppdEmitFd(ppd_file_t    *ppd,
-          int           fd,
-          ppd_section_t section);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ppd</TD>
-       <TD>The PPD file</TD>
-</TR>
-<TR>
-       <TD>fd</TD>
-       <TD>The file descriptor to write to</TD>
-</TR>
-<TR>
-       <TD>section</TD>
-       <TD>The option section to write</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>0 on success, -1 on error.
-
-<H3>Description</H3>
-
-<P>The <CODE>ppdEmitFd()</CODE> function sends printer-specific option
-commands to the specified file descriptor.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h>
-
-ppd_file_t *ppd;
-
-ppdEmitFd(ppd, 1, PPD_ORDER_PAGE);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ppdEmit"><CODE>ppdEmit()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdFindChoice">ppdFindChoice()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ppd_choice_t *
-ppdFindChoice(ppd_option_t *option,
-              const char   *choice);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>option</TD>
-       <TD>A pointer to the option</TD>
-</TR>
-<TR>
-       <TD>choice</TD>
-       <TD>The name of the choice</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the choice data or NULL if the choice does not exist.
-
-<H3>Description</H3>
-
-<P>The <CODE>ppdFindChoice()</CODE> function returns a pointer to the choice
-data for the specified option.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h>
-
-ppd_file_t *ppd;
-ppd_option_t *option;
-ppd_choice_t *choice;
-
-option = ppdFindOption(ppd, "PageSize");
-choice = ppdFindChoice(option, "Letter");
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ppdFindMarkedChoice"><CODE>ppdFindMarkedChoice()</CODE></A>,
-<A HREF="#ppdFindOption"><CODE>ppdFindOption()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdFindMarkedChoice">ppdFindMarkedChoice()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ppd_choice_t *
-ppdFindMarkedChoice(ppd_file_t *ppd,
-                    const char *keyword);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ppd</TD>
-       <TD>The PPD file</TD>
-</TR>
-<TR>
-       <TD>keyword</TD>
-       <TD>The name of the option</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the choice data or NULL if the choice does not exist or
-is not marked.
-
-<H3>Description</H3>
-
-<P>The <CODE>ppdFindMarkedChoice()</CODE> function returns a pointer to
-the marked choice data for the specified option.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h>
-
-ppd_file_t *ppd;
-ppd_choice_t *choice;
-
-choice = ppdFindMarkedChoice(ppd, "PageSize");
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ppdFindChoice"><CODE>ppdFindChoice()</CODE></A>,
-<A HREF="#ppdFindOption"><CODE>ppdFindOption()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdFindOption">ppdFindOption()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ppd_option_t *
-ppdFindOption(ppd_file_t *ppd,
-              const char *keyword);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ppd</TD>
-       <TD>The PPD file</TD>
-</TR>
-<TR>
-       <TD>keyword</TD>
-       <TD>The name of the option</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the option data or NULL if the option does not exist.
-
-<H3>Description</H3>
-
-<P>The <CODE>ppdFindOption()</CODE> function returns a pointer to the option
-data for the specified option.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h>
-
-ppd_file_t *ppd;
-ppd_option_t *option;
-
-option = ppdFindOption(ppd, "PageSize");
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ppdFindChoice"><CODE>ppdFindChoice()</CODE></A>,
-<A HREF="#ppdFindMarkedChoice"><CODE>ppdFindMarkedChoice()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdIsMarked">ppdIsMarked()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-ppdIsMarked(ppd_file_t *ppd,
-            const char *keyword,
-            const char *choice);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ppd</TD>
-       <TD>The PPD file</TD>
-</TR>
-<TR>
-       <TD>keyword</TD>
-       <TD>The name of the option</TD>
-</TR>
-<TR>
-       <TD>choice</TD>
-       <TD>The name of the option choice</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>1 if the choice is marked, 0 otherwise.
-
-<H3>Description</H3>
-
-<P>The <CODE>ppdIsMarked()</CODE> function returns whether or not the
-specified option choice is marked.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h>
-
-ppd_file_t *ppd;
-
-printf("Letter size %s selected.\n",
-       ppdIsMarked(ppd, "PageSize", "Letter") ? "is" : "is not");
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#cupsMarkOptions"><CODE>cupsMarkOptions()</CODE></A>,
-<A HREF="#ppdConflicts"><CODE>ppdConflicts()</CODE></A>,
-<A HREF="#ppdIsMarked"><CODE>ppdIsMarked()</CODE></A>,
-<A HREF="#ppdMarkDefaults"><CODE>ppdMarkDefaults()</CODE></A>,
-<A HREF="#ppdMarkOption"><CODE>ppdMarkOption()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdMarkDefaults">ppdMarkDefaults()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-void
-ppdMarkDefaults(ppd_file_t *ppd);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ppd</TD>
-       <TD>The PPD file</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Description</H3>
-
-<P>The <CODE>ppdMarkDefaults()</CODE> function marks all of the default
-choices in the PPD file.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h>
-
-ppd_file_t *ppd;
-
-ppdMarkDefaults(ppd);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#cupsMarkOptions"><CODE>cupsMarkOptions()</CODE></A>,
-<A HREF="#ppdConflicts"><CODE>ppdConflicts()</CODE></A>,
-<A HREF="#ppdIsMarked"><CODE>ppdIsMarked()</CODE></A>,
-<A HREF="#ppdMarkDefaults"><CODE>ppdMarkDefaults()</CODE></A>,
-<A HREF="#ppdMarkOption"><CODE>ppdMarkOption()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdMarkOption">ppdMarkOption()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-int
-ppdMarkOption(ppd_file_t *ppd,
-              const char *keyword,
-              const char *choice);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ppd</TD>
-       <TD>The PPD file</TD>
-</TR>
-<TR>
-       <TD>keyword</TD>
-       <TD>The name of the option</TD>
-</TR>
-<TR>
-       <TD>choice</TD>
-       <TD>The name of the choice</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The number of conflicts in the PPD file.
-
-<H3>Description</H3>
-
-<P>The <CODE>ppdMarkOption()</CODE> function marks the specified option
-choice.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h>
-
-ppd_file_t *ppd;
-
-ppdMarkOption(ppd, "PageSize", "Letter");
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#cupsMarkOptions"><CODE>cupsMarkOptions()</CODE></A>,
-<A HREF="#ppdConflicts"><CODE>ppdConflicts()</CODE></A>,
-<A HREF="#ppdIsMarked"><CODE>ppdIsMarked()</CODE></A>,
-<A HREF="#ppdMarkDefaults"><CODE>ppdMarkDefaults()</CODE></A>,
-<A HREF="#ppdMarkOption"><CODE>ppdMarkOption()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdOpen">ppdOpen()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ppd_file_t *
-ppdOpen(FILE *file);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>file</TD>
-       <TD>The file to read from</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to a PPD file structure or NULL if the PPD file could not be
-read.
-
-<H3>Description</H3>
-
-<P>The <CODE>ppdOpen()</CODE> function reads a PPD file from the specified
-file into memory.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h>
-
-ppd_file_t *ppd;
-FILE *file;
-
-file = fopen("filename.ppd", "rb");
-ppd = ppdOpen(file);
-fclose(file);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ppdClose"><CODE>ppdClose()</CODE></A>,
-<A HREF="#ppdOpenFd"><CODE>ppdOpenFd()</CODE></A>,
-<A HREF="#ppdOpenFile"><CODE>ppdOpenFile()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdOpenFd">ppdOpenFd()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ppd_file_t *
-ppdOpenFd(int fd);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>fd</TD>
-       <TD>The file descriptor to read from</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to a PPD file structure or NULL if the PPD file could not be
-read.
-
-<H3>Description</H3>
-
-<P>The <CODE>ppdOpenFd()</CODE> function reads a PPD file from the specified
-file descriptor into memory.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h>
-
-ppd_file_t *ppd;
-int        fd;
-
-fd = open("filename.ppd", O_RDONLY);
-ppd = ppdOpenFd(fd);
-close(fd);
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ppdClose"><CODE>ppdClose()</CODE></A>,
-<A HREF="#ppdOpen"><CODE>ppdOpen()</CODE></A>,
-<A HREF="#ppdOpenFile"><CODE>ppdOpenFile()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdOpenFile">ppdOpenFile()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ppd_file_t *
-ppdOpenFile(const char *filename);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>filename</TD>
-       <TD>The name of the file to read from</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to a PPD file structure or NULL if the PPD file could not be
-read.
-
-<H3>Description</H3>
-
-<P>The <CODE>ppdOpenFile()</CODE> function reads a PPD file from the named
-file into memory.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h>
-
-ppd_file_t *ppd;
-
-ppd = ppdOpenFile("filename.ppd");
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ppdClose"><CODE>ppdClose()</CODE></A>,
-<A HREF="#ppdOpen"><CODE>ppdOpen()</CODE></A>,
-<A HREF="#ppdOpenFd"><CODE>ppdOpenFd()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdPageLength">ppdPageLength()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-float
-ppdPageLength(ppd_file_t *ppd,
-              const char *name);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ppd</TD>
-       <TD>The PPD file</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of the page size</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The length of the specified page size in points or 0 if the page size
-does not exist.
-
-<H3>Description</H3>
-
-<P>The <CODE>ppdPageLength()</CODE> function returns the page length of the
-specified page size.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h>
-
-ppd_file_t *ppd;
-
-printf("Length = %.0f\n", ppdPageLength(ppd, "Letter"));
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ppdPageLength"><CODE>ppdPageLength()</CODE></A>,
-<A HREF="#ppdPageSize"><CODE>ppdPageSize()</CODE></A>,
-<A HREF="#ppdPageWidth"><CODE>ppdPageWidth()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdPageSize">ppdPageSize()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-ppd_size_t *
-ppdPageSize(ppd_file_t *ppd,
-            const char *name);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ppd</TD>
-       <TD>The PPD file</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of the page size</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>A pointer to the page size record of the specified page size in
-points or NULL if the page size does not exist.
-
-<H3>Description</H3>
-
-<P>The <CODE>ppdPageSize()</CODE> function returns the page size record for the
-specified page size.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h>
-
-ppd_file_t *ppd;
-ppd_size_t *size;
-
-size = ppdPageSize(ppd, "Letter");
-if (size != NULL)
-{
-  printf(" Width = %.0f\n", size->width);
-  printf("Length = %.0f\n", size->length);
-  printf("  Left = %.0f\n", size->left);
-  printf(" Right = %.0f\n", size->right);
-  printf("Bottom = %.0f\n", size->bottom);
-  printf("   Top = %.0f\n", size->top);
-}
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ppdPageLength"><CODE>ppdPageLength()</CODE></A>,
-<A HREF="#ppdPageWidth"><CODE>ppdPageWidth()</CODE></A>
-
-
-<!-- NEW PAGE --><H2><A NAME="ppdPageWidth">ppdPageWidth()</A></H2>
-
-<H3>Usage</H3>
-
-<PRE>
-float
-ppdPageWidth(ppd_file_t *ppd,
-             const char *name);
-</PRE>
-
-<H3>Arguments</H3>
-
-<CENTER><TABLE WIDTH="80%" BORDER>
-<TR>
-       <TH>Argument</TH>
-       <TH>Description</TH>
-</TR>
-<TR>
-       <TD>ppd</TD>
-       <TD>The PPD file</TD>
-</TR>
-<TR>
-       <TD>name</TD>
-       <TD>The name of the page size</TD>
-</TR>
-</TABLE></CENTER>
-
-<H3>Returns</H3>
-
-<P>The width of the specified page size in points or 0 if the page size
-does not exist.
-
-<H3>Description</H3>
-
-<P>The <CODE>ppdPageWidth()</CODE> function returns the page width of the
-specified page size.
-
-<H3>Example</H3>
-
-<PRE>
-#include &lt;cups/ppd.h>
-
-ppd_file_t *ppd;
-
-printf("Width = %.0f\n", ppdPageWidth(ppd, "Letter"));
-</PRE>
-
-<H3>See Also</H3>
-
-<A HREF="#ppdPageLength"><CODE>ppdPageLength()</CODE></A>,
-<A HREF="#ppdPageSize"><CODE>ppdPageSize()</CODE></A>
-
-
-</BODY>
-</HTML>