]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Merge changes from CUPS 1.4svn-r7282.
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Thu, 31 Jan 2008 17:01:57 +0000 (17:01 +0000)
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Thu, 31 Jan 2008 17:01:57 +0000 (17:01 +0000)
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@614 a1ca3aef-8c08-0410-bb20-df032aa958be

75 files changed:
CHANGES-1.3.txt
CHANGES.txt
backend/backend-private.h
berkeley/lprm.c
cgi-bin/ipp-var.c
cups/Makefile
cups/adminutil.c
cups/api-array.header [new file with mode: 0644]
cups/api-array.shtml
cups/api-cups.header [new file with mode: 0644]
cups/api-cups.shtml
cups/api-filedir.header [new file with mode: 0644]
cups/api-filedir.shtml
cups/api-filter.header [new file with mode: 0644]
cups/api-filter.shtml
cups/api-httpipp.header [new file with mode: 0644]
cups/api-httpipp.shtml
cups/api-overview.header [new file with mode: 0644]
cups/api-overview.shtml [new file with mode: 0644]
cups/api-ppd.header [new file with mode: 0644]
cups/api-ppd.shtml
cups/array.c
cups/array.h
cups/attr.c
cups/auth.c
cups/backend.h
cups/cups.h
cups/dest.c
cups/dir.c
cups/emit.c
cups/encode.c
cups/file.c
cups/getputfile.c
cups/ipp-private.h
cups/ipp.c
cups/ipp.h
cups/language.c
cups/libcups.exp
cups/localize.c
cups/mark.c
cups/notify.c
cups/options.c
cups/ppd.c
cups/ppd.h
cups/sidechannel.h
cups/tempfile.c
cups/test.ppd
cups/testppd.c
cups/usersys.c
cups/util.c
doc/Makefile
doc/cups-printable.css
doc/cups.css
doc/help/api-array.html
doc/help/api-cups.html
doc/help/api-filedir.html
doc/help/api-filter.html
doc/help/api-httpipp.html
doc/help/api-overview.html [new file with mode: 0644]
doc/help/api-ppd.html
doc/help/api-raster.html
doc/help/policies.html
doc/help/spec-ipp.html
doc/help/spec-ppd.html
filter/Makefile
filter/api-raster.header [new file with mode: 0644]
filter/api-raster.shtml
filter/interpret.c
filter/raster.h
scheduler/client.c
scheduler/ipp.c
scheduler/job.c
scheduler/printers.c
scheduler/printers.h
scheduler/process.c

index dd43d52cdf3d2a9b6f035de261a3b92df562926b..3e05bf7dce7cbfe92bb6f0b4592b9963afe39208 100644 (file)
@@ -4,6 +4,15 @@ CHANGES-1.3.txt
 CHANGES IN CUPS V1.3.6
 
        - Documentation updates (STR #2646, STR #2647, STR #2649)
+       - The scheduler did not support printer supply attributes
+         (STR #1307)
+       - The Kerberos credentials provided by some Windows KDCs
+         were still too large - now use a dynamic buffer to
+         support credentials up to 64k in size (STR #2695)
+       - Printing a test page from the web interface incorrectly
+         defaulted to the "guest" user (STR #2688)
+       - The cupsEncodeOptions2() function did not parse multiple-
+         value attribute values properly (STR #2690)
        - The scheduler incorrectly sent printer-stopped events for
          status updates from the print filters (STR #2680)
        - The IPP backend could crash when handling printer errors
index c6f9a4b248adb370afe380e6e7ddbdd90161a8bd..5d31aead481bab2b376f33a98b5e67206ad2f586 100644 (file)
@@ -1,8 +1,10 @@
-CHANGES.txt - 2008-01-23
+CHANGES.txt - 2008-01-30
 ------------------------
 
 CHANGES IN CUPS V1.4b1
 
+       - Added a new ppdLocalizeMarkerName() function to get
+         the localized version of a marker-names value.
        - The scheduler now provides the printer-dns-sd-name
          attribute for printers shared via DNS-SD/Bonjour.
        - The pdftops filter now executes the Xpdf or poppler
index cd6f78b38370a5a866df5b0e7d9a2cfeca33cfd2..cd5aaaf47a1fd61023a38c31a1cde0ccb63ad664 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Backend support definitions for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -161,6 +161,12 @@ extern "C" {
 #define CUPS_TC_langPDF                                54
 #define CUPS_TC_langJPEG                       61
 
+#define CUPS_TC_supplyThatIsConsumed           3
+#define CUPS_TC_receptacleThatIsFilled         4
+
+#define CUPS_TC_process                                3
+#define CUPS_TC_spot                           4
+
 #define CUPS_TC_toner                          3
 #define CUPS_TC_wasteToner                     4
 #define CUPS_TC_ink                            5
index d453af13cde9e2f407900f32c95e3aa5eed95a71..d00372c55106153a5817acdfe952fe755246b618 100644 (file)
@@ -37,19 +37,13 @@ int                         /* O - Exit status */
 main(int  argc,                        /* I - Number of command-line arguments */
      char *argv[])             /* I - Command-line arguments */
 {
-  http_t       *http;          /* HTTP connection to server */
   int          i;              /* Looping var */
   int          job_id;         /* Job ID */
-  const char   *dest;          /* Destination printer */
+  const char   *name;          /* Destination printer */
   char         *instance;      /* Pointer to instance name */
-  char         uri[1024];      /* Printer or job URI */
-  ipp_t                *request;       /* IPP request */
-  ipp_t                *response;      /* IPP response */
-  ipp_op_t     op;             /* Operation */
-  int          num_dests;      /* Number of destinations */
-  cups_dest_t  *dests,         /* Destinations */
+  cups_dest_t  *dest,          /* Destination */
                *defdest;       /* Default destination */
-  http_encryption_t encryption;        /* Encryption? */
+  int          did_cancel;     /* Did we cancel something? */
 
 
   _cupsSetLocale(argv);
@@ -58,26 +52,9 @@ main(int  argc,                      /* I - Number of command-line arguments */
   * Setup to cancel individual print jobs...
   */
 
-  op         = IPP_CANCEL_JOB;
-  job_id     = 0;
-  dest       = NULL;
-  response   = NULL;
-  http       = NULL;
-  encryption = cupsEncryption();
-
- /*
-  * Open a connection to the server...
-  */
-
-  if ((http = httpConnectEncrypt(cupsServer(), ippPort(), encryption)) == NULL)
-  {
-    _cupsLangPuts(stderr, _("lprm: Unable to contact server!\n"));
-    return (1);
-  }
-
-  num_dests  = cupsGetDests2(http, &dests);
-  defdest    = cupsGetDest(NULL, NULL, num_dests, dests);
-  dest       = defdest ? defdest->name : NULL;
+  did_cancel = 0;
+  defdest    = cupsGetNamedDest(CUPS_HTTP_DEFAULT, NULL, NULL);
+  name       = defdest ? defdest->name : NULL;
 
  /*
   * Process command-line arguments...
@@ -89,10 +66,7 @@ main(int  argc,                      /* I - Number of command-line arguments */
       {
         case 'E' : /* Encrypt */
 #ifdef HAVE_SSL
-           encryption = HTTP_ENCRYPT_REQUIRED;
-
-           httpEncryption(http, encryption);
-           cupsSetEncryption(encryption);
+           cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
 #else
             _cupsLangPrintf(stderr,
                            _("%s: Sorry, no encryption support compiled in!\n"),
@@ -102,25 +76,26 @@ main(int  argc,                    /* I - Number of command-line arguments */
 
         case 'P' : /* Cancel jobs on a printer */
            if (argv[i][2])
-             dest = argv[i] + 2;
+             name = argv[i] + 2;
            else
            {
              i ++;
-             dest = argv[i];
+             name = argv[i];
            }
 
-           if ((instance = strchr(dest, '/')) != NULL)
+           if ((instance = strchr(name, '/')) != NULL)
              *instance = '\0';
 
-           if (cupsGetDest(dest, NULL, num_dests, dests) == NULL)
+           if ((dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, name,
+                                        NULL)) == NULL)
            {
              _cupsLangPrintf(stderr,
                              _("%s: Error - unknown destination \"%s\"!\n"),
-                             argv[0], dest);
-              cupsFreeDests(num_dests, dests);
-             httpClose(http);
-             return(1);
+                             argv[0], name);
+              goto error;
            }
+
+           cupsFreeDests(1, dest);
            break;
 
         case 'U' : /* Username */
@@ -135,7 +110,7 @@ main(int  argc,                     /* I - Number of command-line arguments */
                                _("%s: Error - expected username after "
                                  "\'-U\' option!\n"),
                                argv[0]);
-               return (1);
+               goto error;
              }
 
               cupsSetUser(argv[i]);
@@ -155,34 +130,24 @@ main(int  argc,                   /* I - Number of command-line arguments */
                                _("%s: Error - expected hostname after "
                                  "\'-h\' option!\n"),
                                argv[0]);
-               return (1);
+               goto error;
               }
              else
                 cupsSetServer(argv[i]);
            }
 
-            httpClose(http);
-            cupsFreeDests(num_dests, dests);
+            if (defdest)
+             cupsFreeDests(1, defdest);
 
-           if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
-                                          encryption)) == NULL)
-           {
-             _cupsLangPuts(stderr, _("lprm: Unable to contact server!\n"));
-             return (1);
-           }
-
-           num_dests  = cupsGetDests2(http, &dests);
-           defdest    = cupsGetDest(NULL, NULL, num_dests, dests);
-           dest       = defdest ? defdest->name : NULL;
+           defdest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, NULL, NULL);
+           name    = defdest ? defdest->name : NULL;
            break;
 
        default :
            _cupsLangPrintf(stderr,
                            _("%s: Error - unknown option \'%c\'!\n"),
                            argv[0], argv[i][1]);
-            cupsFreeDests(num_dests, dests);
-           httpClose(http);
-           return (1);
+            goto error;
       }
     else
     {
@@ -190,11 +155,17 @@ main(int  argc,                   /* I - Number of command-line arguments */
       * Cancel a job or printer...
       */
 
-      if (isdigit(argv[i][0] & 255) &&
-          cupsGetDest(argv[i], NULL, num_dests, dests) == NULL)
+      if ((dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, argv[i], NULL)) != NULL)
+        cupsFreeDests(1, dest);
+
+      if (dest)
       {
-        dest   = NULL;
-       op     = IPP_CANCEL_JOB;
+        name   = argv[i];
+        job_id = 0;
+      }
+      else if (isdigit(argv[i][0] & 255))
+      {
+        name   = NULL;
         job_id = atoi(argv[i]);
       }
       else if (!strcmp(argv[i], "-"))
@@ -203,64 +174,23 @@ main(int  argc,                   /* I - Number of command-line arguments */
         * Cancel all jobs
         */
 
-        op = IPP_PURGE_JOBS;
-      }
-      else
-      {
-        dest   = argv[i];
-        job_id = 0;
-      }
-
-     /*
-      * Build an IPP request, which requires the following
-      * attributes:
-      *
-      *    attributes-charset
-      *    attributes-natural-language
-      *    printer-uri + job-id *or* job-uri
-      *    [requesting-user-name]
-      */
-
-      request = ippNewRequest(op);
-
-      if (dest)
-      {
-        httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
-                        "localhost", 0, "/printers/%s", dest);
-       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
-                    "printer-uri", NULL, uri);
-       ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id",
-                     job_id);
+        job_id = -1;
       }
       else
       {
-        sprintf(uri, "ipp://localhost/jobs/%d", job_id);
-       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL,
-                    uri);
+       _cupsLangPrintf(stderr,
+                       _("%s: Error - unknown destination \"%s\"!\n"),
+                       argv[0], argv[i]);
+       goto error;
       }
 
-      ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
-                   "requesting-user-name", NULL, cupsUser());
-
-     /*
-      * Do the request and get back a response...
-      */
-
-      if (op == IPP_PURGE_JOBS)
-        response = cupsDoRequest(http, request, "/admin/");
-      else
-        response = cupsDoRequest(http, request, "/jobs/");
-
-      ippDelete(response);
-
-      if (cupsLastError() > IPP_OK_CONFLICT)
+      if (cupsCancelJob2(CUPS_HTTP_DEFAULT, name, job_id, 0) != IPP_OK)
       {
         _cupsLangPrintf(stderr, "%s: %s\n", argv[0], cupsLastErrorString());
-
-        cupsFreeDests(num_dests, dests);
-        httpClose(http);
-       return (1);
+       goto error;
       }
+
+      did_cancel = 1;
     }
 
  /*
@@ -268,19 +198,27 @@ main(int  argc,                   /* I - Number of command-line arguments */
   * (or default) printer...
   */
 
-  if (response == NULL)
-    if (!cupsCancelJob(dest, 0))
+  if (!did_cancel && cupsCancelJob2(CUPS_HTTP_DEFAULT, name, 0, 0) != IPP_OK)
     {
       _cupsLangPrintf(stderr, "%s: %s\n", argv[0], cupsLastErrorString());
-      cupsFreeDests(num_dests, dests);
-      httpClose(http);
-      return (1);
+      goto error;
     }
 
-  cupsFreeDests(num_dests, dests);
-  httpClose(http);
+  if (defdest)
+    cupsFreeDests(1, defdest);
 
   return (0);
+
+ /*
+  * If we get here there was an error, so clean up...
+  */
+
+  error:
+
+  if (defdest)
+    cupsFreeDests(1, defdest);
+
+  return (1);
 }
 
 
index 8f86191274172060ccf59053d67c01554acbd627..c1703e101afed0b8e4d7bb7ffbf9e34a48a63b40 100644 (file)
@@ -525,8 +525,7 @@ cgiPrintTestPage(http_t     *http,  /* I - Connection to server */
   * See who is logged in...
   */
 
-  if ((user = getenv("REMOTE_USER")) == NULL)
-    user = "guest";
+  user = getenv("REMOTE_USER");
 
  /*
   * Locate the test page file...
@@ -564,8 +563,9 @@ cgiPrintTestPage(http_t     *http,  /* I - Connection to server */
   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                NULL, uri);
 
-  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
-               "requesting-user-name", NULL, user);
+  if (user)
+    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+                "requesting-user-name", NULL, user);
 
   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
                NULL, "Test Page");
index e00a368e3281890b7ab0c1d5f97db491f1254edb..4ea63e200b40a93d246562bdaa563a3411aaa3ab 100644 (file)
@@ -444,29 +444,86 @@ testsnmp: testsnmp.o libcups.a
 
 apihelp:
        echo Generating CUPS API help files...
+       mxmldoc --section "Programming" \
+               --title "Introduction to CUPS Programming" \
+               --css ../doc/cups-printable.css \
+               --header api-overview.header --intro api-overview.shtml \
+               >../doc/help/api-overview.html
        mxmldoc --section "Programming" --title "Array API" \
-               --intro api-array.shtml \
+               --css ../doc/cups-printable.css \
+               --header api-array.header --intro api-array.shtml \
                array.h array.c >../doc/help/api-array.html
        mxmldoc --section "Programming" --title "CUPS API" \
-               --intro api-cups.shtml \
+               --css ../doc/cups-printable.css \
+               --header api-cups.header --intro api-cups.shtml \
                cups.h dest.c getputfile.c language.c notify.c \
                options.c tempfile.c usersys.c \
                util.c >../doc/help/api-cups.html
        mxmldoc --section "Programming" --title "File and Directory APIs" \
-               --intro api-filedir.shtml \
+               --css ../doc/cups-printable.css \
+               --header api-filedir.header --intro api-filedir.shtml \
                file.h file.c dir.h dir.c >../doc/help/api-filedir.html
        mxmldoc --section "Programming" --title "PPD API" \
-               --intro api-ppd.shtml \
+               --css ../doc/cups-printable.css \
+               --header api-ppd.header --intro api-ppd.shtml \
                ppd.h attr.c custom.c emit.c localize.c mark.c page.c \
                ppd.c >../doc/help/api-ppd.html
        mxmldoc --section "Programming" --title "HTTP and IPP APIs" \
-               --intro api-httpipp.shtml \
+               --css ../doc/cups-printable.css \
+               --header api-httpipp.header --intro api-httpipp.shtml \
                http.h ipp.h auth.c encode.c http.c http-addr.c \
                http-support.c ipp.c ipp-support.c md5passwd.c \
                request.c >../doc/help/api-httpipp.html
-       mxmldoc --section "Programming" --title "Filter and Backend APIs" \
-               --intro api-filter.shtml \
-               backchannel.c sidechannel.c sidechannel.h >../doc/help/api-filter.html
+       mxmldoc --section "Programming" \
+               --title "Filter and Backend Programming" \
+               --css ../doc/cups-printable.css \
+               --header api-filter.header --intro api-filter.shtml \
+               backchannel.c backend.h sidechannel.c sidechannel.h \
+               >../doc/help/api-filter.html
+
+framedhelp:
+       echo Generating CUPS API help files...
+       mxmldoc --framed api-overview \
+               --section "Programming" \
+               --title "Introduction to CUPS Programming" \
+               --css ../doc/cups-printable.css \
+               --header api-overview.header --intro api-overview.shtml
+       mxmldoc --framed api-array \
+               --section "Programming" --title "Array API" \
+               --css ../doc/cups-printable.css \
+               --header api-array.header --intro api-array.shtml \
+               array.h array.c
+       mxmldoc --framed api-cups \
+               --section "Programming" --title "CUPS API" \
+               --css ../doc/cups-printable.css \
+               --header api-cups.header --intro api-cups.shtml \
+               cups.h dest.c getputfile.c language.c notify.c \
+               options.c tempfile.c usersys.c \
+               util.c >../doc/help/api-cups.html
+       mxmldoc --framed api-filedir \
+               --section "Programming" --title "File and Directory APIs" \
+               --css ../doc/cups-printable.css \
+               --header api-filedir.header --intro api-filedir.shtml \
+               file.h file.c dir.h dir.c >../doc/help/api-filedir.html
+       mxmldoc --framed api-ppd \
+               --section "Programming" --title "PPD API" \
+               --css ../doc/cups-printable.css \
+               --header api-ppd.header --intro api-ppd.shtml \
+               ppd.h attr.c custom.c emit.c localize.c mark.c page.c \
+               ppd.c >../doc/help/api-ppd.html
+       mxmldoc --framed api-httpipp \
+               --section "Programming" --title "HTTP and IPP APIs" \
+               --css ../doc/cups-printable.css \
+               --header api-httpipp.header --intro api-httpipp.shtml \
+               http.h ipp.h auth.c encode.c http.c http-addr.c \
+               http-support.c ipp.c ipp-support.c md5passwd.c \
+               request.c >../doc/help/api-httpipp.html
+       mxmldoc --framed api-filter \
+               --section "Programming" \
+               --title "Filter and Backend Programming" \
+               --css ../doc/cups-printable.css \
+               --header api-filter.header --intro api-filter.shtml \
+               backchannel.c backend.h sidechannel.c sidechannel.h
 
 
 #
index 3eda26dba8823cd0c80fcf7b9f95084ae93a8297..c75b0d904c088addc3945515f8fb393798bf51ec 100644 (file)
@@ -1613,8 +1613,6 @@ _cupsAdminSetServerSettings(
        if (remote_admin)
          cupsFilePrintf(temp, "  Allow %s\n",
                         remote_any > 0 ? "all" : "@LOCAL");
-       else
-         cupsFilePuts(temp, "  Allow localhost\n");
       }
       else if (in_conf_location && remote_admin >= 0)
       {
@@ -1632,8 +1630,6 @@ _cupsAdminSetServerSettings(
        if (remote_admin)
          cupsFilePrintf(temp, "  Allow %s\n",
                         remote_any > 0 ? "all" : "@LOCAL");
-       else
-         cupsFilePuts(temp, "  Allow localhost\n");
       }
       else if (in_root_location && (remote_admin >= 0 || share_printers >= 0))
       {
@@ -1654,8 +1650,6 @@ _cupsAdminSetServerSettings(
        if (remote_admin > 0 || share_printers > 0)
          cupsFilePrintf(temp, "  Allow %s\n",
                         remote_any > 0 ? "all" : "@LOCAL");
-       else
-         cupsFilePuts(temp, "  Allow localhost\n");
       }
 
       in_admin_location = 0;
@@ -1876,8 +1870,6 @@ _cupsAdminSetServerSettings(
 
     if (remote_admin > 0 || share_printers > 0)
       cupsFilePrintf(temp, "  Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");
-    else
-      cupsFilePuts(temp, "  Allow localhost\n");
 
     cupsFilePuts(temp, "</Location>\n");
   }
@@ -1894,8 +1886,6 @@ _cupsAdminSetServerSettings(
 
     if (remote_admin)
       cupsFilePrintf(temp, "  Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");
-    else
-      cupsFilePuts(temp, "  Allow localhost\n");
 
     cupsFilePuts(temp, "</Location>\n");
   }
@@ -1915,8 +1905,6 @@ _cupsAdminSetServerSettings(
 
     if (remote_admin)
       cupsFilePrintf(temp, "  Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");
-    else
-      cupsFilePuts(temp, "  Allow localhost\n");
 
     cupsFilePuts(temp, "</Location>\n");
   }
diff --git a/cups/api-array.header b/cups/api-array.header
new file mode 100644 (file)
index 0000000..34b796f
--- /dev/null
@@ -0,0 +1,34 @@
+<!--
+  "$Id$"
+
+  Array API header for the Common UNIX Printing System (CUPS).
+
+  Copyright 2008 by Apple Inc.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">Array API</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+       <th>Header</th>
+       <th>cups/array.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <th>Library</th>
+       <td>-lcups</td>
+</tr>
+<tr>
+       <th>See Also</th>
+       <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a></td>
+</tr>
+</tbody>
+</table></div>
index 355aa4822604fe2e35db9ee9135e98479d8aadd7..92c540b098f915c9a834354daec60e57042457ce 100644 (file)
@@ -3,7 +3,7 @@
 
   Array API introduction for the Common UNIX Printing System (CUPS).
 
-  Copyright 2007 by Apple Inc.
+  Copyright 2007-2008 by Apple Inc.
   Copyright 1997-2006 by Easy Software Products, all rights reserved.
 
   These coded instructions, statements, and computer programs are the
   file is missing or damaged, see the license at "http://www.cups.org/".
 -->
 
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
 
-<p>The CUPS array API provides a high-performance generic array
-container. The contents of the array container can be sorted and
-the container itself is designed for optimal speed and memory
-usage under a wide variety of conditions.</p>
+<p>The CUPS array API provides a high-performance generic array container.
+The contents of the array container can be sorted and the container itself is
+designed for optimal speed and memory usage under a wide variety of conditions.
+Sorted arrays use a binary search algorithm from the last found or inserted
+element to quickly find matching elements in the array. Arrays created with the
+optional hash function can often find elements with a single lookup. The
+<a href='#cups_array_t'><code>cups_array_t</code></a> type is used when
+referring to a CUPS array.</p>
 
 <p>The CUPS scheduler (<tt>cupsd</tt>) and many of the CUPS API
 functions use the array API to efficiently manage large lists of
 data.</p>
 
-<h2 class='title'>General Usage</h2>
+<h3><a name='MANAGING_ARRAYS'>Managing Arrays</a></h3>
 
-<p>The <var>&lt;cups/array.h&gt;</var> header file must be
-included to use the <tt>cupsArray</tt> functions.</p>
+<p>Arrays are created using either the
+<a href='#cupsArrayNew'><code>cupsArrayNew</code></a> or
+<a href='#cupsArrayNew2'><code>cupsArrayNew2</code></a> functions. The
+first function creates a new array with the specified callback function
+and user data pointer:</p>
 
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+<pre class='example'>
+#include &lt;cups/array.h&gt;
 
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
+static int compare_func(void *first, void *second, void *user_data);
+
+void *user_data;
+<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew'>cupsArrayNew</a>(compare_func, user_data);
+</pre>
+
+<p>The comparison function (type
+<a href="#cups_arrayfunc_t"><code>cups_arrayfunc_t</code></a>) is called
+whenever an element is added to the array and can be <code>NULL</code> to
+create an unsorted array. The function returns -1 if the first element should
+come before the second, 0 if the first and second elements should have the same
+ordering, and 1 if the first element should come after the second.</p>
+
+<p>The "user_data" pointer is passed to your comparison function. Pass
+<code>NULL</code> if you do not need to associate the elements in your array
+with additional information.</p>
+
+<p>The <a href='#cupsArrayNew2'><code>cupsArrayNew2</code></a> function adds
+two more arguments to support hashed lookups, which can potentially provide
+instantaneous ("O(1)") lookups in your array:</p>
+
+<pre class='example'>
+#include &lt;cups/array.h&gt;
+
+#define HASH_SIZE 512 /* Size of hash table */
+
+static int compare_func(void *first, void *second, void *user_data);
+static int hash_func(void *element, void *user_data);
+
+void *user_data;
+<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew2'>cupsArrayNew2</a>(compare_func, user_data, hash_func, HASH_SIZE);
+</pre>
+
+<p>The hash function (type
+<a href="#cups_ahash_func_t"><code>cups_ahash_func_t</code></a>) returns a
+number from 0 to (hash_size-1) that (hopefully) uniquely identifies the
+element and is called whenever you look up an element in the array with
+<a href='#cupsArrayFind'><code>cupsArrayFind</code></a>. The hash size is
+only limited by available memory, but generally should not be larger than
+16384 to realize any performance improvement.</p>
+
+<p>Once you have created the array, you add elements using the
+<a href='#cupsArrayAdd'><code>cupsArrayAdd</code></a>
+<a href='#cupsArrayInsert'><code>cupsArrayInsert</code></a> functions.
+The first function adds an element to the array, adding the new element
+after any elements that have the same order, while the second inserts the
+element before others with the same order. For unsorted arrays,
+<a href='#cupsArrayAdd'><code>cupsArrayAdd</code></a> appends the elemnt to
+the end of the array while
+<a href='#cupsArrayInsert'><code>cupsArrayInsert</code></a> inserts the
+element at the beginning of the array. For example, the following code
+creates a sorted array of character strings:</p>
+
+<pre class='example'>
+#include &lt;cups/array.h&gt;
+
+/* Use strcmp() to compare strings - it will ignore the user_data pointer */
+<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew'>cupsArrayNew</a>((<a href='#cups_array_func_t'>cups_array_func_t</a>)strcmp, NULL);
+
+/* Add four strings to the array */
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "One Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Two Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Red Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Blue Fish");
 </pre>
 
-<h2 class='title'>Compatibility</h2>
+<p>Elements are removed using the
+<a href='#cupsArrayRemove'><code>cupsArrayRemove</code></a> function, for
+example:</p>
 
-<p>All of these functions require CUPS 1.2 or higher.</p>
+<pre class='example'>
+#include &lt;cups/array.h&gt;
+
+/* Use strcmp() to compare strings - it will ignore the user_data pointer */
+<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew'>cupsArrayNew</a>((<a href='#cups_array_func_t'>cups_array_func_t</a>)strcmp, NULL);
+
+/* Add four strings to the array */
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "One Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Two Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Red Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Blue Fish");
+
+/* Remove "Red Fish" */
+<a href='#cupsArrayRemove'>cupsArrayRemove</a>(array, "Red Fish");
+</pre>
+
+<p>Finally, you free the memory used by the array using the
+<a href='#cupsArrayDelete'><code>cupsArrayDelete</code></a> function. All
+of the memory for the array and hash table (if any) is freed, however <em>CUPS
+does not free the elements</em> - if necessary, you must allocate and free the
+elements yourself.</p>
+
+<h3><a name='FINDING_AND_ENUMERATING'>Finding and Enumerating Elements</a></h3>
+
+<p>CUPS provides several functions to find and enumerate elements in an
+array. Each one sets or updates a "current index" into the array, such that
+future lookups will start where the last one left off:</p>
+
+<dl>
+       <dt><a href='#cupsArrayFind'><code>cupsArrayFind</code></a></dt>
+       <dd>Returns the first matching element .</dd>
+       <dt><a href='#cupsArrayFirst'><code>cupsArrayFirst</code></a></dt>
+       <dd>Returns the first element in the array.</dd>
+       <dt><a href='#cupsArrayIndex'><code>cupsArrayIndex</code></a></dt>
+       <dd>Returns the Nth element in the array.</dd>
+       <dt><a href='#cupsArrayLast'><code>cupsArrayLast</code></a></dt>
+       <dd>Returns the last element in the array.</dd>
+       <dt><a href='#cupsArrayNext'><code>cupsArrayNext</code></a></dt>
+       <dd>Returns the next element in the array.</dd>
+       <dt><a href='#cupsArrayPrev'><code>cupsArrayPrev</code></a></dt>
+       <dd>Returns the previous element in the array.</dd>
+</dl>
+
+<p>Each of these functions returns <code>NULL</code> when there is no
+corresponding element.  For example, a simple <code>for</code> loop using the
+<a href='#cupsArrayFirst'><code>cupsArrayFirst</code></a> and
+<a href='#cupsArrayNext'><code>cupsArrayNext</code></a> functions will
+enumerate all of the strings in our previous example:</p> 
+
+<pre class='example'>
+#include &lt;cups/array.h&gt;
+
+/* Use strcmp() to compare strings - it will ignore the user_data pointer */
+<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew'>cupsArrayNew</a>((<a href='#cups_array_func_t'>cups_array_func_t</a>)strcmp, NULL);
+
+/* Add four strings to the array */
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "One Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Two Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Red Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Blue Fish");
+
+/* Show all of the strings in the array */
+char *s;
+for (s = (char *)<a href='#cupsArrayFirst'>cupsArrayFirst</a>(array); s != NULL; s = (char *)<a href='#cupsArrayNext'>cupsArrayNext</a>(array))
+  puts(s);
+</pre>
diff --git a/cups/api-cups.header b/cups/api-cups.header
new file mode 100644 (file)
index 0000000..a706b55
--- /dev/null
@@ -0,0 +1,40 @@
+<!--
+  "$Id$"
+
+  CUPS API header for the Common UNIX Printing System (CUPS).
+
+  Copyright 2008 by Apple Inc.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">CUPS API</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+       <th>Header</th>
+       <th>cups/cups.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <th>Library</th>
+       <td>-lcups</td>
+</tr>
+<tr>
+       <th>See Also</th>
+       <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
+       Programming: <a href='api-array.html' target='_top'>Array API</a><br>
+       Programming: <a href='api-filedir.html' target='_top'>File and Directory APIs</a><br>
+       Programming: <a href='api-filter.html' target='_top'>Filter and Backend Programming</a><br>
+       Programming: <a href='api-httpipp.html' target='_top'>HTTP and IPP APIs</a><br>
+       Programming: <a href='api-ppd.html' target='_top'>PPD API</a><br>
+       Programming: <a href='api-raster.html' target='_top'>Raster API</a></td>
+</tr>
+</tbody>
+</table></div>
index 483feb30b06fe5de5a46930562207baf74c4e0c8..29982e58d708f68d88d31d27a2fd56952815b336 100644 (file)
@@ -3,7 +3,7 @@
 
   CUPS API introduction for the Common UNIX Printing System (CUPS).
 
-  Copyright 2007 by Apple Inc.
+  Copyright 2007-2008 by Apple Inc.
   Copyright 1997-2006 by Easy Software Products, all rights reserved.
 
   These coded instructions, statements, and computer programs are the
   file is missing or damaged, see the license at "http://www.cups.org/".
 -->
 
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name='OVERVIEW'>Overview</a></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>
+<p>The CUPS API provides the convenience functions needed to support
+applications, filters, printer drivers, and backends that need to interface
+with the CUPS scheduler.</p>
 
-<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>
+<h3><a name='PRINTERS_AND_CLASSES'>Printers and Classes</a></h3>
 
-<h2 class='title'>General Usage</h2>
+<p>Printers and classes (collections of printers) are accessed through
+the <a href="#cups_dest_t"><code>cups_dest_t</code></a> structure which
+includes the name (<code>name</code>), instance (<code>instance</code> -
+a way of selected certain saved options), and the options and attributes
+associated with that destination (<code>num_options</code> and
+<code>options</code>). Destinations are created using the
+<a href="#cupsGetDests"><code>cupsGetDests</code></a> function and freed
+using the <a href='#cupsFreeDests'><code>cupsFreeDests</code></a> function.
+The <a href='#cupsGetDest'><code>cupsGetDest</code></a> function finds a
+specific destination for printing:</p>
 
-<p>The <var>&lt;cups/cups.h&gt;</var> header file must be included to
-use the CUPS functions.</p>
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
 
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+<a href='#cups_dest_t'>cups_dest_t</a> *dests;
+int num_dests = <a href='#cupsGetDests'>cupsGetDests</a>(&amp;dests);
+<a href='#cups_dest_t'>cups_dest_t</a> *dest = <a href='#cupsGetDest'>cupsGetDest</a>("name", NULL, num_dests, dests);
 
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
+/* do something wiith dest */
+
+<a href='#cupsFreeDests'>cupsFreeDests</a>(num_dests, dests);
 </pre>
 
-<h2 class='title'>Compatibility</h2>
+<p>Passing <code>NULL</code> to
+<a href='#cupsGetDest'><code>cupsGetDest</code></a> for the destination name
+will return the default destination. Similarly, passing a <code>NULL</code>
+instance will return the default instance for that destination.</p>
+
+<div class='table'><table summary='Table 1: Printer Attributes' width='80%'>
+<caption>Table 1: <a name='TABLE1'>Printer Attributes</a></caption>
+<thead>
+<tr>
+       <th>Attribute Name</th>
+       <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <td>"auth-info-required"</td>
+       <td>The type of authentication required for printing to this
+       destination: "none", "username,password", "domain,username,password",
+       or "negotiate" (Kerberos)</td>
+</tr>
+<tr>
+       <td>"printer-info"</td>
+       <td>The human-readable description of the destination such as "My
+       Laser Printer".</td>
+</tr>
+<tr>
+       <td>"printer-is-accepting-jobs"</td>
+       <td>"1" if the destination is accepting new jobs, "0" if not.</td>
+</tr>
+<tr>
+       <td>"printer-is-shared"</td>
+       <td>"1" if the destination is being shared with other computers, "0" if
+       not.</td>
+</tr>
+<tr>
+       <td>"printer-location"</td>
+       <td>The human-readable location of the destination such as "Lab 4".</td>
+</tr>
+<tr>
+       <td>"printer-make-and-model"</td>
+       <td>The human-readable make and model of the destination such as "HP
+       LaserJet 4000 Series".</td>
+</tr>
+<tr>
+       <td>"printer-state"</td>
+       <td>"3" if the destination is idle, "4" if the destination is printing
+       a job, and "5" if the destination is stopped.</td>
+</tr>
+<tr>
+       <td>"printer-state-change-time"</td>
+       <td>The UNIX time when the destination entered the current state.</td>
+</tr>
+<tr>
+       <td>"printer-state-reasons"</td>
+       <td>Additional comma-delimited state keywords for the destination
+       such as "media-tray-empty-error" and "toner-low-warning".</td>
+</tr>
+<tr>
+       <td>"printer-type"</td>
+       <td>The <a href='#cups_printer_t'><code>cups_printer_t</code></a>
+       value associated with the destination.</td>
+</tr>
+</tbody>
+</table></div>
+
+<h3><a name='OPTIONS'>Options</a></h3>
+
+<p>Options are stored in arrays of
+<a href='#cups_option_t'><code>cups_option_t</code></a> structures. Each
+option has a name (<code>name</code>) and value (<code>value</code>)
+associated with it. The <a href='#cups_dest_t'><code>cups_dest_t</code></a>
+<code>num_options</code> and <code>options</code> members contain the
+default options for a particular destination, along with several informational
+attributes about the destination as shown in <a href='#TABLE1'>Table 1</a>.
+The <a href='#cupsGetOption'><code>cupsGetOption</code></a> function gets
+the value for the named option. For example, the following code lists the
+available destinations and their human-readable descriptions:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dests;
+int num_dests = <a href='#cupsGetDests'>cupsGetDests</a>(&amp;dests);
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int i;
+const char *value;
+
+for (i = num_dests, dest = dests; i > 0; i --, dest ++)
+  if (dest->instance == NULL)
+  {
+    value = <a href='#cupsGetOption'>cupsGetOption</a>("printer-info", dest->num_options, dest->options);
+    printf("%s (%s)\n", dest->name, value ? value : "no description");
+  }
+
+<a href='#cupsFreeDests'>cupsFreeDests</a>(num_dests, dests);
+</pre>
+
+<p>You can create your own option arrays using the
+<a href='#cupsAddOption'><code>cupsAddOption</code></a> function, which
+adds a single named option to an array:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+int num_options = 0;
+<a href='#cups_option_t'>cups_option_t</a> *options = NULL;
+
+/* The returned num_options value is updated as needed */
+num_options = <a href='#cupsAddOption'>cupsAddOption</a>("first", "value", num_options, &amp;options);
+
+/* This adds a second option value */
+num_options = <a href='#cupsAddOption'>cupsAddOption</a>("second", "value", num_options, &amp;options);
+
+/* This replaces the first option we added */
+num_options = <a href='#cupsAddOption'>cupsAddOption</a>("first", "new value", num_options, &amp;options);
+</pre>
+
+<p>Use a <code>for</code> loop to copy the options from a destination:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+int i;
+int num_options = 0;
+<a href='#cups_option_t'>cups_option_t</a> *options = NULL;
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+
+for (i = 0; i < dest->num_options; i ++)
+  num_options = <a href='#cupsAddOption'>cupsAddOption</a>(dest->options[i].name, dest->options[i].value, num_options, &amp;options);
+</pre>
+
+<p>Use the <a href='#cupsFreeOptions'><code>cupsFreeOptions</code></a>
+function to free the options array when you are done using it:</p>
+
+<pre class='example'>
+<a href='#cupsFreeOptions'>cupsFreeOptions</a>(num_options, options);
+</pre>
+
+<h3><a name='PRINT_JOBS'>Print Jobs</a></h3>
+
+<p>Print jobs are identified by a locally-unique job ID number from 1 to
+2<sup>31</sup>-1 and have options and one or more files for printing to a
+single destination. The <a href='#cupsPrintFile'><code>cupsPrintFile</code></a>
+function creates a new job with one file. The following code prints the CUPS
+test page file:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int num_options;
+<a href='#cups_option_t'>cups_option_t</a> *options;
+int job_id;
+
+/* Print a single file */
+job_id = <a href='#cupsPrintFile'>cupsPrintFile</a>(dest->name, "/usr/share/cups/data/testprint.ps", "Test Print", num_options, options);
+</pre>
+
+<p>The <a href='#cupsPrintFiles'><code>cupsPrintFiles</code></a> function
+creates a job with multiple files. The files are provided in a
+<code>char *</code> array:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int num_options;
+<a href='#cups_option_t'>cups_option_t</a> *options;
+int job_id;
+char *files[3] = { "file1.pdf", "file2.pdf", "file3.pdf" };
+
+/* Print three files */
+job_id = <a href='#cupsPrintFiles'>cupsPrintFiles</a>(dest->name, 3, files, "Test Print", num_options, options);
+</pre>
+
+<p>Finally, the <a href='#cupsCreateJob'><code>cupsCreateJob</code></a>
+function creates a new job with no files in it. Files are added using the
+<a href='#cupsStartDocument'><code>cupsStartDocument</code></a>, 
+<a href='api-httpipp.html#cupsWriteRequestData'><code>cupsWriteRequestData</code></a>,
+and <a href='#cupsFinishDocument'><code>cupsFinishDocument</code></a> functions.
+The following example creates a job with 10 text files for printing:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int num_options;
+<a href='#cups_option_t'>cups_option_t</a> *options;
+int job_id;
+int i;
+char buffer[1024];
+
+/* Create the job */
+job_id = <a href='#cupsCreateJob'>cupsCreateJob</a>(CUPS_HTTP_DEFAULT, dest->name, "10 Text Files", num_options, options);
+
+/* If the job is created, add 10 files */
+if (job_id > 0)
+{
+  for (i = 1; i &lt;= 10; i ++)
+  {
+    snprintf(buffer, sizeof(buffer), "file%d.txt", i);
+
+    <a href='#cupsStartDocument'>cupsStartDocument</a>(CUPS_HTTP_DEFAULT, dest->name, job_id, buffer, CUPS_FORMAT_TEXT, i == 10);
+
+    snprintf(buffer, sizeof(buffer),
+             "File %d\n"
+             "\n"
+             "One fish,\n"
+             "Two fish,\n
+             "Red fish,\n
+             "Blue fish\n", i);
+
+    /* cupsWriteRequestData can be called as many times as needed */
+    <a href='#cupsWriteRequestData'>cupsWriteRequestData</a>(CUPS_HTTP_DEFAULT, buffer, strlen(buffer));
+
+    <a href='#cupsFinishDocument'>cupsFinishDocument</a>(CUPS_HTTP_DEFAULT, dest->name);
+  }
+}
+</pre>
+
+<p>Once you have created a job, you can monitor its status using the
+<a href='#cupsGetJobs'><code>cupsGetJobs</code></a> function, which returns
+an array of <a href='#cups_job_t'><code>cups_job_t</code></a> structures.
+Each contains the job ID (<code>id</code>), destination name
+(<code>dest</code>), title (<code>title</code>), and other information
+associated with the job. The job array is freed using the
+<a href='#cupsFreeJobs'><code>cupsFreeJobs</code></a> function. The following
+example monitors a specific job ID, showing the current job state once every
+5 seconds until the job is completed:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int job_id;
+int num_jobs;
+<a href='#cups_job_t'>cups_job_t</a> *jobs;
+int i;
+ipp_jstate_t job_state = IPP_JOB_PENDING;
+while (job_state &lt; IPP_JOB_STOPPED)
+{
+  /* Get my jobs (1) with any state (-1) */
+  num_jobs = <a href='#cupsGetJobs'>cupsGetJobs</a>(&amp;jobs, dest->name, 1, -1);
+
+  /* Loop to find my job */
+  job_state = IPP_JOB_COMPLETED;
+
+  for (i = 0; i &lt; num_jobs; i ++)
+    if (jobs[i].id == job_id)
+    {
+      job_state = jobs[i].state;
+      break;
+    }
+
+  /* Free the job array */
+  <a href='#cupsFreeJobs'>cupsFreeJobs</a>(num_jobs, jobs);
+
+  /* Show the current state */
+  switch (job_state)
+  {
+    case IPP_JOB_PENDING :
+        printf("Job %d is pending.\n", job_id);
+        break;
+    case IPP_JOB_HELD :
+        printf("Job %d is held.\n", job_id);
+        break;
+    case IPP_JOB_PROCESSING :
+        printf("Job %d is processing.\n", job_id);
+        break;
+    case IPP_JOB_STOPPED :
+        printf("Job %d is stopped.\n", job_id);
+        break;
+    case IPP_JOB_CANCELED :
+        printf("Job %d is canceled.\n", job_id);
+        break;
+    case IPP_JOB_ABORTED :
+        printf("Job %d is aborted.\n", job_id);
+        break;
+    case IPP_JOB_COMPLETED :
+        printf("Job %d is completed.\n", job_id);
+        break;
+  }
+
+  /* Sleep if the job is not finished */
+  if (job_state &lt; IPP_JOB_STOPPED)
+    sleep(5);
+}
+</pre>
+
+<p>To cancel a job, use the
+<a href='#cupsCancelJob'><code>cupsCancelJob</code></a> function with the
+job ID:</p>
+
+<pre class='exmaple'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int job_id;
+
+<a href='#cupsCancelJob'>cupsCancelJob</a>(dest->name, job_id);
+</pre>
+
+<h3><a name='ERROR_HANDLING'>Error Handling</a></h3>
+
+<p>If any of the CUPS API printing functions returns an error, the reason for
+that error can be found by calling the
+<a href='#cupsLastError'><code>cupsLastError</code></a> and
+<a href='#cupsLastErrorString'><code>cupsLastErrorString</code></a> functions.
+<a href='#cupsLastError'><code>cupsLastError</code></a> returns the last IPP
+error code
+(<a href='api-httpipp.html#ipp_status_t'><code>ipp_status_t</code></a>)
+that was encountered, while
+<a href='#cupsLastErrorString'><code>cupsLastErrorString</code></a> returns
+a (localized) human-readable string that can be shown to the user. For example,
+if any of the job creation functions returns a job ID of 0, you can use
+<a href='#cupsLastErrorString'><code>cupsLastErrorString</code></a> to show
+the reason why the job could not be created:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+int job_id;
+
+if (job_id == 0)
+  puts(cupsLastErrorString());
+</pre>
+
+<h3><a name='PASSWORDS_AND_AUTHENTICATION'>Passwords and Authentication</a></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>
+
+<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>
+
+<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>
+
+<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>
+
+<p>The following example shows a simple password callback that gets a
+username and password from the user:</p>
+
+<pre class='example'>
+#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';
+
+  <a href='#cupsSetUser'>cupsSetUser</a>(user);
+
+  /* Use getpass() to ask for the password... */
+  return (getpass("Password: "));
+}
+
+<a href='#cupsSetPasswordCB'>cupsSetPasswordCB</a>(my_password_cb);
+</pre>
 
-<p>Unless otherwise specified, the CUPS API functions require
-CUPS 1.1 or higher.</p>
+<p>Similarly, a GUI could display the prompt string in a window with input
+fields for the username and password. The username should default to the
+string returned by the <a href="#cupsUser"><code>cupsUser</code></a>
+function.</p>
diff --git a/cups/api-filedir.header b/cups/api-filedir.header
new file mode 100644 (file)
index 0000000..7553115
--- /dev/null
@@ -0,0 +1,36 @@
+<!--
+  "$Id$"
+
+  File and Directory API header for the Common UNIX Printing System (CUPS).
+
+  Copyright 2008 by Apple Inc.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">File and Directory APIs</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+       <th>Headers</th>
+       <th>cups/file.h<br>
+       cups/dir.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <th>Library</th>
+       <td>-lcups</td>
+</tr>
+<tr>
+       <th>See Also</th>
+       <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
+       Programming: <a href='api-cups.html' target='_top'>CUPS API</a></td>
+</tr>
+</tbody>
+</table></div>
index b356e655cd350605e828021418b1239fa9331062..2b19efa8a8265b831efc93235c90034c098c5a97 100644 (file)
@@ -3,7 +3,7 @@
 
   File and directory API introduction for the Common UNIX Printing System (CUPS).
 
-  Copyright 2007 by Apple Inc.
+  Copyright 2007-2008 by Apple Inc.
   Copyright 1997-2005 by Easy Software Products, all rights reserved.
 
   These coded instructions, statements, and computer programs are the
   file is missing or damaged, see the license at "http://www.cups.org/".
 -->
 
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name="OVERVIEW">Overview</a></h2>
 
 <p>The CUPS file and directory APIs provide portable interfaces
 for manipulating files and listing files and directories. Unlike
-stdio <tt>FILE</tt> streams, the <tt>cupsFile</tt> functions
+stdio <code>FILE</code> streams, the <code>cupsFile</code> functions
 allow you to open more than 256 files at any given time. They
 also manage the platform-specific details of locking, large file
 support, line endings (CR, LF, or CR LF), and reading and writing
 files using Flate ("gzip") compression. Finally, you can also
 connect, read from, and write to network connections using the
-<tt>cupsFile</tt> functions.</p>
+<code>cupsFile</code> functions.</p>
 
-<p>The <tt>cupsDir</tt> functions manage the platform-specific
+<p>The <code>cupsDir</code> functions manage the platform-specific
 details of directory access/listing and provide a convenient way
 to get both a list of files and the information (permissions,
 size, timestamp, etc.) for each of those files.</p>
-
-<p>The CUPS scheduler (<tt>cupsd</tt>), <tt>mailto</tt> notifier,
-and many of the CUPS API functions use these functions for
-everything except console (stdin, stdout, stderr) I/O.</p>
-
-<h2 class='title'>General Usage</h2>
-
-<p>The <var>&lt;cups/dir.h&gt;</var> and
-<var>&lt;cups/file.h&gt;</var> header files must be included to
-use the <tt>cupsDir</tt> and <tt>cupsFile</tt> functions,
-respectively.</p>
-
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
-
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
-</pre>
-
-<h2 class='title'>Compatibility</h2>
-
-<p>All of these functions require CUPS 1.2 or higher.</p>
diff --git a/cups/api-filter.header b/cups/api-filter.header
new file mode 100644 (file)
index 0000000..f7ae6a3
--- /dev/null
@@ -0,0 +1,39 @@
+<!--
+  "$Id$"
+
+  Filter and backend programming header for the Common UNIX Printing System
+  (CUPS).
+
+  Copyright 2008 by Apple Inc.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">Filter and Backend Programming</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+       <th>Header</th>
+       <th>cups/backend.h<br>
+       cups/sidechannel.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <th>Library</th>
+       <td>-lcups</td>
+</tr>
+<tr>
+       <th>See Also</th>
+       <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
+       Programming: <a href='api-cups.html' target='_top'>CUPS API</a><br>
+       Programming: <a href='api-ppd.html' target='_top'>PPD API</a><br>
+       Programming: <a href='api-raster.html' target='_top'>Raster API</a></td>
+</tr>
+</tbody>
+</table></div>
index 0eda305c7a01d5297b2ecc20cb96a6ed27ad9947..4f72dfe7193fc9632f969f7d587b8fcdf25db776 100644 (file)
@@ -1,9 +1,10 @@
 <!--
   "$Id: api-filter.shtml 6649 2007-07-11 21:46:42Z mike $"
 
-  Filter and backend API introduction for the Common UNIX Printing System (CUPS).
+  Filter and backend programming introduction for the Common UNIX Printing
+  System (CUPS).
 
-  Copyright 2007 by Apple Inc.
+  Copyright 2007-2008 by Apple Inc.
   Copyright 1997-2006 by Easy Software Products, all rights reserved.
 
   These coded instructions, statements, and computer programs are the
   file is missing or damaged, see the license at "http://www.cups.org/".
 -->
 
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name="OVERVIEW">Overview</a></h2>
 
-<p>The CUPS filter and backend APIs define standard exit codes
-and provide access to the backchannel data stream. They are only
-used when writing backends, filters, and port monitors.</p>
+<p>Filters, printer drivers, port monitors, and backends use a common interface
+for processing print jobs and communicating status information to the scheduler.
+Each filter is run with a standard set of command-line arguments:<p>
 
-<h2 class='title'>General Usage</h2>
+<dl class="code">
 
-<p>The <var>&lt;cups/backend.h&gt;</var> and
-<var>&lt;cups/cups.h&gt;</var> header files must be included to
-use the <tt>CUPS_BACKEND_</tt> constants and
-<tt>cupsBackChannel</tt> functions, respectively.</p>
+       <dt>argv[1]</dt>
+       <dd>The job ID</dd>
 
-<p>The <var>&lt;cups/sidechannel.h&gt;</var> header file must be
-included to use the <tt>CUPS_SC_</tt> constants and <tt>cupsSideChannel</tt> functions.</p>
+       <dt>argv[2]</dt>
+       <dd>The user printing the job</dd>
 
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+       <dt>argv[3]</dt>
+       <dd>The job name/title</dd>
 
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
-</pre>
+       <dt>argv[4]</dt>
+       <dd>The number of copies to print</dd>
 
+       <dt>argv[5]</dt>
+       <dd>The options that were provided when the job was submitted</dd>
 
-<h2 class='title'>Compatibility</h2>
+       <dt>argv[6]</dt>
+       <dd>The file to print (first filter only)</dd>
+</dl>
 
-<p>The <tt>cupsBackChannel</tt> functions require CUPS 1.2 or higher. The <tt>cupsSideChannel</tt> functions require CUPS 1.3 or higher.</p>
+<p>The scheduler runs one or more of these programs to print any given job. The
+first filter reads from the print file and writes to the standard output, while
+the remaining filters read from the standard input and write to the standard
+output. The backend is the last filter in the chain and writes to the
+device.</p>
 
+<h3><a name="EXITCODES">Exit Codes</a></h3>
 
-<h2 class='title'>Using the cupsBackChannel APIs</h2>
+<p>Filters must exit with status 0 when they successfully generate print data
+or 1 when they encounter an error. Backends can return any of the
+<a href="#cups_backend_t"><code>cups_backend_t</code></a> constants.</p>
 
-<p>The <tt>cupsBackChannel</tt> APIs allow your filters, drivers, and port monitors to read data back from a printer and your backends to send data from a printer to the filters, drivers, and port monitors associated with the current job. Back-channel data is normally sent by the printer in response to a command sent from your program to the printer via <tt>stdout</tt>.</p>
+<h3><a name="ENVIRONMENT">Environment Variables</a></h3>
 
-<p>The <tt>cupsBackChannelRead()</tt> function reads data from the printer via the backend. You provide a timeout in seconds along with a buffer pointer and the size of that buffer. It returns the number of bytes or -1 if there was an error. The following code example shows how to poll for back-channel data in your program:</p>
+<p>The following environment variables are defined by the printing system:</p>
 
-<pre class='command'>
-#include &lt;cups/cups.h&gt;
+<dl class="code">
 
-char buffer[8192];
-ssize_t bytes;
+       <dt>APPLE_LANGUAGES</dt>
+       <dd>The Apple language identifier associated with the job
+       (Mac OS X only).</dd>
 
-/* Use a timeout of 0.0 seconds to poll for back-channel data */
-bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0);
-</pre>
+       <dt>CHARSET</dt>
+       <dd>The job character set, typically "utf-8".</dd>
 
-<p>If you are writing a backend, the <tt>cupsBackChannelWrite()</tt> function sends any back-channel data you have received from the printer to upstream filters in the print filter chain. We recommend using a timeout of 1.0 seconds:</p>
+       <dt>CLASS</dt>
+       <dd>When a job is submitted to a printer class, contains the name of
+       the destination printer class. Otherwise this environment
+       variable will not be set.</dd>
 
-<pre class='command'>
-#include &lt;cups/cups.h&gt;
+       <dt>CONTENT_TYPE</dt>
+       <dd>The MIME type associated with the file (e.g.
+       application/postscript).</dd>
 
-char buffer[8192];
-ssize_t bytes;
-
-/* Use a timeout of 1.0 seconds to give filters a chance to read */
-cupsBackChannelWrite(buffer, bytes, 1.0);
-</pre>
+       <dt>CUPS_CACHEDIR</dt>
+       <dd>The directory where cache files can be stored.</dd>
 
+       <dt>CUPS_DATADIR</dt>
+       <dd>The directory where data files can be found.</dd>
 
-<h2 class='title'>Using the cupsSideChannel APIs</h2>
+       <dt>CUPS_SERVERROOT</dt>
+       <dd>The root directory of the server.</dd>
 
-<p>The <tt>cupsSideChannel</tt> APIs allow your filters, drivers, port monitors, and backend to send and receive the following out-of-band commands:</p>
+       <dt>DEVICE_URI</dt>
+       <dd>The device-uri associated with the printer.</dd>
 
-<ul>
+       <dt>FINAL_CONTENT_TYPE</dt>
+       <dd>The MIME type associated with the printer (e.g.
+       application/vnd.cups-postscript).</dd>
 
-       <li><tt>CUPS_SC_CMD_SOFT_RESET</tt> -  Do a soft reset</li>
-       <li><tt>CUPS_SC_CMD_DRAIN_OUTPUT</tt> -  Drain all pending output</li>
-       <li><tt>CUPS_SC_CMD_GET_BIDI</tt> -  Return bidirectional capabilities</li>
-       <li><tt>CUPS_SC_CMD_GET_DEVICE_ID</tt> -  Return the IEEE-1284 device ID</li>
-       <li><tt>CUPS_SC_CMD_GET_STATE</tt> - Return the device state</li>
+       <dt>LANG</dt>
+       <dd>The language locale associated with the job.</dd>
 
-</ul>
+       <dt>PPD</dt>
+       <dd>The full pathname of the PostScript Printer Description (PPD)
+       file for this printer.</dd>
 
+       <dt>PRINTER</dt>
+       <dd>The name of the printer.</dd>
 
-<h3>Sending Commands from a Filter, Driver, or Port Monitor</h3>
+       <dt>RIP_CACHE</dt>
+       <dd>The recommended amount of memory to use for Raster Image
+       Processors (RIPs).</dd>
 
-<p>The <tt>cupsSideChannelDoRequest()</tt> function is used by filters, drivers, and port monitors to send a command to the backend and read back a response:</p>
-
-<pre class='command'>
-cups_sc_status_t cupsSideChannelDoRequest(cups_sc_command_t command,
-                                          char *data, int *datalen,
-                                          double timeout);
-</pre>
+</dl>
 
-<p>The <tt>CUPS_SC_CMD_SOFT_RESET</tt> and <tt>CUPS_SC_CMD_DRAIN_OUTPUT</tt> commands do not return any data values, while the others return one or more bytes. The <tt>timeout</tt> parameter allows your program to poll or wait for the command to complete - use a timeout of 30 seconds for <tt>CUPS_SC_CMD_SOFT_RESET</tt> and <tt>CUPS_SC_CMD_DRAIN_OUTPUT</tt> and a timeout of 1 second for all other commands.</p>
+<h3><a name="MESSAGES">Communicating with the Scheduler</a></h3>
 
-<p><tt>CUPS_SC_CMD_GET_BIDI</tt> returns a single <tt>char</tt> value that tells you whether the backend supports bidirectional communications:</p>
+<p>Filters and backends communicate wih the scheduler by writing messages
+to the standard error file. For example, the following code sets the current
+printer state message to "Printing page 5":</p>
 
-<pre class='command'>
-#include &lt;cups/sidechannel.h&gt;
+<pre class="example">
+int page = 5;
 
-char data;
-int datalen;
-cups_sc_bidi_t bidi;
-cups_sc_status_t status;
+fprintf(stderr, "INFO: Printing page %d\n", page);
+</pre>
 
-/* Tell cupsSideChannelDoRequest() how big our buffer is... */
-datalen = 1;
+<p>Each message is a single line of text starting with one of the following
+prefix strings:</p>
+
+<dl class="code">
+
+       <dt>ALERT: message</dt>
+       <dd>Sets the printer-state-message attribute and adds the specified
+       message to the current error log file using the "alert" log level.</dd>
+
+       <dt>ATTR: attribute=value [attribute=value]</dt>
+       <dd>Sets the named printer or job attribute(s). Typically this is used
+       to set the <code>marker-colors</code>, <code>marker-levels</code>,
+       <code>marker-names</code>, <code>marker-types</code>,
+       <code>printer-alert</code>, and <code>printer-alert-description</code>
+       printer attributes.</dd>
+
+       <dt>CRIT: message</dt>
+       <dd>Sets the printer-state-message attribute and adds the specified
+       message to the current error log file using the "critical" log
+       level.</dd>
+
+       <dt>DEBUG: message</dt>
+       <dd>Sets the printer-state-message attribute and adds the specified
+       message to the current error log file using the "debug" log level.</dd>
+
+       <dt>DEBUG2: message</dt>
+       <dd>Sets the printer-state-message attribute and adds the specified
+       message to the current error log file using the "debug2" log level.</dd>
+
+       <dt>EMERG: message</dt>
+       <dd>Sets the printer-state-message attribute and adds the specified
+       message to the current error log file using the "emergency" log
+       level.</dd>
+
+       <dt>ERROR: message</dt>
+       <dd>Sets the printer-state-message attribute and adds the specified
+       message to the current error log file using the "error" log level.</dd>
+
+       <dt>INFO: message</dt>
+       <dd>Sets the printer-state-message attribute. If the current log level
+       is set to "debug2", also adds the specified message to the current error
+       log file using the "info" log level.</dd>
+
+       <dt>NOTICE: message</dt>
+       <dd>Sets the printer-state-message attribute and adds the specified
+       message to the current error log file using the "notice" log level.</dd>
+
+       <dt>PAGE: page-number #-copies</dt>
+       <dt>PAGE: total #-pages</dt>
+       <dd>Adds an entry to the current page log file. The first form adds
+       #-copies to the job-media-sheets-completed attribute. The second
+       form sets the job-media-sheets-completed attribute to #-pages.</dd>
+
+       <dt>STATE: printer-state-reason [printer-state-reason ...]</dt>
+       <dt>STATE: + printer-state-reason [printer-state-reason ...]</dt>
+       <dt>STATE: - printer-state-reason [printer-state-reason ...]</dt>
+       <dd>Sets, adds, or removes printer-state-reason keywords to the
+       current queue. Typically this is used to indicate media, ink, and
+       toner conditions on a printer.</dd>
+
+       <dt>WARNING: message</dt>
+       <dd>Sets the printer-state-message attribute and adds the specified
+       message to the current error log file using the "warning" log
+       level.</dd>
+
+</dl>
+
+<p>Messages without one of these prefixes are treated as if they began with
+the "DEBUG:" prefix string.</p>
+
+<h3><a name="COMMUNICATING">Communicating with the Backend</a></h3>
+
+<p>Filters can communicate with the backend via the
+<a href="#cupsBackChannelRead"><code>cupsBackChannelRead</code></a> and
+<a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a>
+functions. The 
+<a href="#cupsBackChannelRead"><code>cupsBackChannelRead</code></a> function
+reads data that has been sent back from the device and is typically used to
+obtain status and configuration information. For example, the following code
+polls the backend for back-channel data:</p>
+
+<pre class="example">
+#include &lt;cups/cups.h&gt;
 
-/* Get the bidirectional capabilities, waiting for up to 1 second */
-status  = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_BIDI, &amp;data, &amp;datalen, 1.0);
+char buffer[8192];
+ssize_t bytes;
 
-/* Use the returned value if OK was returned and the length is still 1 */
-if (status == CUPS_SC_STATUS_OK && datalen == 1)
-  bidi = (cups_sc_bidi_t)data;
-else
-  bidi = CUPS_SC_BIDI_NOT_SUPPORTED;
+/* Use a timeout of 0.0 seconds to poll for back-channel data */
+bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0);
 </pre>
 
-<p><tt>CUPS_SC_CMD_GET_DEVICE_ID</tt> returns a string of characters containing the IEEE-1284 device ID for the connected printer:</p>
+The
+<a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a>
+function allows you to get out-of-band status information and do synchronization
+with the device. For example, the following code gets the current IEEE-1284
+device ID string from the backend:</p>
 
-<pre class='command'>
+<pre class="example">
 #include &lt;cups/sidechannel.h&gt;
 
 char data[2049];
 int datalen;
-cups_sc_status_t status;
+<a href="#cups_sc_status_t">cups_sc_status_t</a> status;
 
 /* Tell cupsSideChannelDoRequest() how big our buffer is, less 1 byte for nul-termination... */
 datalen = sizeof(data) - 1;
 
 /* Get the IEEE-1284 device ID, waiting for up to 1 second */
-status  = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_DEVICE_ID, data, &amp;datalen, 1.0);
+status = <a href="#cupsSideChannelDoRequest">cupsSideChannelDoRequest</a>(CUPS_SC_CMD_GET_DEVICE_ID, data, &amp;datalen, 1.0);
 
 /* Use the returned value if OK was returned and the length is non-zero */
 if (status == CUPS_SC_STATUS_OK && datalen > 0)
@@ -147,59 +236,53 @@ else
   data[0] = '\0';
 </pre>
 
-<p><tt>CUPS_SC_CMD_GET_STATE</tt> returns a single <tt>char</tt> value that tells you the current device state:</p>
-
-<pre class='command'>
-#include &lt;cups/sidechannel.h&gt;
+<p>Backends communicate with filters using the reciprocal functions
+<a href="#cupsBackChannelWrite"><code>cupsBackChannelWrite</code></a>,
+<a href="#cupsSideChannelRead"><code>cupsSideChannelRead</code></a>, and
+<a href="#cupsSideChannelWrite"><code>cupsSideChannelWrite</code></a>. We
+recommend writing back-channel data using a timeout of 1.0 seconds:</p>
 
-char data;
-int datalen;
-cups_sc_state_t state;
-cups_sc_status_t status;
-
-/* Tell cupsSideChannelDoRequest() how big our buffer is... */
-datalen = 1;
-
-/* Get the bidirectional capabilities, waiting for up to 1 second */
-status  = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_STATE, &amp;data, &amp;datalen, 1.0);
-
-/* Use the returned value if OK was returned and the length is still 1 */
-if (status == CUPS_SC_STATUS_OK && datalen == 1)
-  state = (cups_sc_state_t)data;
-else
-  state = CUPS_SC_STATE_OFFLINE;
-</pre>
-
-
-<h3>Handling Commands in your Backend</h3>
+<pre class="example">
+#include &lt;cups/cups.h&gt;
 
-<p>The <tt>cupsSideChannelRead()</tt> function is used by backends to read a command from a filter, driver, or port monitor:</p>
+char buffer[8192];
+ssize_t bytes;
 
-<pre class='command'>
-int cupsSideChannelRead(cups_sc_command_t &amp;command,
-                        cups_sc_status_t  &amp;status,
-                        char *data, int *datalen, double timeout);
+/* Use a timeout of 1.0 seconds to give filters a chance to read */
+cupsBackChannelWrite(buffer, bytes, 1.0);
 </pre>
 
-<p>Backends can either poll for commands using a <tt>timeout</tt> of 0.0, wait indefinitely for commands using a <tt>timeout</tt> of -1.0 (probably in a separate thread for that purpose), or use <tt>select()</tt> or <tt>poll()</tt> on the <tt>CUPS_SC_FD</tt> file descriptor (4) to handle input and output on several file descriptors at the same time. Backends can pass <tt>NULL</tt> for the <tt>data</tt> and <tt>datalen</tt> parameters, since none of the commands sent by upstream filters contain any data at this time.</p>
-
-<p>Once a command is processed, the backend uses the <tt>cupsSideChannelWrite()</tt> function to send its response:</p>
-
-<pre class='command'>
+<p>The <a href="#cupsSideChannelRead"><code>cupsSideChannelRead</code></a>
+function reads a side-channel command from a filter, driver, or port monitor.
+Backends can either poll for commands using a <code>timeout</code> of 0.0, wait
+indefinitely for commands using a <code>timeout</code> of -1.0 (probably in a
+separate thread for that purpose), or use <code>select</code> or
+<code>poll</code> on the <code>CUPS_SC_FD</code> file descriptor (4) to handle
+input and output on several file descriptors at the same time. Backends can pass
+<code>NULL</code> for the <code>data</code> and <code>datalen</code> parameters
+since none of the commands sent by upstream filters contain any data at this
+time.</p>
+
+<p>Once a command is processed, the backend uses the
+<a href="#cupsSideChannelWrite"><code>cupsSideChannelWrite</code></a> function
+to send its response. For example, the following code shows how to poll for a
+side-channel command and respond to it:</p>
+
+<pre class="example">
 #include &lt;cups/sidechannel.h&gt;
 
-cups_sc_command_t command;
-cups_sc_status_t status;
+<a href="#cups_sc_command_t">cups_sc_command_t</a> command;
+<a href="#cups_sc_status_t">cups_sc_status_t</a> status;
 
 /* Poll for a command... */
-if (!cupsSideChannelRead(&amp;command, &amp;status, NULL, NULL, 0.0))
+if (!<a href="#cupsSideChannelRead">cupsSideChannelRead</a>(&amp;command, &amp;status, NULL, NULL, 0.0))
 {
   char data[2048];
   int datalen;
 
   switch (command)
   {
-    ... handle supported commands, file data/datalen/status with values as needed ...
+    /* handle supported commands, file data/datalen/status with values as needed */
 
     default :
         status  = CUPS_SC_STATUS_NOT_IMPLEMENTED;
@@ -208,6 +291,6 @@ if (!cupsSideChannelRead(&amp;command, &amp;status, NULL, NULL, 0.0))
   }
 
   /* Send a response... */
-  cupsSideChannelWrite(command, status, data, datalen, 1.0);
+  <a href="#cupsSideChannelWrite">cupsSideChannelWrite</a>(command, status, data, datalen, 1.0);
 }
 </pre>
diff --git a/cups/api-httpipp.header b/cups/api-httpipp.header
new file mode 100644 (file)
index 0000000..03d5a8d
--- /dev/null
@@ -0,0 +1,37 @@
+<!--
+  "$Id$"
+
+  HTTP and IPP API header for the Common UNIX Printing System (CUPS).
+
+  Copyright 2007-2008 by Apple Inc.
+  Copyright 1997-2006 by Easy Software Products, all rights reserved.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">HTTP and IPP APIs</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+       <th>Header</th>
+       <th>cups/cups.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <th>Library</th>
+       <td>-lcups</td>
+</tr>
+<tr>
+       <th>See Also</th>
+       <td>Programming: <a href='api-overview.html'>Introduction to CUPS Programming</a><br>
+       Programming: <a href='api-cups.html'>CUPS API</a><br>
+       References: <a href='spec-ipp.html'>CUPS Implementation of IPP</a></td>
+</tr>
+</tbody>
+</table></div>
index 93e34f9345b77a4616984a8ca76bb54e21b2b591..b755b7dedbae0db7787b193c5872c684b58237aa 100644 (file)
@@ -3,7 +3,7 @@
 
   HTTP and IPP API introduction for the Common UNIX Printing System (CUPS).
 
-  Copyright 2007 by Apple Inc.
+  Copyright 2007-2008 by Apple Inc.
   Copyright 1997-2006 by Easy Software Products, all rights reserved.
 
   These coded instructions, statements, and computer programs are the
   file is missing or damaged, see the license at "http://www.cups.org/".
 -->
 
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
 
-<p>The CUPS HTTP and IPP APIs provide low-level access to the
-HTTP and IPP protocols and CUPS scheduler. They are typically
-used by monitoring and administration programs to perform
-specific functions not supported by the high-level CUPS API
-functions.</p>
+<p>The CUPS HTTP and IPP APIs provide low-level access to the HTTP and IPP
+protocols and CUPS scheduler. They are typically used by monitoring and
+administration programs to perform specific functions not supported by the
+high-level CUPS API functions.</p>
 
-<h2 class='title'>General Usage</h2>
+<p>The HTTP APIs use an opaque structure called
+<a href='#http_t'><code>http_t</code></a> to manage connections to
+a particular HTTP or IPP server. The
+<a href='#httpConnectEncrypt'><code>httpConnectEncrypt</code></a> function is
+used to create an instance of this structure for a particular server.
+The constant <code>CUPS_HTTP_DEFAULT</code> can be used with all of the
+<code>cups</code> functions to refer to the default CUPS server - the functions
+create a per-thread <a href='#http_t'><code>http_t</code></a> as needed.</p>
 
-<p>The <var>&lt;cups/cups.h&gt;</var> header file must be included to
-use the HTTP and IPP functions.</p>
+<p>The IPP APIs use two structures for requests (messages sent to the CUPS
+scheduler) and responses (messages sent back to your application from the
+scheduler). The <a href='#ipp_t'><code>ipp_t</code></a> structure holds a
+complete request or response and is allocated using the
+<a href='#ippNew'><code>ippNew</code></a> or
+<a href='#ippNewRequest'><code>ippNewRequest</code></a> functions and
+freed using the <a href='#ippDelete'><code>ippDelete</code></a> function.</p>
 
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+<p>The second structure is called
+<a href='#ipp_attribute_t'><code>ipp_attribute_t</code></a> and holds a
+single IPP attribute which consists of a group tag (<code>group_tag</code>), a
+value type tag (<code>value_tag</code>), the attribute name (<code>name</code>),
+and 1 or more values (<code>values[]</code>). Attributes are added to an
+<a href='#ipp_t'><code>ipp_t</code></a> structure using one of the
+<code>ippAdd</code> functions. For example, use
+<a href='#ippAddString'><code>ippAddString</code></a> to add a
+"requesting-user-name" string attribute to a request:</p>
 
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
+<pre class='example'>
+<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(IPP_GET_JOBS);
+
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+             NULL, cupsUser());
+</pre>
+
+<p>Once you have created an IPP request, use the <code>cups</code>
+functions to send the request to and read the response from the server.
+For example, the <a href='#cupsDoRequest'><code>cupsDoRequest</code></a>
+function can be used for simple query operations that do not involve files:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+
+<a href='#ipp_t'>ipp_t</a> *<a name='get_jobs'>get_jobs</a>(void)
+{
+  <a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(IPP_GET_JOBS);
+
+  <a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+               NULL, cupsUser());
+
+  return (<a href='#cupsDoRequest'>cupsDoRequest</a>(CUPS_HTTP_DEFAULT, request, "/"));
+}
+</pre>
+
+<p>The <a href='#cupsDoRequest'><code>cupsDoRequest</code></a> function frees
+the request structure and returns an IPP response structure or NULL pointer if
+the request could not be sent to the server. Once you have a response from
+the server, you can either use the
+<a href='#ippFindAttribute'><code>ippFindAttribute</code></a> and
+<a href='#ippFindNextAttribute'><code>ippFindNextAttribute</code></a> functions
+to find specific attributes, for example:</p>
+
+<pre class='example'>
+<a href='#ipp_t'>ipp_t</a> *response;
+<a href='#ipp_attribute_t'>ipp_attribute_t</a> *attr;
+
+attr = <a href='#ippFindAttribute'>ippFindAttribute</a>(response, "printer-state", IPP_TAG_ENUM);
+</pre>
+
+<p>You can also walk the list of attributes with a simple <code>for</code> loop
+like this:</p>
+
+<pre class='example'>
+<a href='#ipp_t'>ipp_t</a> *response;
+<a href='#ipp_attribute_t'>ipp_attribute_t</a> *attr;
+
+for (attr = response->attrs; attr != NULL; attr = attr->next)
+  if (attr->name == NULL)
+    puts("--SEPARATOR--");
+  else
+    puts(attr->name);
 </pre>
 
-<h2 class='title'>Compatibility</h2>
+<p>The <code>for</code> loop approach is normally used when collecting
+attributes for multiple objects (jobs, printers, etc.) in a response. Attributes
+with <code>NULL</code> names indicate a separator between the attributes of
+each object. For example, the following code will list the jobs returned from
+our previous <a href='#get_jobs'><code>get_jobs</code></a> example code:</p>
+
+<pre class='example'>
+<a href='#ipp_t'>ipp_t</a> *response = <a href='#get_jobs'>get_jobs</a>();
+
+if (response != NULL)
+{
+  <a href='#ipp_attribute_t'>ipp_attribute_t</a> *attr;
+  int job_id = 0;
+  char *job_name = NULL;
+  char *job_originating_user_name = NULL;
+
+  puts("Job ID  Owner             Title");
+  puts("------  ----------------  ---------------------------------");
+
+  for (attr = response->attrs; attr != NULL; attr = attr->next)
+  {
+   /* Attributes without names are separators between jobs */
+    if (attr->name == NULL)
+    {
+      if (job_id > 0 &amp;&amp; job_name != NULL &amp;&amp; job_originating_user_name != NULL)
+        printf("%5d  %-16s  %s\n", job_id, job_originating_user_name, job_name);
+
+      job_id = 0;
+      job_name = NULL;
+      job_originating_user_name = NULL;
+      continue;
+    }
+    else if (!strcmp(attr->name, "job-id") &amp;&amp; attr->value_tag == IPP_TAG_INTEGER)
+      job_id = attr->values[0].integer;
+    else if (!strcmp(attr->name, "job-name") &amp;&amp; attr->value_tag == IPP_TAG_NAME)
+      job_name = attr->values[0].string.text;
+    else if (!strcmp(attr->name, "job-originating-user-name") &amp;&amp;
+             attr->value_tag == IPP_TAG_NAME)
+      job_originating_user_name = attr->values[0].string.text;
+  }
+
+  if (job_id > 0 &amp;&amp; job_name != NULL &amp;&amp; job_originating_user_name != NULL)
+    printf("%5d  %-16s  %s\n", job_id, job_originating_user_name, job_name);
+}
+</pre>
+
+<h3><a name='CREATING_URI_STRINGS'>Creating URI Strings</a></h3>
+
+<p>To ensure proper encoding, the
+<a href='#httpAssembleURIf'><code>httpAssembleURIf</code></a> function must be
+used to format a "printer-uri" string for all printer-based requests:</p>
+
+<pre class='example'>
+const char *name = "Foo";
+char uri[1024];
+<a href='#ipp_t'>ipp_t</a> *request;
+
+<a href='#httpAssembleURIf'>httpAssembleURIf</a>(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, cupsServer(),
+                 ippPort(), "/printers/%s", name);
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
+</pre>
+
+<h3><a name='SENDING_REQUESTS_WITH_FILES'>Sending Requests with Files</a></h3>
+
+<p>The <a href='#cupsDoFileRequest'><code>cupsDoFileRequest</code></a> and
+<a href='#cupsDoIORequest'><code>cupsDoIORequest</code></a> functions are
+used for requests involving files. The
+<a href='#cupsDoFileRequest'><code>cupsDoFileRequest</code></a> function
+attaches the named file to a request and is typically used when sending a print
+file or changing a printer's PPD file:</p>
+
+<pre class='example'>
+const char *filename = "/usr/share/cups/data/testprint.ps";
+const char *name = "Foo";
+char uri[1024];
+char resource[1024];
+<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(IPP_PRINT_JOB);
+<a href='#ipp_t'>ipp_t</a> *response;
+
+/* Use httpAssembleURIf for the printer-uri string */
+<a href='#httpAssembleURIf'>httpAssembleURIf</a>(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, cupsServer(),
+                 ippPort(), "/printers/%s", name);
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+             NULL, cupsUser());
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
+             NULL, "testprint.ps");
 
-<p>Unless otherwise specified, the HTTP and IPP API functions
-require CUPS 1.1 or higher.</p>
+/* Use snprintf for the resource path */
+snprintf(resource, sizeof(resource), "/printers/%s", name);
+
+response = <a href='#cupsDoFileRequest'>cupsDoFileRequest</a>(CUPS_HTTP_DEFAULT, request, resource, filename);
+</pre>
+
+<p>The <a href='#cupsDoIORequest'><code>cupsDoIORequest</code></a> function
+optionally attaches a file to the request and optionally saves a file in the
+response from the server. It is used when using a pipe for the request
+attachment or when using a request that returns a file, currently only
+<code>CUPS_GET_DOCUMENT</code> and <code>CUPS_GET_PPD</code>. For example,
+the following code will download the PPD file for the sample HP LaserJet
+printer driver:</p>
+
+<pre class='example'>
+char tempfile[1024];
+int tempfd;
+<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(CUPS_GET_PPD);
+<a href='#ipp_t'>ipp_t</a> *response;
+
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
+             NULL, "laserjet.ppd");
+
+tempfd = cupsTempFd(tempfile, sizeof(tempfile));
+
+response = <a href='#cupsDoIORequest'>cupsDoIORequest</a>(CUPS_HTTP_DEFAULT, request, "/", -1, tempfd);
+</pre>
+
+<p>The example passes <code>-1</code> for the input file descriptor to specify
+that no file is to be attached to the request. The PPD file attached to the
+response is written to the temporary file descriptor we created using the
+<code>cupsTempFd</code> function.</p>
+
+<h3><a name='ASYNCHRONOUS_REQUEST_PROCESSING'>Asynchronous Request Processing</a></h3>
+
+<p>The <a href='#cupsSendRequest'><code>cupsSendRequest</code></a> and
+<a href='#cupsGetResponse'><code>cupsGetResponse</code></a> support
+asynchronous communications with the server. Unlike the other request
+functions, the IPP request is not automatically freed, so remember to
+free your request with the <a href='#ippDelete'><code>ippDelete</code></a>
+function.</p>
+
+<p>File data is attached to the request using the
+<a href='#cupsWriteRequestData'><code>cupsWriteRequestData</code></a>
+function, while file data returned from the server is read using the
+<a href='#cupsReadResponseData'><code>cupsReadResponseData</code></a>
+function. We can rewrite the previous <code>CUPS_GET_PPD</code> example
+to use the asynchronous functions quite easily:</p>
+
+<pre class='example'>
+char tempfile[1024];
+int tempfd;
+<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(CUPS_GET_PPD);
+<a href='#ipp_t'>ipp_t</a> *response;
+
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
+             NULL, "laserjet.ppd");
+
+tempfd = cupsTempFd(tempfile, sizeof(tempfile));
+
+if (<a href='#cupsSendRequest'>cupsSendRequest</a>(CUPS_HTTP_DEFAULT, request, "/") == HTTP_CONTINUE)
+{
+  response = <a href='#cupsGetResponse'>cupsGetResponse</a>(CUPS_HTTP_DEFAULT, "/");
+
+  if (response != NULL)
+  {
+    ssize_t bytes;
+    char buffer[8192];
+
+    while ((bytes = <a href='#cupsReadResponseData'>cupsReadResponseData</a>(CUPS_HTTP_DEFAULT, buffer, sizeof(buffer))) > 0)
+      write(tempfd, buffer, bytes);
+  }
+}
+
+/* Free the request! */
+<a href='#ippDelete'>ippDelete</a>(request);
+</pre>
+
+<p>The <a href='#cupsSendRequest'><code>cupsSendRequest</code></a> function
+returns the initial HTTP request status, typically either
+<code>HTTP_CONTINUE</code> or <code>HTTP_UNAUTHORIZED</code>. The latter status
+is returned when the request requires authentication of some sort. The
+<a href='#cupsDoAuthentication'><code>cupsDoAuthentication</code></a> function
+must be called when your see <code>HTTP_UNAUTHORIZED</code> and the request
+re-sent. We can add authentication support to our example code by using a
+<code>do ... while</code> loop:</p>
+
+<pre class='example'>
+char tempfile[1024];
+int tempfd;
+<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(CUPS_GET_PPD);
+<a href='#ipp_t'>ipp_t</a> *response;
+http_status_t status;
+
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
+             NULL, "laserjet.ppd");
+
+tempfd = cupsTempFd(tempfile, sizeof(tempfile));
+
+/* Loop for authentication */
+do
+{
+  status = a href='#cupsSendRequest'>cupsSendRequest</a>(CUPS_HTTP_DEFAULT, request, "/");
+
+  if (status == HTTP_UNAUTHORIZED)
+  {
+    /* Try to authenticate, break out of the loop if that fails */
+    if (<a href='#cupsDoAuthentication'>cupsDoAuthentication</a>(CUPS_HTTP_DEFAULT, "POST", "/"))
+      break;
+  }
+}
+while (status != HTTP_CONTINUE &amp;&amp; status != HTTP_UNAUTHORIZED);
+
+if (status == HTTP_CONTINUE)
+{
+  response = <a href='#cupsGetResponse'>cupsGetResponse</a>(CUPS_HTTP_DEFAULT, "/");
+
+  if (response != NULL)
+  {
+    ssize_t bytes;
+    char buffer[8192];
+
+    while ((bytes = <a href='#cupsReadResponseData'>cupsReadResponseData</a>(CUPS_HTTP_DEFAULT, buffer, sizeof(buffer))) > 0)
+      write(tempfd, buffer, bytes);
+  }
+}
+
+/* Free the request! */
+<a href='#ippDelete'>ippDelete</a>(request);
+</pre>
diff --git a/cups/api-overview.header b/cups/api-overview.header
new file mode 100644 (file)
index 0000000..51dbb27
--- /dev/null
@@ -0,0 +1,49 @@
+<!--
+  "$Id: api-cups.header 7279 2008-01-31 01:50:44Z mike $"
+
+  Introduction to CUPS programming header for the Common UNIX Printing System
+  (CUPS).
+
+  Copyright 2008 by Apple Inc.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">Introduction to CUPS Programming</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+       <th>Headers</th>
+       <th>cups/cups.h<br>
+       cups/array.h<br>
+       cups/backend.h<br>
+       cups/dir.h<br>
+       cups/file.h<br>
+       cups/ppd.h<br>
+       cups/raster.h<br>
+       cups/sidechannel.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <th>Libraries</th>
+       <td>-lcups<br>
+       -lcupsimage</td>
+</tr>
+<tr>
+       <th>See Also</th>
+       <td>Programming: <a href='api-cups.html' target='_top'>CUPS API</a><br>
+       Programming: <a href='api-array.html' target='_top'>Array API</a><br>
+       Programming: <a href='api-filedir.html' target='_top'>File and Directory APIs</a><br>
+       Programming: <a href='api-filter.html' target='_top'>Filter and Backend Programming</a><br>
+       Programming: <a href='api-httpipp.html' target='_top'>HTTP and IPP APIs</a><br>
+       Programming: <a href='api-ppd.html' target='_top'>PPD API</a><br>
+       Programming: <a href='api-raster.html' target='_top'>Raster API</a></td>
+</tr>
+</tbody>
+</table></div>
diff --git a/cups/api-overview.shtml b/cups/api-overview.shtml
new file mode 100644 (file)
index 0000000..dd1d606
--- /dev/null
@@ -0,0 +1,95 @@
+<!--
+  "$Id: api-cups.header 7279 2008-01-31 01:50:44Z mike $"
+
+  Introduction to CUPS programming content for the Common UNIX Printing System
+  (CUPS).
+
+  Copyright 2008 by Apple Inc.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h2 class="title"><a name="OVERVIEW">Overview</a></h2>
+
+<p>CUPS provides two libraries that interface with the different parts of the
+printing system. The "cups" library provides all of the common application and
+filter functions while the "cupsimage" library provides all of the imaging
+functions used in raster printer drivers. The "cups" library functions are
+accessed by including the <var>&lt;cups/cups.h&gt;</var> header, while
+"cupsimage" functions are found in the <var>&lt;cups/raster.h&gt;</var>
+header.</p>
+
+<h2 class="title"><a name="COMPILING">Compiling Programs</a></h2>
+
+<p>The CUPS libraries can be used from any C, C++, or Objective C program.
+The method of compiling against the libraries varies depending on the
+operating system and installation of CUPS. The following sections show how
+to compile a simple program (shown below) in two common environments.</p>
+
+<p>The following simple program lists the available printers on the system:</p>
+
+<pre class="example">
+#include &lt;stdio.h&gt;
+#include &lt;cups/cups.h&gt;
+
+int main(void)
+{
+  int i;
+  cups_dest_t *dests, *dest;
+  int num_dests = cupsGetDests(&amp;dests);
+
+  for (i = num_dests, dest = dests; i &gt; 0; i --, dest ++)
+  {
+    if (dest->instance)
+      printf("%s/%s\n", dest->name, dest->instance);
+    else
+      puts(dest->name);
+  }
+
+  return (0);
+}
+</pre>
+
+<h3><a name="XCODE">Compiling with Xcode</a></h3>
+
+<p>In Xcode, choose <var>New Project...</var> from the <var>File</var> menu,
+then select the <var>Standard Tool</var> project type under <var>Command Line
+Utility</var>. Click <var>Next</var> and choose a project directory. Click
+<var>Next</var> to create the project.</p>
+
+<p>In the project window, double-click on the <var>Targets</var> group and
+control-click on the simple target to show the context menu. Choose
+<var>Existing Framework...</var> from the <var>Add</var> submenu. When the file
+chooser sheet appears, press the <kbd>/</kbd> key and enter "/usr/lib". Scroll
+down the file list and select the <var>libcups.dylib</var> file. Click the
+<var>Add</var> button in the file chooser and attributes sheets.</p>
+
+<p>In the project window, double-click on the <var>main.c</var> source file.
+Replace the template source code with the listing above and save it. Click the
+<var>Build and Go</var> button to build the sample program and run it.</p>
+
+<h3><a name="COMMANDLINE">Compiling with GCC</a></h3>
+
+<p>From the command-line, create a file called <var>sample.c</var> using your
+favorite editor and then run the following command to compile it with GCC and
+run it:</p>
+
+<pre class="command">
+gcc -o simple `cups-config --cflags` simple.c `cups-config --libs`
+./simple
+</pre>
+
+<p>The <code>cups-config</code> command provides the compiler flags
+("cups-config --cflags") and libraries ("cups-config --libs") needed for the
+local system.</p>
+
+<h2 class="title"><a name="WHERETOGO">Where to Go Next</a></h2>
+
+<p>If you are developing a print filter, driver, or backend, see the
+<a href="api-filter.html" target="_top">Filter and Backend Programming</a>
+guide. Raster printer driver developers should also read the
+<a href="api-raster.html" target="_top">Raster API</a> reference.</p>
diff --git a/cups/api-ppd.header b/cups/api-ppd.header
new file mode 100644 (file)
index 0000000..dfcb26a
--- /dev/null
@@ -0,0 +1,36 @@
+<!--
+  "$Id$"
+
+  PPD API header for the Common UNIX Printing System (CUPS).
+
+  Copyright 2008 by Apple Inc.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">PPD API</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+       <th>Header</th>
+       <th>cups/ppd.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <th>Library</th>
+       <td>-lcups</td>
+</tr>
+<tr>
+       <th>See Also</th>
+       <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
+       Programming: <a href='api-cups.html' target='_top'>CUPS API</a><br>
+       Reference: <a href='spec-ppd.html' target='_top'>CUPS PPD Specification</a></td>
+</tr>
+</tbody>
+</table></div>
index 497e7ae6b564fc382a13e4733d62184fc9a6fa9c..c1c2402d3b7eace7eb984d5844bcbe825f2bc169 100644 (file)
   file is missing or damaged, see the license at "http://www.cups.org/".
 -->
 
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
 
-<p>The CUPS PPD API provides read-only access the data in
-PostScript Printer Description ("PPD") files. With it you can
-display printer options to users, mark option choices and check
-for conflicting choices, and output marked choices in PostScript
-output.</p>
+<p>The CUPS PPD API provides read-only access the data in PostScript Printer
+Description ("PPD") files which are used for all printers with a driver. With
+it you can display printer options to users, mark option choices and check for
+conflicting choices, and output marked choices in PostScript output. The
+<a href="#ppd_file_t"><code>ppd_file_t</code></a> structure contains all of
+the information in a PPD file.</p>
 
-<h2 class='title'>General Usage</h2>
+<h3><a name="LOADING">Loading a PPD File</a></h3>
 
-<p>The <var>&lt;cups/ppd.h&gt;</var> header file must be included
-to use the <tt>ppd</tt> functions.</p>
+<p>The <a href="#ppdOpenFile"><code>ppdOpenFile</code></a> function "opens" a
+PPD file and loads it into memory. For example, the following code opens the
+current printer's PPD file in a CUPS filter:</p>
 
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
 
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
+<a href="#ppd_file_t">ppd_file_t</a> *ppd = <a href="#ppdOpenFile">ppdOpenFile</a>(getenv("PPD"));
 </pre>
 
-<h2 class='title'>Compatibility</h2>
+<p>The return value is a pointer to a new
+<a href="#ppd_file_t"><code>ppd_file_t</code></a> structure or <code>NULL</code>
+if the PPD file does not exist or cannot be loaded. The
+<a href="#ppdClose"><code>ppdClose</code></a> function frees the memory used
+by the structure:</p>
 
-<p>Unless otherwise specified, the PPD API functions require CUPS
-1.1 or higher.</p>
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+
+<a href="#ppdClose">ppdClose</a>(ppd);
+</pre>
+
+<h3><a name="OPTIONS_AND_GROUPS">Options and Groups</a></h3>
+
+<p>PPD files support multiple options, which are stored in arrays of
+<a href="#ppd_option_t"><code>ppd_option_t</code></a> and
+<a href="#ppd_choice_t"><code>ppd_choice_t</code></a> structures.</p>
+
+<p>Each option in turn is associated with a group stored in a
+<a href="#ppd_group_t"><code>ppd_group_t</code></a> structure. Groups can be
+specified in the PPD file; if an option is not associated with a group
+then it is put in an automatically-generated "General" group. Groups can also
+have sub-groups, however CUPS currently ignores sub-groups because of past
+abuses of this functionality.</p>
+
+<p>Options are selected by marking them using one of three functions. The
+first is <a href="#ppdMarkDefaults"><code>ppdMarkDefaults</code></a> which
+selects all of the default options in the PPD file:</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+
+<a href="#ppdMarkDefaults">ppdMarkDefaults</a>(ppd);
+</pre>
+
+<p>The second is <a href="#ppdMarkOption"><code>ppdMarkOption</code></a>
+which selects a single option choice in the PPD file. For example, the following
+code selects the manual feed media source:</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+
+<a href="#ppdMarkOption">ppdMarkOption</a>(ppd, "InputSlot", "ManualFeed");
+</pre>
+
+<p>The last function is
+<a href="#cupsMarkOptions"><code>cupsMarkOptions</code></a> which selects
+multiple option choices in the PPD file from an array of CUPS options, mapping
+IPP attributes like "media" and "sides" to their corresponding PPD options. You
+typically use this function in a print filter with
+<code>cupsParseOptions</code> and
+<a href="#ppdMarkDefaults"><code>ppdMarkDefaults</code></a> to select all of
+the option choices needed for the job, for example:</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd = <a href="#ppdOpenFile">ppdOpenFile</a>(getenv("PPD"));
+cups_option_t *options = NULL;
+int num_options = cupsParseOptions(argv[5], 0, &amp;options);
+
+<a href="#ppdMarkDefaults">ppdMarkDefaults</a>(ppd);
+<a href="#cupsMarkOptions">cupsMarkOptions</a>(ppd, num_options, options);
+</pre>
+
+<h3><a name="CONSTRAINTS">Constraints</a></h3>
+
+<p>PPD files support specification of conflict conditions, called
+constraints, between different options. Constraints are stored in an array of
+<a href="#ppd_const_t"><code>ppd_const_t</code></a> structures which specify
+the options and choices that conflict with each other. The
+<a href="#ppdConflicts"><code>ppdConflicts</code></a> function tells you
+how many of the selected options are incompatible.</p>
+
+<h3><a name="PAGE_SIZES">Page Sizes</a></h3>
+
+<p>Page sizes are special options which have physical dimensions and margins
+associated with them. The size information is stored in
+<a href="#ppd_size_t"><code>ppd_size_t</code></a> structures and is available
+by looking up the named size with the
+<a href="#ppdPageSize"><code>ppdPageSize</code></a> function. The page size and
+margins are returned in units called points; there are 72 points per inch. If
+you pass <code>NULL</code> for the size, the currently selected size is
+returned:</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, NULL);
+</pre>
+
+<p>Besides the standard page sizes listed in a PPD file, some printers
+support variable or custom page sizes. Custom page sizes are supported if the
+<code>variables_sizes</code> member of the
+<a href="#ppd_file_t"><code>ppd_file_t</code></a> structure is non-zero.
+The <code>custom_min</code>, <code>custom_max</code>, and
+<code>custom_margins</code> members of the
+<a href="#ppd_file_t"><code>ppd_file_t</code></a> structure define the limits
+of the printable area. To get the resulting media size, use a page size string
+of the form "Custom.<I>width</I>x<I>length</I>", where "width" and "length" are
+in points. Custom page size names can also be specified in inches
+("Custom.<i>width</i>x<i>height</i>in"), centimeters
+("Custom.<i>width</i>x<i>height</i>cm"), or millimeters
+("Custom.<i>width</i>x<i>height</i>mm"):</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+
+/* Get an 576x720 point custom page size */
+<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.576x720");
+
+/* Get an 8x10 inch custom page size */
+<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.8x10in");
+
+/* Get a 100x200 millimeter custom page size */
+<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.100x200mm");
+
+/* Get a 12.7x34.5 centimeter custom page size */
+<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.12.7x34.5cm");
+</pre>
+
+<h3><a name="ATTRIBUTES">Attributes</a></h3>
+
+<p>Every PPD file is composed of one or more attributes. Most of these
+attributes are used to define groups, options, choices, and page sizes,
+however several informations attributes are available which you may need
+to access in your program or filter. Attributes normally look like one of
+the following examples in a PPD file:</p>
+
+<pre class="example">
+*name: "value"
+*name spec: "value"
+*name spec/text: "value"
+</pre>
+
+<p>The <a href="#ppdFindAttr"><code>ppdFindAttr</code></a> and
+<a href="#ppdFindNextAttr"><code>ppdFindNextAttr</code></a> functions find the
+first and next instances, respectively, of the named attribute with the given
+"spec" string and return a <a href="#ppd_attr_t"><code>ppd_attr_t</code></a>
+structure. If you provide a NULL specifier string, all attributes with the
+given name will be returned. For example, the following code lists all of the
+<code>Product</code> attributes in a PPD file:</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+<a href="#ppd_attr_t">ppd_attr_t</a> *attr;
+
+for (attr = <a href="#ppdFindAttr">ppdFindAttr</a>(ppd, "Product", NULL);
+     attr != NULL;
+     attr = <a href="#ppdFindNextAttr">ppdFindNextAttr</a>(ppd, "Product", NULL))
+  puts(attr->value);
+</pre>
index 5728d51e418ed9b104c61a0057f10db5473c5ef8..df1ae2e5405574dd5db0e041c5e0b97541238ff2 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Sorted array routines for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -101,6 +101,8 @@ static int  cups_array_find(cups_array_t *a, void *e, int prev, int *rdiff);
  * When adding an element to a sorted array, non-unique elements are
  * appended at the end of the run.  For unsorted arrays, the element
  * is inserted at the end of the array.
+ *
+ * @since CUPS 1.2@
  */
 
 int                                    /* O - 1 on success, 0 on failure */
@@ -129,6 +131,8 @@ cupsArrayAdd(cups_array_t *a,               /* I - Array */
 
 /*
  * 'cupsArrayClear()' - Clear the array.
+ *
+ * @since CUPS 1.2@
  */
 
 void
@@ -156,6 +160,8 @@ cupsArrayClear(cups_array_t *a)             /* I - Array */
 
 /*
  * 'cupsArrayCount()' - Get the number of elements in the array.
+ *
+ * @since CUPS 1.2@
  */
 
 int                                    /* O - Number of elements */
@@ -178,6 +184,8 @@ cupsArrayCount(cups_array_t *a)             /* I - Array */
 
 /*
  * 'cupsArrayCurrent()' - Return the current element in the array.
+ *
+ * @since CUPS 1.2@
  */
 
 void *                                 /* O - Element */
@@ -203,6 +211,8 @@ cupsArrayCurrent(cups_array_t *a)   /* I - Array */
 
 /*
  * 'cupsArrayDelete()' - Free all memory used by the array.
+ *
+ * @since CUPS 1.2@
  */
 
 void
@@ -232,6 +242,8 @@ cupsArrayDelete(cups_array_t *a)    /* I - Array */
 
 /*
  * 'cupsArrayDup()' - Duplicate the array.
+ *
+ * @since CUPS 1.2@
  */
 
 cups_array_t *                         /* O - Duplicate array */
@@ -296,9 +308,11 @@ cupsArrayDup(cups_array_t *a)              /* I - Array */
 
 /*
  * 'cupsArrayFind()' - Find an element in the array.
+ *
+ * @since CUPS 1.2@
  */
 
-void *                                 /* O - Element found or NULL */
+void *                                 /* O - Element found or @code NULL@ */
 cupsArrayFind(cups_array_t *a,         /* I - Array */
               void         *e)         /* I - Element */
 {
@@ -389,9 +403,11 @@ cupsArrayFind(cups_array_t *a,             /* I - Array */
 
 /*
  * 'cupsArrayFirst()' - Get the first element in the array.
+ *
+ * @since CUPS 1.2@
  */
 
-void *                                 /* O - First element or NULL */
+void *                                 /* O - First element or @code NULL@ */
 cupsArrayFirst(cups_array_t *a)                /* I - Array */
 {
  /*
@@ -445,9 +461,11 @@ cupsArrayGetInsert(cups_array_t *a)        /* I - Array */
 
 /*
  * 'cupsArrayIndex()' - Get the N-th element in the array.
+ *
+ * @since CUPS 1.2@
  */
 
-void *                                 /* O - N-th element or NULL */
+void *                                 /* O - N-th element or @code NULL@ */
 cupsArrayIndex(cups_array_t *a,                /* I - Array */
                int          n)         /* I - Index into array, starting at 0 */
 {
@@ -466,6 +484,8 @@ cupsArrayIndex(cups_array_t *a,             /* I - Array */
  * When inserting an element in a sorted array, non-unique elements are
  * inserted at the beginning of the run.  For unsorted arrays, the element
  * is inserted at the beginning of the array.
+ *
+ * @since CUPS 1.2@
  */
 
 int                                    /* O - 0 on failure, 1 on success */
@@ -494,9 +514,11 @@ cupsArrayInsert(cups_array_t *a,   /* I - Array */
 
 /*
  * 'cupsArrayLast()' - Get the last element in the array.
+ *
+ * @since CUPS 1.2@
  */
 
-void *                                 /* O - Last element or NULL */
+void *                                 /* O - Last element or @code NULL@ */
 cupsArrayLast(cups_array_t *a)         /* I - Array */
 {
  /*
@@ -518,6 +540,8 @@ cupsArrayLast(cups_array_t *a)              /* I - Array */
 
 /*
  * 'cupsArrayNew()' - Create a new array.
+ *
+ * @since CUPS 1.2@
  */
 
 cups_array_t *                         /* O - Array */
@@ -579,9 +603,11 @@ cupsArrayNew2(cups_array_func_t  f,        /* I - Comparison function */
 
 /*
  * 'cupsArrayNext()' - Get the next element in the array.
+ *
+ * @since CUPS 1.2@
  */
 
-void *                                 /* O - Next element or NULL */
+void *                                 /* O - Next element or @code NULL@ */
 cupsArrayNext(cups_array_t *a)         /* I - Array */
 {
  /*
@@ -604,9 +630,11 @@ cupsArrayNext(cups_array_t *a)             /* I - Array */
 
 /*
  * 'cupsArrayPrev()' - Get the previous element in the array.
+ *
+ * @since CUPS 1.2@
  */
 
-void *                                 /* O - Previous element or NULL */
+void *                                 /* O - Previous element or @code NULL@ */
 cupsArrayPrev(cups_array_t *a)         /* I - Array */
 {
  /*
@@ -629,6 +657,8 @@ cupsArrayPrev(cups_array_t *a)              /* I - Array */
 
 /*
  * 'cupsArrayRemove()' - Remove an element from the array.
+ *
+ * @since CUPS 1.2@
  */
 
 int                                    /* O - 1 on success, 0 on failure */
@@ -689,6 +719,8 @@ cupsArrayRemove(cups_array_t *a,    /* I - Array */
 
 /*
  * 'cupsArrayRestore()' - Reset the current element to the last cupsArraySave.
+ *
+ * @since CUPS 1.2@
  */
 
 void *                                 /* O - New current element */
@@ -714,6 +746,8 @@ cupsArrayRestore(cups_array_t *a)   /* I - Array */
  * 'cupsArraySave()' - Mark the current element for a later cupsArrayRestore.
  *
  * The save/restore stack is guaranteed to be at least 32 elements deep.
+ *
+ * @since CUPS 1.2@
  */
 
 int                                    /* O - 1 on success, 0 on failure */
@@ -734,6 +768,8 @@ cupsArraySave(cups_array_t *a)              /* I - Array */
 
 /*
  * 'cupsArrayUserData()' - Return the user data for an array.
+ *
+ * @since CUPS 1.2@
  */
 
 void *                                 /* O - User data */
@@ -748,6 +784,8 @@ cupsArrayUserData(cups_array_t *a)  /* I - Array */
 
 /*
  * 'cups_array_add()' - Insert or append an element to the array...
+ *
+ * @since CUPS 1.2@
  */
 
 static int                             /* O - 1 on success, 0 on failure */
@@ -916,6 +954,8 @@ cups_array_add(cups_array_t *a,             /* I - Array */
 
 /*
  * 'cups_array_find()' - Find an element in the array...
+ *
+ * @since CUPS 1.2@
  */
 
 static int                             /* O - Index of match */
index 74785a4c6929a2e3897a1bdaffcdc6561713220c..ae5752195b882d0a34ba267d6c2946ae012b51dd 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Sorted array definitions for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
index d65b3ef456cbf4aa3c760836a271f92cf4f1843e..83e6ba887f927f0150749d4dd6324ff890632a28 100644 (file)
@@ -4,7 +4,7 @@
  *   PPD model-specific attribute routines for the Common UNIX Printing System
  *   (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -15,8 +15,8 @@
  *
  * Contents:
  *
- *   ppdFindAttr()     - Find the first matching attribute...
- *   ppdFindNextAttr() - Find the next matching attribute...
+ *   ppdFindAttr()     - Find the first matching attribute.
+ *   ppdFindNextAttr() - Find the next matching attribute.
  */
 
 /*
 
 
 /*
- * 'ppdFindAttr()' - Find the first matching attribute...
+ * 'ppdFindAttr()' - Find the first matching attribute.
  *
  * @since CUPS 1.1.19@
  */
 
-ppd_attr_t *                           /* O - Attribute or NULL if not found */
+ppd_attr_t *                           /* O - Attribute or @code NULL@ if not found */
 ppdFindAttr(ppd_file_t *ppd,           /* I - PPD file data */
             const char *name,          /* I - Attribute name */
-            const char *spec)          /* I - Specifier string or NULL */
+            const char *spec)          /* I - Specifier string or @code NULL@ */
 {
   ppd_attr_t   key,                    /* Search key */
                *attr;                  /* Current attribute */
@@ -102,15 +102,15 @@ ppdFindAttr(ppd_file_t *ppd,              /* I - PPD file data */
 
 
 /*
- * 'ppdFindNextAttr()' - Find the next matching attribute...
+ * 'ppdFindNextAttr()' - Find the next matching attribute.
  *
  * @since CUPS 1.1.19@
  */
 
-ppd_attr_t *                           /* O - Attribute or NULL if not found */
+ppd_attr_t *                           /* O - Attribute or @code NULL@ if not found */
 ppdFindNextAttr(ppd_file_t *ppd,       /* I - PPD file data */
                 const char *name,      /* I - Attribute name */
-               const char *spec)       /* I - Specifier string or NULL */
+               const char *spec)       /* I - Specifier string or @code NULL@ */
 {
   ppd_attr_t   *attr;                  /* Current attribute */
 
index dd2d22c519d6f4e92ed4d58be515610f0a64ca1b..adc2436c90fc1d2d1da32e7f2769f2221ef7680b 100644 (file)
@@ -76,7 +76,7 @@ static int    cups_local_auth(http_t *http);
 /*
  * 'cupsDoAuthentication()' - Authenticate a request.
  *
- * This function should be called in response to a HTTP_UNAUTHORIZED
+ * This function should be called in response to a @code HTTP_UNAUTHORIZED@
  * status, prior to resubmitting your request.
  *
  * @since CUPS 1.1.20@
@@ -84,15 +84,14 @@ static int  cups_local_auth(http_t *http);
 
 int                                    /* O - 0 on success, -1 on error */
 cupsDoAuthentication(http_t     *http, /* I - HTTP connection to server */
-                     const char *method,/* I - Request method (GET, POST, PUT) */
+                     const char *method,/* I - Request method ("GET", "POST", "PUT") */
                     const char *resource)
                                        /* I - Resource path */
 {
   const char   *password;              /* Password string */
   char         prompt[1024],           /* Prompt for user */
                realm[HTTP_MAX_VALUE],  /* realm="xyz" string */
-               nonce[HTTP_MAX_VALUE],  /* nonce="xyz" string */
-               encode[4096];           /* Encoded username:password */
+               nonce[HTTP_MAX_VALUE];  /* nonce="xyz" string */
   int          localauth;              /* Local authentication result */
   _cups_globals_t *cg;                 /* Global data */
 
@@ -301,14 +300,40 @@ cupsDoAuthentication(http_t     *http,    /* I - HTTP connection to server */
     if (major_status == GSS_S_CONTINUE_NEEDED)
       DEBUG_gss_printf(major_status, minor_status, "Continuation needed!");
 
-    if (output_token.length)
+    if (output_token.length > 0 && output_token.length <= 65536)
     {
-      httpEncode64_2(encode, sizeof(encode), output_token.value,
+     /*
+      * Allocate the authorization string since Windows KDCs can have
+      * arbitrarily large credentials...
+      */
+
+      int authsize = 10 +                              /* "Negotiate " */
+                     output_token.length * 4 / 3 + 1 + /* Base64 */
+                    1;                                 /* nul */
+
+      httpSetAuthString(http, NULL, NULL);
+
+      if ((http->authstring = malloc(authsize)) == NULL)
+      {
+        http->authstring = http->_authstring;
+       authsize         = sizeof(http->_authstring);
+      }
+
+      strcpy(http->authstring, "Negotiate ");
+      httpEncode64_2(http->authstring + 10, authsize - 10, output_token.value,
                     output_token.length);
-      httpSetAuthString(http, "Negotiate", encode);
  
       major_status = gss_release_buffer(&minor_status, &output_token);
     }
+    else
+    {
+      DEBUG_printf(("cupsDoAuthentication: Kerberos credentials too large - "
+                    "%d bytes!\n", output_token.length));
+
+      major_status = gss_release_buffer(&minor_status, &output_token);
+
+      return (-1);
+    }
 #endif /* HAVE_GSSAPI */
   }
   else if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Digest", 6))
@@ -317,6 +342,9 @@ cupsDoAuthentication(http_t     *http,      /* I - HTTP connection to server */
     * Basic authentication...
     */
 
+    char       encode[256];            /* Base64 buffer */
+
+
     httpEncode64_2(encode, sizeof(encode), http->userpass,
                    (int)strlen(http->userpass));
     httpSetAuthString(http, "Basic", encode);
@@ -327,7 +355,8 @@ cupsDoAuthentication(http_t     *http,      /* I - HTTP connection to server */
     * Digest authentication...
     */
 
-    char digest[1024];                 /* Digest auth data */
+    char       encode[33],             /* MD5 buffer */
+               digest[1024];           /* Digest auth data */
 
 
     httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "realm", realm);
index 5057f086fb5366917ad9057e57000907e8b0bd2c..67d5e811585487dc37eb04bbd7f081d225e4c888 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Backend definitions for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2005 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -30,7 +30,7 @@
  * Constants...
  */
 
-typedef enum cups_backend_e            /**** Backend exit codes ****/
+enum cups_backend_e                    /**** Backend exit codes ****/
 {
   CUPS_BACKEND_OK = 0,                 /* Job completed successfully */
   CUPS_BACKEND_FAILED = 1,             /* Job failed, use error-policy */
@@ -38,7 +38,9 @@ typedef enum cups_backend_e           /**** Backend exit codes ****/
   CUPS_BACKEND_HOLD = 3,               /* Job failed, hold job */
   CUPS_BACKEND_STOP = 4,               /* Job failed, stop queue */
   CUPS_BACKEND_CANCEL = 5              /* Job failed, cancel job */
-} cups_backend_t;
+};
+typedef enum cups_backend_e cups_backend_t;
+                                       /**** Backend exit codes ****/
 
 
 /*
index 187071682fab3c7e2d4a56044d5b2d12b489470b..fd8cc3aa31f8452e4c24070429a31612986ef644 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   API definitions for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -71,16 +71,21 @@ extern "C" {
 #  define CUPS_FORMAT_RAW      "application/vnd.cups-raw"
 #  define CUPS_FORMAT_TEXT     "text/plain"
 #  define CUPS_HTTP_DEFAULT    (http_t *)0
+#  define CUPS_JOBID_ALL       -1
+#  define CUPS_JOBID_CURRENT   0
 #  define CUPS_LENGTH_VARIABLE (ssize_t)0
+#  define CUPS_WHICHJOBS_ALL   -1
+#  define CUPS_WHICHJOBS_ACTIVE        0
+#  define CUPS_WHICHJOBS_COMPLETED 1
 
 
 /*
  * Types and structures...
  */
 
-typedef unsigned cups_ptype_t;         /**** Printer Type/Capability Bits ****/
-enum cups_ptype_e                      /* Not a typedef'd enum so we can OR */
-{
+typedef unsigned cups_ptype_t;         /**** Printer type/capability bits ****/
+enum cups_ptype_e                      /**** Printer type/capability bit constants ****/
+{                                      /* Not a typedef'd enum so we can OR */
   CUPS_PRINTER_LOCAL = 0x0000,         /* Local printer or class */
   CUPS_PRINTER_CLASS = 0x0001,         /* Printer class */
   CUPS_PRINTER_REMOTE = 0x0002,                /* Remote printer or class */
@@ -107,7 +112,7 @@ enum cups_ptype_e                   /* Not a typedef'd enum so we can OR */
   CUPS_PRINTER_AUTHENTICATED = 0x400000,/* Printer requires authentication @since CUPS 1.2@ */
   CUPS_PRINTER_COMMANDS = 0x800000,    /* Printer supports maintenance commands @since CUPS 1.2@ */
   CUPS_PRINTER_DISCOVERED = 0x1000000, /* Printer was automatically discovered and added @since CUPS 1.3@ */
-  CUPS_PRINTER_OPTIONS = 0x6fffc       /* ~(CLASS | REMOTE | IMPLICIT | DEFAULT | FAX | REJECTING | DELETE | NOT_SHARED | AUTHENTICATED | COMMANDS | DISCOVERED) */
+  CUPS_PRINTER_OPTIONS = 0x6fffc       /* ~(CLASS | REMOTE | IMPLICIT | DEFAULT | FAX | REJECTING | DELETE | NOT_SHARED | AUTHENTICATED | COMMANDS | DISCOVERED) @private@ */
 };
 
 typedef const char *(*cups_password_cb_t)(const char *);
@@ -158,8 +163,8 @@ extern http_encryption_t cupsEncryption(void);
 extern void            cupsFreeJobs(int num_jobs, cups_job_t *jobs);
 extern int             cupsGetClasses(char ***classes) _CUPS_DEPRECATED;
 extern const char      *cupsGetDefault(void);
-extern int             cupsGetJobs(cups_job_t **jobs, const char *dest,
-                                   int myjobs, int completed);
+extern int             cupsGetJobs(cups_job_t **jobs, const char *name,
+                                   int myjobs, int whichjobs);
 extern const char      *cupsGetPPD(const char *name);
 extern int             cupsGetPrinters(char ***printers) _CUPS_DEPRECATED;
 extern ipp_status_t    cupsLastError(void);
@@ -215,7 +220,7 @@ extern const char   *cupsGetDefault2(http_t *http) _CUPS_API_1_1_21;
 extern int             cupsGetDests2(http_t *http, cups_dest_t **dests) _CUPS_API_1_1_21;
 extern int             cupsGetJobs2(http_t *http, cups_job_t **jobs,
                                     const char *name, int myjobs,
-                                    int completed) _CUPS_API_1_1_21;
+                                    int whichjobs) _CUPS_API_1_1_21;
 extern const char      *cupsGetPPD2(http_t *http, const char *name) _CUPS_API_1_1_21;
 extern int             cupsPrintFile2(http_t *http, const char *name,
                                       const char *filename,
@@ -257,7 +262,8 @@ extern void         cupsSetDefaultDest(const char *name,
                                           cups_dest_t *dests) _CUPS_API_1_3;
 
 /**** New in CUPS 1.4 ****/
-extern ipp_status_t    cupsCancelJob2(http_t *http, int job_id, int purge);
+extern ipp_status_t    cupsCancelJob2(http_t *http, const char *name,
+                                      int job_id, int purge) _CUPS_API_1_4;
 extern int             cupsCreateJob(http_t *http, const char *name,
                                      const char *title, int num_options,
                                      cups_option_t *options) _CUPS_API_1_4;
index 64b2ca431c1f177efdff61e12cc493de458375ef..6f61181d61192718f6497b88fcbf64d47918f7fb 100644 (file)
@@ -101,13 +101,13 @@ static int        cups_get_sdests(http_t *http, ipp_op_t op, const char *name,
  * returned unchanged.  Adding a new instance of a destination creates
  * a copy of that destination's options.
  *
- * Use the cupsSaveDests() function to save the updated list of
+ * Use the @link cupsSaveDests@ function to save the updated list of
  * destinations to the user's lpoptions file.
  */
 
 int                                    /* O  - New number of destinations */
 cupsAddDest(const char  *name,         /* I  - Destination name */
-            const char *instance,      /* I  - Instance name or NULL for none/primary */
+            const char *instance,      /* I  - Instance name or @code NULL@ for none/primary */
             int         num_dests,     /* I  - Number of destinations */
             cups_dest_t **dests)       /* IO - Destinations */
 {
@@ -218,13 +218,13 @@ cupsFreeDests(int         num_dests,      /* I - Number of destinations */
 /*
  * 'cupsGetDest()' - Get the named destination from the list.
  *
- * Use the cupsGetDests() or cupsGetDests2() functions to get a
+ * Use the @link cupsGetDests@ or @link cupsGetDests2@ functions to get a
  * list of supported destinations for the current user.
  */
 
-cups_dest_t *                          /* O - Destination pointer or NULL */
-cupsGetDest(const char  *name,         /* I - Destination name or NULL for the default destination */
-            const char *instance,      /* I - Instance name or NULL */
+cups_dest_t *                          /* O - Destination pointer or @code NULL@ */
+cupsGetDest(const char  *name,         /* I - Destination name or @code NULL@ for the default destination */
+            const char *instance,      /* I - Instance name or @code NULL@ */
             int         num_dests,     /* I - Number of destinations */
             cups_dest_t *dests)                /* I - Destinations */
 {
@@ -284,8 +284,8 @@ cupsGetDest(const char  *name,              /* I - Destination name or NULL for the default
  * printer-make-and-model, printer-state, printer-state-change-time,
  * printer-state-reasons, and printer-type attributes as options.
  *
- * Use the cupsFreeDests() function to free the destination list and
- * the cupsGetDest() function to find a particular destination.
+ * Use the @link cupsFreeDests@ function to free the destination list and
+ * the @link cupsGetDest@ function to find a particular destination.
  */
 
 int                                    /* O - Number of destinations */
@@ -303,14 +303,14 @@ cupsGetDests(cups_dest_t **dests) /* O - Destinations */
  * printer-make-and-model, printer-state, printer-state-change-time,
  * printer-state-reasons, and printer-type attributes as options.
  *
- * Use the cupsFreeDests() function to free the destination list and
- * the cupsGetDest() function to find a particular destination.
+ * Use the @link cupsFreeDests@ function to free the destination list and
+ * the @link cupsGetDest@ function to find a particular destination.
  *
  * @since CUPS 1.1.21@
  */
 
 int                                    /* O - Number of destinations */
-cupsGetDests2(http_t      *http,       /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+cupsGetDests2(http_t      *http,       /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
               cups_dest_t **dests)     /* O - Destinations */
 {
   int          i;                      /* Looping var */
@@ -477,26 +477,27 @@ cupsGetDests2(http_t      *http,  /* I - HTTP connection or CUPS_HTTP_DEFAULT */
  * 'cupsGetNamedDest()' - Get options for the named destination.
  *
  * This function is optimized for retrieving a single destination and should
- * be used instead of cupsGetDests() and cupsGetDest() when you either know
- * the name of the destination or want to print to the default destination.
- * If NULL is returned, the destination does not exist or there is no default
- * destination.
+ * be used instead of @link cupsGetDests@ and @link cupsGetDest@ when you either
+ * know the name of the destination or want to print to the default destination.
+ * If @code NULL@ is returned, the destination does not exist or there is no
+ * default destination.
  *
- * If "http" is CUPS_HTTP_DEFAULT, the connection to the default print server
- * will be used.
+ * If "http" is @code CUPS_HTTP_DEFAULT@, the connection to the default print
+ * server will be used.
  *
- * If "name" is NULL, the default printer for the current user will be returned.
+ * If "name" is @code NULL@, the default printer for the current user will be
+ * returned.
  *
- * The returned destination must be freed using cupsFreeDests() with a
- * "num_dests" of 1.
+ * The returned destination must be freed using @link cupsFreeDests@ with a
+ * "num_dests" value of 1.
  *
  * @since CUPS 1.4@
  */
 
-cups_dest_t *                          /* O - Destination or NULL */
-cupsGetNamedDest(http_t     *http,     /* I - HTTP connection or CUPS_HTTP_DEFAULT */
-                 const char *name,     /* I - Destination name or NULL */
-                 const char *instance) /* I - Instance name or NULL */
+cups_dest_t *                          /* O - Destination or @code NULL@ */
+cupsGetNamedDest(http_t     *http,     /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
+                 const char *name,     /* I - Destination name or @code NULL@ */
+                 const char *instance) /* I - Instance name or @code NULL@ */
 {
   cups_dest_t  *dest;                  /* Destination */
   char         filename[1024],         /* Path to lpoptions */
@@ -595,15 +596,15 @@ cupsGetNamedDest(http_t     *http,        /* I - HTTP connection or CUPS_HTTP_DEFAULT *
  *
  * Removing a destination/instance does not delete the class or printer
  * queue, merely the lpoptions for that destination/instance.  Use the
- * cupsSetDests() or cupsSetDests2() functions to save the new options
- * for the user.
+ * @link cupsSetDests@ or @link cupsSetDests2@ functions to save the new
+ * options for the user.
  *
  * @since CUPS 1.3@
  */
 
 int                                    /* O  - New number of destinations */
 cupsRemoveDest(const char  *name,      /* I  - Destination name */
-               const char  *instance,  /* I  - Instance name or NULL */
+               const char  *instance,  /* I  - Instance name or @code NULL@ */
               int         num_dests,   /* I  - Number of destinations */
               cups_dest_t **dests)     /* IO - Destinations */
 {
@@ -650,7 +651,7 @@ cupsRemoveDest(const char  *name,   /* I  - Destination name */
 void
 cupsSetDefaultDest(
     const char  *name,                 /* I - Destination name */
-    const char  *instance,             /* I - Instance name or NULL */
+    const char  *instance,             /* I - Instance name or @code NULL@ */
     int         num_dests,             /* I - Number of destinations */
     cups_dest_t *dests)                        /* I - Destinations */
 {
@@ -703,7 +704,7 @@ cupsSetDests(int         num_dests, /* I - Number of destinations */
  */
 
 int                                    /* O - 0 on success, -1 on error */
-cupsSetDests2(http_t      *http,       /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+cupsSetDests2(http_t      *http,       /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
               int         num_dests,   /* I - Number of destinations */
               cups_dest_t *dests)      /* I - Destinations */
 {
index b3a689b70d11416d5022c8ffa37b13d6d12561fd..1ef2046b71bab940f2cf527684737388bc7515d3 100644 (file)
@@ -5,7 +5,7 @@
  *
  *   This set of APIs abstracts enumeration of directory entries.
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2005 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -80,10 +80,12 @@ _cups_dir_time(FILETIME ft)         /* I - File time */
 
 /*
  * 'cupsDirClose()' - Close a directory.
+ *
+ * @since CUPS 1.2@
  */
 
 void
-cupsDirClose(cups_dir_t *dp)           /* I - Directory */
+cupsDirClose(cups_dir_t *dp)           /* I - Directory pointer */
 {
  /*
   * Range check input...
@@ -109,9 +111,11 @@ cupsDirClose(cups_dir_t *dp)               /* I - Directory */
 
 /*
  * 'cupsDirOpen()' - Open a directory.
+ *
+ * @since CUPS 1.2@
  */
 
-cups_dir_t *                           /* O - Directory */
+cups_dir_t *                           /* O - Directory pointer or @code NULL@ if the directory could not be opened. */
 cupsDirOpen(const char *directory)     /* I - Directory name */
 {
   cups_dir_t   *dp;                    /* Directory */
@@ -150,10 +154,12 @@ cupsDirOpen(const char *directory)        /* I - Directory name */
 
 /*
  * 'cupsDirRead()' - Read the next directory entry.
+ *
+ * @since CUPS 1.2@
  */
 
-cups_dentry_t *                        /* O - Directory entry */
-cupsDirRead(cups_dir_t *dp)            /* I - Directory */
+cups_dentry_t *                                /* O - Directory entry or @code NULL@ if there are no more */
+cupsDirRead(cups_dir_t *dp)            /* I - Directory pointer */
 {
   WIN32_FIND_DATA      entry;          /* Directory entry data */
 
@@ -208,10 +214,12 @@ cupsDirRead(cups_dir_t *dp)               /* I - Directory */
 
 /*
  * 'cupsDirRewind()' - Rewind to the start of the directory.
+ *
+ * @since CUPS 1.2@
  */
 
 void
-cupsDirRewind(cups_dir_t *dp)          /* I - Directory */
+cupsDirRewind(cups_dir_t *dp)          /* I - Directory pointer */
 {
  /*
   * Range check input...
@@ -256,10 +264,12 @@ struct _cups_dir_s                        /**** Directory data structure ****/
 
 /*
  * 'cupsDirClose()' - Close a directory.
+ *
+ * @since CUPS 1.2@
  */
 
 void
-cupsDirClose(cups_dir_t *dp)           /* I - Directory */
+cupsDirClose(cups_dir_t *dp)           /* I - Directory pointer */
 {
   DEBUG_printf(("cupsDirClose(dp=%p)\n", dp));
 
@@ -281,9 +291,11 @@ cupsDirClose(cups_dir_t *dp)               /* I - Directory */
 
 /*
  * 'cupsDirOpen()' - Open a directory.
+ *
+ * @since CUPS 1.2@
  */
 
-cups_dir_t *                           /* O - Directory */
+cups_dir_t *                           /* O - Directory pointer or @code NULL@ if the directory could not be opened. */
 cupsDirOpen(const char *directory)     /* I - Directory name */
 {
   cups_dir_t   *dp;                    /* Directory */
@@ -333,10 +345,12 @@ cupsDirOpen(const char *directory)        /* I - Directory name */
 
 /*
  * 'cupsDirRead()' - Read the next directory entry.
+ *
+ * @since CUPS 1.2@
  */
 
-cups_dentry_t *                                /* O - Directory entry */
-cupsDirRead(cups_dir_t *dp)            /* I - Directory */
+cups_dentry_t *                                /* O - Directory entry or @code NULL@ when there are no more */
+cupsDirRead(cups_dir_t *dp)            /* I - Directory pointer */
 {
   struct dirent        *entry;                 /* Pointer to entry */
   char         filename[1024];         /* Full filename */
@@ -428,10 +442,12 @@ cupsDirRead(cups_dir_t *dp)               /* I - Directory */
 
 /*
  * 'cupsDirRewind()' - Rewind to the start of the directory.
+ *
+ * @since CUPS 1.2@
  */
 
 void
-cupsDirRewind(cups_dir_t *dp)          /* I - Directory */
+cupsDirRewind(cups_dir_t *dp)          /* I - Directory pointer */
 {
   DEBUG_printf(("cupsDirRewind(dp=%p)\n", dp));
 
index 5ac480f35e07a3dcaa03f4756d9ded5045d875d0..494b1d45e26b31c46b9950e2ff880f441aac8b11 100644 (file)
@@ -68,6 +68,9 @@ static const char ppd_custom_code[] =
 /*
  * 'ppdCollect()' - Collect all marked options that reside in the specified
  *                  section.
+ *
+ * The choices array should be freed using @code free@ when you are
+ * finished with it.
  */
 
 int                                    /* O - Number of options marked */
@@ -83,6 +86,9 @@ ppdCollect(ppd_file_t    *ppd,                /* I - PPD file data */
  * 'ppdCollect2()' - Collect all marked options that reside in the
  *                   specified section and minimum order.
  *
+ * The choices array should be freed using @code free@ when you are
+ * finished with it.
+ *
  * @since CUPS 1.2@
  */
 
@@ -545,12 +551,12 @@ ppdEmitJCLEnd(ppd_file_t *ppd,            /* I - PPD file record */
  * returned string.
  *
  * The return string is allocated on the heap and should be freed using
- * free() when you are done with it.
+ * @code free@ when you are done with it.
  *
  * @since CUPS 1.2@
  */
 
-char *                                 /* O - String containing option code */
+char *                                 /* O - String containing option code or @code NULL@ if there is no option code */
 ppdEmitString(ppd_file_t    *ppd,      /* I - PPD file record */
               ppd_section_t section,   /* I - Section to write */
              float         min_order)  /* I - Lowest OrderDependency */
index 9ac62b870d99dd23f061704f45bba046041a406f..506b87f0f9e7cf3ac5461efbb2fab68922b20aad 100644 (file)
 
 static const _ipp_option_t ipp_options[] =
 {
-  { "auth-info",               IPP_TAG_TEXT,           IPP_TAG_JOB },
-  { "auth-info-required",      IPP_TAG_KEYWORD,        IPP_TAG_PRINTER },
-  { "blackplot",               IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
-  { "blackplot-default",       IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER },
-  { "brightness",              IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "brightness-default",      IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
-  { "columns",                 IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "columns-default",         IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
-  { "copies",                  IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "copies-default",          IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
-  { "document-format",         IPP_TAG_MIMETYPE,       IPP_TAG_OPERATION },
-  { "document-format-default", IPP_TAG_MIMETYPE,       IPP_TAG_PRINTER },
-  { "finishings",              IPP_TAG_ENUM,           IPP_TAG_JOB },
-  { "finishings-default",      IPP_TAG_ENUM,           IPP_TAG_PRINTER },
-  { "fitplot",                 IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
-  { "fitplot-default",         IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER },
-  { "gamma",                   IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "gamma-default",           IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
-  { "hue",                     IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "hue-default",             IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
-  { "job-k-limit",             IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "job-page-limit",          IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "job-priority",            IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "job-quota-period",                IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "job-uuid",                        IPP_TAG_URI,            IPP_TAG_JOB },
-  { "landscape",               IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
-  { "media",                   IPP_TAG_KEYWORD,        IPP_TAG_JOB },
-  { "mirror",                  IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
-  { "mirror-default",          IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER },
-  { "natural-scaling",         IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "natural-scaling-default", IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
-  { "notify-charset",          IPP_TAG_CHARSET,        IPP_TAG_SUBSCRIPTION },
-  { "notify-events",           IPP_TAG_KEYWORD,        IPP_TAG_SUBSCRIPTION },
-  { "notify-events-default",   IPP_TAG_KEYWORD,        IPP_TAG_PRINTER },
-  { "notify-lease-duration",   IPP_TAG_INTEGER,        IPP_TAG_SUBSCRIPTION },
-  { "notify-lease-duration-default", IPP_TAG_INTEGER,  IPP_TAG_PRINTER },
-  { "notify-natural-language", IPP_TAG_LANGUAGE,       IPP_TAG_SUBSCRIPTION },
-  { "notify-pull-method",      IPP_TAG_KEYWORD,        IPP_TAG_SUBSCRIPTION },
-  { "notify-recipient-uri",    IPP_TAG_URI,            IPP_TAG_SUBSCRIPTION },
-  { "notify-time-interval",    IPP_TAG_INTEGER,        IPP_TAG_SUBSCRIPTION },
-  { "notify-user-data",                IPP_TAG_STRING,         IPP_TAG_SUBSCRIPTION },
-  { "number-up",               IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "number-up-default",       IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
-  { "orientation-requested",   IPP_TAG_ENUM,           IPP_TAG_JOB },
-  { "orientation-requested-default", IPP_TAG_ENUM,     IPP_TAG_PRINTER },
-  { "page-bottom",             IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "page-bottom-default",     IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
-  { "page-left",               IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "page-left-default",       IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
-  { "page-ranges",             IPP_TAG_RANGE,          IPP_TAG_JOB },
-  { "page-ranges-default",     IPP_TAG_RANGE,          IPP_TAG_PRINTER },
-  { "page-right",              IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "page-right-default",      IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
-  { "page-top",                        IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "page-top-default",                IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
-  { "penwidth",                        IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "penwidth-default",                IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
-  { "port-monitor",             IPP_TAG_NAME,           IPP_TAG_PRINTER },
-  { "ppi",                     IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "ppi-default",             IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
-  { "prettyprint",             IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
-  { "prettyprint-default",     IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER },
-  { "print-quality",           IPP_TAG_ENUM,           IPP_TAG_JOB },
-  { "print-quality-default",   IPP_TAG_ENUM,           IPP_TAG_PRINTER },
-  { "printer-error-policy",    IPP_TAG_NAME,           IPP_TAG_PRINTER },
-  { "printer-info",            IPP_TAG_TEXT,           IPP_TAG_PRINTER },
-  { "printer-is-accepting-jobs",IPP_TAG_BOOLEAN,       IPP_TAG_PRINTER },
-  { "printer-is-shared",       IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER },
-  { "printer-location",                IPP_TAG_TEXT,           IPP_TAG_PRINTER },
-  { "printer-make-and-model",  IPP_TAG_TEXT,           IPP_TAG_PRINTER },
-  { "printer-more-info",       IPP_TAG_URI,            IPP_TAG_PRINTER },
-  { "printer-op-policy",       IPP_TAG_NAME,           IPP_TAG_PRINTER },
-  { "printer-resolution",      IPP_TAG_RESOLUTION,     IPP_TAG_JOB },
-  { "printer-state",           IPP_TAG_ENUM,           IPP_TAG_PRINTER },
-  { "printer-state-change-time",IPP_TAG_INTEGER,       IPP_TAG_PRINTER },
-  { "printer-state-reasons",   IPP_TAG_KEYWORD,        IPP_TAG_PRINTER },
-  { "printer-type",            IPP_TAG_ENUM,           IPP_TAG_PRINTER },
-  { "printer-uri",             IPP_TAG_URI,            IPP_TAG_OPERATION },
-  { "queued-job-count",                IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
-  { "raw",                     IPP_TAG_MIMETYPE,       IPP_TAG_OPERATION },
-  { "requesting-user-name-allowed",    IPP_TAG_NAME,   IPP_TAG_PRINTER },
-  { "requesting-user-name-denied",     IPP_TAG_NAME,   IPP_TAG_PRINTER },
-  { "resolution",              IPP_TAG_RESOLUTION,     IPP_TAG_JOB },
-  { "resolution-default",      IPP_TAG_RESOLUTION,     IPP_TAG_PRINTER },
-  { "saturation",              IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "saturation-default",      IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
-  { "scaling",                 IPP_TAG_INTEGER,        IPP_TAG_JOB },
-  { "scaling-default",         IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
-  { "sides",                   IPP_TAG_KEYWORD,        IPP_TAG_JOB },
-  { "sides-default",           IPP_TAG_KEYWORD,        IPP_TAG_PRINTER },
-  { "wrap",                    IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
-  { "wrap-default",            IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER }
+  { 1, "auth-info",            IPP_TAG_TEXT,           IPP_TAG_JOB },
+  { 1, "auth-info-required",   IPP_TAG_KEYWORD,        IPP_TAG_PRINTER },
+  { 0, "blackplot",            IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
+  { 0, "blackplot-default",    IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER },
+  { 0, "brightness",           IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "brightness-default",   IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
+  { 0, "columns",              IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "columns-default",      IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
+  { 0, "copies",               IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "copies-default",       IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
+  { 0, "document-format",      IPP_TAG_MIMETYPE,       IPP_TAG_OPERATION },
+  { 0, "document-format-default", IPP_TAG_MIMETYPE,    IPP_TAG_PRINTER },
+  { 1, "finishings",           IPP_TAG_ENUM,           IPP_TAG_JOB },
+  { 1, "finishings-default",   IPP_TAG_ENUM,           IPP_TAG_PRINTER },
+  { 0, "fitplot",              IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
+  { 0, "fitplot-default",      IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER },
+  { 0, "gamma",                        IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "gamma-default",                IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
+  { 0, "hue",                  IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "hue-default",          IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
+  { 0, "job-k-limit",          IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "job-page-limit",       IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "job-priority",         IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "job-quota-period",     IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "job-uuid",             IPP_TAG_URI,            IPP_TAG_JOB },
+  { 0, "landscape",            IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
+  { 1, "media",                        IPP_TAG_KEYWORD,        IPP_TAG_JOB },
+  { 0, "mirror",               IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
+  { 0, "mirror-default",       IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER },
+  { 0, "natural-scaling",      IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "natural-scaling-default", IPP_TAG_INTEGER,     IPP_TAG_PRINTER },
+  { 0, "notify-charset",       IPP_TAG_CHARSET,        IPP_TAG_SUBSCRIPTION },
+  { 1, "notify-events",                IPP_TAG_KEYWORD,        IPP_TAG_SUBSCRIPTION },
+  { 1, "notify-events-default",        IPP_TAG_KEYWORD,        IPP_TAG_PRINTER },
+  { 0, "notify-lease-duration",        IPP_TAG_INTEGER,        IPP_TAG_SUBSCRIPTION },
+  { 0, "notify-lease-duration-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+  { 0, "notify-natural-language", IPP_TAG_LANGUAGE,    IPP_TAG_SUBSCRIPTION },
+  { 0, "notify-pull-method",   IPP_TAG_KEYWORD,        IPP_TAG_SUBSCRIPTION },
+  { 0, "notify-recipient-uri", IPP_TAG_URI,            IPP_TAG_SUBSCRIPTION },
+  { 0, "notify-time-interval", IPP_TAG_INTEGER,        IPP_TAG_SUBSCRIPTION },
+  { 0, "notify-user-data",     IPP_TAG_STRING,         IPP_TAG_SUBSCRIPTION },
+  { 0, "number-up",            IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "number-up-default",    IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
+  { 0, "orientation-requested",        IPP_TAG_ENUM,           IPP_TAG_JOB },
+  { 0, "orientation-requested-default", IPP_TAG_ENUM,  IPP_TAG_PRINTER },
+  { 0, "page-bottom",          IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "page-bottom-default",  IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
+  { 0, "page-left",            IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "page-left-default",    IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
+  { 1, "page-ranges",          IPP_TAG_RANGE,          IPP_TAG_JOB },
+  { 1, "page-ranges-default",  IPP_TAG_RANGE,          IPP_TAG_PRINTER },
+  { 0, "page-right",           IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "page-right-default",   IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
+  { 0, "page-top",             IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "page-top-default",     IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
+  { 0, "penwidth",             IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "penwidth-default",     IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
+  { 0, "port-monitor",         IPP_TAG_NAME,           IPP_TAG_PRINTER },
+  { 0, "ppi",                  IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "ppi-default",          IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
+  { 0, "prettyprint",          IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
+  { 0, "prettyprint-default",  IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER },
+  { 0, "print-quality",                IPP_TAG_ENUM,           IPP_TAG_JOB },
+  { 0, "print-quality-default",        IPP_TAG_ENUM,           IPP_TAG_PRINTER },
+  { 0, "printer-error-policy", IPP_TAG_NAME,           IPP_TAG_PRINTER },
+  { 0, "printer-info",         IPP_TAG_TEXT,           IPP_TAG_PRINTER },
+  { 0, "printer-is-accepting-jobs", IPP_TAG_BOOLEAN,   IPP_TAG_PRINTER },
+  { 0, "printer-is-shared",    IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER },
+  { 0, "printer-location",     IPP_TAG_TEXT,           IPP_TAG_PRINTER },
+  { 0, "printer-make-and-model", IPP_TAG_TEXT,         IPP_TAG_PRINTER },
+  { 0, "printer-more-info",    IPP_TAG_URI,            IPP_TAG_PRINTER },
+  { 0, "printer-op-policy",    IPP_TAG_NAME,           IPP_TAG_PRINTER },
+  { 0, "printer-resolution",   IPP_TAG_RESOLUTION,     IPP_TAG_JOB },
+  { 0, "printer-state",                IPP_TAG_ENUM,           IPP_TAG_PRINTER },
+  { 0, "printer-state-change-time", IPP_TAG_INTEGER,   IPP_TAG_PRINTER },
+  { 1, "printer-state-reasons",        IPP_TAG_KEYWORD,        IPP_TAG_PRINTER },
+  { 0, "printer-type",         IPP_TAG_ENUM,           IPP_TAG_PRINTER },
+  { 0, "printer-uri",          IPP_TAG_URI,            IPP_TAG_OPERATION },
+  { 0, "queued-job-count",     IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
+  { 0, "raw",                  IPP_TAG_MIMETYPE,       IPP_TAG_OPERATION },
+  { 1, "requesting-user-name-allowed", IPP_TAG_NAME,   IPP_TAG_PRINTER },
+  { 1, "requesting-user-name-denied", IPP_TAG_NAME,    IPP_TAG_PRINTER },
+  { 0, "resolution",           IPP_TAG_RESOLUTION,     IPP_TAG_JOB },
+  { 0, "resolution-default",   IPP_TAG_RESOLUTION,     IPP_TAG_PRINTER },
+  { 0, "saturation",           IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "saturation-default",   IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
+  { 0, "scaling",              IPP_TAG_INTEGER,        IPP_TAG_JOB },
+  { 0, "scaling-default",      IPP_TAG_INTEGER,        IPP_TAG_PRINTER },
+  { 0, "sides",                        IPP_TAG_KEYWORD,        IPP_TAG_JOB },
+  { 0, "sides-default",                IPP_TAG_KEYWORD,        IPP_TAG_PRINTER },
+  { 0, "wrap",                 IPP_TAG_BOOLEAN,        IPP_TAG_JOB },
+  { 0, "wrap-default",         IPP_TAG_BOOLEAN,        IPP_TAG_PRINTER }
 };
 
 
@@ -192,7 +192,8 @@ cupsEncodeOptions2(
   char         *s,                     /* Pointer into option value */
                *val,                   /* Pointer to option value */
                *copy,                  /* Copy of option value */
-               *sep;                   /* Option separator */
+               *sep,                   /* Option separator */
+               quote;                  /* Quote character */
   ipp_attribute_t *attr;               /* IPP attribute */
   ipp_tag_t    value_tag;              /* IPP value tag */
   cups_option_t        *option;                /* Current option */
@@ -284,41 +285,28 @@ cupsEncodeOptions2(
     * Count the number of values...
     */
 
-    for (count = 1, sep = option->value; *sep; sep ++)
+    if (match && match->multivalue)
     {
-      if (*sep == '\'')
+      for (count = 1, sep = option->value, quote = 0; *sep; sep ++)
       {
-       /*
-        * Skip quoted option value...
-       */
-
-        sep ++;
-
-        while (*sep && *sep != '\'')
-         sep ++;
-
-       if (!*sep)
-         sep --;
-      }
-      else if (*sep == '\"')
-      {
-       /*
-        * Skip quoted option value...
-       */
-
-        sep ++;
+       if (*sep == quote)
+         quote = 0;
+       else if (!quote && (*sep == '\'' || *sep == '\"'))
+       {
+        /*
+         * Skip quoted option value...
+         */
 
-        while (*sep && *sep != '\"')
+         quote = *sep++;
+       }
+       else if (*sep == ',' && !quote)
+         count ++;
+       else if (*sep == '\\' && sep[1])
          sep ++;
-
-       if (!*sep)
-         sep --;
       }
-      else if (*sep == ',')
-        count ++;
-      else if (*sep == '\\' && sep[1])
-        sep ++;
     }
+    else
+      count = 1;
 
     DEBUG_printf(("cupsEncodeOptions2: option = \'%s\', count = %d\n",
                   option->name, count));
@@ -390,50 +378,47 @@ cupsEncodeOptions2(
     * Scan the value string for values...
     */
 
-    for (j = 0; j < count; val = sep, j ++)
+    for (j = 0, sep = val; j < count; val = sep, j ++)
     {
      /*
       * Find the end of this value and mark it if needed...
       */
 
-      for (sep = val; *sep; sep ++)
+      if (count > 1)
       {
-       if (*sep == '\'')
+       for (quote = 0; *sep; sep ++)
        {
-        /*
-         * Skip quoted option value...
-         */
-
-         sep ++;
-
-         while (*sep && *sep != '\'')
-           sep ++;
+         if (*sep == quote)
+         {
+          /*
+           * Finish quoted value...
+           */
 
-         if (!*sep)
-           sep --;
-       }
-       else if (*sep == '\"')
-       {
-        /*
-         * Skip quoted option value...
-         */
+           quote = 0;
+         }
+         else if (!quote && (*sep == '\'' || *sep == '\"'))
+         {
+          /*
+           * Handle quoted option value...
+           */
 
-         sep ++;
+           quote = *sep;
+         }
+         else if (*sep == ',' && count > 1)
+           break;
+         else if (*sep == '\\' && sep[1])
+         {
+          /*
+           * Skip quoted character...
+           */
 
-         while (*sep && *sep != '\"')
            sep ++;
-
-         if (!*sep)
-           sep --;
+         }
        }
-       else if (*sep == ',')
-         break;
-       else if (*sep == '\\' && sep[1])
-         sep ++;
-      }
 
-      if (*sep == ',')
-       *sep++ = '\0';
+       if (*sep == ',')
+         *sep++ = '\0';
+      }
 
      /*
       * Copy the option value(s) over as needed by the type...
@@ -447,7 +432,7 @@ cupsEncodeOptions2(
            * Integer/enumeration value...
            */
 
-            attr->values[j].integer = strtol(val, &s, 0);
+            attr->values[j].integer = strtol(val, &s, 10);
 
             DEBUG_printf(("cupsEncodeOptions2: Added integer option value %d...\n",
                          attr->values[j].integer));
@@ -489,12 +474,12 @@ cupsEncodeOptions2(
              s = val;
            }
            else
-             attr->values[j].range.lower = strtol(val, &s, 0);
+             attr->values[j].range.lower = strtol(val, &s, 10);
 
            if (*s == '-')
            {
              if (s[1])
-               attr->values[j].range.upper = strtol(s + 1, NULL, 0);
+               attr->values[j].range.upper = strtol(s + 1, NULL, 10);
              else
                attr->values[j].range.upper = 2147483647;
             }
@@ -511,10 +496,10 @@ cupsEncodeOptions2(
            * Resolution...
            */
 
-           attr->values[j].resolution.xres = strtol(val, &s, 0);
+           attr->values[j].resolution.xres = strtol(val, &s, 10);
 
            if (*s == 'x')
-             attr->values[j].resolution.yres = strtol(s + 1, &s, 0);
+             attr->values[j].resolution.yres = strtol(s + 1, &s, 10);
            else
              attr->values[j].resolution.yres = attr->values[j].resolution.xres;
 
@@ -533,7 +518,7 @@ cupsEncodeOptions2(
            */
 
             attr->values[j].unknown.length = (int)strlen(val);
-           attr->values[j].unknown.data   = _cupsStrAlloc(val);
+           attr->values[j].unknown.data   = strdup(val);
 
             DEBUG_printf(("cupsEncodeOptions2: Added octet-string value \"%s\"...\n",
                          attr->values[j].unknown.data));
index e7c7b0b15a85319b1e71fe2a7c309c845d6da99a..9f92727a280a4a023dd200779f4930041bb6c3f3 100644 (file)
@@ -8,7 +8,7 @@
  *   our own file functions allows us to provide transparent support of
  *   gzip'd print files, PPD files, etc.
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -26,8 +26,8 @@
  *   cupsFileFlush()       - Flush pending output.
  *   cupsFileGetChar()     - Get a single character from a file.
  *   cupsFileGetConf()     - Get a line from a configuration file...
- *   cupsFileGetLine()     - Get a CR and/or LF-terminated line that may
- *                           contain binary data.
+ *   cupsFileGetLine()     - Get a CR and/or LF-terminated line that may contain
+ *                           binary data.
  *   cupsFileGets()        - Get a CR and/or LF-terminated line.
  *   cupsFileLock()        - Temporarily lock access to a file.
  *   cupsFileNumber()      - Return the file descriptor associated with a CUPS
@@ -39,7 +39,8 @@
  *   cupsFilePutChar()     - Write a character.
  *   cupsFilePuts()        - Write a string.
  *   cupsFileRead()        - Read from a file.
- *   cupsFileRewind()      - Rewind a file.
+ *   cupsFileRewind()      - Set the current file position to the beginning of
+ *                           the file.
  *   cupsFileSeek()        - Seek in a file.
  *   cupsFileStderr()      - Return a CUPS file associated with stderr.
  *   cupsFileStdin()       - Return a CUPS file associated with stdin.
@@ -134,6 +135,8 @@ static ssize_t      cups_write(cups_file_t *fp, const char *buf, size_t bytes);
 
 /*
  * 'cupsFileClose()' - Close a CUPS file.
+ *
+ * @since CUPS 1.2@
  */
 
 int                                    /* O - 0 on success, -1 on error */
@@ -261,9 +264,11 @@ cupsFileClose(cups_file_t *fp)             /* I - CUPS file */
 
 /*
  * 'cupsFileCompression()' - Return whether a file is compressed.
+ *
+ * @since CUPS 1.2@
  */
 
-int                                    /* O - CUPS_FILE_NONE or CUPS_FILE_GZIP */
+int                                    /* O - @code CUPS_FILE_NONE@ or @code CUPS_FILE_GZIP@ */
 cupsFileCompression(cups_file_t *fp)   /* I - CUPS file */
 {
   return (fp ? fp->compressed : CUPS_FILE_NONE);
@@ -272,9 +277,11 @@ cupsFileCompression(cups_file_t *fp)       /* I - CUPS file */
 
 /*
  * 'cupsFileEOF()' - Return the end-of-file status.
+ *
+ * @since CUPS 1.2@
  */
 
-int                                    /* O - 1 on EOF, 0 otherwise */
+int                                    /* O - 1 on end of file, 0 otherwise */
 cupsFileEOF(cups_file_t *fp)           /* I - CUPS file */
 {
   return (fp ? fp->eof : 1);
@@ -287,11 +294,13 @@ cupsFileEOF(cups_file_t *fp)              /* I - CUPS file */
  * This function allows the paths in the path string to be separated by
  * colons (UNIX standard) or semicolons (Windows standard) and stores the
  * result in the buffer supplied.  If the file cannot be found in any of
- * the supplied paths, NULL is returned. A NULL path only matches the
- * current directory.
+ * the supplied paths, @code NULL@ is returned. A @code NULL@ path only
+ * matches the current directory.
+ *
+ * @since CUPS 1.2@
  */
 
-const char *                           /* O - Full path to file or NULL */
+const char *                           /* O - Full path to file or @code NULL@ if not found */
 cupsFileFind(const char *filename,     /* I - File to find */
              const char *path,         /* I - Colon/semicolon-separated path */
              int        executable,    /* I - 1 = executable files, 0 = any file/dir */
@@ -386,6 +395,8 @@ cupsFileFind(const char *filename,  /* I - File to find */
 
 /*
  * 'cupsFileFlush()' - Flush pending output.
+ *
+ * @since CUPS 1.2@
  */
 
 int                                    /* O - 0 on success, -1 on error */
@@ -431,9 +442,11 @@ cupsFileFlush(cups_file_t *fp)             /* I - CUPS file */
 
 /*
  * 'cupsFileGetChar()' - Get a single character from a file.
+ *
+ * @since CUPS 1.2@
  */
 
-int                                    /* O - Character or -1 on EOF */
+int                                    /* O - Character or -1 on end of file */
 cupsFileGetChar(cups_file_t *fp)       /* I - CUPS file */
 {
  /*
@@ -469,9 +482,11 @@ cupsFileGetChar(cups_file_t *fp)   /* I - CUPS file */
 
 /*
  * 'cupsFileGetConf()' - Get a line from a configuration file...
+ *
+ * @since CUPS 1.2@
  */
 
-char *                                 /* O  - Line read or NULL on eof/error */
+char *                                 /* O  - Line read or @code NULL@ on end of file or error */
 cupsFileGetConf(cups_file_t *fp,       /* I  - CUPS file */
                 char        *buf,      /* O  - String buffer */
                size_t      buflen,     /* I  - Size of string buffer */
@@ -603,13 +618,15 @@ cupsFileGetConf(cups_file_t *fp,  /* I  - CUPS file */
  * 'cupsFileGetLine()' - Get a CR and/or LF-terminated line that may
  *                       contain binary data.
  *
- * This function differs from cupsFileGets() in that the trailing CR and LF
- * are preserved, as is any binary data on the line. The buffer is nul-
- * terminated, however you should use the returned length to determine
+ * This function differs from @link cupsFileGets@ in that the trailing CR
+ * and LF are preserved, as is any binary data on the line. The buffer is
+ * nul-terminated, however you should use the returned length to determine
  * the number of bytes on the line.
+ *
+ * @since CUPS 1.2@
  */
 
-size_t                                 /* O - Number of bytes on line or 0 on EOF */
+size_t                                 /* O - Number of bytes on line or 0 on end of file */
 cupsFileGetLine(cups_file_t *fp,       /* I - File to read from */
                 char        *buf,      /* I - Buffer */
                 size_t      buflen)    /* I - Size of buffer */
@@ -671,9 +688,11 @@ cupsFileGetLine(cups_file_t *fp,   /* I - File to read from */
 
 /*
  * 'cupsFileGets()' - Get a CR and/or LF-terminated line.
+ *
+ * @since CUPS 1.2@
  */
 
-char *                                 /* O - Line read or NULL on eof/error */
+char *                                 /* O - Line read or @code NULL@ on end of file or error */
 cupsFileGets(cups_file_t *fp,          /* I - CUPS file */
              char        *buf,         /* O - String buffer */
             size_t      buflen)        /* I - Size of string buffer */
@@ -742,10 +761,12 @@ cupsFileGets(cups_file_t *fp,             /* I - CUPS file */
 
 /*
  * 'cupsFileLock()' - Temporarily lock access to a file.
+ *
+ * @since CUPS 1.2@
  */
 
 int                                    /* O - 0 on success, -1 on error */
-cupsFileLock(cups_file_t *fp,          /* I - File to lock */
+cupsFileLock(cups_file_t *fp,          /* I - CUPS file */
              int         block)                /* I - 1 to wait for the lock, 0 to fail right away */
 {
  /*
@@ -769,20 +790,39 @@ cupsFileLock(cups_file_t *fp,             /* I - File to lock */
 
 /*
  * 'cupsFileNumber()' - Return the file descriptor associated with a CUPS file.
+ *
+ * @since CUPS 1.2@
  */
 
 int                                    /* O - File descriptor */
 cupsFileNumber(cups_file_t *fp)                /* I - CUPS file */
 {
-  return (fp->fd);
+  if (fp)
+    return (fp->fd);
+  else
+    return (-1);
 }
 
 
 /*
  * 'cupsFileOpen()' - Open a CUPS file.
+ *
+ * The "mode" parameter can be "r" to read, "w" to write, overwriting any
+ * existing file, "a" to append to an existing file or create a new file,
+ * or "s" to open a socket connection.
+ *
+ * When opening for writing ("w") or appending ("a"), an optional number from
+ * 1 to 9 can be supplied which enables Flate compression of the file.
+ *
+ * When opening a socket connection, the filename is a string of the form
+ * "address:port" or "hostname:port". The socket will make an IPv4 or IPv6
+ * connection as needed, generally preferring IPv6 connections when there is
+ * a choice.
+ *
+ * @since CUPS 1.2@
  */
 
-cups_file_t *                          /* O - CUPS file or NULL */
+cups_file_t *                          /* O - CUPS file or @code NULL@ if the file or socket cannot be opened */
 cupsFileOpen(const char *filename,     /* I - Name of file */
              const char *mode)         /* I - Open mode */
 {
@@ -877,9 +917,17 @@ cupsFileOpen(const char *filename, /* I - Name of file */
 
 /*
  * 'cupsFileOpenFd()' - Open a CUPS file using a file descriptor.
+ *
+ * The "mode" parameter can be "r" to read, "a" or "w" to write, or "s"
+ * to treat the file descriptor as a bidirectional socket connection.
+ *
+ * When opening for writing ("w") or appending ("a"), an optional number from
+ * 1 to 9 can be supplied which enables Flate compression of the file.
+ *
+ * @since CUPS 1.2@
  */
 
-cups_file_t *                          /* O - CUPS file or NULL */
+cups_file_t *                          /* O - CUPS file or @code NULL@ if the file could not be opened */
 cupsFileOpenFd(int        fd,          /* I - File descriptor */
               const char *mode)        /* I - Open mode */
 {
@@ -984,9 +1032,11 @@ cupsFileOpenFd(int        fd,             /* I - File descriptor */
 
 /*
  * 'cupsFilePeekChar()' - Peek at the next character from a file.
+ *
+ * @since CUPS 1.2@
  */
 
-int                                    /* O - Character or -1 on EOF */
+int                                    /* O - Character or -1 on end of file */
 cupsFilePeekChar(cups_file_t *fp)      /* I - CUPS file */
 {
  /*
@@ -1014,9 +1064,11 @@ cupsFilePeekChar(cups_file_t *fp)        /* I - CUPS file */
 
 /*
  * 'cupsFilePrintf()' - Write a formatted string.
+ *
+ * @since CUPS 1.2@
  */
 
-int                                    /* O - Number of bytes written or -1 */
+int                                    /* O - Number of bytes written or -1 on error */
 cupsFilePrintf(cups_file_t *fp,                /* I - CUPS file */
                const char  *format,    /* I - Printf-style format string */
               ...)                     /* I - Additional args as necessary */
@@ -1067,6 +1119,8 @@ cupsFilePrintf(cups_file_t *fp,           /* I - CUPS file */
 
 /*
  * 'cupsFilePutChar()' - Write a character.
+ *
+ * @since CUPS 1.2@
  */
 
 int                                    /* O - 0 on success, -1 on error */
@@ -1115,9 +1169,13 @@ cupsFilePutChar(cups_file_t *fp, /* I - CUPS file */
 
 /*
  * 'cupsFilePuts()' - Write a string.
+ *
+ * Like the @code fputs@ function, no newline is appended to the string.
+ *
+ * @since CUPS 1.2@
  */
 
-int                                    /* O - Number of bytes written or -1 */
+int                                    /* O - Number of bytes written or -1 on error */
 cupsFilePuts(cups_file_t *fp,          /* I - CUPS file */
              const char  *s)           /* I - String to write */
 {
@@ -1173,9 +1231,11 @@ cupsFilePuts(cups_file_t *fp,            /* I - CUPS file */
 
 /*
  * 'cupsFileRead()' - Read from a file.
+ *
+ * @since CUPS 1.2@
  */
 
-ssize_t                                        /* O - Number of bytes read or -1 */
+ssize_t                                        /* O - Number of bytes read or -1 on error */
 cupsFileRead(cups_file_t *fp,          /* I - CUPS file */
              char        *buf,         /* O - Buffer */
             size_t      bytes)         /* I - Number of bytes to read */
@@ -1242,10 +1302,13 @@ cupsFileRead(cups_file_t *fp,           /* I - CUPS file */
 
 
 /*
- * 'cupsFileRewind()' - Rewind a file.
+ * 'cupsFileRewind()' - Set the current file position to the beginning of the
+ *                      file.
+ *
+ * @since CUPS 1.2@
  */
 
-off_t                                  /* O - New file position or -1 */
+off_t                                  /* O - New file position or -1 on error */
 cupsFileRewind(cups_file_t *fp)                /* I - CUPS file */
 {
  /*
@@ -1299,9 +1362,11 @@ cupsFileRewind(cups_file_t *fp)          /* I - CUPS file */
 
 /*
  * 'cupsFileSeek()' - Seek in a file.
+ *
+ * @since CUPS 1.2@
  */
 
-off_t                                  /* O - New file position or -1 */
+off_t                                  /* O - New file position or -1 on error */
 cupsFileSeek(cups_file_t *fp,          /* I - CUPS file */
              off_t       pos)          /* I - Position in file */
 {
@@ -1454,9 +1519,11 @@ cupsFileSeek(cups_file_t *fp,            /* I - CUPS file */
 
 /*
  * 'cupsFileStderr()' - Return a CUPS file associated with stderr.
+ *
+ * @since CUPS 1.2@
  */
 
-cups_file_t *
+cups_file_t *                          /* O - CUPS file */
 cupsFileStderr(void)
 {
   _cups_globals_t *cg = _cupsGlobals();        /* Pointer to library globals... */
@@ -1488,9 +1555,11 @@ cupsFileStderr(void)
 
 /*
  * 'cupsFileStdin()' - Return a CUPS file associated with stdin.
+ *
+ * @since CUPS 1.2@
  */
 
-cups_file_t *
+cups_file_t *                          /* O - CUPS file */
 cupsFileStdin(void)
 {
   _cups_globals_t *cg = _cupsGlobals();        /* Pointer to library globals... */
@@ -1516,9 +1585,11 @@ cupsFileStdin(void)
 
 /*
  * 'cupsFileStdout()' - Return a CUPS file associated with stdout.
+ *
+ * @since CUPS 1.2@
  */
 
-cups_file_t *
+cups_file_t *                          /* O - CUPS file */
 cupsFileStdout(void)
 {
   _cups_globals_t *cg = _cupsGlobals();        /* Pointer to library globals... */
@@ -1550,6 +1621,8 @@ cupsFileStdout(void)
 
 /*
  * 'cupsFileTell()' - Return the current file position.
+ *
+ * @since CUPS 1.2@
  */
 
 off_t                                  /* O - File position */
@@ -1561,10 +1634,12 @@ cupsFileTell(cups_file_t *fp)           /* I - CUPS file */
 
 /*
  * 'cupsFileUnlock()' - Unlock access to a file.
+ *
+ * @since CUPS 1.2@
  */
 
 int                                    /* O - 0 on success, -1 on error */
-cupsFileUnlock(cups_file_t *fp)                /* I - File to lock */
+cupsFileUnlock(cups_file_t *fp)                /* I - CUPS file */
 {
  /*
   * Range check...
@@ -1587,9 +1662,11 @@ cupsFileUnlock(cups_file_t *fp)          /* I - File to lock */
 
 /*
  * 'cupsFileWrite()' - Write to a file.
+ *
+ * @since CUPS 1.2@
  */
 
-ssize_t                                        /* O - Number of bytes written */
+ssize_t                                        /* O - Number of bytes written or -1 on error */
 cupsFileWrite(cups_file_t *fp,         /* I - CUPS file */
               const char  *buf,                /* I - Buffer */
              size_t      bytes)        /* I - Number of bytes to write */
index b39a8339ba2968157c013a372f8633c0f05b9024..e144bd8e6335a7db1c1ca3f6f66171a87a2d7a87 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Get/put file functions for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
 /*
  * 'cupsGetFd()' - Get a file from the server.
  *
- * This function returns HTTP_OK when the file is successfully retrieved.
+ * This function returns @code HTTP_OK@ when the file is successfully retrieved.
  *
  * @since CUPS 1.1.20@
  */
 
 http_status_t                          /* O - HTTP status */
-cupsGetFd(http_t     *http,            /* I - HTTP connection to server */
+cupsGetFd(http_t     *http,            /* I - HTTP connection to server or @code CUPS_HTTP_DEFAULT@ */
          const char *resource,         /* I - Resource name */
          int        fd)                /* I - File descriptor */
 {
@@ -69,7 +69,7 @@ cupsGetFd(http_t     *http,           /* I - HTTP connection to server */
   DEBUG_printf(("cupsGetFd(http=%p, resource=\"%s\", fd=%d)\n", http,
                 resource, fd));
 
-  if (!http || !resource || fd < 0)
+  if (!resource || fd < 0)
   {
     if (http)
       http->error = EINVAL;
@@ -77,6 +77,9 @@ cupsGetFd(http_t     *http,           /* I - HTTP connection to server */
     return (HTTP_ERROR);
   }
 
+  if (!http)
+    http = _cupsConnect();
+
  /*
   * Then send GET requests to the HTTP server...
   */
@@ -182,13 +185,13 @@ cupsGetFd(http_t     *http,               /* I - HTTP connection to server */
 /*
  * 'cupsGetFile()' - Get a file from the server.
  *
- * This function returns HTTP_OK when the file is successfully retrieved.
+ * This function returns @code HTTP_OK@ when the file is successfully retrieved.
  *
  * @since CUPS 1.1.20@
  */
 
 http_status_t                          /* O - HTTP status */
-cupsGetFile(http_t     *http,          /* I - HTTP connection to server */
+cupsGetFile(http_t     *http,          /* I - HTTP connection to server or @code CUPS_HTTP_DEFAULT@ */
            const char *resource,       /* I - Resource name */
            const char *filename)       /* I - Filename */
 {
@@ -249,13 +252,14 @@ cupsGetFile(http_t     *http,             /* I - HTTP connection to server */
 /*
  * 'cupsPutFd()' - Put a file on the server.
  *
- * This function returns HTTP_CREATED when the file is stored successfully.
+ * This function returns @code HTTP_CREATED@ when the file is stored
+ * successfully.
  *
  * @since CUPS 1.1.20@
  */
 
 http_status_t                          /* O - HTTP status */
-cupsPutFd(http_t     *http,            /* I - HTTP connection to server */
+cupsPutFd(http_t     *http,            /* I - HTTP connection to server or @code CUPS_HTTP_DEFAULT@ */
           const char *resource,                /* I - Resource name */
          int        fd)                /* I - File descriptor */
 {
@@ -272,7 +276,7 @@ cupsPutFd(http_t     *http,         /* I - HTTP connection to server */
   DEBUG_printf(("cupsPutFd(http=%p, resource=\"%s\", fd=%d)\n", http,
                 resource, fd));
 
-  if (!http || !resource || fd < 0)
+  if (!resource || fd < 0)
   {
     if (http)
       http->error = EINVAL;
@@ -280,6 +284,9 @@ cupsPutFd(http_t     *http,         /* I - HTTP connection to server */
     return (HTTP_ERROR);
   }
 
+  if (!http)
+    http = _cupsConnect();
+
  /*
   * Then send PUT requests to the HTTP server...
   */
@@ -430,13 +437,14 @@ cupsPutFd(http_t     *http,               /* I - HTTP connection to server */
 /*
  * 'cupsPutFile()' - Put a file on the server.
  *
- * This function returns HTTP_CREATED when the file is stored successfully.
+ * This function returns @code HTTP_CREATED@ when the file is stored
+ * successfully.
  *
  * @since CUPS 1.1.20@
  */
 
 http_status_t                          /* O - HTTP status */
-cupsPutFile(http_t     *http,          /* I - HTTP connection to server */
+cupsPutFile(http_t     *http,          /* I - HTTP connection to server or @code CUPS_HTTP_DEFAULT@ */
             const char *resource,      /* I - Resource name */
            const char *filename)       /* I - Filename */
 {
index e38ca26e1aa30f171ae946e3dd42dc3d0b649a41..0083d2a384f9e710cea8c6a52062956113237d4d 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Private IPP definitions for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -40,6 +40,7 @@ extern "C" {
 
 typedef struct                         /**** Attribute mapping data ****/
 {
+  int          multivalue;             /* Option has multiple values? */
   const char   *name;                  /* Option/attribute name */
   ipp_tag_t    value_tag;              /* Value tag for this attribute */
   ipp_tag_t    group_tag;              /* Group tag for this attribute */
index f212fd1179eaed642f7561c7d37d9913e663468f..41f65c1d69ab3d3e226bde03094508d0a54c01d8 100644 (file)
@@ -1187,17 +1187,15 @@ ippReadIO(void       *src,              /* I - Data source */
 
              attr->value_tag = tag;
            }
-           else if (value_tag == IPP_TAG_STRING ||
-                    (value_tag >= IPP_TAG_TEXTLANG &&
-                     value_tag <= IPP_TAG_MIMETYPE))
+           else if (value_tag >= IPP_TAG_TEXTLANG &&
+                    value_tag <= IPP_TAG_MIMETYPE)
             {
             /*
              * String values can sometimes come across in different
              * forms; accept sets of differing values...
              */
 
-             if (tag != IPP_TAG_STRING &&
-                 (tag < IPP_TAG_TEXTLANG || tag > IPP_TAG_MIMETYPE))
+             if (tag < IPP_TAG_TEXTLANG || tag > IPP_TAG_MIMETYPE)
                return (IPP_ERROR);
             }
            else if (value_tag != tag)
@@ -1334,6 +1332,7 @@ ippReadIO(void       *src,                /* I - Data source */
 
                 value->integer = n;
                break;
+
            case IPP_TAG_BOOLEAN :
                if (n != 1)
                {
@@ -1349,10 +1348,10 @@ ippReadIO(void       *src,              /* I - Data source */
 
                 value->boolean = buffer[0];
                break;
+
            case IPP_TAG_TEXT :
            case IPP_TAG_NAME :
            case IPP_TAG_KEYWORD :
-           case IPP_TAG_STRING :
            case IPP_TAG_URI :
            case IPP_TAG_URISCHEME :
            case IPP_TAG_CHARSET :
@@ -1375,6 +1374,7 @@ ippReadIO(void       *src,                /* I - Data source */
                DEBUG_printf(("ippReadIO: value = \'%s\'\n",
                              value->string.text));
                break;
+
            case IPP_TAG_DATE :
                if (n != 11)
                {
@@ -1388,6 +1388,7 @@ ippReadIO(void       *src,                /* I - Data source */
                  return (IPP_ERROR);
                }
                break;
+
            case IPP_TAG_RESOLUTION :
                if (n != 9)
                {
@@ -1410,6 +1411,7 @@ ippReadIO(void       *src,                /* I - Data source */
                 value->resolution.units =
                    (ipp_res_t)buffer[8];
                break;
+
            case IPP_TAG_RANGE :
                if (n != 8)
                {
@@ -1430,6 +1432,7 @@ ippReadIO(void       *src,                /* I - Data source */
                    (((((buffer[4] << 8) | buffer[5]) << 8) | buffer[6]) << 8) |
                    buffer[7];
                break;
+
            case IPP_TAG_TEXTLANG :
            case IPP_TAG_NAMELANG :
                if (n >= sizeof(buffer) || n < 4)
@@ -1955,7 +1958,6 @@ ippWriteIO(void       *dst,               /* I - Destination */
            case IPP_TAG_TEXT :
            case IPP_TAG_NAME :
            case IPP_TAG_KEYWORD :
-           case IPP_TAG_STRING :
            case IPP_TAG_URI :
            case IPP_TAG_URISCHEME :
            case IPP_TAG_CHARSET :
@@ -2521,7 +2523,6 @@ _ippFreeAttr(ipp_attribute_t *attr)       /* I - Attribute to free */
     case IPP_TAG_TEXT :
     case IPP_TAG_NAME :
     case IPP_TAG_KEYWORD :
-    case IPP_TAG_STRING :
     case IPP_TAG_URI :
     case IPP_TAG_URISCHEME :
     case IPP_TAG_CHARSET :
@@ -2560,6 +2561,13 @@ _ippFreeAttr(ipp_attribute_t *attr)      /* I - Attribute to free */
           ippDelete(value->collection);
        break;
 
+    case IPP_TAG_STRING :
+       for (i = 0, value = attr->values;
+            i < attr->num_values;
+            i ++, value ++)
+         free(value->unknown.data);
+        break;
+
     default :
         if (!((int)attr->value_tag & IPP_TAG_COPY))
        {
@@ -2648,7 +2656,6 @@ ipp_length(ipp_t *ipp,                    /* I - IPP message or collection */
       case IPP_TAG_TEXT :
       case IPP_TAG_NAME :
       case IPP_TAG_KEYWORD :
-      case IPP_TAG_STRING :
       case IPP_TAG_URI :
       case IPP_TAG_URISCHEME :
       case IPP_TAG_CHARSET :
index 29ef86afd37e38fff89f0f783fd8f884ebe5d131..2a36fe35bfb238cbcec73c49e87fd372210aacc6 100644 (file)
@@ -265,7 +265,7 @@ typedef enum ipp_status_e           /**** IPP status codes... ****/
   IPP_OK_TOO_MANY_EVENTS,              /* successful-ok-too-many-events */
   IPP_OK_BUT_CANCEL_SUBSCRIPTION,      /* successful-ok-but-cancel-subscription */
   IPP_OK_EVENTS_COMPLETE,              /* successful-ok-events-complete */
-  IPP_REDIRECTION_OTHER_SITE = 0x200,  /*  */
+  IPP_REDIRECTION_OTHER_SITE = 0x200,  /* redirection-other-site @private@ */
   CUPS_SEE_OTHER = 0x280,              /* cups-see-other */
   IPP_BAD_REQUEST = 0x0400,            /* client-error-bad-request */
   IPP_FORBIDDEN,                       /* client-error-forbidden */
index ea629c9031cfd674d2f624b76f6626d1b34e85b8..e08bde6262830cafea23d7bde39994e4e49582c5 100644 (file)
@@ -344,7 +344,7 @@ cupsLangFlush(void)
 /*
  * 'cupsLangFree()' - Free language data.
  *
- * This does not actually free anything; use cupsLangFlush() for that.
+ * This does not actually free anything; use @link cupsLangFlush@ for that.
  */
 
 void
index a757eedcd78316cb1b5108130fcc875c6c4138ce..930c0d5d22c9b6f662cb3b2caa00ab8c8b746cdc 100644 (file)
@@ -305,6 +305,7 @@ _ppdIsMarked
 _ppdLastError
 _ppdLocalize
 _ppdLocalizeIPPReason
+_ppdLocalizeMarkerName
 _ppdMarkDefaults
 _ppdMarkOption
 _ppdNextCustomParam
index c03786ff350f519c08b7dfd0ff1f8cb8f4b2a219..9c91f6260575ee7788306320e2a3bfe251764b34 100644 (file)
@@ -1,9 +1,9 @@
 /*
  * "$Id: localize.c 6882 2007-08-29 21:05:10Z mike $"
  *
- *   PPD custom option routines for the Common UNIX Printing System (CUPS).
+ *   PPD localization routines for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
  *
  * Contents:
  *
- *   ppdLocalize()          - Localize the PPD file to the current locale.
- *   ppdLocalizeIPPReason() - Get the localized version of a cupsIPPReason
- *                            attribute.
- *   ppd_ll_CC()            - Get the current locale names.
- *   ppd_localized_attr()   - Find a localized attribute.
+ *   ppdLocalize()           - Localize the PPD file to the current locale.
+ *   ppdLocalizeIPPReason()  - Get the localized version of a cupsIPPReason
+ *                             attribute.
+ *   ppdLocalizeMarkerName() - Get the localized version of a marker-names
+ *                             attribute value.
+ *   ppd_ll_CC()             - Get the current locale names.
+ *   ppd_localized_attr()    - Find a localized attribute.
  */
 
 /*
@@ -386,6 +388,52 @@ ppdLocalizeIPPReason(
 }
 
 
+/*
+ * 'ppdLocalizeMarkerName()' - Get the localized version of a marker-names
+ *                             attribute value.
+ *
+ * This function uses the current locale to find the corresponding name
+ * text from the attribute value. If no localized text for the requested
+ * name can be found, @code NULL@ is returned.
+ *
+ * @since CUPS 1.4@
+ */
+
+const char *                           /* O - Value or @code NULL@ if not found */
+ppdLocalizeMarkerName(
+    ppd_file_t *ppd,                   /* I - PPD file */
+    const char *name)                  /* I - Marker name to look up */
+{
+  ppd_attr_t   *locattr;               /* Localized attribute */
+  char         ll_CC[6],               /* Language + country locale */
+               ll[3];                  /* Language locale */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (!ppd || !name)
+    return (NULL);
+
+ /*
+  * Get the default language...
+  */
+
+  ppd_ll_CC(ll_CC, sizeof(ll_CC), ll, sizeof(ll));
+
+ /*
+  * Find the localized attribute...
+  */
+
+  if ((locattr = ppd_localized_attr(ppd, "cupsMarkerName", name,
+                                    ll_CC, ll)) == NULL)
+    locattr = ppdFindAttr(ppd, "cupsMarkerName", name);
+
+  return (locattr ? locattr->text : NULL);
+}
+
+
 /*
  * 'ppd_ll_CC()' - Get the current locale names.
  */
index 689aefb0ffca5c8d5299b80022202f751f6bdf87..0dbb0b8d1859c97c048896fe02af768b120366a9 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * "$Id: mark.c 6939 2007-09-10 21:18:02Z mike $"
+ * "$Id: mark.c 7278 2008-01-31 01:23:09Z mike $"
  *
  *   Option marking routines for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
  *
  * Contents:
  *
- *   ppdConflicts()        - Check to see if there are any conflicts.
+ *   cupsMarkOptions()     - Mark command-line options in a PPD file.
+ *   ppdConflicts()        - Check to see if there are any conflicts among the
+ *                           marked option choices.
  *   ppdFindChoice()       - Return a pointer to an option choice.
  *   ppdFindMarkedChoice() - Return the marked choice for the specified option.
  *   ppdFindOption()       - Return a pointer to the specified option.
- *   ppdFirstOption()      - Return the first option in the PPD file.
- *   ppdNextOption()       - Return the next option in the PPD file.
- *   ppdIsMarked()         - Check to see if an option is marked...
+ *   ppdIsMarked()         - Check to see if an option is marked.
  *   ppdMarkDefaults()     - Mark all default options in the PPD file.
  *   ppdMarkOption()       - Mark an option in a PPD file.
+ *   ppdFirstOption()      - Return the first option in the PPD file.
+ *   ppdNextOption()       - Return the next option in the PPD file.
+ *   debug_marked()        - Output the marked array to stdout...
  *   ppd_defaults()        - Set the defaults for this group and all sub-groups.
+ *   ppd_mark_choices()    - Mark one or more option choices from a string.
  */
 
 /*
  * Local functions...
  */
 
+#ifdef DEBUG
+static void    debug_marked(ppd_file_t *ppd, const char *title);
+#else
+#  define debug_marked(ppd,title)
+#endif /* DEBUG */
 static void    ppd_defaults(ppd_file_t *ppd, ppd_group_t *g);
+static int     ppd_mark_choices(ppd_file_t *ppd, const char *options);
 
 
 /*
- * 'ppdConflicts()' - Check to see if there are any conflicts.
+ * 'cupsMarkOptions()' - Mark command-line options in a PPD file.
+ *
+ * This function maps the IPP "finishings", "media", "mirror",
+ * "multiple-document-handling", "output-bin", "printer-resolution", and
+ * "sides" attributes to their corresponding PPD options and choices.
+ */
+
+int                                    /* O - 1 if conflicting */
+cupsMarkOptions(
+    ppd_file_t    *ppd,                        /* I - PPD file */
+    int           num_options,         /* I - Number of options */
+    cups_option_t *options)            /* I - Options */
+{
+  int          i, j, k;                /* Looping vars */
+  int          conflict;               /* Option conflicts */
+  char         *val,                   /* Pointer into value */
+               *ptr,                   /* Pointer into string */
+               s[255];                 /* Temporary string */
+  const char   *page_size;             /* PageSize option */
+  cups_option_t        *optptr;                /* Current option */
+  ppd_option_t *option;                /* PPD option */
+  ppd_attr_t   *attr;                  /* PPD attribute */
+  static const char * const duplex_options[] =
+               {                       /* Duplex option names */
+                 "Duplex",             /* Adobe */
+                 "EFDuplex",           /* EFI */
+                 "EFDuplexing",        /* EFI */
+                 "KD03Duplex",         /* Kodak */
+                 "JCLDuplex"           /* Samsung */
+               };
+  static const char * const duplex_one[] =
+               {                       /* one-sided names */
+                 "None",
+                 "False"
+               };
+  static const char * const duplex_two_long[] =
+               {                       /* two-sided-long-edge names */
+                 "DuplexNoTumble",     /* Adobe */
+                 "LongEdge",           /* EFI */
+                 "Top"                 /* EFI */
+               };
+  static const char * const duplex_two_short[] =
+               {                       /* two-sided-long-edge names */
+                 "DuplexTumble",       /* Adobe */
+                 "ShortEdge",          /* EFI */
+                 "Bottom"              /* EFI */
+               };
+
+
+ /*
+  * Check arguments...
+  */
+
+  if (!ppd || num_options <= 0 || !options)
+    return (0);
+
+  debug_marked(ppd, "Before...");
+
+ /*
+  * Mark options...
+  */
+
+  conflict  = 0;
+
+  for (i = num_options, optptr = options; i > 0; i --, optptr ++)
+    if (!strcasecmp(optptr->name, "media"))
+    {
+     /*
+      * Loop through the option string, separating it at commas and
+      * marking each individual option as long as the corresponding
+      * PPD option (PageSize, InputSlot, etc.) is not also set.
+      *
+      * For PageSize, we also check for an empty option value since
+      * some versions of MacOS X use it to specify auto-selection
+      * of the media based solely on the size.
+      */
+
+      page_size = cupsGetOption("PageSize", num_options, options);
+
+      for (val = optptr->value; *val;)
+      {
+       /*
+        * Extract the sub-option from the string...
+       */
+
+        for (ptr = s; *val && *val != ',' && (ptr - s) < (sizeof(s) - 1);)
+         *ptr++ = *val++;
+       *ptr++ = '\0';
+
+       if (*val == ',')
+         val ++;
+
+       /*
+        * Mark it...
+       */
+
+        if (!page_size || !page_size[0])
+         if (ppdMarkOption(ppd, "PageSize", s))
+            conflict = 1;
+
+        if (cupsGetOption("InputSlot", num_options, options) == NULL)
+         if (ppdMarkOption(ppd, "InputSlot", s))
+            conflict = 1;
+
+        if (cupsGetOption("MediaType", num_options, options) == NULL)
+         if (ppdMarkOption(ppd, "MediaType", s))
+            conflict = 1;
+
+        if (cupsGetOption("EFMediaType", num_options, options) == NULL)
+         if (ppdMarkOption(ppd, "EFMediaType", s))             /* EFI */
+            conflict = 1;
+
+        if (cupsGetOption("EFMediaQualityMode", num_options, options) == NULL)
+         if (ppdMarkOption(ppd, "EFMediaQualityMode", s))      /* EFI */
+            conflict = 1;
+
+       if (strcasecmp(s, "manual") == 0 &&
+           cupsGetOption("ManualFeed", num_options, options) == NULL)
+          if (ppdMarkOption(ppd, "ManualFeed", "True"))
+           conflict = 1;
+      }
+    }
+    else if (!strcasecmp(optptr->name, "sides"))
+    {
+      for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
+        if (cupsGetOption(duplex_options[j], num_options, options) != NULL)
+         break;
+
+      if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
+      {
+       /*
+        * Don't override the PPD option with the IPP attribute...
+       */
+
+        continue;
+      }
+
+      if (!strcasecmp(optptr->value, "one-sided"))
+      {
+       /*
+        * Mark the appropriate duplex option for one-sided output...
+       */
+
+        for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
+         if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
+           break;
+
+       if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
+       {
+          for (k = 0; k < (int)(sizeof(duplex_one) / sizeof(duplex_one[0])); k ++)
+            if (ppdFindChoice(option, duplex_one[k]))
+           {
+             if (ppdMarkOption(ppd, duplex_options[j], duplex_one[k]))
+               conflict = 1;
+
+             break;
+            }
+        }
+      }
+      else if (!strcasecmp(optptr->value, "two-sided-long-edge"))
+      {
+       /*
+        * Mark the appropriate duplex option for two-sided-long-edge output...
+       */
+
+        for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
+         if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
+           break;
+
+       if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
+       {
+          for (k = 0; k < (int)(sizeof(duplex_two_long) / sizeof(duplex_two_long[0])); k ++)
+            if (ppdFindChoice(option, duplex_two_long[k]))
+           {
+             if (ppdMarkOption(ppd, duplex_options[j], duplex_two_long[k]))
+               conflict = 1;
+
+             break;
+            }
+        }
+      }
+      else if (!strcasecmp(optptr->value, "two-sided-short-edge"))
+      {
+       /*
+        * Mark the appropriate duplex option for two-sided-short-edge output...
+       */
+
+        for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
+         if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
+           break;
+
+       if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
+       {
+          for (k = 0; k < (int)(sizeof(duplex_two_short) / sizeof(duplex_two_short[0])); k ++)
+            if (ppdFindChoice(option, duplex_two_short[k]))
+           {
+             if (ppdMarkOption(ppd, duplex_options[j], duplex_two_short[k]))
+               conflict = 1;
+
+             break;
+            }
+        }
+      }
+    }
+    else if (!strcasecmp(optptr->name, "resolution") ||
+             !strcasecmp(optptr->name, "printer-resolution"))
+    {
+      if (ppdMarkOption(ppd, "Resolution", optptr->value))
+        conflict = 1;
+      if (ppdMarkOption(ppd, "SetResolution", optptr->value))
+       /* Calcomp, Linotype, QMS, Summagraphics, Tektronix, Varityper */
+        conflict = 1;
+      if (ppdMarkOption(ppd, "JCLResolution", optptr->value))  /* HP */
+        conflict = 1;
+      if (ppdMarkOption(ppd, "CNRes_PGP", optptr->value))      /* Canon */
+        conflict = 1;
+    }
+    else if (!strcasecmp(optptr->name, "output-bin"))
+    {
+      if (!cupsGetOption("OutputBin", num_options, options))
+        if (ppdMarkOption(ppd, "OutputBin", optptr->value))
+          conflict = 1;
+    }
+    else if (!strcasecmp(optptr->name, "multiple-document-handling"))
+    {
+      if (!cupsGetOption("Collate", num_options, options) &&
+          ppdFindOption(ppd, "Collate"))
+      {
+        if (strcasecmp(optptr->value, "separate-documents-uncollated-copies"))
+       {
+         if (ppdMarkOption(ppd, "Collate", "True"))
+            conflict = 1;
+        }
+       else
+       {
+         if (ppdMarkOption(ppd, "Collate", "False"))
+            conflict = 1;
+        }
+      }
+    }
+    else if (!strcasecmp(optptr->name, "finishings"))
+    {
+     /*
+      * Lookup cupsIPPFinishings attributes for each value...
+      */
+
+      for (ptr = optptr->value; *ptr;)
+      {
+       /*
+        * Get the next finishings number...
+       */
+
+        if (!isdigit(*ptr & 255))
+         break;
+
+        if ((j = strtol(ptr, &ptr, 10)) < 3)
+         break;
+
+       /*
+        * Skip separator as needed...
+       */
+
+        if (*ptr == ',')
+         ptr ++;
+
+       /*
+        * Look it up in the PPD file...
+       */
+
+       sprintf(s, "%d", j);
+
+        if ((attr = ppdFindAttr(ppd, "cupsIPPFinishings", s)) == NULL)
+         continue;
+
+       /*
+        * Apply "*Option Choice" settings from the attribute value...
+       */
+
+        if (ppd_mark_choices(ppd, attr->value))
+         conflict = 1;
+      }
+    }
+    else if (!strcasecmp(optptr->name, "mirror"))
+    {
+      if (ppdMarkOption(ppd, "MirrorPrint", optptr->value))
+       conflict = 1;
+    }
+    else if (ppdMarkOption(ppd, optptr->name, optptr->value))
+      conflict = 1;
+
+  debug_marked(ppd, "After...");
+
+  return (conflict);
+}
+
+
+/*
+ * 'ppdConflicts()' - Check to see if there are any conflicts among the
+ *                    marked option choices.
+ *
+ * The returned value is the same as returned by @link ppdMarkOption@.
  */
 
 int                                    /* O - Number of conflicts found */
@@ -189,7 +499,7 @@ ppdConflicts(ppd_file_t *ppd)               /* I - PPD to check */
  * 'ppdFindChoice()' - Return a pointer to an option choice.
  */
 
-ppd_choice_t *                         /* O - Choice pointer or NULL */
+ppd_choice_t *                         /* O - Choice pointer or @code NULL@ */
 ppdFindChoice(ppd_option_t *o,         /* I - Pointer to option */
               const char   *choice)    /* I - Name of choice */
 {
@@ -212,7 +522,7 @@ ppdFindChoice(ppd_option_t *o,              /* I - Pointer to option */
  * 'ppdFindMarkedChoice()' - Return the marked choice for the specified option.
  */
 
-ppd_choice_t *                         /* O - Pointer to choice or NULL */
+ppd_choice_t *                         /* O - Pointer to choice or @code NULL@ */
 ppdFindMarkedChoice(ppd_file_t *ppd,   /* I - PPD file */
                     const char *option)        /* I - Keyword/option name */
 {
@@ -230,7 +540,7 @@ ppdFindMarkedChoice(ppd_file_t *ppd,        /* I - PPD file */
  * 'ppdFindOption()' - Return a pointer to the specified option.
  */
 
-ppd_option_t *                         /* O - Pointer to option or NULL */
+ppd_option_t *                         /* O - Pointer to option or @code NULL@ */
 ppdFindOption(ppd_file_t *ppd,         /* I - PPD file data */
               const char *option)      /* I - Option/Keyword name */
 {
@@ -278,7 +588,7 @@ ppdFindOption(ppd_file_t *ppd,              /* I - PPD file data */
 
 
 /*
- * 'ppdIsMarked()' - Check to see if an option is marked...
+ * 'ppdIsMarked()' - Check to see if an option is marked.
  */
 
 int                                    /* O - Non-zero if option is marked */
@@ -338,11 +648,6 @@ ppdMarkDefaults(ppd_file_t *ppd)   /* I - PPD file record */
 
 /*
  * 'ppdMarkOption()' - Mark an option in a PPD file.
- *
- * Notes:
- *
- *   -1 is returned if the given option would conflict with any currently
- *   selected option.
  */
 
 int                                    /* O - Number of conflicts */
@@ -668,12 +973,12 @@ ppdMarkOption(ppd_file_t *ppd,            /* I - PPD file record */
 /*
  * 'ppdFirstOption()' - Return the first option in the PPD file.
  *
- * Options are returned from all groups in sorted order.
+ * Options are returned from all groups in ascending alphanumeric order.
  *
  * @since CUPS 1.2@
  */
 
-ppd_option_t *                         /* O - First option or NULL */
+ppd_option_t *                         /* O - First option or @code NULL@ */
 ppdFirstOption(ppd_file_t *ppd)                /* I - PPD file */
 {
   if (!ppd)
@@ -686,12 +991,12 @@ ppdFirstOption(ppd_file_t *ppd)           /* I - PPD file */
 /*
  * 'ppdNextOption()' - Return the next option in the PPD file.
  *
- * Options are returned from all groups in sorted order.
+ * Options are returned from all groups in ascending alphanumeric order.
  *
  * @since CUPS 1.2@
  */
 
-ppd_option_t *                         /* O - Next option or NULL */
+ppd_option_t *                         /* O - Next option or @code NULL@ */
 ppdNextOption(ppd_file_t *ppd)         /* I - PPD file */
 {
   if (!ppd)
@@ -701,17 +1006,39 @@ ppdNextOption(ppd_file_t *ppd)           /* I - PPD file */
 }
 
 
+#ifdef DEBUG
+/*
+ * 'debug_marked()' - Output the marked array to stdout...
+ */
+
+static void
+debug_marked(ppd_file_t *ppd,          /* I - PPD file data */
+             const char *title)                /* I - Title for list */
+{
+  ppd_choice_t *c;                     /* Current choice */
+
+
+  printf("cupsMarkOptions: %s\n", title);
+
+  for (c = (ppd_choice_t *)cupsArrayFirst(ppd->marked);
+       c;
+       c = (ppd_choice_t *)cupsArrayNext(ppd->marked))
+    printf("cupsMarkOptions: %s=%s\n", c->option->keyword, c->choice);
+}
+#endif /* DEBUG */
+
+
 /*
  * 'ppd_defaults()' - Set the defaults for this group and all sub-groups.
  */
 
 static void
-ppd_defaults(ppd_file_t  *ppd, /* I - PPD file */
-             ppd_group_t *g)   /* I - Group to default */
+ppd_defaults(ppd_file_t  *ppd,         /* I - PPD file */
+             ppd_group_t *g)           /* I - Group to default */
 {
-  int          i;              /* Looping var */
-  ppd_option_t *o;             /* Current option */
-  ppd_group_t  *sg;            /* Current sub-group */
+  int          i;                      /* Looping var */
+  ppd_option_t *o;                     /* Current option */
+  ppd_group_t  *sg;                    /* Current sub-group */
 
 
   for (i = g->num_options, o = g->options; i > 0; i --, o ++)
@@ -724,5 +1051,87 @@ ppd_defaults(ppd_file_t  *ppd,    /* I - PPD file */
 
 
 /*
- * End of "$Id: mark.c 6939 2007-09-10 21:18:02Z mike $".
+ * 'ppd_mark_choices()' - Mark one or more option choices from a string.
+ */
+
+static int                             /* O - 1 if there are conflicts, 0 otherwise */
+ppd_mark_choices(ppd_file_t *ppd,      /* I - PPD file */
+                 const char *options)  /* I - "*Option Choice ..." string */
+{
+  char option[PPD_MAX_NAME],           /* Current option */
+       choice[PPD_MAX_NAME],           /* Current choice */
+       *ptr;                           /* Pointer into option or choice */
+  int  conflict = 0;                   /* Do we have a conflict? */
+
+
+  if (!options)
+    return (0);
+
+ /*
+  * Read all of the "*Option Choice" pairs from the string, marking PPD
+  * options as we go...
+  */
+
+  while (*options)
+  {
+   /*
+    * Skip leading whitespace...
+    */
+
+    while (isspace(*options & 255))
+      options ++;
+
+    if (*options != '*')
+      break;
+
+   /*
+    * Get the option name...
+    */
+
+    options ++;
+    ptr = option;
+    while (*options && !isspace(*options & 255) &&
+              ptr < (option + sizeof(option) - 1))
+      *ptr++ = *options++;
+
+    if (ptr == option)
+      break;
+
+    *ptr = '\0';
+
+   /*
+    * Get the choice...
+    */
+
+    while (isspace(*options & 255))
+      options ++;
+
+    if (!*options)
+      break;
+
+    ptr = choice;
+    while (*options && !isspace(*options & 255) &&
+              ptr < (choice + sizeof(choice) - 1))
+      *ptr++ = *options++;
+
+    *ptr = '\0';
+
+   /*
+    * Mark the option...
+    */
+
+    if (ppdMarkOption(ppd, option, choice))
+      conflict = 1;
+  }
+
+ /*
+  * Return whether we had any conflicts...
+  */
+
+  return (conflict);
+}
+
+
+/*
+ * End of "$Id: mark.c 7278 2008-01-31 01:23:09Z mike $".
  */
index 02bb74560ef47e51412e401e3cb3317290c71500..32ff2c805d22e58367ba8823c3ee50726f6e8415 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Notification routines for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 2005-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -36,7 +36,7 @@
  * @since CUPS 1.2@
  */
 
-char *                                 /* O - Subject string or NULL */
+char *                                 /* O - Subject string or @code NULL@ */
 cupsNotifySubject(cups_lang_t *lang,   /* I - Language data */
                   ipp_t       *event)  /* I - Event data */
 {
@@ -162,12 +162,12 @@ cupsNotifySubject(cups_lang_t *lang,      /* I - Language data */
 /*
  * 'cupsNotifyText()' - Return the text for the given notification message.
  *
- * The returned string must be freed by the caller using free().
+ * The returned string must be freed by the caller using @code free@.
  *
  * @since CUPS 1.2@
  */
 
-char *                                 /* O - Message text or NULL */
+char *                                 /* O - Message text or @code NULL@ */
 cupsNotifyText(cups_lang_t *lang,      /* I - Language data */
                ipp_t       *event)     /* I - Event data */
 {
index f04138497dd1e10a29185f86a26315bd72c7877f..4ffb39f8244aa05359fb4b0078b9cf18df6c1278 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: options.c 6943 2007-09-10 23:00:33Z mike $"
+ * "$Id: options.c 7278 2008-01-31 01:23:09Z mike $"
  *
  *   Option routines for the Common UNIX Printing System (CUPS).
  *
  *
  * Contents:
  *
- *   cupsAddOption()     - Add an option to an option array.
- *   cupsFreeOptions()   - Free all memory used by options.
- *   cupsGetOption()     - Get an option value.
- *   cupsMarkOptions()   - Mark command-line options in a PPD file.
- *   cupsParseOptions()  - Parse options from a command-line argument.
- *   cupsRemoveOptions() - Remove an option from an option array.
- *   debug_marked()      - Output the marked array to stdout...
- *   ppd_mark_choices()  - Mark one or more option choices from a string.
+ *   cupsAddOption()    - Add an option to an option array.
+ *   cupsFreeOptions()  - Free all memory used by options.
+ *   cupsGetOption()    - Get an option value.
+ *   cupsParseOptions() - Parse options from a command-line argument.
+ *   cupsRemoveOption() - Remove an option from an option array.
  */
 
 /*
 #include "debug.h"
 
 
-/*
- * Local functions...
- */
-
-#ifdef DEBUG
-static void    debug_marked(ppd_file_t *ppd, const char *title);
-#else
-#  define debug_marked(ppd,title)
-#endif /* DEBUG */
-static int     ppd_mark_choices(ppd_file_t *ppd, const char *options);
-
-
 /*
  * 'cupsAddOption()' - Add an option to an option array.
+ *
+ * New option arrays can be initialized simply by passing 0 for the
+ * "num_options" parameter.
  */
 
-int                                    /* O - Number of options */
-cupsAddOption(const char    *name,     /* I - Name of option */
-              const char    *value,    /* I - Value of option */
-             int           num_options,/* I - Number of options */
+int                                    /* O  - Number of options */
+cupsAddOption(const char    *name,     /* I  - Name of option */
+              const char    *value,    /* I  - Value of option */
+             int           num_options,/* I  - Number of options */
               cups_option_t **options) /* IO - Pointer to options */
 {
   int          i;                      /* Looping var */
@@ -139,7 +127,7 @@ cupsFreeOptions(
  * 'cupsGetOption()' - Get an option value.
  */
 
-const char *                           /* O - Option value or NULL */
+const char *                           /* O - Option value or @code NULL@ */
 cupsGetOption(const char    *name,     /* I - Name of option */
               int           num_options,/* I - Number of options */
               cups_option_t *options)  /* I - Options */
@@ -158,307 +146,14 @@ cupsGetOption(const char    *name,       /* I - Name of option */
 }
 
 
-/*
- * 'cupsMarkOptions()' - Mark command-line options in a PPD file.
- */
-
-int                                    /* O - 1 if conflicting */
-cupsMarkOptions(
-    ppd_file_t    *ppd,                        /* I - PPD file */
-    int           num_options,         /* I - Number of options */
-    cups_option_t *options)            /* I - Options */
-{
-  int          i, j, k;                /* Looping vars */
-  int          conflict;               /* Option conflicts */
-  char         *val,                   /* Pointer into value */
-               *ptr,                   /* Pointer into string */
-               s[255];                 /* Temporary string */
-  const char   *page_size;             /* PageSize option */
-  cups_option_t        *optptr;                /* Current option */
-  ppd_option_t *option;                /* PPD option */
-  ppd_attr_t   *attr;                  /* PPD attribute */
-  static const char * const duplex_options[] =
-               {                       /* Duplex option names */
-                 "Duplex",             /* Adobe */
-                 "EFDuplex",           /* EFI */
-                 "EFDuplexing",        /* EFI */
-                 "KD03Duplex",         /* Kodak */
-                 "JCLDuplex"           /* Samsung */
-               };
-  static const char * const duplex_one[] =
-               {                       /* one-sided names */
-                 "None",
-                 "False"
-               };
-  static const char * const duplex_two_long[] =
-               {                       /* two-sided-long-edge names */
-                 "DuplexNoTumble",     /* Adobe */
-                 "LongEdge",           /* EFI */
-                 "Top"                 /* EFI */
-               };
-  static const char * const duplex_two_short[] =
-               {                       /* two-sided-long-edge names */
-                 "DuplexTumble",       /* Adobe */
-                 "ShortEdge",          /* EFI */
-                 "Bottom"              /* EFI */
-               };
-
-
- /*
-  * Check arguments...
-  */
-
-  if (ppd == NULL || num_options <= 0 || options == NULL)
-    return (0);
-
-  debug_marked(ppd, "Before...");
-
- /*
-  * Mark options...
-  */
-
-  conflict  = 0;
-
-  for (i = num_options, optptr = options; i > 0; i --, optptr ++)
-    if (!strcasecmp(optptr->name, "media"))
-    {
-     /*
-      * Loop through the option string, separating it at commas and
-      * marking each individual option as long as the corresponding
-      * PPD option (PageSize, InputSlot, etc.) is not also set.
-      *
-      * For PageSize, we also check for an empty option value since
-      * some versions of MacOS X use it to specify auto-selection
-      * of the media based solely on the size.
-      */
-
-      page_size = cupsGetOption("PageSize", num_options, options);
-
-      for (val = optptr->value; *val;)
-      {
-       /*
-        * Extract the sub-option from the string...
-       */
-
-        for (ptr = s; *val && *val != ',' && (ptr - s) < (sizeof(s) - 1);)
-         *ptr++ = *val++;
-       *ptr++ = '\0';
-
-       if (*val == ',')
-         val ++;
-
-       /*
-        * Mark it...
-       */
-
-        if (!page_size || !page_size[0])
-         if (ppdMarkOption(ppd, "PageSize", s))
-            conflict = 1;
-
-        if (cupsGetOption("InputSlot", num_options, options) == NULL)
-         if (ppdMarkOption(ppd, "InputSlot", s))
-            conflict = 1;
-
-        if (cupsGetOption("MediaType", num_options, options) == NULL)
-         if (ppdMarkOption(ppd, "MediaType", s))
-            conflict = 1;
-
-        if (cupsGetOption("EFMediaType", num_options, options) == NULL)
-         if (ppdMarkOption(ppd, "EFMediaType", s))             /* EFI */
-            conflict = 1;
-
-        if (cupsGetOption("EFMediaQualityMode", num_options, options) == NULL)
-         if (ppdMarkOption(ppd, "EFMediaQualityMode", s))      /* EFI */
-            conflict = 1;
-
-       if (strcasecmp(s, "manual") == 0 &&
-           cupsGetOption("ManualFeed", num_options, options) == NULL)
-          if (ppdMarkOption(ppd, "ManualFeed", "True"))
-           conflict = 1;
-      }
-    }
-    else if (!strcasecmp(optptr->name, "sides"))
-    {
-      for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
-        if (cupsGetOption(duplex_options[j], num_options, options) != NULL)
-         break;
-
-      if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
-      {
-       /*
-        * Don't override the PPD option with the IPP attribute...
-       */
-
-        continue;
-      }
-
-      if (!strcasecmp(optptr->value, "one-sided"))
-      {
-       /*
-        * Mark the appropriate duplex option for one-sided output...
-       */
-
-        for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
-         if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
-           break;
-
-       if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
-       {
-          for (k = 0; k < (int)(sizeof(duplex_one) / sizeof(duplex_one[0])); k ++)
-            if (ppdFindChoice(option, duplex_one[k]))
-           {
-             if (ppdMarkOption(ppd, duplex_options[j], duplex_one[k]))
-               conflict = 1;
-
-             break;
-            }
-        }
-      }
-      else if (!strcasecmp(optptr->value, "two-sided-long-edge"))
-      {
-       /*
-        * Mark the appropriate duplex option for two-sided-long-edge output...
-       */
-
-        for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
-         if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
-           break;
-
-       if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
-       {
-          for (k = 0; k < (int)(sizeof(duplex_two_long) / sizeof(duplex_two_long[0])); k ++)
-            if (ppdFindChoice(option, duplex_two_long[k]))
-           {
-             if (ppdMarkOption(ppd, duplex_options[j], duplex_two_long[k]))
-               conflict = 1;
-
-             break;
-            }
-        }
-      }
-      else if (!strcasecmp(optptr->value, "two-sided-short-edge"))
-      {
-       /*
-        * Mark the appropriate duplex option for two-sided-short-edge output...
-       */
-
-        for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
-         if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
-           break;
-
-       if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
-       {
-          for (k = 0; k < (int)(sizeof(duplex_two_short) / sizeof(duplex_two_short[0])); k ++)
-            if (ppdFindChoice(option, duplex_two_short[k]))
-           {
-             if (ppdMarkOption(ppd, duplex_options[j], duplex_two_short[k]))
-               conflict = 1;
-
-             break;
-            }
-        }
-      }
-    }
-    else if (!strcasecmp(optptr->name, "resolution") ||
-             !strcasecmp(optptr->name, "printer-resolution"))
-    {
-      if (ppdMarkOption(ppd, "Resolution", optptr->value))
-        conflict = 1;
-      if (ppdMarkOption(ppd, "SetResolution", optptr->value))
-       /* Calcomp, Linotype, QMS, Summagraphics, Tektronix, Varityper */
-        conflict = 1;
-      if (ppdMarkOption(ppd, "JCLResolution", optptr->value))  /* HP */
-        conflict = 1;
-      if (ppdMarkOption(ppd, "CNRes_PGP", optptr->value))      /* Canon */
-        conflict = 1;
-    }
-    else if (!strcasecmp(optptr->name, "output-bin"))
-    {
-      if (!cupsGetOption("OutputBin", num_options, options))
-        if (ppdMarkOption(ppd, "OutputBin", optptr->value))
-          conflict = 1;
-    }
-    else if (!strcasecmp(optptr->name, "multiple-document-handling"))
-    {
-      if (!cupsGetOption("Collate", num_options, options) &&
-          ppdFindOption(ppd, "Collate"))
-      {
-        if (strcasecmp(optptr->value, "separate-documents-uncollated-copies"))
-       {
-         if (ppdMarkOption(ppd, "Collate", "True"))
-            conflict = 1;
-        }
-       else
-       {
-         if (ppdMarkOption(ppd, "Collate", "False"))
-            conflict = 1;
-        }
-      }
-    }
-    else if (!strcasecmp(optptr->name, "finishings"))
-    {
-     /*
-      * Lookup cupsIPPFinishings attributes for each value...
-      */
-
-      for (ptr = optptr->value; *ptr;)
-      {
-       /*
-        * Get the next finishings number...
-       */
-
-        if (!isdigit(*ptr & 255))
-         break;
-
-        if ((j = strtol(ptr, &ptr, 10)) < 3)
-         break;
-
-       /*
-        * Skip separator as needed...
-       */
-
-        if (*ptr == ',')
-         ptr ++;
-
-       /*
-        * Look it up in the PPD file...
-       */
-
-       sprintf(s, "%d", j);
-
-        if ((attr = ppdFindAttr(ppd, "cupsIPPFinishings", s)) == NULL)
-         continue;
-
-       /*
-        * Apply "*Option Choice" settings from the attribute value...
-       */
-
-        if (ppd_mark_choices(ppd, attr->value))
-         conflict = 1;
-      }
-    }
-    else if (!strcasecmp(optptr->name, "mirror"))
-    {
-      if (ppdMarkOption(ppd, "MirrorPrint", optptr->value))
-       conflict = 1;
-    }
-    else if (ppdMarkOption(ppd, optptr->name, optptr->value))
-      conflict = 1;
-
-  debug_marked(ppd, "After...");
-
-  return (conflict);
-}
-
-
 /*
  * 'cupsParseOptions()' - Parse options from a command-line argument.
  *
  * This function converts space-delimited name/value pairs according
  * to the PAPI text option ABNF specification. Collection values
  * ("name={a=... b=... c=...}") are stored with the curley brackets
- * intact - use cupsParseOptions() on the value to extract the collection
- * attributes.
+ * intact - use @code cupsParseOptions@ on the value to extract the
+ * collection attributes.
  */
 
 int                                    /* O - Number of options found */
@@ -470,7 +165,8 @@ cupsParseOptions(
   char *copyarg,                       /* Copy of input string */
        *ptr,                           /* Pointer into string */
        *name,                          /* Pointer to name */
-       *value;                         /* Pointer to value */
+       *value,                         /* Pointer to value */
+       quote;                          /* Quote character */
 
 
  /*
@@ -510,7 +206,7 @@ cupsParseOptions(
     */
 
     name = ptr;
-    while (!isspace(*ptr & 255) && *ptr != '=' && *ptr != '\0')
+    while (!isspace(*ptr & 255) && *ptr != '=' && *ptr)
       ptr ++;
 
    /*
@@ -530,10 +226,10 @@ cupsParseOptions(
     if (*ptr != '=')
     {
      /*
-      * Start of another option...
+      * Boolean option...
       */
 
-      if (strncasecmp(name, "no", 2) == 0)
+      if (!strncasecmp(name, "no", 2))
         num_options = cupsAddOption(name + 2, "false", num_options,
                                    options);
       else
@@ -548,38 +244,18 @@ cupsParseOptions(
 
     *ptr++ = '\0';
 
-    if (*ptr == '\'')
+    if (*ptr == '\'' || *ptr == '\"')
     {
      /*
       * Quoted string constant...
       */
 
-      ptr ++;
-      value = ptr;
-
-      while (*ptr != '\'' && *ptr != '\0')
-      {
-        if (*ptr == '\\')
-         _cups_strcpy(ptr, ptr + 1);
-
-        ptr ++;
-      }
-
-      if (*ptr != '\0')
-        *ptr++ = '\0';
-    }
-    else if (*ptr == '\"')
-    {
-     /*
-      * Double-quoted string constant...
-      */
-
-      ptr ++;
+      quote = *ptr++;
       value = ptr;
 
-      while (*ptr != '\"' && *ptr != '\0')
+      while (*ptr != quote && *ptr)
       {
-        if (*ptr == '\\')
+        if (*ptr == '\\' && ptr[1])
          _cups_strcpy(ptr, ptr + 1);
 
         ptr ++;
@@ -612,7 +288,7 @@ cupsParseOptions(
              break;
          }
         }
-        else if (*ptr == '\\')
+        else if (*ptr == '\\' && ptr[1])
          _cups_strcpy(ptr, ptr + 1);
 
       if (*ptr != '\0')
@@ -626,9 +302,9 @@ cupsParseOptions(
 
       value = ptr;
 
-      while (!isspace(*ptr & 255) && *ptr != '\0')
+      while (!isspace(*ptr & 255) && *ptr)
       {
-        if (*ptr == '\\')
+        if (*ptr == '\\' && ptr[1])
          _cups_strcpy(ptr, ptr + 1);
 
         ptr ++;
@@ -715,110 +391,6 @@ cupsRemoveOption(
 }
 
 
-#ifdef DEBUG
-/*
- * 'debug_marked()' - Output the marked array to stdout...
- */
-
-static void
-debug_marked(ppd_file_t *ppd,          /* I - PPD file data */
-             const char *title)                /* I - Title for list */
-{
-  ppd_choice_t *c;                     /* Current choice */
-
-
-  printf("cupsMarkOptions: %s\n", title);
-
-  for (c = (ppd_choice_t *)cupsArrayFirst(ppd->marked);
-       c;
-       c = (ppd_choice_t *)cupsArrayNext(ppd->marked))
-    printf("cupsMarkOptions: %s=%s\n", c->option->keyword, c->choice);
-}
-#endif /* DEBUG */
-
-
-/*
- * 'ppd_mark_choices()' - Mark one or more option choices from a string.
- */
-
-static int                             /* O - 1 if there are conflicts, 0 otherwise */
-ppd_mark_choices(ppd_file_t *ppd,      /* I - PPD file */
-                 const char *options)  /* I - "*Option Choice ..." string */
-{
-  char option[PPD_MAX_NAME],           /* Current option */
-       choice[PPD_MAX_NAME],           /* Current choice */
-       *ptr;                           /* Pointer into option or choice */
-  int  conflict = 0;                   /* Do we have a conflict? */
-
-
-  if (!options)
-    return (0);
-
- /*
-  * Read all of the "*Option Choice" pairs from the string, marking PPD
-  * options as we go...
-  */
-
-  while (*options)
-  {
-   /*
-    * Skip leading whitespace...
-    */
-
-    while (isspace(*options & 255))
-      options ++;
-
-    if (*options != '*')
-      break;
-
-   /*
-    * Get the option name...
-    */
-
-    options ++;
-    ptr = option;
-    while (*options && !isspace(*options & 255) &&
-              ptr < (option + sizeof(option) - 1))
-      *ptr++ = *options++;
-
-    if (ptr == option)
-      break;
-
-    *ptr = '\0';
-
-   /*
-    * Get the choice...
-    */
-
-    while (isspace(*options & 255))
-      options ++;
-
-    if (!*options)
-      break;
-
-    ptr = choice;
-    while (*options && !isspace(*options & 255) &&
-              ptr < (choice + sizeof(choice) - 1))
-      *ptr++ = *options++;
-
-    *ptr = '\0';
-
-   /*
-    * Mark the option...
-    */
-
-    if (ppdMarkOption(ppd, option, choice))
-      conflict = 1;
-  }
-
- /*
-  * Return whether we had any conflicts...
-  */
-
-  return (conflict);
-}
-
-
 /*
- * End of "$Id: options.c 6943 2007-09-10 23:00:33Z mike $".
+ * End of "$Id: options.c 7278 2008-01-31 01:23:09Z mike $".
  */
index ea9eb86b77fc3e8ef1327ce2240ad5b1839eb9fe..a70a0cfebdfb67e67e44d90d32ca9736d214a671 100644 (file)
@@ -428,7 +428,7 @@ ppdOpen(FILE *fp)                   /* I - File to read from */
  * @since CUPS 1.2@
  */
 
-ppd_file_t *                           /* O - PPD file record */
+ppd_file_t *                           /* O - PPD file record or @code NULL@ if the PPD file could not be opened. */
 ppdOpen2(cups_file_t *fp)              /* I - File to read from */
 {
   int                  i, j, k;        /* Looping vars */
@@ -2020,7 +2020,7 @@ ppdOpen2(cups_file_t *fp)         /* I - File to read from */
  * 'ppdOpenFd()' - Read a PPD file into memory.
  */
 
-ppd_file_t *                           /* O - PPD file record */
+ppd_file_t *                           /* O - PPD file record or @code NULL@ if the PPD file could not be opened. */
 ppdOpenFd(int fd)                      /* I - File to read from */
 {
   cups_file_t          *fp;            /* CUPS file pointer */
@@ -2070,7 +2070,7 @@ ppdOpenFd(int fd)                 /* I - File to read from */
  * 'ppdOpenFile()' - Read a PPD file into memory.
  */
 
-ppd_file_t *                           /* O - PPD file record */
+ppd_file_t *                           /* O - PPD file record or @code NULL@ if the PPD file could not be opened. */
 ppdOpenFile(const char *filename)      /* I - File to read from */
 {
   cups_file_t          *fp;            /* File pointer */
index f154c6ba3f1d71fa984dfb6d3f8cc085d602f40c..c99981793f3fc686cfdb73edb976d20ac47c20f0 100644 (file)
@@ -4,7 +4,7 @@
  *   PostScript Printer Description definitions for the Common UNIX Printing
  *   System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -118,11 +118,14 @@ typedef enum ppd_status_e         /**** Status Codes @since CUPS 1.1.19@ ****/
   PPD_BAD_CUSTOM_PARAM                 /* Bad custom parameter */
 } ppd_status_t;
 
-typedef enum ppd_conform_e             /**** Conformance Levels @since CUPS 1.1.19@ ****/
+enum ppd_conform_e                     /**** Conformance Levels @since CUPS 1.1.19@ ****/
 {
   PPD_CONFORM_RELAXED,                 /* Relax whitespace and control char */
   PPD_CONFORM_STRICT                   /* Require strict conformance */
-} ppd_conform_t;
+};
+
+typedef enum ppd_conform_e ppd_conform_t;
+                                       /**** Conformance Levels @since CUPS 1.1.19@ ****/
 
 typedef struct ppd_attr_s              /**** PPD Attribute Structure @since CUPS 1.1.19@ ****/
 {
@@ -172,7 +175,7 @@ typedef struct ppd_group_s          /**** Groups ****/
   struct ppd_group_s *subgroups;       /* Sub-groups (max depth = 1) */
 } ppd_group_t;
 
-typedef struct                         /**** Constraints ****/
+typedef struct ppd_const_s             /**** Constraints ****/
 {
   char         option1[PPD_MAX_NAME];  /* First keyword */
   char         choice1[PPD_MAX_NAME];  /* First option/choice (blank for all) */
@@ -392,7 +395,12 @@ extern ppd_file_t  *ppdOpen2(cups_file_t *fp) _CUPS_API_1_2;
 extern const char      *ppdLocalizeIPPReason(ppd_file_t *ppd,
                                              const char *reason,
                                              const char *scheme,
-                                             char *buffer, size_t bufsize) _CUPS_API_1_3;
+                                             char *buffer,
+                                             size_t bufsize) _CUPS_API_1_3;
+
+/**** New in CUPS 1.4 ****/
+extern const char      *ppdLocalizeMarkerName(ppd_file_t *ppd,
+                                              const char *name) _CUPS_API_1_4;
 
 
 /*
index bfe3cc0d6fe45c331702870c81d9d61292438272..e2eae6eb78c842be5e6e04c06eccbe9acb8fb6b0 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Side-channel API definitions for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -45,22 +45,26 @@ extern "C" {
  * Enumerations...
  */
 
-typedef enum                           /**** Bidirectional capabilities ****/
+enum cups_sc_bidi_e                    /**** Bidirectional capabilities ****/
 {
   CUPS_SC_BIDI_NOT_SUPPORTED = 0,      /* Bidirectional I/O is not supported */
   CUPS_SC_BIDI_SUPPORTED = 1           /* Bidirectional I/O is supported */
-} cups_sc_bidi_t;
+};
+typedef enum cups_sc_bidi_e cups_sc_bidi_t;
+                                       /**** Bidirectional capabilities ****/
 
-typedef enum                           /**** Request command codes ****/
+enum cups_sc_command_e                 /**** Request command codes ****/
 {
   CUPS_SC_CMD_SOFT_RESET = 1,          /* Do a soft reset */
   CUPS_SC_CMD_DRAIN_OUTPUT = 2,                /* Drain all pending output */
   CUPS_SC_CMD_GET_BIDI = 3,            /* Return bidirectional capabilities */
   CUPS_SC_CMD_GET_DEVICE_ID = 4,       /* Return the IEEE-1284 device ID */
   CUPS_SC_CMD_GET_STATE = 5            /* Return the device state */
-} cups_sc_command_t;
+};
+typedef enum cups_sc_command_e cups_sc_command_t;
+                                       /**** Request command codes ****/
 
-typedef enum                           /**** Printer state bits ****/
+enum cups_sc_state_e                   /**** Printer state bits ****/
 {
   CUPS_SC_STATE_OFFLINE = 0,           /* Device is off-line */
   CUPS_SC_STATE_ONLINE = 1,            /* Device is on-line */
@@ -70,9 +74,11 @@ typedef enum                         /**** Printer state bits ****/
   CUPS_SC_STATE_MEDIA_EMPTY = 32,      /* Paper out condition */
   CUPS_SC_STATE_MARKER_LOW = 64,       /* Toner/ink low condition */
   CUPS_SC_STATE_MARKER_EMPTY = 128     /* Toner/ink out condition */
-} cups_sc_state_t;
+};
+typedef enum cups_sc_state_e cups_sc_state_t;
+                                       /**** Printer state bits ****/
 
-typedef enum                           /**** Response status codes ****/
+enum cups_sc_status_e                  /**** Response status codes ****/
 {
   CUPS_SC_STATUS_NONE,                 /* No status */
   CUPS_SC_STATUS_OK,                   /* Operation succeeded */
@@ -82,7 +88,9 @@ typedef enum                          /**** Response status codes ****/
   CUPS_SC_STATUS_BAD_MESSAGE,          /* The command/response message was invalid */
   CUPS_SC_STATUS_TOO_BIG,              /* Response too big */
   CUPS_SC_STATUS_NOT_IMPLEMENTED       /* Command not implemented */
-} cups_sc_status_t;
+};
+typedef enum cups_sc_status_e cups_sc_status_t;
+                                       /**** Response status codes ****/
 
 
 /*
index 5d5bd5206c8fa54dd31b094ba84a17c011f07fb3..30cbc0cae078fe07cb2b57954faa9eae78a61f9a 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Temp file utilities for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -155,8 +155,8 @@ cupsTempFd(char *filename,          /* I - Pointer to buffer */
  * 'cupsTempFile()' - Generates a temporary filename.
  *
  * The temporary filename is returned in the filename buffer.
- * This function is deprecated - use cupsTempFd() or cupsTempFile2()
- * instead.
+ * This function is deprecated - use @link cupsTempFd@ or
+ * @link cupsTempFile2@ instead.
  *
  * @deprecated@
  */
index 05d36c010796e90d869d5f51dfbda035489a9d14..35682234a7c4d5e4b46d4e058034a1049d1ff44d 100644 (file)
 
 *CloseGroup: Extended
 
-*% IPP reasons (for ppdLocalizeIPPReason tests)
+*% IPP reasons for ppdLocalizeIPPReason tests
 *cupsIPPReason foo/Foo Reason: "http://foo/bar.html
 help:anchor='foo'%20bookID=Vendor%20Help
 /help/foo/bar.html"
@@ -163,6 +163,12 @@ help:anchor='foo'%20bookID=Vendor%20Help
 /help/zh/foo/bar.html"
 *End
 
+*% Marker names for ppdLocalizeMarkerName tests
+*cupsMarkerName cyan/Cyan Toner: ""
+*fr.cupsMarkerName cyan/La Toner Cyan: ""
+*zh_TW.cupsMarkerName cyan/Number 1 Cyan Toner: ""
+*zh.cupsMarkerName cyan/Number 2 Cyan Toner: ""
+
 *DefaultFont: Courier
 *Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
 *Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
index e88a125682f6bbc5294a4936a8022024e5e632d5..9efa851f5a32e5af2a3923accaf4ed33cff36de8 100644 (file)
@@ -99,6 +99,7 @@ main(int  argc,                               /* I - Number of command-line arguments */
   int          conflicts;              /* Number of conflicts */
   char         *s;                     /* String */
   char         buffer[8192];           /* String buffer */
+  const char   *text;                  /* Localized text */
 
 
   status = 0;
@@ -235,6 +236,60 @@ main(int  argc,                            /* I - Number of command-line arguments */
       status ++;
       printf("FAIL (\"%s\" instead of \"Number 1 Foo Reason\")\n", buffer);
     }
+
+   /*
+    * cupsMarkerName localization...
+    */
+
+    putenv("LANG=en");
+
+    fputs("ppdLocalizeMarkerName(bogus): ", stdout);
+
+    if ((text = ppdLocalizeMarkerName(ppd, "bogus")) != NULL)
+    {
+      status ++;
+      printf("FAIL (\"%s\" instead of NULL)\n", text);
+    }
+    else
+      puts("PASS");
+
+    fputs("ppdLocalizeMarkerName(cyan): ", stdout);
+
+    if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
+        !strcmp(text, "Cyan Toner"))
+      puts("PASS");
+    else
+    {
+      status ++;
+      printf("FAIL (\"%s\" instead of \"Cyan Toner\")\n",
+             text ? text : "(null)");
+    }
+
+    putenv("LANG=fr");
+
+    fputs("ppdLocalizeMarkerName(fr cyan): ", stdout);
+    if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
+        !strcmp(text, "La Toner Cyan"))
+      puts("PASS");
+    else
+    {
+      status ++;
+      printf("FAIL (\"%s\" instead of \"La Toner Cyan\")\n",
+             text ? text : "(null)");
+    }
+
+    putenv("LANG=zh_TW");
+
+    fputs("ppdLocalizeMarkerName(zh_TW cyan): ", stdout);
+    if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
+        !strcmp(text, "Number 1 Cyan Toner"))
+      puts("PASS");
+    else
+    {
+      status ++;
+      printf("FAIL (\"%s\" instead of \"Number 1 Cyan Toner\")\n",
+             text ? text : "(null)");
+    }
   }
   else
   {
index 64d71d22a81e9a2a473cf6f93b5d12e22eab6036..c8d2b286460fe108f5c5a8b4f67cc51bac2a9979 100644 (file)
@@ -4,7 +4,7 @@
  *   User, system, and password routines for the Common UNIX Printing
  *   System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -56,7 +56,7 @@ static cups_file_t    *cups_open_client_conf(void);
  * The default encryption setting comes from the CUPS_ENCRYPTION
  * environment variable, then the ~/.cupsrc file, and finally the
  * /etc/cups/client.conf file. If not set, the default is
- * HTTP_ENCRYPT_IF_REQUESTED.
+ * @code HTTP_ENCRYPT_IF_REQUESTED@.
  */
 
 http_encryption_t                      /* O - Encryption settings */
@@ -133,7 +133,7 @@ cupsEncryption(void)
 /*
  * 'cupsGetPassword()' - Get a password from the user.
  *
- * Uses the current password callback function. Returns NULL if the
+ * Uses the current password callback function. Returns @code NULL@ if the
  * user does not provide a password.
  */
 
@@ -151,7 +151,13 @@ cupsGetPassword(const char *prompt)        /* I - Prompt string */
 void
 cupsSetEncryption(http_encryption_t e) /* I - New encryption preference */
 {
-  _cupsGlobals()->encryption = e;
+  _cups_globals_t *cg = _cupsGlobals();        /* Pointer to library globals */
+
+
+  cg->encryption = e;
+
+  if (cg->http)
+    httpEncryption(cg->http, e);
 }
 
 
@@ -266,7 +272,7 @@ cupsServer(void)
 /*
  * 'cupsSetPasswordCB()' - Set the password callback for CUPS.
  *
- * Pass NULL to restore the default (console) password callback.
+ * Pass @code NULL@ to restore the default (console) password callback.
  */
 
 void
@@ -286,7 +292,7 @@ cupsSetPasswordCB(cups_password_cb_t cb)/* I - Callback function */
  * 'cupsSetServer()' - Set the default server name.
  *
  * The "server" string can be a fully-qualified hostname, a numeric
- * IPv4 or IPv6 address, or a domain socket pathname. Pass NULL to
+ * IPv4 or IPv6 address, or a domain socket pathname. Pass @code NULL@ to
  * restore the default server name.
  */
 
@@ -319,13 +325,19 @@ cupsSetServer(const char *server) /* I - Server name */
     cg->server[0]     = '\0';
     cg->servername[0] = '\0';
   }
+
+  if (cg->http)
+  {
+    httpClose(cg->http);
+    cg->http = NULL;
+  }
 }
 
 
 /*
  * 'cupsSetUser()' - Set the default user name.
  *
- * Pass NULL to restore the default user name.
+ * Pass @code NULL@ to restore the default user name.
  */
 
 void
index 6dea980850a76c1dfb5e0171139da36b619f5215..eade62f081ddad7246f0d5343603e884ce243563 100644 (file)
@@ -84,7 +84,10 @@ static int   cups_get_printer_uri(http_t *http, const char *name,
 /*
  * 'cupsCancelJob()' - Cancel a print job on the default server.
  *
- * Use the cupsLastError() and cupsLastErrorString() functions to get
+ * Pass @code CUPS_JOBID_ALL@ to cancel all jobs or @code CUPS_JOBID_CURRENT@
+ * to cancel the current job on the named destination.
+ *
+ * Use the @link cupsLastError@ and @link cupsLastErrorString@ functions to get
  * the cause of any failure.
  */
 
@@ -92,7 +95,7 @@ int                                   /* O - 1 on success, 0 on failure */
 cupsCancelJob(const char *name,                /* I - Name of printer or class */
               int        job_id)       /* I - Job ID */
 {
-  return (cupsCancelJob2(CUPS_HTTP_DEFAULT, job_id, 0)
+  return (cupsCancelJob2(CUPS_HTTP_DEFAULT, name, job_id, 0)
               < IPP_REDIRECTION_OTHER_SITE);
 }
 
@@ -103,18 +106,22 @@ cupsCancelJob(const char *name,           /* I - Name of printer or class */
  * Canceled jobs remain in the job history while purged jobs are removed
  * from the job history.
  *
- * Use the cupsLastError() and cupsLastErrorString() functions to get
+ * Pass @code CUPS_JOBID_ALL@ to cancel all jobs or @code CUPS_JOBID_CURRENT@
+ * to cancel the current job on the named destination.
+ *
+ * Use the @link cupsLastError@ and @link cupsLastErrorString@ functions to get
  * the cause of any failure.
  *
  * @since CUPS 1.4@
  */
 
 ipp_status_t                           /* O - IPP status */
-cupsCancelJob2(http_t *http,           /* I - HTTP connection or CUPS_HTTP_DEFAULT */
-               int    job_id,          /* I - Job ID */
-              int    purge)            /* I - 1 to purge, 0 to cancel */
+cupsCancelJob2(http_t     *http,       /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
+               const char *name,       /* I - Name of printer or class */
+               int        job_id,      /* I - Job ID or 0 for the current job, -1 for all jobs */
+              int        purge)        /* I - 1 to purge, 0 to cancel */
 {
-  char         uri[HTTP_MAX_URI];      /* Job URI */
+  char         uri[HTTP_MAX_URI];      /* Job/printer URI */
   ipp_t                *request;               /* IPP request */
 
 
@@ -122,7 +129,7 @@ cupsCancelJob2(http_t *http,                /* I - HTTP connection or CUPS_HTTP_DEFAULT */
   * Range check input...
   */
 
-  if (job_id <= 0)
+  if (job_id < -1 || (!name && job_id == 0))
   {
     _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL));
     return (0);
@@ -137,25 +144,42 @@ cupsCancelJob2(http_t *http,              /* I - HTTP connection or CUPS_HTTP_DEFAULT */
       return (IPP_SERVICE_UNAVAILABLE);
 
  /*
-  * Build an IPP_CANCEL_JOB request, which requires the following
+  * Build an IPP_CANCEL_JOB or IPP_PURGE_JOBS request, which requires the following
   * attributes:
   *
   *    attributes-charset
   *    attributes-natural-language
-  *    job-uri
+  *    job-uri or printer-uri + job-id
   *    requesting-user-name
-  *    [purge-job]
+  *    [purge-job] or [purge-jobs]
   */
 
-  request = ippNewRequest(IPP_CANCEL_JOB);
+  request = ippNewRequest(job_id < 0 ? IPP_PURGE_JOBS : IPP_CANCEL_JOB);
 
-  snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id);
+  if (name)
+  {
+    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                     "localhost", ippPort(), "/printers/%s", name);
+
+    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
+                 uri);
+    ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id",
+                  job_id);
+  }
+  else if (job_id > 0)
+  {
+    snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id);
+
+    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
+  }
 
-  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
                NULL, cupsUser());
-  if (purge)
+
+  if (purge && job_id >= 0)
     ippAddBoolean(request, IPP_TAG_OPERATION, "purge-job", 1);
+  else if (!purge && job_id < 0)
+    ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", 0);
 
  /*
   * Do the request...
@@ -170,15 +194,15 @@ cupsCancelJob2(http_t *http,              /* I - HTTP connection or CUPS_HTTP_DEFAULT */
 /*
  * 'cupsCreateJob()' - Create an empty job.
  *
- * Submit files for printing to the job using the cupsStartDocument(),
- * cupsWriteRequestData(), and cupsFinishDocument() functions.
+ * Submit files for printing to the job using the @link cupsStartDocument@,
+ * @link cupsWriteRequestData@, and @link cupsFinishDocument@ functions.
  *
  * @since CUPS 1.4@
  */
 
 int                                    /* O - Job ID or 0 on error */
 cupsCreateJob(
-    http_t        *http,               /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+    http_t        *http,               /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
     const char    *name,               /* I - Printer or class name */
     const char    *title,              /* I - Title of job */
     int           num_options,         /* I - Number of options */
@@ -251,11 +275,13 @@ cupsCreateJob(
 /*
  * 'cupsFinishDocument()' - Finish sending a document.
  *
+ * The document must have been started using @link cupsStartDocument@.
+ *
  * @since CUPS 1.4@
  */
 
 ipp_status_t                           /* O - Status of document submission */
-cupsFinishDocument(http_t     *http,   /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+cupsFinishDocument(http_t     *http,   /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
                    const char *name)   /* I - Printer or class name */
 {
   char resource[1024];                 /* Printer resource */
@@ -299,7 +325,7 @@ cupsFreeJobs(int        num_jobs,   /* I - Number of jobs */
 /*
  * 'cupsGetClasses()' - Get a list of printer classes from the default server.
  *
- * This function is deprecated - use cupsGetDests() instead.
+ * This function is deprecated - use @link cupsGetDests@ instead.
  *
  * @deprecated@
  */
@@ -394,12 +420,12 @@ cupsGetClasses(char ***classes)           /* O - Classes */
  * This function returns the default printer or class as defined by
  * the LPDEST or PRINTER environment variables. If these environment
  * variables are not set, the server default destination is returned.
- * Applications should use the cupsGetDests() and cupsGetDest() functions
- * to get the user-defined default printer, as this function does not
- * support the lpoptions-defined default printer.
+ * Applications should use the @link cupsGetDests@ and @link cupsGetDest@
+ * functions to get the user-defined default printer, as this function does
+ * not support the lpoptions-defined default printer.
  */
 
-const char *                           /* O - Default printer or NULL */
+const char *                           /* O - Default printer or @code NULL@ */
 cupsGetDefault(void)
 {
  /*
@@ -416,15 +442,15 @@ cupsGetDefault(void)
  * This function returns the default printer or class as defined by
  * the LPDEST or PRINTER environment variables. If these environment
  * variables are not set, the server default destination is returned.
- * Applications should use the cupsGetDests() and cupsGetDest() functions
- * to get the user-defined default printer, as this function does not
- * support the lpoptions-defined default printer.
+ * Applications should use the @link cupsGetDests@ and @link cupsGetDest@
+ * functions to get the user-defined default printer, as this function does
+ * not support the lpoptions-defined default printer.
  *
  * @since CUPS 1.1.21@
  */
 
-const char *                           /* O - Default printer or NULL */
-cupsGetDefault2(http_t *http)          /* I - HTTP connection */
+const char *                           /* O - Default printer or @code NULL@ */
+cupsGetDefault2(http_t *http)          /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
 {
   ipp_t                *request,               /* IPP Request */
                *response;              /* IPP Response */
@@ -487,21 +513,24 @@ cupsGetDefault2(http_t *http)             /* I - HTTP connection */
 
 /*
  * 'cupsGetJobs()' - Get the jobs from the default server.
+ *
+ * A "whichjobs" value of @code CUPS_WHICHJOBS_ALL@ returns all jobs regardless
+ * of state, while @code CUPS_WHICHJOBS_ACTIVE@ returns jobs that are
+ * pending, processing, or held and @code CUPS_WHICHJOBS_COMPLETED@ returns
+ * jobs that are stopped, canceled, aborted, or completed.
  */
 
 int                                    /* O - Number of jobs */
 cupsGetJobs(cups_job_t **jobs,         /* O - Job data */
-            const char *mydest,                /* I - NULL = all destinations,       *
-                                        *     otherwise show jobs for mydest */
+            const char *name,          /* I - @code NULL@ = all destinations, otherwise show jobs for mydest */
             int        myjobs,         /* I - 0 = all users, 1 = mine */
-           int        completed)       /* I - -1 = show all, 0 = active, *
-                                        *     1 = completed jobs         */
+           int        whichjobs)       /* I - @code CUPS_WHICHJOBS_ALL@, @code CUPS_WHICHJOBS_ACTIVE@, or @code CUPS_WHICHJOBS_COMPLETED@ */
 {
  /*
   * Return the jobs...
   */
 
-  return (cupsGetJobs2(CUPS_HTTP_DEFAULT, jobs, mydest, myjobs, completed));
+  return (cupsGetJobs2(CUPS_HTTP_DEFAULT, jobs, name, myjobs, whichjobs));
 }
 
 
@@ -509,17 +538,20 @@ cupsGetJobs(cups_job_t **jobs,            /* O - Job data */
 /*
  * 'cupsGetJobs2()' - Get the jobs from the specified server.
  *
+ * A "whichjobs" value of @code CUPS_WHICHJOBS_ALL@ returns all jobs regardless
+ * of state, while @code CUPS_WHICHJOBS_ACTIVE@ returns jobs that are
+ * pending, processing, or held and @code CUPS_WHICHJOBS_COMPLETED@ returns
+ * jobs that are stopped, canceled, aborted, or completed.
+ *
  * @since CUPS 1.1.21@
  */
 
 int                                    /* O - Number of jobs */
-cupsGetJobs2(http_t     *http,         /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+cupsGetJobs2(http_t     *http,         /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
              cups_job_t **jobs,                /* O - Job data */
-             const char *mydest,       /* I - NULL = all destinations,       *
-                                        *     otherwise show jobs for mydest */
+             const char *name,         /* I - @code NULL@ = all destinations, otherwise show jobs for mydest */
              int        myjobs,                /* I - 0 = all users, 1 = mine */
-            int        completed)      /* I - -1 = show all, 0 = active, *
-                                        *     1 = completed jobs         */
+            int        whichjobs)      /* I - @code CUPS_WHICHJOBS_ALL@, @code CUPS_WHICHJOBS_ACTIVE@, or @code CUPS_WHICHJOBS_COMPLETED@ */
 {
   int          n;                      /* Number of jobs */
   ipp_t                *request,               /* IPP Request */
@@ -570,10 +602,10 @@ cupsGetJobs2(http_t     *http,            /* I - HTTP connection or CUPS_HTTP_DEFAULT */
   * Get the right URI...
   */
 
-  if (mydest)
+  if (name)
   {
     if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
-                         "localhost", 0, "/printers/%s", mydest) != HTTP_URI_OK)
+                         "localhost", 0, "/printers/%s", name) != HTTP_URI_OK)
     {
       _cupsSetError(IPP_INTERNAL_ERROR, NULL);
 
@@ -611,10 +643,10 @@ cupsGetJobs2(http_t     *http,            /* I - HTTP connection or CUPS_HTTP_DEFAULT */
   if (myjobs)
     ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1);
 
-  if (completed > 0)
+  if (whichjobs == CUPS_WHICHJOBS_COMPLETED)
     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
                  "which-jobs", NULL, "completed");
-  else if (completed < 0)
+  else if (whichjobs == CUPS_WHICHJOBS_ALL)
     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
                  "which-jobs", NULL, "all");
 
@@ -776,7 +808,7 @@ cupsGetJobs2(http_t     *http,              /* I - HTTP connection or CUPS_HTTP_DEFAULT */
 /*
  * 'cupsGetPPD()' - Get the PPD file for a printer on the default server.
  *
- * For classes, cupsGetPPD() returns the PPD file for the first printer
+ * For classes, @code cupsGetPPD@ returns the PPD file for the first printer
  * in the class.
  */
 
@@ -804,14 +836,14 @@ cupsGetPPD(const char *name)              /* I - Printer name */
 /*
  * 'cupsGetPPD2()' - Get the PPD file for a printer from the specified server.
  *
- * For classes, cupsGetPPD2() returns the PPD file for the first printer
+ * For classes, @code cupsGetPPD2@ returns the PPD file for the first printer
  * in the class.
  *
  * @since CUPS 1.1.21@
  */
 
 const char *                           /* O - Filename for PPD file */
-cupsGetPPD2(http_t     *http,          /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+cupsGetPPD2(http_t     *http,          /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
             const char *name)          /* I - Printer name */
 {
   _cups_globals_t *cg = _cupsGlobals();        /* Pointer to library globals */
@@ -840,12 +872,16 @@ cupsGetPPD2(http_t     *http,             /* I - HTTP connection or CUPS_HTTP_DEFAULT */
  * the empty string, a new temporary file is created, otherwise the existing
  * file will be overwritten as needed.
  *
- * On success, HTTP_OK is returned for a new PPD file and HTTP_NOT_MODIFIED
- * if the existing PPD file is up-to-date.  Any other status is an error.
+ * On success, @code HTTP_OK@ is returned for a new PPD file and
+ * @code HTTP_NOT_MODIFIED@ if the existing PPD file is up-to-date.  Any other
+ * status is an error.
+ *
+ * For classes, @code cupsGetPPD3@ returns the PPD file for the first printer
+ * in the class.
  */
 
 http_status_t                          /* O  - HTTP status */
-cupsGetPPD3(http_t     *http,          /* I  - HTTP connection or CUPS_HTTP_DEFAULT */
+cupsGetPPD3(http_t     *http,          /* I  - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
             const char *name,          /* I  - Printer name */
            time_t     *modtime,        /* IO - Modification time */
            char       *buffer,         /* I  - Filename buffer */
@@ -1026,7 +1062,7 @@ cupsGetPPD3(http_t     *http,             /* I  - HTTP connection or CUPS_HTTP_DEFAULT */
 /*
  * 'cupsGetPrinters()' - Get a list of printers from the default server.
  *
- * This function is deprecated - use cupsGetDests() instead.
+ * This function is deprecated - use @link cupsGetDests@ instead.
  *
  * @deprecated@
  */
@@ -1133,19 +1169,19 @@ cupsGetPrinters(char ***printers)       /* O - Printers */
  * 'cupsGetServerPPD()' - Get an available PPD file from the server.
  *
  * This function returns the named PPD file from the server.  The
- * list of available PPDs is provided by the IPP CUPS_GET_PPDS
+ * list of available PPDs is provided by the IPP @code CUPS_GET_PPDS@
  * operation.
  *
  * You must remove (unlink) the PPD file when you are finished with
  * it. The PPD filename is stored in a static location that will be
- * overwritten on the next call to cupsGetPPD(), cupsGetPPD2(), or
- * cupsGetServerPPD().
+ * overwritten on the next call to @link cupsGetPPD@, @link cupsGetPPD2@,
+ * or @link cupsGetServerPPD@.
  *
  * @since CUPS 1.3@
  */
 
-char *                                 /* O - Name of PPD file or NULL on error */
-cupsGetServerPPD(http_t     *http,     /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+char *                                 /* O - Name of PPD file or @code NULL@ on error */
+cupsGetServerPPD(http_t     *http,     /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
                  const char *name)     /* I - Name of PPD file ("ppd-name") */
 {
   int                  fd;             /* PPD file descriptor */
@@ -1234,7 +1270,7 @@ cupsLastErrorString(void)
  * 'cupsPrintFile()' - Print a file to a printer or class on the default server.
  */
 
-int                                    /* O - Job ID */
+int                                    /* O - Job ID or 0 on error */
 cupsPrintFile(const char    *name,     /* I - Printer or class name */
               const char    *filename, /* I - File to print */
              const char    *title,     /* I - Title of job */
@@ -1251,12 +1287,13 @@ cupsPrintFile(const char    *name,      /* I - Printer or class name */
 
 
 /*
- * 'cupsPrintFile2()' - Print a file to a printer or class on the specified server.
+ * 'cupsPrintFile2()' - Print a file to a printer or class on the specified
+ *                      server.
  *
  * @since CUPS 1.1.21@
  */
 
-int                                    /* O - Job ID */
+int                                    /* O - Job ID or 0 on error */
 cupsPrintFile2(
     http_t        *http,               /* I - HTTP connection */
     const char    *name,               /* I - Printer or class name */
@@ -1279,7 +1316,7 @@ cupsPrintFile2(
  *                      default server.
  */
 
-int                                    /* O - Job ID */
+int                                    /* O - Job ID or 0 on error */
 cupsPrintFiles(
     const char    *name,               /* I - Printer or class name */
     int           num_files,           /* I - Number of files */
@@ -1309,9 +1346,9 @@ cupsPrintFiles(
  * @since CUPS 1.1.21@
  */
 
-int                                    /* O - Job ID */
+int                                    /* O - Job ID or 0 on error */
 cupsPrintFiles2(
-    http_t        *http,               /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+    http_t        *http,               /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
     const char    *name,               /* I - Printer or class name */
     int           num_files,           /* I - Number of files */
     const char    **files,             /* I - File(s) to print */
@@ -1378,7 +1415,7 @@ cupsPrintFiles2(
       * Unable to open print file, cancel the job and return...
       */
 
-      cupsCancelJob2(http, job_id, 0);
+      cupsCancelJob2(http, name, job_id, 0);
       return (0);
     }
 
@@ -1397,7 +1434,7 @@ cupsPrintFiles2(
       * Unable to queue, cancel the job and return...
       */
 
-      cupsCancelJob2(http, job_id, 0);
+      cupsCancelJob2(http, name, job_id, 0);
       return (0);
     }
   }
@@ -1409,24 +1446,24 @@ cupsPrintFiles2(
 /*
  * 'cupsStartDocument()' - Add a document to a job created with cupsCreateJob().
  *
- * Use cupsWriteRequestData() to write data for the document and
- * cupsFinishDocument() to finish the document and get the submission status.
+ * Use @link cupsWriteRequestData@ to write data for the document and
+ * @link cupsFinishDocument@ to finish the document and get the submission status.
  *
- * The MIME type constants CUPS_FORMAT_AUTO, CUPS_FORMAT_PDF,
- * CUPS_FORMAT_POSTSCRIPT, CUPS_FORMAT_RAW, and CUPS_FORMAT_TEXT are provided
- * for the "format" argument, although any supported MIME type string can be
- * supplied.
+ * The MIME type constants @code CUPS_FORMAT_AUTO@, @code CUPS_FORMAT_PDF@,
+ * @code CUPS_FORMAT_POSTSCRIPT@, @code CUPS_FORMAT_RAW@, and
+ * @code CUPS_FORMAT_TEXT@ are provided for the "format" argument, although
+ * any supported MIME type string can be supplied.
  *
  * @since CUPS 1.4@
  */
 
 http_status_t                          /* O - HTTP status of request */
 cupsStartDocument(
-    http_t     *http,                  /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+    http_t     *http,                  /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
     const char *name,                  /* I - Printer or class name */
-    int        job_id,                 /* I - Job ID from cupsCreateJob() */
+    int        job_id,                 /* I - Job ID from @link cupsCreateJob@ */
     const char *docname,               /* I - Name of document */
-    const char *format,                        /* I - MIME type or CUPS_FORMAT_foo */
+    const char *format,                        /* I - MIME type or @code CUPS_FORMAT_foo@ */
     int        last_document)          /* I - 1 for last document in job, 0 otherwise */
 {
   char         resource[1024],         /* Resource for destinatio */
index 6e2260b3a9df9b33d8d855d335322af4b027d176..197344c151b07a27236df8d47b42f96cc401caed 100644 (file)
@@ -54,6 +54,7 @@ HELPFILES     =       \
                        help/api-filedir.html \
                        help/api-filter.html \
                        help/api-httpipp.html \
+                       help/api-overview.html \
                        help/api-ppd.html \
                        help/api-raster.html \
                        help/cgi.html \
index 4b8bc87bdc1a135a098ebae7454d5062b6981761..12e7e7dbee1711a6fd5c5df2df9b08c3092916ea 100644 (file)
@@ -1,26 +1,37 @@
 BODY {
-  font-family: sans-serif;
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
 }
 
 H1, H2, H3, H4, H5, H6, P, TD, TH {
-  font-family: sans-serif;
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
 }
 
 KBD {
-  font-family: monospace;
+  font-family: monaco, courier, monospace;
   font-weight: bold;
 }
 
 PRE {
-  font-family: monospace;
+  font-family: monaco, courier, monospace;
 }
 
 PRE.command {
   margin-left: 36pt;
 }
 
+PRE.example {
+  background: #eeeeee;
+  border: dotted thin #999999;
+  margin-left: 36pt;
+  padding: 10px;
+}
+
+PRE.command EM, PRE.example EM {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
 P.command {
-  font-family: monospace;
+  font-family: monaco, courier, monospace;
   margin-left: 36pt;
 }
 
@@ -51,6 +62,7 @@ SUB, SUP {
 
 DIV.table TABLE {
   border: solid thin #999999;
+  border-collapse: collapse;
   border-spacing: 0;
   margin-left: auto;
   margin-right: auto;
@@ -134,10 +146,94 @@ DL.category DT {
 
 P.summary {
   margin-left: 36pt;
-  font-family: monospace;
+  font-family: monaco, courier, monospace;
 }
 
 SPAN.message {
   font-style: italic;
   font-size: smaller;
 }
+
+DIV.summary TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin: 10px;
+}
+
+DIV.summary TABLE TD, DIV.summary TABLE TH {
+  border: solid thin #999999;
+  padding: 5px;
+  text-align: left;
+  vertical-align: top;
+}
+
+DIV.summary TABLE THEAD TH {
+  background: #eeeeee;
+}
+
+/* API documentation styles... */
+div.body h1 {
+  margin: 0;
+}
+div.body h2 {
+  margin-top: 1.5em;
+}
+div.body h3, div.body h4, div.body h5 {
+  margin-bottom: 0.5em;
+  margin-top: 1.5em;
+}
+.class, .enumeration, .function, .struct, .typedef, .union {
+  border-bottom: solid thin #999999;
+  margin-bottom: 0;
+  margin-top: 2em;
+}
+.description {
+  margin-top: 0.5em;
+}
+code, p.code, pre, ul.code li {
+  font-family: monaco, courier, monospace;
+  font-size: 90%;
+}
+ul.code, ul.contents, ul.subcontents {
+  list-style-type: none;
+  margin: 0;
+  padding-left: 0;
+}
+ul.code li {
+  margin: 0;
+}
+ul.contents > li {
+  margin-top: 1em;
+}
+ul.contents li ul.code, ul.contents li ul.subcontents {
+  padding-left: 2em;
+}
+div.body dl {
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dt {
+  font-style: italic;
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dd {
+  margin-bottom: 0.5em;
+}
+
+/* This is just for the HTML files generated with the framedhelp target */
+div.contents {
+  background: #e8e8e8;
+  border: solid thin black;
+  padding: 10px;
+}
+div.contents h1 {
+  font-size: 110%;
+}
+div.contents h2 {
+  font-size: 100%;
+}
+div.contents ul.contents {
+  font-size: 80%;
+}
index 6d356f6d051d345d337e87ea25342cec4d6aade1..935c428214fd516e8c1fe8b9c350c23648942f5d 100644 (file)
@@ -1,21 +1,21 @@
 BODY {
   background: #e8e8e8;
   color: #000000;
-  font-family: sans-serif;
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
 }
 
 H1, H2, H3, H4, H5, H6, P, TD, TH {
-  font-family: sans-serif;
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
 }
 
 KBD {
   color: #006600;
-  font-family: monospace;
+  font-family: monaco, courier, monospace;
   font-weight: bold;
 }
 
 PRE {
-  font-family: monospace;
+  font-family: monaco, courier, monospace;
 }
 
 PRE.command {
@@ -23,13 +23,21 @@ PRE.command {
   margin-left: 36pt;
 }
 
-PRE.command EM {
+PRE.example {
+  background: white;
+  border: dotted thin #999999;
+  margin-left: 36pt;
+  padding: 10px;
+}
+
+PRE.command EM, PRE.example EM {
   color: #3f0000;
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
 }
 
 P.command {
   color: #7f0000;
-  font-family: monospace;
+  font-family: monaco, courier, monospace;
   margin-left: 36pt;
 }
 
@@ -137,7 +145,7 @@ FORM {
 }
 
 INPUT[TYPE="TEXT"], TEXTAREA {
-  font-family: monospace;
+  font-family: monaco, courier, monospace;
 }
 
 INPUT[TYPE="IMAGE"] {
@@ -164,6 +172,7 @@ TR.data TH {
 
 DIV.table TABLE {
   border: solid thin #999999;
+  border-collapse: collapse;
   border-spacing: 0;
   margin-left: auto;
   margin-right: auto;
@@ -179,12 +188,13 @@ DIV.table CAPTION {
 }
 
 DIV.table TABLE TD {
+  background: white;
   border: solid thin #bbbbbb;
   padding-top: 5pt;
 }
 
 DIV.table TABLE TH {
-  background: #bbbbbb;
+  background: #eeeeee;
   border: none;
   border-bottom: solid thin #999999;
 }
@@ -304,10 +314,80 @@ DL.category DT {
 
 P.summary {
   margin-left: 36pt;
-  font-family: monospace;
+  font-family: monaco, courier, monospace;
 }
 
 SPAN.message {
   font-style: italic;
   font-size: smaller;
 }
+
+DIV.summary TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin: 10px;
+}
+
+DIV.summary TABLE TD, DIV.summary TABLE TH {
+  background: white;
+  border: solid thin #999999;
+  border-spacing: 0;
+  padding: 5px;
+  text-align: left;
+  vertical-align: top;
+}
+
+DIV.summary TABLE THEAD TH {
+  background: #eeeeee;
+}
+
+/* API documentation styles... */
+div.body h1 {
+  margin: 0;
+}
+div.body h2 {
+  margin-top: 1.5em;
+}
+div.body h3, div.body h4, div.body h5 {
+  margin-bottom: 0.5em;
+  margin-top: 1.5em;
+}
+.class, .enumeration, .function, .struct, .typedef, .union {
+  border-bottom: solid thin #999999;
+  margin-bottom: 0;
+  margin-top: 2em;
+}
+.description {
+  margin-top: 0.5em;
+}
+code, p.code, pre, ul.code li {
+  font-family: monaco, courier, monospace;
+  font-size: 90%;
+}
+ul.code, ul.contents, ul.subcontents {
+  list-style-type: none;
+  margin: 0;
+  padding-left: 0;
+}
+ul.code li {
+  margin: 0;
+}
+ul.contents > li {
+  margin-top: 1em;
+}
+ul.contents li ul.code, ul.contents li ul.subcontents {
+  padding-left: 2em;
+}
+div.body dl {
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dt {
+  font-style: italic;
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dd {
+  margin-bottom: 0.5em;
+}
index aabafd45f76c03090e579d68a948e3f1626d5b64..175f6fecdb5d3c130e9c200e7d85f94a03b4761e 100644 (file)
 <html>
 <!-- SECTION: Programming -->
 <head>
-       <title>Array API</title>
-       <meta name='keywords' content='Programming'>
-       <meta name='creator' content='Mini-XML v2.4'>
-       <style type='text/css'><!--
-       h1, h2, h3, p { font-family: sans-serif; text-align: justify; }
-       tt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }
-       pre { font-weight: bold; color: #7f0000; margin-left: 2em; }
-       span.info { background: #000000; border: solid thin #000000; color: #ffffff; font-size: 80%; font-style: italic; font-weight: bold; white-space: nowrap; }
-       h3 span.info { float: right; font-size: 100%; }
-       h1.title, h2.title, h3.title { border-bottom: solid 2px #000000; }
-       --></style>
+<title>Array API</title>
+<meta name="keywords" content="Programming">
+<meta name="creator" content="Mini-XML v2.5">
+<style type="text/css"><!--
+BODY {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+H1, H2, H3, H4, H5, H6, P, TD, TH {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+KBD {
+  font-family: monaco, courier, monospace;
+  font-weight: bold;
+}
+
+PRE {
+  font-family: monaco, courier, monospace;
+}
+
+PRE.command {
+  margin-left: 36pt;
+}
+
+PRE.example {
+  background: #eeeeee;
+  border: dotted thin #999999;
+  margin-left: 36pt;
+  padding: 10px;
+}
+
+PRE.command EM, PRE.example EM {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+P.command {
+  font-family: monaco, courier, monospace;
+  margin-left: 36pt;
+}
+
+P.formula {
+  font-style: italic;
+  margin-left: 36pt;
+}
+
+BLOCKQUOTE {
+  background: #cccccc;
+  border: solid thin #999999;
+  padding: 10pt;
+}
+
+A:link, A:visited {
+  text-decoration: none;
+  font-weight: bold;
+}
+
+A:link:hover, A:visited:hover, A:active {
+  text-decoration: underline;
+  font-weight: bold;
+}
+
+SUB, SUP {
+  font-size: 50%;
+}
+
+DIV.table TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.table CAPTION {
+  caption-side: top;
+  font-size: 120%;
+  font-style: italic;
+  font-weight: bold;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.table TABLE TD {
+  border: solid thin #cccccc;
+  padding-top: 5pt;
+}
+
+DIV.table TABLE TH {
+  background: #cccccc;
+  border: none;
+  border-bottom: solid thin #999999;
+}
+
+DIV.figure TABLE {
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.figure CAPTION {
+  caption-side: bottom;
+  font-size: 120%;
+  font-style: italic;
+  font-weight: bold;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+TH.label {
+  padding-top: 5pt;
+  text-align: right;
+  vertical-align: top;
+}
+
+HR {
+  border: solid thin;
+}
+
+SPAN.info {
+  background: #000000;
+  border: thin solid #000000;
+  color: #ffffff;
+  font-size: 80%;
+  font-style: italic;
+  font-weight: bold;
+  white-space: nowrap;
+}
+
+H2 SPAN.info, H3 SPAN.info, H4 SPAN.info {
+  float: right;
+  font-size: 100%;
+}
+
+H2.title, H3.title {
+  border-bottom: solid 2pt #000000;
+}
+
+DT {
+  margin-left: 36pt;
+  margin-top: 12pt;
+}
+
+DD {
+  margin-left: 54pt;
+}
+
+DL.category DT {
+  font-weight: bold;
+}
+
+P.summary {
+  margin-left: 36pt;
+  font-family: monaco, courier, monospace;
+}
+
+SPAN.message {
+  font-style: italic;
+  font-size: smaller;
+}
+
+DIV.summary TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin: 10px;
+}
+
+DIV.summary TABLE TD, DIV.summary TABLE TH {
+  border: solid thin #999999;
+  padding: 5px;
+  text-align: left;
+  vertical-align: top;
+}
+
+DIV.summary TABLE THEAD TH {
+  background: #eeeeee;
+}
+
+/* API documentation styles... */
+div.body h1 {
+  margin: 0;
+}
+div.body h2 {
+  margin-top: 1.5em;
+}
+div.body h3, div.body h4, div.body h5 {
+  margin-bottom: 0.5em;
+  margin-top: 1.5em;
+}
+.class, .enumeration, .function, .struct, .typedef, .union {
+  border-bottom: solid thin #999999;
+  margin-bottom: 0;
+  margin-top: 2em;
+}
+.description {
+  margin-top: 0.5em;
+}
+code, p.code, pre, ul.code li {
+  font-family: monaco, courier, monospace;
+  font-size: 90%;
+}
+ul.code, ul.contents, ul.subcontents {
+  list-style-type: none;
+  margin: 0;
+  padding-left: 0;
+}
+ul.code li {
+  margin: 0;
+}
+ul.contents > li {
+  margin-top: 1em;
+}
+ul.contents li ul.code, ul.contents li ul.subcontents {
+  padding-left: 2em;
+}
+div.body dl {
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dt {
+  font-style: italic;
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dd {
+  margin-bottom: 0.5em;
+}
+
+/* This is just for the HTML files generated with the framedhelp target */
+div.contents {
+  background: #e8e8e8;
+  border: solid thin black;
+  padding: 10px;
+}
+div.contents h1 {
+  font-size: 110%;
+}
+div.contents h2 {
+  font-size: 100%;
+}
+div.contents ul.contents {
+  font-size: 80%;
+}
+--></style>
 </head>
 <body>
+<div class='body'>
+<!--
+  "$Id: api-array.header 7266 2008-01-29 02:15:29Z mike $"
+
+  Array API header for the Common UNIX Printing System (CUPS).
+
+  Copyright 2008 by Apple Inc.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">Array API</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+       <th>Header</th>
+       <th>cups/array.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <th>Library</th>
+       <td>-lcups</td>
+</tr>
+<tr>
+       <th>See Also</th>
+       <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a></td>
+</tr>
+</tbody>
+</table></div>
+<h2 class="title">Contents</h2>
+<ul class="contents">
+</li>
+<li><a href="#OVERVIEW">Overview</a><ul class="subcontents">
+<li><a href="#MANAGING_ARRAYS">Managing Arrays</a></li>
+<li><a href="#FINDING_AND_ENUMERATING">Finding and Enumerating Elements</a></li>
+</ul></li>
+<li><a href="#FUNCTIONS">Functions</a><ul class="code">
+<li><a href="#cupsArrayAdd" title="Add an element to the array.">cupsArrayAdd</a></li>
+<li><a href="#cupsArrayClear" title="Clear the array.">cupsArrayClear</a></li>
+<li><a href="#cupsArrayCount" title="Get the number of elements in the array.">cupsArrayCount</a></li>
+<li><a href="#cupsArrayCurrent" title="Return the current element in the array.">cupsArrayCurrent</a></li>
+<li><a href="#cupsArrayDelete" title="Free all memory used by the array.">cupsArrayDelete</a></li>
+<li><a href="#cupsArrayDup" title="Duplicate the array.">cupsArrayDup</a></li>
+<li><a href="#cupsArrayFind" title="Find an element in the array.">cupsArrayFind</a></li>
+<li><a href="#cupsArrayFirst" title="Get the first element in the array.">cupsArrayFirst</a></li>
+<li><a href="#cupsArrayGetIndex" title="Get the index of the current element.">cupsArrayGetIndex</a></li>
+<li><a href="#cupsArrayGetInsert" title="Get the index of the last inserted element.">cupsArrayGetInsert</a></li>
+<li><a href="#cupsArrayIndex" title="Get the N-th element in the array.">cupsArrayIndex</a></li>
+<li><a href="#cupsArrayInsert" title="Insert an element in the array.">cupsArrayInsert</a></li>
+<li><a href="#cupsArrayLast" title="Get the last element in the array.">cupsArrayLast</a></li>
+<li><a href="#cupsArrayNew" title="Create a new array.">cupsArrayNew</a></li>
+<li><a href="#cupsArrayNew2" title="Create a new array with hash.">cupsArrayNew2</a></li>
+<li><a href="#cupsArrayNext" title="Get the next element in the array.">cupsArrayNext</a></li>
+<li><a href="#cupsArrayPrev" title="Get the previous element in the array.">cupsArrayPrev</a></li>
+<li><a href="#cupsArrayRemove" title="Remove an element from the array.">cupsArrayRemove</a></li>
+<li><a href="#cupsArrayRestore" title="Reset the current element to the last cupsArraySave.">cupsArrayRestore</a></li>
+<li><a href="#cupsArraySave" title="Mark the current element for a later cupsArrayRestore.">cupsArraySave</a></li>
+<li><a href="#cupsArrayUserData" title="Return the user data for an array.">cupsArrayUserData</a></li>
+</ul>
+<li><a href="#TYPES">Data Types</a><ul class="code">
+       <li><a href="#cups_ahash_func_t" title="Array hash function">cups_ahash_func_t</a></li>
+       <li><a href="#cups_array_func_t" title="Array comparison function">cups_array_func_t</a></li>
+       <li><a href="#cups_array_t" title="CUPS array type">cups_array_t</a></li>
+</ul></li>
+</ul>
 <!--
-  "$Id: api-array.shtml 6649 2007-07-11 21:46:42Z mike $"
+  "$Id: api-array.shtml 7266 2008-01-29 02:15:29Z mike $"
 
   Array API introduction for the Common UNIX Printing System (CUPS).
 
-  Copyright 2007 by Apple Inc.
+  Copyright 2007-2008 by Apple Inc.
   Copyright 1997-2006 by Easy Software Products, all rights reserved.
 
   These coded instructions, statements, and computer programs are the
   file is missing or damaged, see the license at "http://www.cups.org/".
 -->
 
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
 
-<p>The CUPS array API provides a high-performance generic array
-container. The contents of the array container can be sorted and
-the container itself is designed for optimal speed and memory
-usage under a wide variety of conditions.</p>
+<p>The CUPS array API provides a high-performance generic array container.
+The contents of the array container can be sorted and the container itself is
+designed for optimal speed and memory usage under a wide variety of conditions.
+Sorted arrays use a binary search algorithm from the last found or inserted
+element to quickly find matching elements in the array. Arrays created with the
+optional hash function can often find elements with a single lookup. The
+<a href='#cups_array_t'><code>cups_array_t</code></a> type is used when
+referring to a CUPS array.</p>
 
 <p>The CUPS scheduler (<tt>cupsd</tt>) and many of the CUPS API
 functions use the array API to efficiently manage large lists of
 data.</p>
 
-<h2 class='title'>General Usage</h2>
+<h3><a name='MANAGING_ARRAYS'>Managing Arrays</a></h3>
+
+<p>Arrays are created using either the
+<a href='#cupsArrayNew'><code>cupsArrayNew</code></a> or
+<a href='#cupsArrayNew2'><code>cupsArrayNew2</code></a> functions. The
+first function creates a new array with the specified callback function
+and user data pointer:</p>
 
-<p>The <var>&lt;cups/array.h&gt;</var> header file must be
-included to use the <tt>cupsArray</tt> functions.</p>
+<pre class='example'>
+#include &lt;cups/array.h&gt;
 
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+static int compare_func(void *first, void *second, void *user_data);
 
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
+void *user_data;
+<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew'>cupsArrayNew</a>(compare_func, user_data);
 </pre>
 
-<h2 class='title'>Compatibility</h2>
+<p>The comparison function (type
+<a href="#cups_arrayfunc_t"><code>cups_arrayfunc_t</code></a>) is called
+whenever an element is added to the array and can be <code>NULL</code> to
+create an unsorted array. The function returns -1 if the first element should
+come before the second, 0 if the first and second elements should have the same
+ordering, and 1 if the first element should come after the second.</p>
 
-<p>All of these functions require CUPS 1.2 or higher.</p>
-<h2 class='title'>Contents</h2>
-<ul>
-       <li><a href='#FUNCTIONS'>Functions</a></li>
-       <li><a href='#TYPES'>Types</a></li>
-</ul>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='FUNCTIONS'>Functions</a></h2>
-<ul>
-       <li><a href='#cupsArrayAdd'><tt>cupsArrayAdd()</tt></a> </li>
-       <li><a href='#cupsArrayClear'><tt>cupsArrayClear()</tt></a> </li>
-       <li><a href='#cupsArrayCount'><tt>cupsArrayCount()</tt></a> </li>
-       <li><a href='#cupsArrayCurrent'><tt>cupsArrayCurrent()</tt></a> </li>
-       <li><a href='#cupsArrayDelete'><tt>cupsArrayDelete()</tt></a> </li>
-       <li><a href='#cupsArrayDup'><tt>cupsArrayDup()</tt></a> </li>
-       <li><a href='#cupsArrayFind'><tt>cupsArrayFind()</tt></a> </li>
-       <li><a href='#cupsArrayFirst'><tt>cupsArrayFirst()</tt></a> </li>
-       <li><a href='#cupsArrayGetIndex'><tt>cupsArrayGetIndex()</tt></a> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></li>
-       <li><a href='#cupsArrayGetInsert'><tt>cupsArrayGetInsert()</tt></a> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></li>
-       <li><a href='#cupsArrayIndex'><tt>cupsArrayIndex()</tt></a> </li>
-       <li><a href='#cupsArrayInsert'><tt>cupsArrayInsert()</tt></a> </li>
-       <li><a href='#cupsArrayLast'><tt>cupsArrayLast()</tt></a> </li>
-       <li><a href='#cupsArrayNew'><tt>cupsArrayNew()</tt></a> </li>
-       <li><a href='#cupsArrayNew2'><tt>cupsArrayNew2()</tt></a> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></li>
-       <li><a href='#cupsArrayNext'><tt>cupsArrayNext()</tt></a> </li>
-       <li><a href='#cupsArrayPrev'><tt>cupsArrayPrev()</tt></a> </li>
-       <li><a href='#cupsArrayRemove'><tt>cupsArrayRemove()</tt></a> </li>
-       <li><a href='#cupsArrayRestore'><tt>cupsArrayRestore()</tt></a> </li>
-       <li><a href='#cupsArraySave'><tt>cupsArraySave()</tt></a> </li>
-       <li><a href='#cupsArrayUserData'><tt>cupsArrayUserData()</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayAdd'>cupsArrayAdd()</a></h3>
-<h4>Description</h4>
-<p>Add an element to the array.
-<p>When adding an element to a sorted array, non-unique elements are
+<p>The "user_data" pointer is passed to your comparison function. Pass
+<code>NULL</code> if you do not need to associate the elements in your array
+with additional information.</p>
+
+<p>The <a href='#cupsArrayNew2'><code>cupsArrayNew2</code></a> function adds
+two more arguments to support hashed lookups, which can potentially provide
+instantaneous ("O(1)") lookups in your array:</p>
+
+<pre class='example'>
+#include &lt;cups/array.h&gt;
+
+#define HASH_SIZE 512 /* Size of hash table */
+
+static int compare_func(void *first, void *second, void *user_data);
+static int hash_func(void *element, void *user_data);
+
+void *user_data;
+<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew2'>cupsArrayNew2</a>(compare_func, user_data, hash_func, HASH_SIZE);
+</pre>
+
+<p>The hash function (type
+<a href="#cups_ahash_func_t"><code>cups_ahash_func_t</code></a>) returns a
+number from 0 to (hash_size-1) that (hopefully) uniquely identifies the
+element and is called whenever you look up an element in the array with
+<a href='#cupsArrayFind'><code>cupsArrayFind</code></a>. The hash size is
+only limited by available memory, but generally should not be larger than
+16384 to realize any performance improvement.</p>
+
+<p>Once you have created the array, you add elements using the
+<a href='#cupsArrayAdd'><code>cupsArrayAdd</code></a>
+<a href='#cupsArrayInsert'><code>cupsArrayInsert</code></a> functions.
+The first function adds an element to the array, adding the new element
+after any elements that have the same order, while the second inserts the
+element before others with the same order. For unsorted arrays,
+<a href='#cupsArrayAdd'><code>cupsArrayAdd</code></a> appends the elemnt to
+the end of the array while
+<a href='#cupsArrayInsert'><code>cupsArrayInsert</code></a> inserts the
+element at the beginning of the array. For example, the following code
+creates a sorted array of character strings:</p>
+
+<pre class='example'>
+#include &lt;cups/array.h&gt;
+
+/* Use strcmp() to compare strings - it will ignore the user_data pointer */
+<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew'>cupsArrayNew</a>((<a href='#cups_array_func_t'>cups_array_func_t</a>)strcmp, NULL);
+
+/* Add four strings to the array */
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "One Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Two Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Red Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Blue Fish");
+</pre>
+
+<p>Elements are removed using the
+<a href='#cupsArrayRemove'><code>cupsArrayRemove</code></a> function, for
+example:</p>
+
+<pre class='example'>
+#include &lt;cups/array.h&gt;
+
+/* Use strcmp() to compare strings - it will ignore the user_data pointer */
+<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew'>cupsArrayNew</a>((<a href='#cups_array_func_t'>cups_array_func_t</a>)strcmp, NULL);
+
+/* Add four strings to the array */
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "One Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Two Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Red Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Blue Fish");
+
+/* Remove "Red Fish" */
+<a href='#cupsArrayRemove'>cupsArrayRemove</a>(array, "Red Fish");
+</pre>
+
+<p>Finally, you free the memory used by the array using the
+<a href='#cupsArrayDelete'><code>cupsArrayDelete</code></a> function. All
+of the memory for the array and hash table (if any) is freed, however <em>CUPS
+does not free the elements</em> - if necessary, you must allocate and free the
+elements yourself.</p>
+
+<h3><a name='FINDING_AND_ENUMERATING'>Finding and Enumerating Elements</a></h3>
+
+<p>CUPS provides several functions to find and enumerate elements in an
+array. Each one sets or updates a "current index" into the array, such that
+future lookups will start where the last one left off:</p>
+
+<dl>
+       <dt><a href='#cupsArrayFind'><code>cupsArrayFind</code></a></dt>
+       <dd>Returns the first matching element .</dd>
+       <dt><a href='#cupsArrayFirst'><code>cupsArrayFirst</code></a></dt>
+       <dd>Returns the first element in the array.</dd>
+       <dt><a href='#cupsArrayIndex'><code>cupsArrayIndex</code></a></dt>
+       <dd>Returns the Nth element in the array.</dd>
+       <dt><a href='#cupsArrayLast'><code>cupsArrayLast</code></a></dt>
+       <dd>Returns the last element in the array.</dd>
+       <dt><a href='#cupsArrayNext'><code>cupsArrayNext</code></a></dt>
+       <dd>Returns the next element in the array.</dd>
+       <dt><a href='#cupsArrayPrev'><code>cupsArrayPrev</code></a></dt>
+       <dd>Returns the previous element in the array.</dd>
+</dl>
+
+<p>Each of these functions returns <code>NULL</code> when there is no
+corresponding element.  For example, a simple <code>for</code> loop using the
+<a href='#cupsArrayFirst'><code>cupsArrayFirst</code></a> and
+<a href='#cupsArrayNext'><code>cupsArrayNext</code></a> functions will
+enumerate all of the strings in our previous example:</p> 
+
+<pre class='example'>
+#include &lt;cups/array.h&gt;
+
+/* Use strcmp() to compare strings - it will ignore the user_data pointer */
+<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew'>cupsArrayNew</a>((<a href='#cups_array_func_t'>cups_array_func_t</a>)strcmp, NULL);
+
+/* Add four strings to the array */
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "One Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Two Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Red Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Blue Fish");
+
+/* Show all of the strings in the array */
+char *s;
+for (s = (char *)<a href='#cupsArrayFirst'>cupsArrayFirst</a>(array); s != NULL; s = (char *)<a href='#cupsArrayNext'>cupsArrayNext</a>(array))
+  puts(s);
+</pre>
+<h2 class="title"><a name="FUNCTIONS">Functions</a></h2>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayAdd">cupsArrayAdd</a></h3>
+<p class="description">Add an element to the array.</p>
+<p class="code">
+int cupsArrayAdd (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;void *e<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+<dt>e</dt>
+<dd class="description">Element</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 on success, 0 on failure</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">When adding an element to a sorted array, non-unique elements are
 appended at the end of the run.  For unsorted arrays, the element
 is inserted at the end of the array.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsArrayAdd(
-    <a href='#cups_array_t'>cups_array_t</a> * a,
-    void * e);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-<tr><td><tt>e</tt></td><td>Element</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>1 on success, 0 on failure</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayClear'>cupsArrayClear()</a></h3>
-<h4>Description</h4>
-<p>Clear the array.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsArrayClear(
-    <a href='#cups_array_t'>cups_array_t</a> * a);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayCount'>cupsArrayCount()</a></h3>
-<h4>Description</h4>
-<p>Get the number of elements in the array.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsArrayCount(
-    <a href='#cups_array_t'>cups_array_t</a> * a);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of elements</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayCurrent'>cupsArrayCurrent()</a></h3>
-<h4>Description</h4>
-<p>Return the current element in the array.
-<h4>Syntax</h4>
-<p><tt>
-void *<br>
-cupsArrayCurrent(
-    <a href='#cups_array_t'>cups_array_t</a> * a);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Element</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayDelete'>cupsArrayDelete()</a></h3>
-<h4>Description</h4>
-<p>Free all memory used by the array.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsArrayDelete(
-    <a href='#cups_array_t'>cups_array_t</a> * a);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayDup'>cupsArrayDup()</a></h3>
-<h4>Description</h4>
-<p>Duplicate the array.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#cups_array_t'>cups_array_t</a> *<br>
-cupsArrayDup(
-    <a href='#cups_array_t'>cups_array_t</a> * a);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Duplicate array</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayFind'>cupsArrayFind()</a></h3>
-<h4>Description</h4>
-<p>Find an element in the array.
-<h4>Syntax</h4>
-<p><tt>
-void *<br>
-cupsArrayFind(
-    <a href='#cups_array_t'>cups_array_t</a> * a,
-    void * e);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-<tr><td><tt>e</tt></td><td>Element</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Element found or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayFirst'>cupsArrayFirst()</a></h3>
-<h4>Description</h4>
-<p>Get the first element in the array.
-<h4>Syntax</h4>
-<p><tt>
-void *<br>
-cupsArrayFirst(
-    <a href='#cups_array_t'>cups_array_t</a> * a);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>First element or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.3&nbsp;</span><a name='cupsArrayGetIndex'>cupsArrayGetIndex()</a></h3>
-<h4>Description</h4>
-<p>Get the index of the current element.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsArrayGetIndex(
-    <a href='#cups_array_t'>cups_array_t</a> * a);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Index of the current element</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.3&nbsp;</span><a name='cupsArrayGetInsert'>cupsArrayGetInsert()</a></h3>
-<h4>Description</h4>
-<p>Get the index of the last inserted element.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsArrayGetInsert(
-    <a href='#cups_array_t'>cups_array_t</a> * a);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Index of the last inserted element</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayIndex'>cupsArrayIndex()</a></h3>
-<h4>Description</h4>
-<p>Get the N-th element in the array.
-<h4>Syntax</h4>
-<p><tt>
-void *<br>
-cupsArrayIndex(
-    <a href='#cups_array_t'>cups_array_t</a> * a,
-    int n);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-<tr><td><tt>n</tt></td><td>Index into array, starting at 0</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>N-th element or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayInsert'>cupsArrayInsert()</a></h3>
-<h4>Description</h4>
-<p>Insert an element in the array.
-<p>When inserting an element in a sorted array, non-unique elements are
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayClear">cupsArrayClear</a></h3>
+<p class="description">Clear the array.</p>
+<p class="code">
+void cupsArrayClear (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+</dl>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayCount">cupsArrayCount</a></h3>
+<p class="description">Get the number of elements in the array.</p>
+<p class="code">
+int cupsArrayCount (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of elements</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayCurrent">cupsArrayCurrent</a></h3>
+<p class="description">Return the current element in the array.</p>
+<p class="code">
+void *cupsArrayCurrent (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Element</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayDelete">cupsArrayDelete</a></h3>
+<p class="description">Free all memory used by the array.</p>
+<p class="code">
+void cupsArrayDelete (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+</dl>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayDup">cupsArrayDup</a></h3>
+<p class="description">Duplicate the array.</p>
+<p class="code">
+<a href="#cups_array_t">cups_array_t</a> *cupsArrayDup (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Duplicate array</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayFind">cupsArrayFind</a></h3>
+<p class="description">Find an element in the array.</p>
+<p class="code">
+void *cupsArrayFind (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;void *e<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+<dt>e</dt>
+<dd class="description">Element</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Element found or <code>NULL</code></p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayFirst">cupsArrayFirst</a></h3>
+<p class="description">Get the first element in the array.</p>
+<p class="code">
+void *cupsArrayFirst (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">First element or <code>NULL</code></p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.3&nbsp;</span><a name="cupsArrayGetIndex">cupsArrayGetIndex</a></h3>
+<p class="description">Get the index of the current element.</p>
+<p class="code">
+int cupsArrayGetIndex (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Index of the current element</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.3&nbsp;</span><a name="cupsArrayGetInsert">cupsArrayGetInsert</a></h3>
+<p class="description">Get the index of the last inserted element.</p>
+<p class="code">
+int cupsArrayGetInsert (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Index of the last inserted element</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayIndex">cupsArrayIndex</a></h3>
+<p class="description">Get the N-th element in the array.</p>
+<p class="code">
+void *cupsArrayIndex (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int n<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+<dt>n</dt>
+<dd class="description">Index into array, starting at 0</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">N-th element or <code>NULL</code></p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayInsert">cupsArrayInsert</a></h3>
+<p class="description">Insert an element in the array.</p>
+<p class="code">
+int cupsArrayInsert (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;void *e<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+<dt>e</dt>
+<dd class="description">Element</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on failure, 1 on success</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">When inserting an element in a sorted array, non-unique elements are
 inserted at the beginning of the run.  For unsorted arrays, the element
 is inserted at the beginning of the array.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsArrayInsert(
-    <a href='#cups_array_t'>cups_array_t</a> * a,
-    void * e);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-<tr><td><tt>e</tt></td><td>Element</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on failure, 1 on success</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayLast'>cupsArrayLast()</a></h3>
-<h4>Description</h4>
-<p>Get the last element in the array.
-<h4>Syntax</h4>
-<p><tt>
-void *<br>
-cupsArrayLast(
-    <a href='#cups_array_t'>cups_array_t</a> * a);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Last element or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayNew'>cupsArrayNew()</a></h3>
-<h4>Description</h4>
-<p>Create a new array.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#cups_array_t'>cups_array_t</a> *<br>
-cupsArrayNew(
-    <a href='#cups_array_func_t'>cups_array_func_t</a> f,
-    void * d);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>f</tt></td><td>Comparison function</td></tr>
-<tr><td><tt>d</tt></td><td>User data</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Array</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.3&nbsp;</span><a name='cupsArrayNew2'>cupsArrayNew2()</a></h3>
-<h4>Description</h4>
-<p>Create a new array with hash.
-
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#cups_array_t'>cups_array_t</a> *<br>
-cupsArrayNew2(
-    <a href='#cups_array_func_t'>cups_array_func_t</a> f,
-    void * d,
-    <a href='#cups_ahash_func_t'>cups_ahash_func_t</a> h,
-    int hsize);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>f</tt></td><td>Comparison function</td></tr>
-<tr><td><tt>d</tt></td><td>User data</td></tr>
-<tr><td><tt>h</tt></td><td>Hash function</td></tr>
-<tr><td><tt>hsize</tt></td><td>Hash size</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Array</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayNext'>cupsArrayNext()</a></h3>
-<h4>Description</h4>
-<p>Get the next element in the array.
-<h4>Syntax</h4>
-<p><tt>
-void *<br>
-cupsArrayNext(
-    <a href='#cups_array_t'>cups_array_t</a> * a);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Next element or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayPrev'>cupsArrayPrev()</a></h3>
-<h4>Description</h4>
-<p>Get the previous element in the array.
-<h4>Syntax</h4>
-<p><tt>
-void *<br>
-cupsArrayPrev(
-    <a href='#cups_array_t'>cups_array_t</a> * a);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Previous element or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayRemove'>cupsArrayRemove()</a></h3>
-<h4>Description</h4>
-<p>Remove an element from the array.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsArrayRemove(
-    <a href='#cups_array_t'>cups_array_t</a> * a,
-    void * e);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-<tr><td><tt>e</tt></td><td>Element</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>1 on success, 0 on failure</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayRestore'>cupsArrayRestore()</a></h3>
-<h4>Description</h4>
-<p>Reset the current element to the last cupsArraySave.
-<h4>Syntax</h4>
-<p><tt>
-void *<br>
-cupsArrayRestore(
-    <a href='#cups_array_t'>cups_array_t</a> * a);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New current element</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArraySave'>cupsArraySave()</a></h3>
-<h4>Description</h4>
-<p>Mark the current element for a later cupsArrayRestore.
-<p>The save/restore stack is guaranteed to be at least 32 elements deep.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsArraySave(
-    <a href='#cups_array_t'>cups_array_t</a> * a);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>1 on success, 0 on failure</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsArrayUserData'>cupsArrayUserData()</a></h3>
-<h4>Description</h4>
-<p>Return the user data for an array.
-<h4>Syntax</h4>
-<p><tt>
-void *<br>
-cupsArrayUserData(
-    <a href='#cups_array_t'>cups_array_t</a> * a);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>a</tt></td><td>Array</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>User data</p>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='TYPES'>Types</a></h2>
-<ul>
-       <li><a href='#cups_ahash_func_t'><tt>cups_ahash_func_t</tt></a> </li>
-       <li><a href='#cups_array_func_t'><tt>cups_array_func_t</tt></a> </li>
-       <li><a href='#cups_array_t'><tt>cups_array_t</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_ahash_func_t'>cups_ahash_func_t</a></h3>
-<h4>Description</h4>
-<p>Array hash function
-<h4>Definition</h4>
-<p><tt>
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayLast">cupsArrayLast</a></h3>
+<p class="description">Get the last element in the array.</p>
+<p class="code">
+void *cupsArrayLast (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Last element or <code>NULL</code></p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayNew">cupsArrayNew</a></h3>
+<p class="description">Create a new array.</p>
+<p class="code">
+<a href="#cups_array_t">cups_array_t</a> *cupsArrayNew (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_func_t">cups_array_func_t</a> f,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;void *d<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>f</dt>
+<dd class="description">Comparison function</dd>
+<dt>d</dt>
+<dd class="description">User data</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Array</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.3&nbsp;</span><a name="cupsArrayNew2">cupsArrayNew2</a></h3>
+<p class="description">Create a new array with hash.</p>
+<p class="code">
+<a href="#cups_array_t">cups_array_t</a> *cupsArrayNew2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_func_t">cups_array_func_t</a> f,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;void *d,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_ahash_func_t">cups_ahash_func_t</a> h,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int hsize<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>f</dt>
+<dd class="description">Comparison function</dd>
+<dt>d</dt>
+<dd class="description">User data</dd>
+<dt>h</dt>
+<dd class="description">Hash function</dd>
+<dt>hsize</dt>
+<dd class="description">Hash size</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Array</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayNext">cupsArrayNext</a></h3>
+<p class="description">Get the next element in the array.</p>
+<p class="code">
+void *cupsArrayNext (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Next element or <code>NULL</code></p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayPrev">cupsArrayPrev</a></h3>
+<p class="description">Get the previous element in the array.</p>
+<p class="code">
+void *cupsArrayPrev (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Previous element or <code>NULL</code></p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayRemove">cupsArrayRemove</a></h3>
+<p class="description">Remove an element from the array.</p>
+<p class="code">
+int cupsArrayRemove (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;void *e<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+<dt>e</dt>
+<dd class="description">Element</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 on success, 0 on failure</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayRestore">cupsArrayRestore</a></h3>
+<p class="description">Reset the current element to the last cupsArraySave.</p>
+<p class="code">
+void *cupsArrayRestore (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New current element</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArraySave">cupsArraySave</a></h3>
+<p class="description">Mark the current element for a later cupsArrayRestore.</p>
+<p class="code">
+int cupsArraySave (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 on success, 0 on failure</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The save/restore stack is guaranteed to be at least 32 elements deep.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsArrayUserData">cupsArrayUserData</a></h3>
+<p class="description">Return the user data for an array.</p>
+<p class="code">
+void *cupsArrayUserData (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_array_t">cups_array_t</a> *a<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>a</dt>
+<dd class="description">Array</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">User data</p>
+<h2 class="title"><a name="TYPES">Data Types</a></h2>
+<h3 class="typedef"><a name="cups_ahash_func_t">cups_ahash_func_t</a></h3>
+<p class="description">Array hash function</p>
+<p class="code">
 typedef int (*cups_ahash_func_t)(void *element, void *data);
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_array_func_t'>cups_array_func_t</a></h3>
-<h4>Description</h4>
-<p>Array comparison function
-<h4>Definition</h4>
-<p><tt>
+</p>
+<h3 class="typedef"><a name="cups_array_func_t">cups_array_func_t</a></h3>
+<p class="description">Array comparison function</p>
+<p class="code">
 typedef int (*cups_array_func_t)(void *first, void *second, void *data);
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_array_t'>cups_array_t</a></h3>
-<h4>Description</h4>
-<p>CUPS array type
-<h4>Definition</h4>
-<p><tt>
+</p>
+<h3 class="typedef"><a name="cups_array_t">cups_array_t</a></h3>
+<p class="description">CUPS array type</p>
+<p class="code">
 typedef struct _cups_array_s cups_array_t;
-</tt></p>
+</p>
+</div>
 </body>
 </html>
index c95ce89ed80314b74fe8fb02cbac149e9eb2b977..e2ff9ad283ad5d0dc278566f09f1a1e2a19ca6f4 100644 (file)
 <html>
 <!-- SECTION: Programming -->
 <head>
-       <title>CUPS API</title>
-       <meta name='keywords' content='Programming'>
-       <meta name='creator' content='Mini-XML v2.4'>
-       <style type='text/css'><!--
-       h1, h2, h3, p { font-family: sans-serif; text-align: justify; }
-       tt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }
-       pre { font-weight: bold; color: #7f0000; margin-left: 2em; }
-       span.info { background: #000000; border: solid thin #000000; color: #ffffff; font-size: 80%; font-style: italic; font-weight: bold; white-space: nowrap; }
-       h3 span.info { float: right; font-size: 100%; }
-       h1.title, h2.title, h3.title { border-bottom: solid 2px #000000; }
-       --></style>
+<title>CUPS API</title>
+<meta name="keywords" content="Programming">
+<meta name="creator" content="Mini-XML v2.5">
+<style type="text/css"><!--
+BODY {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+H1, H2, H3, H4, H5, H6, P, TD, TH {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+KBD {
+  font-family: monaco, courier, monospace;
+  font-weight: bold;
+}
+
+PRE {
+  font-family: monaco, courier, monospace;
+}
+
+PRE.command {
+  margin-left: 36pt;
+}
+
+PRE.example {
+  background: #eeeeee;
+  border: dotted thin #999999;
+  margin-left: 36pt;
+  padding: 10px;
+}
+
+PRE.command EM, PRE.example EM {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+P.command {
+  font-family: monaco, courier, monospace;
+  margin-left: 36pt;
+}
+
+P.formula {
+  font-style: italic;
+  margin-left: 36pt;
+}
+
+BLOCKQUOTE {
+  background: #cccccc;
+  border: solid thin #999999;
+  padding: 10pt;
+}
+
+A:link, A:visited {
+  text-decoration: none;
+  font-weight: bold;
+}
+
+A:link:hover, A:visited:hover, A:active {
+  text-decoration: underline;
+  font-weight: bold;
+}
+
+SUB, SUP {
+  font-size: 50%;
+}
+
+DIV.table TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.table CAPTION {
+  caption-side: top;
+  font-size: 120%;
+  font-style: italic;
+  font-weight: bold;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.table TABLE TD {
+  border: solid thin #cccccc;
+  padding-top: 5pt;
+}
+
+DIV.table TABLE TH {
+  background: #cccccc;
+  border: none;
+  border-bottom: solid thin #999999;
+}
+
+DIV.figure TABLE {
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.figure CAPTION {
+  caption-side: bottom;
+  font-size: 120%;
+  font-style: italic;
+  font-weight: bold;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+TH.label {
+  padding-top: 5pt;
+  text-align: right;
+  vertical-align: top;
+}
+
+HR {
+  border: solid thin;
+}
+
+SPAN.info {
+  background: #000000;
+  border: thin solid #000000;
+  color: #ffffff;
+  font-size: 80%;
+  font-style: italic;
+  font-weight: bold;
+  white-space: nowrap;
+}
+
+H2 SPAN.info, H3 SPAN.info, H4 SPAN.info {
+  float: right;
+  font-size: 100%;
+}
+
+H2.title, H3.title {
+  border-bottom: solid 2pt #000000;
+}
+
+DT {
+  margin-left: 36pt;
+  margin-top: 12pt;
+}
+
+DD {
+  margin-left: 54pt;
+}
+
+DL.category DT {
+  font-weight: bold;
+}
+
+P.summary {
+  margin-left: 36pt;
+  font-family: monaco, courier, monospace;
+}
+
+SPAN.message {
+  font-style: italic;
+  font-size: smaller;
+}
+
+DIV.summary TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin: 10px;
+}
+
+DIV.summary TABLE TD, DIV.summary TABLE TH {
+  border: solid thin #999999;
+  padding: 5px;
+  text-align: left;
+  vertical-align: top;
+}
+
+DIV.summary TABLE THEAD TH {
+  background: #eeeeee;
+}
+
+/* API documentation styles... */
+div.body h1 {
+  margin: 0;
+}
+div.body h2 {
+  margin-top: 1.5em;
+}
+div.body h3, div.body h4, div.body h5 {
+  margin-bottom: 0.5em;
+  margin-top: 1.5em;
+}
+.class, .enumeration, .function, .struct, .typedef, .union {
+  border-bottom: solid thin #999999;
+  margin-bottom: 0;
+  margin-top: 2em;
+}
+.description {
+  margin-top: 0.5em;
+}
+code, p.code, pre, ul.code li {
+  font-family: monaco, courier, monospace;
+  font-size: 90%;
+}
+ul.code, ul.contents, ul.subcontents {
+  list-style-type: none;
+  margin: 0;
+  padding-left: 0;
+}
+ul.code li {
+  margin: 0;
+}
+ul.contents > li {
+  margin-top: 1em;
+}
+ul.contents li ul.code, ul.contents li ul.subcontents {
+  padding-left: 2em;
+}
+div.body dl {
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dt {
+  font-style: italic;
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dd {
+  margin-bottom: 0.5em;
+}
+
+/* This is just for the HTML files generated with the framedhelp target */
+div.contents {
+  background: #e8e8e8;
+  border: solid thin black;
+  padding: 10px;
+}
+div.contents h1 {
+  font-size: 110%;
+}
+div.contents h2 {
+  font-size: 100%;
+}
+div.contents ul.contents {
+  font-size: 80%;
+}
+--></style>
 </head>
 <body>
+<div class='body'>
+<!--
+  "$Id: api-cups.header 7279 2008-01-31 01:50:44Z mike $"
+
+  CUPS API header for the Common UNIX Printing System (CUPS).
+
+  Copyright 2008 by Apple Inc.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">CUPS API</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+       <th>Header</th>
+       <th>cups/cups.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <th>Library</th>
+       <td>-lcups</td>
+</tr>
+<tr>
+       <th>See Also</th>
+       <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
+       Programming: <a href='api-array.html' target='_top'>Array API</a><br>
+       Programming: <a href='api-filedir.html' target='_top'>File and Directory APIs</a><br>
+       Programming: <a href='api-filter.html' target='_top'>Filter and Backend Programming</a><br>
+       Programming: <a href='api-httpipp.html' target='_top'>HTTP and IPP APIs</a><br>
+       Programming: <a href='api-ppd.html' target='_top'>PPD API</a><br>
+       Programming: <a href='api-raster.html' target='_top'>Raster API</a></td>
+</tr>
+</tbody>
+</table></div>
+<h2 class="title">Contents</h2>
+<ul class="contents">
+</li>
+<li><a href="#OVERVIEW">Overview</a><ul class="subcontents">
+<li><a href="#PRINTERS_AND_CLASSES">Printers and Classes</a></li>
+<li><a href="#OPTIONS">Options</a></li>
+<li><a href="#PRINT_JOBS">Print Jobs</a></li>
+<li><a href="#ERROR_HANDLING">Error Handling</a></li>
+<li><a href="#PASSWORDS_AND_AUTHENTICATION">Passwords and Authentication</a></li>
+</ul></li>
+<li><a href="#FUNCTIONS">Functions</a><ul class="code">
+<li><a href="#cupsAddDest" title="Add a destination to the list of destinations.">cupsAddDest</a></li>
+<li><a href="#cupsAddOption" title="Add an option to an option array.">cupsAddOption</a></li>
+<li><a href="#cupsCancelJob" title="Cancel a print job on the default server.">cupsCancelJob</a></li>
+<li><a href="#cupsCancelJob2" title="Cancel or purge a print job.">cupsCancelJob2</a></li>
+<li><a href="#cupsCreateJob" title="Create an empty job.">cupsCreateJob</a></li>
+<li><a href="#cupsEncryption" title="Get the default encryption settings.">cupsEncryption</a></li>
+<li><a href="#cupsFinishDocument" title="Finish sending a document.">cupsFinishDocument</a></li>
+<li><a href="#cupsFreeDests" title="Free the memory used by the list of destinations.">cupsFreeDests</a></li>
+<li><a href="#cupsFreeJobs" title="Free memory used by job data.">cupsFreeJobs</a></li>
+<li><a href="#cupsFreeOptions" title="Free all memory used by options.">cupsFreeOptions</a></li>
+<li><a href="#cupsGetClasses" title="Get a list of printer classes from the default server.">cupsGetClasses</a></li>
+<li><a href="#cupsGetDefault" title="Get the default printer or class for the default server.">cupsGetDefault</a></li>
+<li><a href="#cupsGetDefault2" title="Get the default printer or class for the specified server.">cupsGetDefault2</a></li>
+<li><a href="#cupsGetDest" title="Get the named destination from the list.">cupsGetDest</a></li>
+<li><a href="#cupsGetDests" title="Get the list of destinations from the default server.">cupsGetDests</a></li>
+<li><a href="#cupsGetDests2" title="Get the list of destinations from the specified server.">cupsGetDests2</a></li>
+<li><a href="#cupsGetFd" title="Get a file from the server.">cupsGetFd</a></li>
+<li><a href="#cupsGetFile" title="Get a file from the server.">cupsGetFile</a></li>
+<li><a href="#cupsGetJobs" title="Get the jobs from the default server.">cupsGetJobs</a></li>
+<li><a href="#cupsGetJobs2" title="Get the jobs from the specified server.">cupsGetJobs2</a></li>
+<li><a href="#cupsGetNamedDest" title="Get options for the named destination.">cupsGetNamedDest</a></li>
+<li><a href="#cupsGetOption" title="Get an option value.">cupsGetOption</a></li>
+<li><a href="#cupsGetPPD" title="Get the PPD file for a printer on the default server.">cupsGetPPD</a></li>
+<li><a href="#cupsGetPPD2" title="Get the PPD file for a printer from the specified server.">cupsGetPPD2</a></li>
+<li><a href="#cupsGetPPD3" title="Get the PPD file for a printer on the specified
+server if it has changed.">cupsGetPPD3</a></li>
+<li><a href="#cupsGetPassword" title="Get a password from the user.">cupsGetPassword</a></li>
+<li><a href="#cupsGetPrinters" title="Get a list of printers from the default server.">cupsGetPrinters</a></li>
+<li><a href="#cupsGetServerPPD" title="Get an available PPD file from the server.">cupsGetServerPPD</a></li>
+<li><a href="#cupsLangDefault" title="Return the default language.">cupsLangDefault</a></li>
+<li><a href="#cupsLangEncoding" title="Return the character encoding (us-ascii, etc.)
+for the given language.">cupsLangEncoding</a></li>
+<li><a href="#cupsLangFlush" title="Flush all language data out of the cache.">cupsLangFlush</a></li>
+<li><a href="#cupsLangFree" title="Free language data.">cupsLangFree</a></li>
+<li><a href="#cupsLangGet" title="Get a language.">cupsLangGet</a></li>
+<li><a href="#cupsLastError" title="Return the last IPP status code.">cupsLastError</a></li>
+<li><a href="#cupsLastErrorString" title="Return the last IPP status-message.">cupsLastErrorString</a></li>
+<li><a href="#cupsNotifySubject" title="Return the subject for the given notification message.">cupsNotifySubject</a></li>
+<li><a href="#cupsNotifyText" title="Return the text for the given notification message.">cupsNotifyText</a></li>
+<li><a href="#cupsParseOptions" title="Parse options from a command-line argument.">cupsParseOptions</a></li>
+<li><a href="#cupsPrintFile" title="Print a file to a printer or class on the default server.">cupsPrintFile</a></li>
+<li><a href="#cupsPrintFile2" title="Print a file to a printer or class on the specified
+server.">cupsPrintFile2</a></li>
+<li><a href="#cupsPrintFiles" title="Print one or more files to a printer or class on the
+default server.">cupsPrintFiles</a></li>
+<li><a href="#cupsPrintFiles2" title="Print one or more files to a printer or class on the
+specified server.">cupsPrintFiles2</a></li>
+<li><a href="#cupsPutFd" title="Put a file on the server.">cupsPutFd</a></li>
+<li><a href="#cupsPutFile" title="Put a file on the server.">cupsPutFile</a></li>
+<li><a href="#cupsRemoveDest" title="Remove a destination from the destination list.">cupsRemoveDest</a></li>
+<li><a href="#cupsRemoveOption" title="Remove an option from an option array.">cupsRemoveOption</a></li>
+<li><a href="#cupsServer" title="Return the hostname/address of the default server.">cupsServer</a></li>
+<li><a href="#cupsSetDefaultDest" title="Set the default destination.">cupsSetDefaultDest</a></li>
+<li><a href="#cupsSetDests" title="Save the list of destinations for the default server.">cupsSetDests</a></li>
+<li><a href="#cupsSetDests2" title="Save the list of destinations for the specified server.">cupsSetDests2</a></li>
+<li><a href="#cupsSetEncryption" title="Set the encryption preference.">cupsSetEncryption</a></li>
+<li><a href="#cupsSetPasswordCB" title="Set the password callback for CUPS.">cupsSetPasswordCB</a></li>
+<li><a href="#cupsSetServer" title="Set the default server name.">cupsSetServer</a></li>
+<li><a href="#cupsSetUser" title="Set the default user name.">cupsSetUser</a></li>
+<li><a href="#cupsStartDocument" title="Add a document to a job created with cupsCreateJob().">cupsStartDocument</a></li>
+<li><a href="#cupsTempFd" title="Creates a temporary file.">cupsTempFd</a></li>
+<li><a href="#cupsTempFile" title="Generates a temporary filename.">cupsTempFile</a></li>
+<li><a href="#cupsTempFile2" title="Creates a temporary CUPS file.">cupsTempFile2</a></li>
+<li><a href="#cupsUser" title="Return the current user's name.">cupsUser</a></li>
+</ul>
+<li><a href="#TYPES">Data Types</a><ul class="code">
+       <li><a href="#cups_dest_t" title="Destination">cups_dest_t</a></li>
+       <li><a href="#cups_job_t" title="Job">cups_job_t</a></li>
+       <li><a href="#cups_option_t" title="Printer Options">cups_option_t</a></li>
+       <li><a href="#cups_password_cb_t" title="Password callback">cups_password_cb_t</a></li>
+       <li><a href="#cups_ptype_t" title="Printer type/capability bits">cups_ptype_t</a></li>
+</ul></li>
+<li><a href="#STRUCTURES">Structures</a><ul class="code">
+       <li><a href="#cups_dest_s" title="Destination">cups_dest_s</a></li>
+       <li><a href="#cups_job_s" title="Job">cups_job_s</a></li>
+       <li><a href="#cups_option_s" title="Printer Options">cups_option_s</a></li>
+</ul></li>
+<li><a href="#ENUMERATIONS">Constants</a><ul class="code">
+       <li><a href="#cups_ptype_e" title="Printer type/capability bit constants">cups_ptype_e</a></li>
+</ul></li>
+</ul>
 <!--
-  "$Id: api-cups.shtml 6649 2007-07-11 21:46:42Z mike $"
+  "$Id: api-cups.shtml 7258 2008-01-28 00:15:05Z mike $"
 
   CUPS API introduction for the Common UNIX Printing System (CUPS).
 
-  Copyright 2007 by Apple Inc.
+  Copyright 2007-2008 by Apple Inc.
   Copyright 1997-2006 by Easy Software Products, all rights reserved.
 
   These coded instructions, statements, and computer programs are the
   file is missing or damaged, see the license at "http://www.cups.org/".
 -->
 
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
+
+<p>The CUPS API provides the convenience functions needed to support
+applications, filters, printer drivers, and backends that need to interface
+with the CUPS scheduler.</p>
 
-<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>
+<h3><a name='PRINTERS_AND_CLASSES'>Printers and Classes</a></h3>
 
-<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>
+<p>Printers and classes (collections of printers) are accessed through
+the <a href="#cups_dest_t"><code>cups_dest_t</code></a> structure which
+includes the name (<code>name</code>), instance (<code>instance</code> -
+a way of selected certain saved options), and the options and attributes
+associated with that destination (<code>num_options</code> and
+<code>options</code>). Destinations are created using the
+<a href="#cupsGetDests"><code>cupsGetDests</code></a> function and freed
+using the <a href='#cupsFreeDests'><code>cupsFreeDests</code></a> function.
+The <a href='#cupsGetDest'><code>cupsGetDest</code></a> function finds a
+specific destination for printing:</p>
 
-<h2 class='title'>General Usage</h2>
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
 
-<p>The <var>&lt;cups/cups.h&gt;</var> header file must be included to
-use the CUPS functions.</p>
+<a href='#cups_dest_t'>cups_dest_t</a> *dests;
+int num_dests = <a href='#cupsGetDests'>cupsGetDests</a>(&amp;dests);
+<a href='#cups_dest_t'>cups_dest_t</a> *dest = <a href='#cupsGetDest'>cupsGetDest</a>("name", NULL, num_dests, dests);
 
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+/* do something wiith dest */
 
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
+<a href='#cupsFreeDests'>cupsFreeDests</a>(num_dests, dests);
 </pre>
 
-<h2 class='title'>Compatibility</h2>
+<p>Passing <code>NULL</code> to
+<a href='#cupsGetDest'><code>cupsGetDest</code></a> for the destination name
+will return the default destination. Similarly, passing a <code>NULL</code>
+instance will return the default instance for that destination.</p>
 
-<p>Unless otherwise specified, the CUPS API functions require
-CUPS 1.1 or higher.</p>
-<h2 class='title'>Contents</h2>
-<ul>
-       <li><a href='#ENUMERATIONS'>Enumerations</a></li>
-       <li><a href='#FUNCTIONS'>Functions</a></li>
-       <li><a href='#STRUCTURES'>Structures</a></li>
-       <li><a href='#TYPES'>Types</a></li>
-</ul>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='ENUMERATIONS'>Enumerations</a></h2>
-<ul>
-       <li><a href='#cups_ptype_e'><tt>cups_ptype_e</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_ptype_e'>cups_ptype_e</a></h3>
-<h4>Description</h4>
-<p>Not a typedef'd enum so we can OR
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
+<div class='table'><table summary='Table 1: Printer Attributes' width='80%'>
+<caption>Table 1: <a name='TABLE1'>Printer Attributes</a></caption>
+<thead>
+<tr>
+       <th>Attribute Name</th>
+       <th>Description</th>
+</tr>
+</thead>
 <tbody>
-<tr><td><tt>CUPS_PRINTER_AUTHENTICATED</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Printer requires authentication 
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_BIND</tt> </td><td>Can bind output
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_BW</tt> </td><td>Can do B&amp;W printing
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_CLASS</tt> </td><td>Printer class
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_COLLATE</tt> </td><td>Can collage copies
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_COLOR</tt> </td><td>Can do color printing
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_COMMANDS</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Printer supports maintenance commands 
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_COPIES</tt> </td><td>Can do copies
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_COVER</tt> </td><td>Can cover output
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_DEFAULT</tt> </td><td>Default printer on network
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_DELETE</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Delete printer 
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_DISCOVERED</tt> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></td><td>Printer was automatically discovered and added 
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_DUPLEX</tt> </td><td>Can do duplexing
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_FAX</tt> </td><td>Fax queue
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_IMPLICIT</tt> </td><td>Implicit class
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_LARGE</tt> </td><td>Can do D/E/A1/A0
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_LOCAL</tt> </td><td>Local printer or class
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_MEDIUM</tt> </td><td>Can do Tabloid/B/C/A3/A2
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_NOT_SHARED</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Printer is not shared 
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_OPTIONS</tt> </td><td>~(CLASS | REMOTE | IMPLICIT | DEFAULT | FAX | REJECTING | DELETE | NOT_SHARED | AUTHENTICATED | COMMANDS | DISCOVERED)
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_PUNCH</tt> </td><td>Can punch output
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_REJECTING</tt> </td><td>Printer is rejecting jobs
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_REMOTE</tt> </td><td>Remote printer or class
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_SMALL</tt> </td><td>Can do Letter/Legal/A4
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_SORT</tt> </td><td>Can sort output
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_STAPLE</tt> </td><td>Can staple output
-</td></tr>
-<tr><td><tt>CUPS_PRINTER_VARIABLE</tt> </td><td>Can do variable sizes
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='FUNCTIONS'>Functions</a></h2>
-<ul>
-       <li><a href='#cupsAddDest'><tt>cupsAddDest()</tt></a> </li>
-       <li><a href='#cupsAddOption'><tt>cupsAddOption()</tt></a> </li>
-       <li><a href='#cupsCancelJob'><tt>cupsCancelJob()</tt></a> </li>
-       <li><a href='#cupsEncryption'><tt>cupsEncryption()</tt></a> </li>
-       <li><a href='#cupsFreeDests'><tt>cupsFreeDests()</tt></a> </li>
-       <li><a href='#cupsFreeJobs'><tt>cupsFreeJobs()</tt></a> </li>
-       <li><a href='#cupsFreeOptions'><tt>cupsFreeOptions()</tt></a> </li>
-       <li><a href='#cupsGetClasses'><tt>cupsGetClasses()</tt></a> <span class='info'>&nbsp;DEPRECATED&nbsp;</span></li>
-       <li><a href='#cupsGetDefault'><tt>cupsGetDefault()</tt></a> </li>
-       <li><a href='#cupsGetDefault2'><tt>cupsGetDefault2()</tt></a> <span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span></li>
-       <li><a href='#cupsGetDest'><tt>cupsGetDest()</tt></a> </li>
-       <li><a href='#cupsGetDests'><tt>cupsGetDests()</tt></a> </li>
-       <li><a href='#cupsGetDests2'><tt>cupsGetDests2()</tt></a> <span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span></li>
-       <li><a href='#cupsGetFd'><tt>cupsGetFd()</tt></a> <span class='info'>&nbsp;CUPS 1.1.20&nbsp;</span></li>
-       <li><a href='#cupsGetFile'><tt>cupsGetFile()</tt></a> <span class='info'>&nbsp;CUPS 1.1.20&nbsp;</span></li>
-       <li><a href='#cupsGetJobs'><tt>cupsGetJobs()</tt></a> </li>
-       <li><a href='#cupsGetJobs2'><tt>cupsGetJobs2()</tt></a> <span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span></li>
-       <li><a href='#cupsGetOption'><tt>cupsGetOption()</tt></a> </li>
-       <li><a href='#cupsGetPPD'><tt>cupsGetPPD()</tt></a> </li>
-       <li><a href='#cupsGetPPD2'><tt>cupsGetPPD2()</tt></a> <span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span></li>
-       <li><a href='#cupsGetPPD3'><tt>cupsGetPPD3()</tt></a> </li>
-       <li><a href='#cupsGetPassword'><tt>cupsGetPassword()</tt></a> </li>
-       <li><a href='#cupsGetPrinters'><tt>cupsGetPrinters()</tt></a> <span class='info'>&nbsp;DEPRECATED&nbsp;</span></li>
-       <li><a href='#cupsGetServerPPD'><tt>cupsGetServerPPD()</tt></a> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></li>
-       <li><a href='#cupsLangDefault'><tt>cupsLangDefault()</tt></a> </li>
-       <li><a href='#cupsLangEncoding'><tt>cupsLangEncoding()</tt></a> </li>
-       <li><a href='#cupsLangFlush'><tt>cupsLangFlush()</tt></a> </li>
-       <li><a href='#cupsLangFree'><tt>cupsLangFree()</tt></a> </li>
-       <li><a href='#cupsLangGet'><tt>cupsLangGet()</tt></a> </li>
-       <li><a href='#cupsLastError'><tt>cupsLastError()</tt></a> </li>
-       <li><a href='#cupsLastErrorString'><tt>cupsLastErrorString()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#cupsMarkOptions'><tt>cupsMarkOptions()</tt></a> </li>
-       <li><a href='#cupsNotifySubject'><tt>cupsNotifySubject()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#cupsNotifyText'><tt>cupsNotifyText()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#cupsParseOptions'><tt>cupsParseOptions()</tt></a> </li>
-       <li><a href='#cupsPrintFile'><tt>cupsPrintFile()</tt></a> </li>
-       <li><a href='#cupsPrintFile2'><tt>cupsPrintFile2()</tt></a> <span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span></li>
-       <li><a href='#cupsPrintFiles'><tt>cupsPrintFiles()</tt></a> </li>
-       <li><a href='#cupsPrintFiles2'><tt>cupsPrintFiles2()</tt></a> <span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span></li>
-       <li><a href='#cupsPutFd'><tt>cupsPutFd()</tt></a> <span class='info'>&nbsp;CUPS 1.1.20&nbsp;</span></li>
-       <li><a href='#cupsPutFile'><tt>cupsPutFile()</tt></a> <span class='info'>&nbsp;CUPS 1.1.20&nbsp;</span></li>
-       <li><a href='#cupsRemoveDest'><tt>cupsRemoveDest()</tt></a> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></li>
-       <li><a href='#cupsRemoveOption'><tt>cupsRemoveOption()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#cupsServer'><tt>cupsServer()</tt></a> </li>
-       <li><a href='#cupsSetDefaultDest'><tt>cupsSetDefaultDest()</tt></a> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></li>
-       <li><a href='#cupsSetDests'><tt>cupsSetDests()</tt></a> </li>
-       <li><a href='#cupsSetDests2'><tt>cupsSetDests2()</tt></a> <span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span></li>
-       <li><a href='#cupsSetEncryption'><tt>cupsSetEncryption()</tt></a> </li>
-       <li><a href='#cupsSetPasswordCB'><tt>cupsSetPasswordCB()</tt></a> </li>
-       <li><a href='#cupsSetServer'><tt>cupsSetServer()</tt></a> </li>
-       <li><a href='#cupsSetUser'><tt>cupsSetUser()</tt></a> </li>
-       <li><a href='#cupsTempFd'><tt>cupsTempFd()</tt></a> </li>
-       <li><a href='#cupsTempFile'><tt>cupsTempFile()</tt></a> <span class='info'>&nbsp;DEPRECATED&nbsp;</span></li>
-       <li><a href='#cupsTempFile2'><tt>cupsTempFile2()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#cupsUser'><tt>cupsUser()</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsAddDest'>cupsAddDest()</a></h3>
-<h4>Description</h4>
-<p>Add a destination to the list of destinations.
-<p>This function cannot be used to add a new class or printer queue,
+<tr>
+       <td>"auth-info-required"</td>
+       <td>The type of authentication required for printing to this
+       destination: "none", "username,password", "domain,username,password",
+       or "negotiate" (Kerberos)</td>
+</tr>
+<tr>
+       <td>"printer-info"</td>
+       <td>The human-readable description of the destination such as "My
+       Laser Printer".</td>
+</tr>
+<tr>
+       <td>"printer-is-accepting-jobs"</td>
+       <td>"1" if the destination is accepting new jobs, "0" if not.</td>
+</tr>
+<tr>
+       <td>"printer-is-shared"</td>
+       <td>"1" if the destination is being shared with other computers, "0" if
+       not.</td>
+</tr>
+<tr>
+       <td>"printer-location"</td>
+       <td>The human-readable location of the destination such as "Lab 4".</td>
+</tr>
+<tr>
+       <td>"printer-make-and-model"</td>
+       <td>The human-readable make and model of the destination such as "HP
+       LaserJet 4000 Series".</td>
+</tr>
+<tr>
+       <td>"printer-state"</td>
+       <td>"3" if the destination is idle, "4" if the destination is printing
+       a job, and "5" if the destination is stopped.</td>
+</tr>
+<tr>
+       <td>"printer-state-change-time"</td>
+       <td>The UNIX time when the destination entered the current state.</td>
+</tr>
+<tr>
+       <td>"printer-state-reasons"</td>
+       <td>Additional comma-delimited state keywords for the destination
+       such as "media-tray-empty-error" and "toner-low-warning".</td>
+</tr>
+<tr>
+       <td>"printer-type"</td>
+       <td>The <a href='#cups_printer_t'><code>cups_printer_t</code></a>
+       value associated with the destination.</td>
+</tr>
+</tbody>
+</table></div>
+
+<h3><a name='OPTIONS'>Options</a></h3>
+
+<p>Options are stored in arrays of
+<a href='#cups_option_t'><code>cups_option_t</code></a> structures. Each
+option has a name (<code>name</code>) and value (<code>value</code>)
+associated with it. The <a href='#cups_dest_t'><code>cups_dest_t</code></a>
+<code>num_options</code> and <code>options</code> members contain the
+default options for a particular destination, along with several informational
+attributes about the destination as shown in <a href='#TABLE1'>Table 1</a>.
+The <a href='#cupsGetOption'><code>cupsGetOption</code></a> function gets
+the value for the named option. For example, the following code lists the
+available destinations and their human-readable descriptions:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dests;
+int num_dests = <a href='#cupsGetDests'>cupsGetDests</a>(&amp;dests);
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int i;
+const char *value;
+
+for (i = num_dests, dest = dests; i > 0; i --, dest ++)
+  if (dest->instance == NULL)
+  {
+    value = <a href='#cupsGetOption'>cupsGetOption</a>("printer-info", dest->num_options, dest->options);
+    printf("%s (%s)\n", dest->name, value ? value : "no description");
+  }
+
+<a href='#cupsFreeDests'>cupsFreeDests</a>(num_dests, dests);
+</pre>
+
+<p>You can create your own option arrays using the
+<a href='#cupsAddOption'><code>cupsAddOption</code></a> function, which
+adds a single named option to an array:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+int num_options = 0;
+<a href='#cups_option_t'>cups_option_t</a> *options = NULL;
+
+/* The returned num_options value is updated as needed */
+num_options = <a href='#cupsAddOption'>cupsAddOption</a>("first", "value", num_options, &amp;options);
+
+/* This adds a second option value */
+num_options = <a href='#cupsAddOption'>cupsAddOption</a>("second", "value", num_options, &amp;options);
+
+/* This replaces the first option we added */
+num_options = <a href='#cupsAddOption'>cupsAddOption</a>("first", "new value", num_options, &amp;options);
+</pre>
+
+<p>Use a <code>for</code> loop to copy the options from a destination:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+int i;
+int num_options = 0;
+<a href='#cups_option_t'>cups_option_t</a> *options = NULL;
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+
+for (i = 0; i < dest->num_options; i ++)
+  num_options = <a href='#cupsAddOption'>cupsAddOption</a>(dest->options[i].name, dest->options[i].value, num_options, &amp;options);
+</pre>
+
+<p>Use the <a href='#cupsFreeOptions'><code>cupsFreeOptions</code></a>
+function to free the options array when you are done using it:</p>
+
+<pre class='example'>
+<a href='#cupsFreeOptions'>cupsFreeOptions</a>(num_options, options);
+</pre>
+
+<h3><a name='PRINT_JOBS'>Print Jobs</a></h3>
+
+<p>Print jobs are identified by a locally-unique job ID number from 1 to
+2<sup>31</sup>-1 and have options and one or more files for printing to a
+single destination. The <a href='#cupsPrintFile'><code>cupsPrintFile</code></a>
+function creates a new job with one file. The following code prints the CUPS
+test page file:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int num_options;
+<a href='#cups_option_t'>cups_option_t</a> *options;
+int job_id;
+
+/* Print a single file */
+job_id = <a href='#cupsPrintFile'>cupsPrintFile</a>(dest->name, "/usr/share/cups/data/testprint.ps", "Test Print", num_options, options);
+</pre>
+
+<p>The <a href='#cupsPrintFiles'><code>cupsPrintFiles</code></a> function
+creates a job with multiple files. The files are provided in a
+<code>char *</code> array:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int num_options;
+<a href='#cups_option_t'>cups_option_t</a> *options;
+int job_id;
+char *files[3] = { "file1.pdf", "file2.pdf", "file3.pdf" };
+
+/* Print three files */
+job_id = <a href='#cupsPrintFiles'>cupsPrintFiles</a>(dest->name, 3, files, "Test Print", num_options, options);
+</pre>
+
+<p>Finally, the <a href='#cupsCreateJob'><code>cupsCreateJob</code></a>
+function creates a new job with no files in it. Files are added using the
+<a href='#cupsStartDocument'><code>cupsStartDocument</code></a>, 
+<a href='api-httpipp.html#cupsWriteRequestData'><code>cupsWriteRequestData</code></a>,
+and <a href='#cupsFinishDocument'><code>cupsFinishDocument</code></a> functions.
+The following example creates a job with 10 text files for printing:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int num_options;
+<a href='#cups_option_t'>cups_option_t</a> *options;
+int job_id;
+int i;
+char buffer[1024];
+
+/* Create the job */
+job_id = <a href='#cupsCreateJob'>cupsCreateJob</a>(CUPS_HTTP_DEFAULT, dest->name, "10 Text Files", num_options, options);
+
+/* If the job is created, add 10 files */
+if (job_id > 0)
+{
+  for (i = 1; i &lt;= 10; i ++)
+  {
+    snprintf(buffer, sizeof(buffer), "file%d.txt", i);
+
+    <a href='#cupsStartDocument'>cupsStartDocument</a>(CUPS_HTTP_DEFAULT, dest->name, job_id, buffer, CUPS_FORMAT_TEXT, i == 10);
+
+    snprintf(buffer, sizeof(buffer),
+             "File %d\n"
+             "\n"
+             "One fish,\n"
+             "Two fish,\n
+             "Red fish,\n
+             "Blue fish\n", i);
+
+    /* cupsWriteRequestData can be called as many times as needed */
+    <a href='#cupsWriteRequestData'>cupsWriteRequestData</a>(CUPS_HTTP_DEFAULT, buffer, strlen(buffer));
+
+    <a href='#cupsFinishDocument'>cupsFinishDocument</a>(CUPS_HTTP_DEFAULT, dest->name);
+  }
+}
+</pre>
+
+<p>Once you have created a job, you can monitor its status using the
+<a href='#cupsGetJobs'><code>cupsGetJobs</code></a> function, which returns
+an array of <a href='#cups_job_t'><code>cups_job_t</code></a> structures.
+Each contains the job ID (<code>id</code>), destination name
+(<code>dest</code>), title (<code>title</code>), and other information
+associated with the job. The job array is freed using the
+<a href='#cupsFreeJobs'><code>cupsFreeJobs</code></a> function. The following
+example monitors a specific job ID, showing the current job state once every
+5 seconds until the job is completed:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int job_id;
+int num_jobs;
+<a href='#cups_job_t'>cups_job_t</a> *jobs;
+int i;
+ipp_jstate_t job_state = IPP_JOB_PENDING;
+while (job_state &lt; IPP_JOB_STOPPED)
+{
+  /* Get my jobs (1) with any state (-1) */
+  num_jobs = <a href='#cupsGetJobs'>cupsGetJobs</a>(&amp;jobs, dest->name, 1, -1);
+
+  /* Loop to find my job */
+  job_state = IPP_JOB_COMPLETED;
+
+  for (i = 0; i &lt; num_jobs; i ++)
+    if (jobs[i].id == job_id)
+    {
+      job_state = jobs[i].state;
+      break;
+    }
+
+  /* Free the job array */
+  <a href='#cupsFreeJobs'>cupsFreeJobs</a>(num_jobs, jobs);
+
+  /* Show the current state */
+  switch (job_state)
+  {
+    case IPP_JOB_PENDING :
+        printf("Job %d is pending.\n", job_id);
+        break;
+    case IPP_JOB_HELD :
+        printf("Job %d is held.\n", job_id);
+        break;
+    case IPP_JOB_PROCESSING :
+        printf("Job %d is processing.\n", job_id);
+        break;
+    case IPP_JOB_STOPPED :
+        printf("Job %d is stopped.\n", job_id);
+        break;
+    case IPP_JOB_CANCELED :
+        printf("Job %d is canceled.\n", job_id);
+        break;
+    case IPP_JOB_ABORTED :
+        printf("Job %d is aborted.\n", job_id);
+        break;
+    case IPP_JOB_COMPLETED :
+        printf("Job %d is completed.\n", job_id);
+        break;
+  }
+
+  /* Sleep if the job is not finished */
+  if (job_state &lt; IPP_JOB_STOPPED)
+    sleep(5);
+}
+</pre>
+
+<p>To cancel a job, use the
+<a href='#cupsCancelJob'><code>cupsCancelJob</code></a> function with the
+job ID:</p>
+
+<pre class='exmaple'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int job_id;
+
+<a href='#cupsCancelJob'>cupsCancelJob</a>(dest->name, job_id);
+</pre>
+
+<h3><a name='ERROR_HANDLING'>Error Handling</a></h3>
+
+<p>If any of the CUPS API printing functions returns an error, the reason for
+that error can be found by calling the
+<a href='#cupsLastError'><code>cupsLastError</code></a> and
+<a href='#cupsLastErrorString'><code>cupsLastErrorString</code></a> functions.
+<a href='#cupsLastError'><code>cupsLastError</code></a> returns the last IPP
+error code
+(<a href='api-httpipp.html#ipp_status_t'><code>ipp_status_t</code></a>)
+that was encountered, while
+<a href='#cupsLastErrorString'><code>cupsLastErrorString</code></a> returns
+a (localized) human-readable string that can be shown to the user. For example,
+if any of the job creation functions returns a job ID of 0, you can use
+<a href='#cupsLastErrorString'><code>cupsLastErrorString</code></a> to show
+the reason why the job could not be created:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+int job_id;
+
+if (job_id == 0)
+  puts(cupsLastErrorString());
+</pre>
+
+<h3><a name='PASSWORDS_AND_AUTHENTICATION'>Passwords and Authentication</a></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>
+
+<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>
+
+<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>
+
+<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>
+
+<p>The following example shows a simple password callback that gets a
+username and password from the user:</p>
+
+<pre class='example'>
+#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';
+
+  <a href='#cupsSetUser'>cupsSetUser</a>(user);
+
+  /* Use getpass() to ask for the password... */
+  return (getpass("Password: "));
+}
+
+<a href='#cupsSetPasswordCB'>cupsSetPasswordCB</a>(my_password_cb);
+</pre>
+
+<p>Similarly, a GUI could display the prompt string in a window with input
+fields for the username and password. The username should default to the
+string returned by the <a href="#cupsUser"><code>cupsUser</code></a>
+function.</p>
+<h2 class="title"><a name="FUNCTIONS">Functions</a></h2>
+<h3 class="function"><a name="cupsAddDest">cupsAddDest</a></h3>
+<p class="description">Add a destination to the list of destinations.</p>
+<p class="code">
+int cupsAddDest (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *instance,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_dests,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> **dests<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>name</dt>
+<dd class="description">Destination name</dd>
+<dt>instance</dt>
+<dd class="description">Instance name or <code>NULL</code> for none/primary</dd>
+<dt>num_dests</dt>
+<dd class="description">Number of destinations</dd>
+<dt>dests</dt>
+<dd class="description">Destinations</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New number of destinations</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function cannot be used to add a new class or printer queue,
 it only adds a new container of saved options for the named
-destination or instance.
-<p>If the named destination already exists, the destination list is
+destination or instance.<br>
+<br>
+If the named destination already exists, the destination list is
 returned unchanged.  Adding a new instance of a destination creates
-a copy of that destination's options.
-<p>Use the cupsSaveDests() function to save the updated list of
-destinations to the user's lpoptions file.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsAddDest(
-    const char * name,
-    const char * instance,
-    int num_dests,
-    <a href='#cups_dest_t'>cups_dest_t</a> ** dests);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name</tt></td><td>Destination name</td></tr>
-<tr><td><tt>instance</tt></td><td>Instance name or NULL for none/primary</td></tr>
-<tr><td><tt>num_dests</tt></td><td>Number of destinations</td></tr>
-<tr><td><tt>dests</tt></td><td>Destinations</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New number of destinations</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsAddOption'>cupsAddOption()</a></h3>
-<h4>Description</h4>
-<p>Add an option to an option array.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsAddOption(
-    const char * name,
-    const char * value,
-    int num_options,
-    <a href='#cups_option_t'>cups_option_t</a> ** options);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name</tt></td><td>Name of option</td></tr>
-<tr><td><tt>value</tt></td><td>Value of option</td></tr>
-<tr><td><tt>num_options</tt></td><td>Number of options</td></tr>
-<tr><td><tt>options</tt></td><td>Pointer to options</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of options</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsCancelJob'>cupsCancelJob()</a></h3>
-<h4>Description</h4>
-<p>Cancel a print job on the default server.
-<p>Use the cupsLastError() and cupsLastErrorString() functions to get
+a copy of that destination's options.<br>
+<br>
+Use the <a href="#cupsSaveDests"><code>cupsSaveDests</code></a> function to save the updated list of
+destinations to the user's lpoptions file.</p>
+<h3 class="function"><a name="cupsAddOption">cupsAddOption</a></h3>
+<p class="description">Add an option to an option array.</p>
+<p class="code">
+int cupsAddOption (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *value,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_options,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_option_t">cups_option_t</a> **options<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>name</dt>
+<dd class="description">Name of option</dd>
+<dt>value</dt>
+<dd class="description">Value of option</dd>
+<dt>num_options</dt>
+<dd class="description">Number of options</dd>
+<dt>options</dt>
+<dd class="description">Pointer to options</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of options</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">New option arrays can be initialized simply by passing 0 for the
+&quot;num_options&quot; parameter.</p>
+<h3 class="function"><a name="cupsCancelJob">cupsCancelJob</a></h3>
+<p class="description">Cancel a print job on the default server.</p>
+<p class="code">
+int cupsCancelJob (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int job_id<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>name</dt>
+<dd class="description">Name of printer or class</dd>
+<dt>job_id</dt>
+<dd class="description">Job ID</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 on success, 0 on failure</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Pass <code>CUPS_JOBID_ALL</code> to cancel all jobs or <code>CUPS_JOBID_CURRENT</code>
+to cancel the current job on the named destination.<br>
+<br>
+Use the <a href="#cupsLastError"><code>cupsLastError</code></a> and <a href="#cupsLastErrorString"><code>cupsLastErrorString</code></a> functions to get
+the cause of any failure.</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsCancelJob2">cupsCancelJob2</a></h3>
+<p class="description">Cancel or purge a print job.</p>
+<p class="code">
+ipp_status_t cupsCancelJob2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int job_id,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int purge<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or <code>CUPS_HTTP_DEFAULT</code></dd>
+<dt>name</dt>
+<dd class="description">Name of printer or class</dd>
+<dt>job_id</dt>
+<dd class="description">Job ID or 0 for the current job, -1 for all jobs</dd>
+<dt>purge</dt>
+<dd class="description">1 to purge, 0 to cancel</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">IPP status</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Canceled jobs remain in the job history while purged jobs are removed
+from the job history.<br>
+<br>
+Pass <code>CUPS_JOBID_ALL</code> to cancel all jobs or <code>CUPS_JOBID_CURRENT</code>
+to cancel the current job on the named destination.<br>
+<br>
+Use the <a href="#cupsLastError"><code>cupsLastError</code></a> and <a href="#cupsLastErrorString"><code>cupsLastErrorString</code></a> functions to get
 the cause of any failure.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsCancelJob(
-    const char * name,
-    int job);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name</tt></td><td>Name of printer or class</td></tr>
-<tr><td><tt>job</tt></td><td>Job ID</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>1 on success, 0 on failure</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsEncryption'>cupsEncryption()</a></h3>
-<h4>Description</h4>
-<p>Get the default encryption settings.
-<p>The default encryption setting comes from the CUPS_ENCRYPTION
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsCreateJob">cupsCreateJob</a></h3>
+<p class="description">Create an empty job.</p>
+<p class="code">
+int cupsCreateJob (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *title,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_options,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_option_t">cups_option_t</a> *options<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or <code>CUPS_HTTP_DEFAULT</code></dd>
+<dt>name</dt>
+<dd class="description">Printer or class name</dd>
+<dt>title</dt>
+<dd class="description">Title of job</dd>
+<dt>num_options</dt>
+<dd class="description">Number of options</dd>
+<dt>options</dt>
+<dd class="description">Options</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Job ID or 0 on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Submit files for printing to the job using the <a href="#cupsStartDocument"><code>cupsStartDocument</code></a>,
+<a href="#cupsWriteRequestData"><code>cupsWriteRequestData</code></a>, and <a href="#cupsFinishDocument"><code>cupsFinishDocument</code></a> functions.
+
+</p>
+<h3 class="function"><a name="cupsEncryption">cupsEncryption</a></h3>
+<p class="description">Get the default encryption settings.</p>
+<p class="code">
+http_encryption_t cupsEncryption (void);</p>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Encryption settings</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The default encryption setting comes from the CUPS_ENCRYPTION
 environment variable, then the ~/.cupsrc file, and finally the
 /etc/cups/client.conf file. If not set, the default is
-HTTP_ENCRYPT_IF_REQUESTED.
-<h4>Syntax</h4>
-<p><tt>
-http_encryption_t<br>
-cupsEncryption(void);
-</tt></p>
-<h4>Arguments</h4>
-<p>None.</p>
-<h4>Returns</h4>
-<p>Encryption settings</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFreeDests'>cupsFreeDests()</a></h3>
-<h4>Description</h4>
-<p>Free the memory used by the list of destinations.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsFreeDests(
-    int num_dests,
-    <a href='#cups_dest_t'>cups_dest_t</a> * dests);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>num_dests</tt></td><td>Number of destinations</td></tr>
-<tr><td><tt>dests</tt></td><td>Destinations</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFreeJobs'>cupsFreeJobs()</a></h3>
-<h4>Description</h4>
-<p>Free memory used by job data.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsFreeJobs(
-    int num_jobs,
-    <a href='#cups_job_t'>cups_job_t</a> * jobs);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>num_jobs</tt></td><td>Number of jobs</td></tr>
-<tr><td><tt>jobs</tt></td><td>Jobs</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFreeOptions'>cupsFreeOptions()</a></h3>
-<h4>Description</h4>
-<p>Free all memory used by options.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsFreeOptions(
-    int num_options,
-    <a href='#cups_option_t'>cups_option_t</a> * options);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>num_options</tt></td><td>Number of options</td></tr>
-<tr><td><tt>options</tt></td><td>Pointer to options</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;DEPRECATED&nbsp;</span><a name='cupsGetClasses'>cupsGetClasses()</a></h3>
-<h4>Description</h4>
-<p>Get a list of printer classes from the default server.
-<p>This function is deprecated - use cupsGetDests() instead.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsGetClasses(
-    char *** classes);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>classes</tt></td><td>Classes</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of classes</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsGetDefault'>cupsGetDefault()</a></h3>
-<h4>Description</h4>
-<p>Get the default printer or class for the default server.
-<p>This function returns the default printer or class as defined by
+<code>HTTP_ENCRYPT_IF_REQUESTED</code>.</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsFinishDocument">cupsFinishDocument</a></h3>
+<p class="description">Finish sending a document.</p>
+<p class="code">
+ipp_status_t cupsFinishDocument (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or <code>CUPS_HTTP_DEFAULT</code></dd>
+<dt>name</dt>
+<dd class="description">Printer or class name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Status of document submission</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The document must have been started using <a href="#cupsStartDocument"><code>cupsStartDocument</code></a>.
+
+</p>
+<h3 class="function"><a name="cupsFreeDests">cupsFreeDests</a></h3>
+<p class="description">Free the memory used by the list of destinations.</p>
+<p class="code">
+void cupsFreeDests (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_dests,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> *dests<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>num_dests</dt>
+<dd class="description">Number of destinations</dd>
+<dt>dests</dt>
+<dd class="description">Destinations</dd>
+</dl>
+<h3 class="function"><a name="cupsFreeJobs">cupsFreeJobs</a></h3>
+<p class="description">Free memory used by job data.</p>
+<p class="code">
+void cupsFreeJobs (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_jobs,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_job_t">cups_job_t</a> *jobs<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>num_jobs</dt>
+<dd class="description">Number of jobs</dd>
+<dt>jobs</dt>
+<dd class="description">Jobs</dd>
+</dl>
+<h3 class="function"><a name="cupsFreeOptions">cupsFreeOptions</a></h3>
+<p class="description">Free all memory used by options.</p>
+<p class="code">
+void cupsFreeOptions (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_options,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_option_t">cups_option_t</a> *options<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>num_options</dt>
+<dd class="description">Number of options</dd>
+<dt>options</dt>
+<dd class="description">Pointer to options</dd>
+</dl>
+<h3 class="function"><span class="info">&nbsp;DEPRECATED&nbsp;</span><a name="cupsGetClasses">cupsGetClasses</a></h3>
+<p class="description">Get a list of printer classes from the default server.</p>
+<p class="code">
+int cupsGetClasses (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char ***classes<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>classes</dt>
+<dd class="description">Classes</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of classes</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function is deprecated - use <a href="#cupsGetDests"><code>cupsGetDests</code></a> instead.
+
+</p>
+<h3 class="function"><a name="cupsGetDefault">cupsGetDefault</a></h3>
+<p class="description">Get the default printer or class for the default server.</p>
+<p class="code">
+const char *cupsGetDefault (void);</p>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Default printer or <code>NULL</code></p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function returns the default printer or class as defined by
 the LPDEST or PRINTER environment variables. If these environment
 variables are not set, the server default destination is returned.
-Applications should use the cupsGetDests() and cupsGetDest() functions
-to get the user-defined default printer, as this function does not
-support the lpoptions-defined default printer.
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-cupsGetDefault(void);
-</tt></p>
-<h4>Arguments</h4>
-<p>None.</p>
-<h4>Returns</h4>
-<p>Default printer or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span><a name='cupsGetDefault2'>cupsGetDefault2()</a></h3>
-<h4>Description</h4>
-<p>Get the default printer or class for the specified server.
-<p>This function returns the default printer or class as defined by
+Applications should use the <a href="#cupsGetDests"><code>cupsGetDests</code></a> and <a href="#cupsGetDest"><code>cupsGetDest</code></a>
+functions to get the user-defined default printer, as this function does
+not support the lpoptions-defined default printer.</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.21&nbsp;</span><a name="cupsGetDefault2">cupsGetDefault2</a></h3>
+<p class="description">Get the default printer or class for the specified server.</p>
+<p class="code">
+const char *cupsGetDefault2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or <code>CUPS_HTTP_DEFAULT</code></dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Default printer or <code>NULL</code></p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function returns the default printer or class as defined by
 the LPDEST or PRINTER environment variables. If these environment
 variables are not set, the server default destination is returned.
-Applications should use the cupsGetDests() and cupsGetDest() functions
-to get the user-defined default printer, as this function does not
-support the lpoptions-defined default printer.
-
-
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-cupsGetDefault2(
-    http_t * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Default printer or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsGetDest'>cupsGetDest()</a></h3>
-<h4>Description</h4>
-<p>Get the named destination from the list.
-<p>Use the cupsGetDests() or cupsGetDests2() functions to get a
-list of supported destinations for the current user.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#cups_dest_t'>cups_dest_t</a> *<br>
-cupsGetDest(
-    const char * name,
-    const char * instance,
-    int num_dests,
-    <a href='#cups_dest_t'>cups_dest_t</a> * dests);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name</tt></td><td>Destination name or NULL for the default destination</td></tr>
-<tr><td><tt>instance</tt></td><td>Instance name or NULL</td></tr>
-<tr><td><tt>num_dests</tt></td><td>Number of destinations</td></tr>
-<tr><td><tt>dests</tt></td><td>Destinations</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Destination pointer or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsGetDests'>cupsGetDests()</a></h3>
-<h4>Description</h4>
-<p>Get the list of destinations from the default server.
-<p>Starting with CUPS 1.2, the returned list of destinations include the
+Applications should use the <a href="#cupsGetDests"><code>cupsGetDests</code></a> and <a href="#cupsGetDest"><code>cupsGetDest</code></a>
+functions to get the user-defined default printer, as this function does
+not support the lpoptions-defined default printer.
+
+</p>
+<h3 class="function"><a name="cupsGetDest">cupsGetDest</a></h3>
+<p class="description">Get the named destination from the list.</p>
+<p class="code">
+<a href="#cups_dest_t">cups_dest_t</a> *cupsGetDest (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *instance,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_dests,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> *dests<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>name</dt>
+<dd class="description">Destination name or <code>NULL</code> for the default destination</dd>
+<dt>instance</dt>
+<dd class="description">Instance name or <code>NULL</code></dd>
+<dt>num_dests</dt>
+<dd class="description">Number of destinations</dd>
+<dt>dests</dt>
+<dd class="description">Destinations</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Destination pointer or <code>NULL</code></p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Use the <a href="#cupsGetDests"><code>cupsGetDests</code></a> or <a href="#cupsGetDests2"><code>cupsGetDests2</code></a> functions to get a
+list of supported destinations for the current user.</p>
+<h3 class="function"><a name="cupsGetDests">cupsGetDests</a></h3>
+<p class="description">Get the list of destinations from the default server.</p>
+<p class="code">
+int cupsGetDests (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> **dests<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>dests</dt>
+<dd class="description">Destinations</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of destinations</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Starting with CUPS 1.2, the returned list of destinations include the
 printer-info, printer-is-accepting-jobs, printer-is-shared,
 printer-make-and-model, printer-state, printer-state-change-time,
-printer-state-reasons, and printer-type attributes as options.
-<p>Use the cupsFreeDests() function to free the destination list and
-the cupsGetDest() function to find a particular destination.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsGetDests(
-    <a href='#cups_dest_t'>cups_dest_t</a> ** dests);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>dests</tt></td><td>Destinations</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of destinations</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span><a name='cupsGetDests2'>cupsGetDests2()</a></h3>
-<h4>Description</h4>
-<p>Get the list of destinations from the specified server.
-<p>Starting with CUPS 1.2, the returned list of destinations include the
+printer-state-reasons, and printer-type attributes as options.<br>
+<br>
+Use the <a href="#cupsFreeDests"><code>cupsFreeDests</code></a> function to free the destination list and
+the <a href="#cupsGetDest"><code>cupsGetDest</code></a> function to find a particular destination.</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.21&nbsp;</span><a name="cupsGetDests2">cupsGetDests2</a></h3>
+<p class="description">Get the list of destinations from the specified server.</p>
+<p class="code">
+int cupsGetDests2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> **dests<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or <code>CUPS_HTTP_DEFAULT</code></dd>
+<dt>dests</dt>
+<dd class="description">Destinations</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of destinations</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Starting with CUPS 1.2, the returned list of destinations include the
 printer-info, printer-is-accepting-jobs, printer-is-shared,
 printer-make-and-model, printer-state, printer-state-change-time,
-printer-state-reasons, and printer-type attributes as options.
-<p>Use the cupsFreeDests() function to free the destination list and
-the cupsGetDest() function to find a particular destination.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsGetDests2(
-    http_t * http,
-    <a href='#cups_dest_t'>cups_dest_t</a> ** dests);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>dests</tt></td><td>Destinations</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of destinations</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.20&nbsp;</span><a name='cupsGetFd'>cupsGetFd()</a></h3>
-<h4>Description</h4>
-<p>Get a file from the server.
-<p>This function returns HTTP_OK when the file is successfully retrieved.
-
-
-<h4>Syntax</h4>
-<p><tt>
-http_status_t<br>
-cupsGetFd(
-    http_t * http,
-    const char * resource,
-    int fd);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection to server</td></tr>
-<tr><td><tt>resource</tt></td><td>Resource name</td></tr>
-<tr><td><tt>fd</tt></td><td>File descriptor</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>HTTP status</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.20&nbsp;</span><a name='cupsGetFile'>cupsGetFile()</a></h3>
-<h4>Description</h4>
-<p>Get a file from the server.
-<p>This function returns HTTP_OK when the file is successfully retrieved.
-
-
-<h4>Syntax</h4>
-<p><tt>
-http_status_t<br>
-cupsGetFile(
-    http_t * http,
-    const char * resource,
-    const char * filename);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection to server</td></tr>
-<tr><td><tt>resource</tt></td><td>Resource name</td></tr>
-<tr><td><tt>filename</tt></td><td>Filename</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>HTTP status</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsGetJobs'>cupsGetJobs()</a></h3>
-<h4>Description</h4>
-<p>Get the jobs from the default server.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsGetJobs(
-    <a href='#cups_job_t'>cups_job_t</a> ** jobs,
-    const char * mydest,
-    int myjobs,
-    int completed);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>jobs</tt></td><td>Job data</td></tr>
-<tr><td><tt>mydest</tt></td><td>NULL = all destinations,       *
-otherwise show jobs for mydest</td></tr>
-<tr><td><tt>myjobs</tt></td><td>0 = all users, 1 = mine</td></tr>
-<tr><td><tt>completed</tt></td><td>-1 = show all, 0 = active, *
-1 = completed jobs</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of jobs</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span><a name='cupsGetJobs2'>cupsGetJobs2()</a></h3>
-<h4>Description</h4>
-<p>Get the jobs from the specified server.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsGetJobs2(
-    http_t * http,
-    <a href='#cups_job_t'>cups_job_t</a> ** jobs,
-    const char * mydest,
-    int myjobs,
-    int completed);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>jobs</tt></td><td>Job data</td></tr>
-<tr><td><tt>mydest</tt></td><td>NULL = all destinations,       *
-otherwise show jobs for mydest</td></tr>
-<tr><td><tt>myjobs</tt></td><td>0 = all users, 1 = mine</td></tr>
-<tr><td><tt>completed</tt></td><td>-1 = show all, 0 = active, *
-1 = completed jobs</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of jobs</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsGetOption'>cupsGetOption()</a></h3>
-<h4>Description</h4>
-<p>Get an option value.
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-cupsGetOption(
-    const char * name,
-    int num_options,
-    <a href='#cups_option_t'>cups_option_t</a> * options);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name</tt></td><td>Name of option</td></tr>
-<tr><td><tt>num_options</tt></td><td>Number of options</td></tr>
-<tr><td><tt>options</tt></td><td>Options</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Option value or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsGetPPD'>cupsGetPPD()</a></h3>
-<h4>Description</h4>
-<p>Get the PPD file for a printer on the default server.
-<p>For classes, cupsGetPPD() returns the PPD file for the first printer
-in the class.
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-cupsGetPPD(
-    const char * name);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name</tt></td><td>Printer name</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Filename for PPD file</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span><a name='cupsGetPPD2'>cupsGetPPD2()</a></h3>
-<h4>Description</h4>
-<p>Get the PPD file for a printer from the specified server.
-<p>For classes, cupsGetPPD2() returns the PPD file for the first printer
-in the class.
+printer-state-reasons, and printer-type attributes as options.<br>
+<br>
+Use the <a href="#cupsFreeDests"><code>cupsFreeDests</code></a> function to free the destination list and
+the <a href="#cupsGetDest"><code>cupsGetDest</code></a> function to find a particular destination.
 
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.20&nbsp;</span><a name="cupsGetFd">cupsGetFd</a></h3>
+<p class="description">Get a file from the server.</p>
+<p class="code">
+http_status_t cupsGetFd (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *resource,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int fd<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection to server or <code>CUPS_HTTP_DEFAULT</code></dd>
+<dt>resource</dt>
+<dd class="description">Resource name</dd>
+<dt>fd</dt>
+<dd class="description">File descriptor</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">HTTP status</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function returns <code>HTTP_OK</code> when the file is successfully retrieved.
 
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-cupsGetPPD2(
-    http_t * http,
-    const char * name);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>name</tt></td><td>Printer name</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Filename for PPD file</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsGetPPD3'>cupsGetPPD3()</a></h3>
-<h4>Description</h4>
-<p>Get the PPD file for a printer on the specified
-server if it has changed.
-<p>The &quot;modtime&quot; parameter contains the modification time of any
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.20&nbsp;</span><a name="cupsGetFile">cupsGetFile</a></h3>
+<p class="description">Get a file from the server.</p>
+<p class="code">
+http_status_t cupsGetFile (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *resource,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *filename<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection to server or <code>CUPS_HTTP_DEFAULT</code></dd>
+<dt>resource</dt>
+<dd class="description">Resource name</dd>
+<dt>filename</dt>
+<dd class="description">Filename</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">HTTP status</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function returns <code>HTTP_OK</code> when the file is successfully retrieved.
+
+</p>
+<h3 class="function"><a name="cupsGetJobs">cupsGetJobs</a></h3>
+<p class="description">Get the jobs from the default server.</p>
+<p class="code">
+int cupsGetJobs (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_job_t">cups_job_t</a> **jobs,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int myjobs,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int whichjobs<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>jobs</dt>
+<dd class="description">Job data</dd>
+<dt>name</dt>
+<dd class="description"><code>NULL</code> = all destinations, otherwise show jobs for mydest</dd>
+<dt>myjobs</dt>
+<dd class="description">0 = all users, 1 = mine</dd>
+<dt>whichjobs</dt>
+<dd class="description"><code>CUPS_WHICHJOBS_ALL</code>, <code>CUPS_WHICHJOBS_ACTIVE</code>, or <code>CUPS_WHICHJOBS_COMPLETED</code></dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of jobs</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">A &quot;whichjobs&quot; value of <code>CUPS_WHICHJOBS_ALL</code> returns all jobs regardless
+of state, while <code>CUPS_WHICHJOBS_ACTIVE</code> returns jobs that are
+pending, processing, or held and <code>CUPS_WHICHJOBS_COMPLETED</code> returns
+jobs that are stopped, canceled, aborted, or completed.</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.21&nbsp;</span><a name="cupsGetJobs2">cupsGetJobs2</a></h3>
+<p class="description">Get the jobs from the specified server.</p>
+<p class="code">
+int cupsGetJobs2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_job_t">cups_job_t</a> **jobs,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int myjobs,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int whichjobs<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or <code>CUPS_HTTP_DEFAULT</code></dd>
+<dt>jobs</dt>
+<dd class="description">Job data</dd>
+<dt>name</dt>
+<dd class="description"><code>NULL</code> = all destinations, otherwise show jobs for mydest</dd>
+<dt>myjobs</dt>
+<dd class="description">0 = all users, 1 = mine</dd>
+<dt>whichjobs</dt>
+<dd class="description"><code>CUPS_WHICHJOBS_ALL</code>, <code>CUPS_WHICHJOBS_ACTIVE</code>, or <code>CUPS_WHICHJOBS_COMPLETED</code></dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of jobs</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">A &quot;whichjobs&quot; value of <code>CUPS_WHICHJOBS_ALL</code> returns all jobs regardless
+of state, while <code>CUPS_WHICHJOBS_ACTIVE</code> returns jobs that are
+pending, processing, or held and <code>CUPS_WHICHJOBS_COMPLETED</code> returns
+jobs that are stopped, canceled, aborted, or completed.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsGetNamedDest">cupsGetNamedDest</a></h3>
+<p class="description">Get options for the named destination.</p>
+<p class="code">
+<a href="#cups_dest_t">cups_dest_t</a> *cupsGetNamedDest (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *instance<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or <code>CUPS_HTTP_DEFAULT</code></dd>
+<dt>name</dt>
+<dd class="description">Destination name or <code>NULL</code></dd>
+<dt>instance</dt>
+<dd class="description">Instance name or <code>NULL</code></dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Destination or <code>NULL</code></p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function is optimized for retrieving a single destination and should
+be used instead of <a href="#cupsGetDests"><code>cupsGetDests</code></a> and <a href="#cupsGetDest"><code>cupsGetDest</code></a> when you either
+know the name of the destination or want to print to the default destination.
+If <code>NULL</code> is returned, the destination does not exist or there is no
+default destination.<br>
+<br>
+If &quot;http&quot; is <code>CUPS_HTTP_DEFAULT</code>, the connection to the default print
+server will be used.<br>
+<br>
+If &quot;name&quot; is <code>NULL</code>, the default printer for the current user will be
+returned.<br>
+<br>
+The returned destination must be freed using <a href="#cupsFreeDests"><code>cupsFreeDests</code></a> with a
+&quot;num_dests&quot; value of 1.
+
+</p>
+<h3 class="function"><a name="cupsGetOption">cupsGetOption</a></h3>
+<p class="description">Get an option value.</p>
+<p class="code">
+const char *cupsGetOption (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_options,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_option_t">cups_option_t</a> *options<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>name</dt>
+<dd class="description">Name of option</dd>
+<dt>num_options</dt>
+<dd class="description">Number of options</dd>
+<dt>options</dt>
+<dd class="description">Options</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Option value or <code>NULL</code></p>
+<h3 class="function"><a name="cupsGetPPD">cupsGetPPD</a></h3>
+<p class="description">Get the PPD file for a printer on the default server.</p>
+<p class="code">
+const char *cupsGetPPD (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>name</dt>
+<dd class="description">Printer name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Filename for PPD file</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">For classes, <code>cupsGetPPD</code> returns the PPD file for the first printer
+in the class.</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.21&nbsp;</span><a name="cupsGetPPD2">cupsGetPPD2</a></h3>
+<p class="description">Get the PPD file for a printer from the specified server.</p>
+<p class="code">
+const char *cupsGetPPD2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or <code>CUPS_HTTP_DEFAULT</code></dd>
+<dt>name</dt>
+<dd class="description">Printer name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Filename for PPD file</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">For classes, <code>cupsGetPPD2</code> returns the PPD file for the first printer
+in the class.
+
+</p>
+<h3 class="function"><a name="cupsGetPPD3">cupsGetPPD3</a></h3>
+<p class="description">Get the PPD file for a printer on the specified
+server if it has changed.</p>
+<p class="code">
+http_status_t cupsGetPPD3 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;time_t *modtime,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *buffer,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t bufsize<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or <code>CUPS_HTTP_DEFAULT</code></dd>
+<dt>name</dt>
+<dd class="description">Printer name</dd>
+<dt>modtime</dt>
+<dd class="description">Modification time</dd>
+<dt>buffer</dt>
+<dd class="description">Filename buffer</dd>
+<dt>bufsize</dt>
+<dd class="description">Size of filename buffer</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">HTTP status</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The &quot;modtime&quot; parameter contains the modification time of any
 locally-cached content and is updated with the time from the PPD file on
-the server.
-<p>The &quot;buffer&quot; parameter contains the local PPD filename.  If it contains
+the server.<br>
+<br>
+The &quot;buffer&quot; parameter contains the local PPD filename.  If it contains
 the empty string, a new temporary file is created, otherwise the existing
-file will be overwritten as needed.
-<p>On success, HTTP_OK is returned for a new PPD file and HTTP_NOT_MODIFIED
-if the existing PPD file is up-to-date.  Any other status is an error.
-<h4>Syntax</h4>
-<p><tt>
-http_status_t<br>
-cupsGetPPD3(
-    http_t * http,
-    const char * name,
-    time_t * modtime,
-    char * buffer,
-    size_t bufsize);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>name</tt></td><td>Printer name</td></tr>
-<tr><td><tt>modtime</tt></td><td>Modification time</td></tr>
-<tr><td><tt>buffer</tt></td><td>Filename buffer</td></tr>
-<tr><td><tt>bufsize</tt></td><td>Size of filename buffer</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>HTTP status</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsGetPassword'>cupsGetPassword()</a></h3>
-<h4>Description</h4>
-<p>Get a password from the user.
-<p>Uses the current password callback function. Returns NULL if the
-user does not provide a password.
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-cupsGetPassword(
-    const char * prompt);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>prompt</tt></td><td>Prompt string</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Password</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;DEPRECATED&nbsp;</span><a name='cupsGetPrinters'>cupsGetPrinters()</a></h3>
-<h4>Description</h4>
-<p>Get a list of printers from the default server.
-<p>This function is deprecated - use cupsGetDests() instead.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsGetPrinters(
-    char *** printers);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>printers</tt></td><td>Printers</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of printers</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.3&nbsp;</span><a name='cupsGetServerPPD'>cupsGetServerPPD()</a></h3>
-<h4>Description</h4>
-<p>Get an available PPD file from the server.
-<p>This function returns the named PPD file from the server.  The
-list of available PPDs is provided by the IPP CUPS_GET_PPDS
-operation.
-<p>You must remove (unlink) the PPD file when you are finished with
+file will be overwritten as needed.<br>
+<br>
+On success, <code>HTTP_OK</code> is returned for a new PPD file and
+<code>HTTP_NOT_MODIFIED</code> if the existing PPD file is up-to-date.  Any other
+status is an error.<br>
+<br>
+For classes, <code>cupsGetPPD3</code> returns the PPD file for the first printer
+in the class.</p>
+<h3 class="function"><a name="cupsGetPassword">cupsGetPassword</a></h3>
+<p class="description">Get a password from the user.</p>
+<p class="code">
+const char *cupsGetPassword (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *prompt<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>prompt</dt>
+<dd class="description">Prompt string</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Password</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Uses the current password callback function. Returns <code>NULL</code> if the
+user does not provide a password.</p>
+<h3 class="function"><span class="info">&nbsp;DEPRECATED&nbsp;</span><a name="cupsGetPrinters">cupsGetPrinters</a></h3>
+<p class="description">Get a list of printers from the default server.</p>
+<p class="code">
+int cupsGetPrinters (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char ***printers<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>printers</dt>
+<dd class="description">Printers</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of printers</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function is deprecated - use <a href="#cupsGetDests"><code>cupsGetDests</code></a> instead.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.3&nbsp;</span><a name="cupsGetServerPPD">cupsGetServerPPD</a></h3>
+<p class="description">Get an available PPD file from the server.</p>
+<p class="code">
+char *cupsGetServerPPD (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or <code>CUPS_HTTP_DEFAULT</code></dd>
+<dt>name</dt>
+<dd class="description">Name of PPD file (&quot;ppd-name&quot;)</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Name of PPD file or <code>NULL</code> on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function returns the named PPD file from the server.  The
+list of available PPDs is provided by the IPP <code>CUPS_GET_PPDS</code>
+operation.<br>
+<br>
+You must remove (unlink) the PPD file when you are finished with
 it. The PPD filename is stored in a static location that will be
-overwritten on the next call to cupsGetPPD(), cupsGetPPD2(), or
-cupsGetServerPPD().
-
-
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-cupsGetServerPPD(
-    http_t * http,
-    const char * name);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>name</tt></td><td>Name of PPD file (&quot;ppd-name&quot;)</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Name of PPD file or NULL on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsLangDefault'>cupsLangDefault()</a></h3>
-<h4>Description</h4>
-<p>Return the default language.
-<h4>Syntax</h4>
-<p><tt>
-cups_lang_t *<br>
-cupsLangDefault(void);
-</tt></p>
-<h4>Arguments</h4>
-<p>None.</p>
-<h4>Returns</h4>
-<p>Language data</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsLangEncoding'>cupsLangEncoding()</a></h3>
-<h4>Description</h4>
-<p>Return the character encoding (us-ascii, etc.)
-for the given language.
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-cupsLangEncoding(
-    cups_lang_t * lang);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>lang</tt></td><td>Language data</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Character encoding</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsLangFlush'>cupsLangFlush()</a></h3>
-<h4>Description</h4>
-<p>Flush all language data out of the cache.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsLangFlush(void);
-</tt></p>
-<h4>Arguments</h4>
-<p>None.</p>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsLangFree'>cupsLangFree()</a></h3>
-<h4>Description</h4>
-<p>Free language data.
-<p>This does not actually free anything; use cupsLangFlush() for that.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsLangFree(
-    cups_lang_t * lang);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>lang</tt></td><td>Language to free</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsLangGet'>cupsLangGet()</a></h3>
-<h4>Description</h4>
-<p>Get a language.
-<h4>Syntax</h4>
-<p><tt>
-cups_lang_t *<br>
-cupsLangGet(
-    const char * language);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>language</tt></td><td>Language or locale</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Language data</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsLastError'>cupsLastError()</a></h3>
-<h4>Description</h4>
-<p>Return the last IPP status code.
-<h4>Syntax</h4>
-<p><tt>
-ipp_status_t<br>
-cupsLastError(void);
-</tt></p>
-<h4>Arguments</h4>
-<p>None.</p>
-<h4>Returns</h4>
-<p>IPP status code from last request</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cupsLastErrorString'>cupsLastErrorString()</a></h3>
-<h4>Description</h4>
-<p>Return the last IPP status-message.
-
-
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-cupsLastErrorString(void);
-</tt></p>
-<h4>Arguments</h4>
-<p>None.</p>
-<h4>Returns</h4>
-<p>status-message text from last request</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsMarkOptions'>cupsMarkOptions()</a></h3>
-<h4>Description</h4>
-<p>Mark command-line options in a PPD file.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsMarkOptions(
-    ppd_file_t * ppd,
-    int num_options,
-    <a href='#cups_option_t'>cups_option_t</a> * options);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file</td></tr>
-<tr><td><tt>num_options</tt></td><td>Number of options</td></tr>
-<tr><td><tt>options</tt></td><td>Options</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>1 if conflicting</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cupsNotifySubject'>cupsNotifySubject()</a></h3>
-<h4>Description</h4>
-<p>Return the subject for the given notification message.
-<p>The returned string must be freed by the caller using free().
-
-
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-cupsNotifySubject(
-    cups_lang_t * lang,
-    ipp_t * event);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>lang</tt></td><td>Language data</td></tr>
-<tr><td><tt>event</tt></td><td>Event data</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Subject string or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cupsNotifyText'>cupsNotifyText()</a></h3>
-<h4>Description</h4>
-<p>Return the text for the given notification message.
-<p>The returned string must be freed by the caller using free().
-
-
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-cupsNotifyText(
-    cups_lang_t * lang,
-    ipp_t * event);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>lang</tt></td><td>Language data</td></tr>
-<tr><td><tt>event</tt></td><td>Event data</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Message text or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsParseOptions'>cupsParseOptions()</a></h3>
-<h4>Description</h4>
-<p>Parse options from a command-line argument.
-<p>This function converts space-delimited name/value pairs according
+overwritten on the next call to <a href="#cupsGetPPD"><code>cupsGetPPD</code></a>, <a href="#cupsGetPPD2"><code>cupsGetPPD2</code></a>,
+or <a href="#cupsGetServerPPD"><code>cupsGetServerPPD</code></a>.
+
+</p>
+<h3 class="function"><a name="cupsLangDefault">cupsLangDefault</a></h3>
+<p class="description">Return the default language.</p>
+<p class="code">
+cups_lang_t *cupsLangDefault (void);</p>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Language data</p>
+<h3 class="function"><a name="cupsLangEncoding">cupsLangEncoding</a></h3>
+<p class="description">Return the character encoding (us-ascii, etc.)
+for the given language.</p>
+<p class="code">
+const char *cupsLangEncoding (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_lang_t *lang<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>lang</dt>
+<dd class="description">Language data</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Character encoding</p>
+<h3 class="function"><a name="cupsLangFlush">cupsLangFlush</a></h3>
+<p class="description">Flush all language data out of the cache.</p>
+<p class="code">
+void cupsLangFlush (void);</p>
+<h3 class="function"><a name="cupsLangFree">cupsLangFree</a></h3>
+<p class="description">Free language data.</p>
+<p class="code">
+void cupsLangFree (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_lang_t *lang<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>lang</dt>
+<dd class="description">Language to free</dd>
+</dl>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This does not actually free anything; use <a href="#cupsLangFlush"><code>cupsLangFlush</code></a> for that.</p>
+<h3 class="function"><a name="cupsLangGet">cupsLangGet</a></h3>
+<p class="description">Get a language.</p>
+<p class="code">
+cups_lang_t *cupsLangGet (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *language<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>language</dt>
+<dd class="description">Language or locale</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Language data</p>
+<h3 class="function"><a name="cupsLastError">cupsLastError</a></h3>
+<p class="description">Return the last IPP status code.</p>
+<p class="code">
+ipp_status_t cupsLastError (void);</p>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">IPP status code from last request</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsLastErrorString">cupsLastErrorString</a></h3>
+<p class="description">Return the last IPP status-message.</p>
+<p class="code">
+const char *cupsLastErrorString (void);</p>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">status-message text from last request</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsNotifySubject">cupsNotifySubject</a></h3>
+<p class="description">Return the subject for the given notification message.</p>
+<p class="code">
+char *cupsNotifySubject (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_lang_t *lang,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_t *event<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>lang</dt>
+<dd class="description">Language data</dd>
+<dt>event</dt>
+<dd class="description">Event data</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Subject string or <code>NULL</code></p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The returned string must be freed by the caller using free().
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsNotifyText">cupsNotifyText</a></h3>
+<p class="description">Return the text for the given notification message.</p>
+<p class="code">
+char *cupsNotifyText (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_lang_t *lang,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_t *event<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>lang</dt>
+<dd class="description">Language data</dd>
+<dt>event</dt>
+<dd class="description">Event data</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Message text or <code>NULL</code></p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The returned string must be freed by the caller using <code>free</code>.
+
+</p>
+<h3 class="function"><a name="cupsParseOptions">cupsParseOptions</a></h3>
+<p class="description">Parse options from a command-line argument.</p>
+<p class="code">
+int cupsParseOptions (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *arg,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_options,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_option_t">cups_option_t</a> **options<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>arg</dt>
+<dd class="description">Argument to parse</dd>
+<dt>num_options</dt>
+<dd class="description">Number of options</dd>
+<dt>options</dt>
+<dd class="description">Options found</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of options found</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function converts space-delimited name/value pairs according
 to the PAPI text option ABNF specification. Collection values
 (&quot;name={a=... b=... c=...}&quot;) are stored with the curley brackets
-intact - use cupsParseOptions() on the value to extract the collection
-attributes.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsParseOptions(
-    const char * arg,
-    int num_options,
-    <a href='#cups_option_t'>cups_option_t</a> ** options);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>arg</tt></td><td>Argument to parse</td></tr>
-<tr><td><tt>num_options</tt></td><td>Number of options</td></tr>
-<tr><td><tt>options</tt></td><td>Options found</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of options found</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsPrintFile'>cupsPrintFile()</a></h3>
-<h4>Description</h4>
-<p>Print a file to a printer or class on the default server.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsPrintFile(
-    const char * name,
-    const char * filename,
-    const char * title,
-    int num_options,
-    <a href='#cups_option_t'>cups_option_t</a> * options);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name</tt></td><td>Printer or class name</td></tr>
-<tr><td><tt>filename</tt></td><td>File to print</td></tr>
-<tr><td><tt>title</tt></td><td>Title of job</td></tr>
-<tr><td><tt>num_options</tt></td><td>Number of options</td></tr>
-<tr><td><tt>options</tt></td><td>Options</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Job ID</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span><a name='cupsPrintFile2'>cupsPrintFile2()</a></h3>
-<h4>Description</h4>
-<p>Print a file to a printer or class on the specified server.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsPrintFile2(
-    http_t * http,
-    const char * name,
-    const char * filename,
-    const char * title,
-    int num_options,
-    <a href='#cups_option_t'>cups_option_t</a> * options);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>name</tt></td><td>Printer or class name</td></tr>
-<tr><td><tt>filename</tt></td><td>File to print</td></tr>
-<tr><td><tt>title</tt></td><td>Title of job</td></tr>
-<tr><td><tt>num_options</tt></td><td>Number of options</td></tr>
-<tr><td><tt>options</tt></td><td>Options</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Job ID</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsPrintFiles'>cupsPrintFiles()</a></h3>
-<h4>Description</h4>
-<p>Print one or more files to a printer or class on the
-default server.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsPrintFiles(
-    const char * name,
-    int num_files,
-    const char ** files,
-    const char * title,
-    int num_options,
-    <a href='#cups_option_t'>cups_option_t</a> * options);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name</tt></td><td>Printer or class name</td></tr>
-<tr><td><tt>num_files</tt></td><td>Number of files</td></tr>
-<tr><td><tt>files</tt></td><td>File(s) to print</td></tr>
-<tr><td><tt>title</tt></td><td>Title of job</td></tr>
-<tr><td><tt>num_options</tt></td><td>Number of options</td></tr>
-<tr><td><tt>options</tt></td><td>Options</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Job ID</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span><a name='cupsPrintFiles2'>cupsPrintFiles2()</a></h3>
-<h4>Description</h4>
-<p>Print one or more files to a printer or class on the
-specified server.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsPrintFiles2(
-    http_t * http,
-    const char * name,
-    int num_files,
-    const char ** files,
-    const char * title,
-    int num_options,
-    <a href='#cups_option_t'>cups_option_t</a> * options);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>name</tt></td><td>Printer or class name</td></tr>
-<tr><td><tt>num_files</tt></td><td>Number of files</td></tr>
-<tr><td><tt>files</tt></td><td>File(s) to print</td></tr>
-<tr><td><tt>title</tt></td><td>Title of job</td></tr>
-<tr><td><tt>num_options</tt></td><td>Number of options</td></tr>
-<tr><td><tt>options</tt></td><td>Options</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Job ID</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.20&nbsp;</span><a name='cupsPutFd'>cupsPutFd()</a></h3>
-<h4>Description</h4>
-<p>Put a file on the server.
-<p>This function returns HTTP_CREATED when the file is stored successfully.
-
-
-<h4>Syntax</h4>
-<p><tt>
-http_status_t<br>
-cupsPutFd(
-    http_t * http,
-    const char * resource,
-    int fd);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection to server</td></tr>
-<tr><td><tt>resource</tt></td><td>Resource name</td></tr>
-<tr><td><tt>fd</tt></td><td>File descriptor</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>HTTP status</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.20&nbsp;</span><a name='cupsPutFile'>cupsPutFile()</a></h3>
-<h4>Description</h4>
-<p>Put a file on the server.
-<p>This function returns HTTP_CREATED when the file is stored successfully.
-
-
-<h4>Syntax</h4>
-<p><tt>
-http_status_t<br>
-cupsPutFile(
-    http_t * http,
-    const char * resource,
-    const char * filename);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection to server</td></tr>
-<tr><td><tt>resource</tt></td><td>Resource name</td></tr>
-<tr><td><tt>filename</tt></td><td>Filename</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>HTTP status</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.3&nbsp;</span><a name='cupsRemoveDest'>cupsRemoveDest()</a></h3>
-<h4>Description</h4>
-<p>Remove a destination from the destination list.
-<p>Removing a destination/instance does not delete the class or printer
+intact - use <code>cupsParseOptions</code> on the value to extract the
+collection attributes.</p>
+<h3 class="function"><a name="cupsPrintFile">cupsPrintFile</a></h3>
+<p class="description">Print a file to a printer or class on the default server.</p>
+<p class="code">
+int cupsPrintFile (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *filename,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *title,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_options,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_option_t">cups_option_t</a> *options<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>name</dt>
+<dd class="description">Printer or class name</dd>
+<dt>filename</dt>
+<dd class="description">File to print</dd>
+<dt>title</dt>
+<dd class="description">Title of job</dd>
+<dt>num_options</dt>
+<dd class="description">Number of options</dd>
+<dt>options</dt>
+<dd class="description">Options</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Job ID or 0 on error</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.21&nbsp;</span><a name="cupsPrintFile2">cupsPrintFile2</a></h3>
+<p class="description">Print a file to a printer or class on the specified
+server.</p>
+<p class="code">
+int cupsPrintFile2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *filename,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *title,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_options,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_option_t">cups_option_t</a> *options<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>name</dt>
+<dd class="description">Printer or class name</dd>
+<dt>filename</dt>
+<dd class="description">File to print</dd>
+<dt>title</dt>
+<dd class="description">Title of job</dd>
+<dt>num_options</dt>
+<dd class="description">Number of options</dd>
+<dt>options</dt>
+<dd class="description">Options</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Job ID or 0 on error</p>
+<h3 class="function"><a name="cupsPrintFiles">cupsPrintFiles</a></h3>
+<p class="description">Print one or more files to a printer or class on the
+default server.</p>
+<p class="code">
+int cupsPrintFiles (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_files,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char **files,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *title,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_options,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_option_t">cups_option_t</a> *options<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>name</dt>
+<dd class="description">Printer or class name</dd>
+<dt>num_files</dt>
+<dd class="description">Number of files</dd>
+<dt>files</dt>
+<dd class="description">File(s) to print</dd>
+<dt>title</dt>
+<dd class="description">Title of job</dd>
+<dt>num_options</dt>
+<dd class="description">Number of options</dd>
+<dt>options</dt>
+<dd class="description">Options</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Job ID or 0 on error</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.21&nbsp;</span><a name="cupsPrintFiles2">cupsPrintFiles2</a></h3>
+<p class="description">Print one or more files to a printer or class on the
+specified server.</p>
+<p class="code">
+int cupsPrintFiles2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_files,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char **files,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *title,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_options,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_option_t">cups_option_t</a> *options<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or <code>CUPS_HTTP_DEFAULT</code></dd>
+<dt>name</dt>
+<dd class="description">Printer or class name</dd>
+<dt>num_files</dt>
+<dd class="description">Number of files</dd>
+<dt>files</dt>
+<dd class="description">File(s) to print</dd>
+<dt>title</dt>
+<dd class="description">Title of job</dd>
+<dt>num_options</dt>
+<dd class="description">Number of options</dd>
+<dt>options</dt>
+<dd class="description">Options</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Job ID or 0 on error</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.20&nbsp;</span><a name="cupsPutFd">cupsPutFd</a></h3>
+<p class="description">Put a file on the server.</p>
+<p class="code">
+http_status_t cupsPutFd (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *resource,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int fd<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection to server or <code>CUPS_HTTP_DEFAULT</code></dd>
+<dt>resource</dt>
+<dd class="description">Resource name</dd>
+<dt>fd</dt>
+<dd class="description">File descriptor</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">HTTP status</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function returns <code>HTTP_CREATED</code> when the file is stored
+successfully.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.20&nbsp;</span><a name="cupsPutFile">cupsPutFile</a></h3>
+<p class="description">Put a file on the server.</p>
+<p class="code">
+http_status_t cupsPutFile (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *resource,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *filename<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection to server or <code>CUPS_HTTP_DEFAULT</code></dd>
+<dt>resource</dt>
+<dd class="description">Resource name</dd>
+<dt>filename</dt>
+<dd class="description">Filename</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">HTTP status</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function returns <code>HTTP_CREATED</code> when the file is stored
+successfully.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.3&nbsp;</span><a name="cupsRemoveDest">cupsRemoveDest</a></h3>
+<p class="description">Remove a destination from the destination list.</p>
+<p class="code">
+int cupsRemoveDest (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *instance,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_dests,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> **dests<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>name</dt>
+<dd class="description">Destination name</dd>
+<dt>instance</dt>
+<dd class="description">Instance name or <code>NULL</code></dd>
+<dt>num_dests</dt>
+<dd class="description">Number of destinations</dd>
+<dt>dests</dt>
+<dd class="description">Destinations</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New number of destinations</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Removing a destination/instance does not delete the class or printer
 queue, merely the lpoptions for that destination/instance.  Use the
-cupsSetDests() or cupsSetDests2() functions to save the new options
-for the user.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsRemoveDest(
-    const char * name,
-    const char * instance,
-    int num_dests,
-    <a href='#cups_dest_t'>cups_dest_t</a> ** dests);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name</tt></td><td>Destination name</td></tr>
-<tr><td><tt>instance</tt></td><td>Instance name or NULL</td></tr>
-<tr><td><tt>num_dests</tt></td><td>Number of destinations</td></tr>
-<tr><td><tt>dests</tt></td><td>Destinations</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New number of destinations</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cupsRemoveOption'>cupsRemoveOption()</a></h3>
-<h4>Description</h4>
-<p>Remove an option from an option array.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsRemoveOption(
-    const char * name,
-    int num_options,
-    <a href='#cups_option_t'>cups_option_t</a> ** options);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name</tt></td><td>Option name</td></tr>
-<tr><td><tt>num_options</tt></td><td>Current number of options</td></tr>
-<tr><td><tt>options</tt></td><td>Options</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New number of options</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsServer'>cupsServer()</a></h3>
-<h4>Description</h4>
-<p>Return the hostname/address of the default server.
-<p>The returned value can be a fully-qualified hostname, a numeric
-IPv4 or IPv6 address, or a domain socket pathname.
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-cupsServer(void);
-</tt></p>
-<h4>Arguments</h4>
-<p>None.</p>
-<h4>Returns</h4>
-<p>Server name</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.3&nbsp;</span><a name='cupsSetDefaultDest'>cupsSetDefaultDest()</a></h3>
-<h4>Description</h4>
-<p>Set the default destination.
-
-
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsSetDefaultDest(
-    const char * name,
-    const char * instance,
-    int num_dests,
-    <a href='#cups_dest_t'>cups_dest_t</a> * dests);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name</tt></td><td>Destination name</td></tr>
-<tr><td><tt>instance</tt></td><td>Instance name or NULL</td></tr>
-<tr><td><tt>num_dests</tt></td><td>Number of destinations</td></tr>
-<tr><td><tt>dests</tt></td><td>Destinations</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsSetDests'>cupsSetDests()</a></h3>
-<h4>Description</h4>
-<p>Save the list of destinations for the default server.
-<p>This function saves the destinations to /etc/cups/lpoptions when run
-as root and ~/.cups/lpoptions when run as a normal user.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsSetDests(
-    int num_dests,
-    <a href='#cups_dest_t'>cups_dest_t</a> * dests);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>num_dests</tt></td><td>Number of destinations</td></tr>
-<tr><td><tt>dests</tt></td><td>Destinations</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span><a name='cupsSetDests2'>cupsSetDests2()</a></h3>
-<h4>Description</h4>
-<p>Save the list of destinations for the specified server.
-<p>This function saves the destinations to /etc/cups/lpoptions when run
+<a href="#cupsSetDests"><code>cupsSetDests</code></a> or <a href="#cupsSetDests2"><code>cupsSetDests2</code></a> functions to save the new
+options for the user.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsRemoveOption">cupsRemoveOption</a></h3>
+<p class="description">Remove an option from an option array.</p>
+<p class="code">
+int cupsRemoveOption (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_options,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_option_t">cups_option_t</a> **options<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>name</dt>
+<dd class="description">Option name</dd>
+<dt>num_options</dt>
+<dd class="description">Current number of options</dd>
+<dt>options</dt>
+<dd class="description">Options</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New number of options</p>
+<h3 class="function"><a name="cupsServer">cupsServer</a></h3>
+<p class="description">Return the hostname/address of the default server.</p>
+<p class="code">
+const char *cupsServer (void);</p>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Server name</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The returned value can be a fully-qualified hostname, a numeric
+IPv4 or IPv6 address, or a domain socket pathname.</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.3&nbsp;</span><a name="cupsSetDefaultDest">cupsSetDefaultDest</a></h3>
+<p class="description">Set the default destination.</p>
+<p class="code">
+void cupsSetDefaultDest (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *instance,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_dests,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> *dests<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>name</dt>
+<dd class="description">Destination name</dd>
+<dt>instance</dt>
+<dd class="description">Instance name or <code>NULL</code></dd>
+<dt>num_dests</dt>
+<dd class="description">Number of destinations</dd>
+<dt>dests</dt>
+<dd class="description">Destinations</dd>
+</dl>
+<h3 class="function"><a name="cupsSetDests">cupsSetDests</a></h3>
+<p class="description">Save the list of destinations for the default server.</p>
+<p class="code">
+void cupsSetDests (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_dests,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> *dests<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>num_dests</dt>
+<dd class="description">Number of destinations</dd>
+<dt>dests</dt>
+<dd class="description">Destinations</dd>
+</dl>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function saves the destinations to /etc/cups/lpoptions when run
+as root and ~/.cups/lpoptions when run as a normal user.</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.21&nbsp;</span><a name="cupsSetDests2">cupsSetDests2</a></h3>
+<p class="description">Save the list of destinations for the specified server.</p>
+<p class="code">
+int cupsSetDests2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_dests,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> *dests<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or <code>CUPS_HTTP_DEFAULT</code></dd>
+<dt>num_dests</dt>
+<dd class="description">Number of destinations</dd>
+<dt>dests</dt>
+<dd class="description">Destinations</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, -1 on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function saves the destinations to /etc/cups/lpoptions when run
 as root and ~/.cups/lpoptions when run as a normal user.
 
+</p>
+<h3 class="function"><a name="cupsSetEncryption">cupsSetEncryption</a></h3>
+<p class="description">Set the encryption preference.</p>
+<p class="code">
+void cupsSetEncryption (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_encryption_t e<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>e</dt>
+<dd class="description">New encryption preference</dd>
+</dl>
+<h3 class="function"><a name="cupsSetPasswordCB">cupsSetPasswordCB</a></h3>
+<p class="description">Set the password callback for CUPS.</p>
+<p class="code">
+void cupsSetPasswordCB (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_password_cb_t">cups_password_cb_t</a> cb<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>cb</dt>
+<dd class="description">Callback function</dd>
+</dl>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Pass <code>NULL</code> to restore the default (console) password callback.</p>
+<h3 class="function"><a name="cupsSetServer">cupsSetServer</a></h3>
+<p class="description">Set the default server name.</p>
+<p class="code">
+void cupsSetServer (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *server<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>server</dt>
+<dd class="description">Server name</dd>
+</dl>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The &quot;server&quot; string can be a fully-qualified hostname, a numeric
+IPv4 or IPv6 address, or a domain socket pathname. Pass <code>NULL</code> to
+restore the default server name.</p>
+<h3 class="function"><a name="cupsSetUser">cupsSetUser</a></h3>
+<p class="description">Set the default user name.</p>
+<p class="code">
+void cupsSetUser (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *user<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>user</dt>
+<dd class="description">User name</dd>
+</dl>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Pass <code>NULL</code> to restore the default user name.</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsStartDocument">cupsStartDocument</a></h3>
+<p class="description">Add a document to a job created with cupsCreateJob().</p>
+<p class="code">
+http_status_t cupsStartDocument (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int job_id,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *docname,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *format,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int last_document<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or <code>CUPS_HTTP_DEFAULT</code></dd>
+<dt>name</dt>
+<dd class="description">Printer or class name</dd>
+<dt>job_id</dt>
+<dd class="description">Job ID from <a href="#cupsCreateJob"><code>cupsCreateJob</code></a></dd>
+<dt>docname</dt>
+<dd class="description">Name of document</dd>
+<dt>format</dt>
+<dd class="description">MIME type or <code>CUPS_FORMAT_foo</code></dd>
+<dt>last_document</dt>
+<dd class="description">1 for last document in job, 0 otherwise</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">HTTP status of request</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Use <a href="#cupsWriteRequestData"><code>cupsWriteRequestData</code></a> to write data for the document and
+<a href="#cupsFinishDocument"><code>cupsFinishDocument</code></a> to finish the document and get the submission status.<br>
+<br>
+The MIME type constants <code>CUPS_FORMAT_AUTO</code>, <code>CUPS_FORMAT_PDF</code>,
+<code>CUPS_FORMAT_POSTSCRIPT</code>, <code>CUPS_FORMAT_RAW</code>, and
+<code>CUPS_FORMAT_TEXT</code> are provided for the &quot;format&quot; argument, although
+any supported MIME type string can be supplied.
 
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsSetDests2(
-    http_t * http,
-    int num_dests,
-    <a href='#cups_dest_t'>cups_dest_t</a> * dests);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>num_dests</tt></td><td>Number of destinations</td></tr>
-<tr><td><tt>dests</tt></td><td>Destinations</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, -1 on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsSetEncryption'>cupsSetEncryption()</a></h3>
-<h4>Description</h4>
-<p>Set the encryption preference.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsSetEncryption(
-    http_encryption_t e);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>e</tt></td><td>New encryption preference</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsSetPasswordCB'>cupsSetPasswordCB()</a></h3>
-<h4>Description</h4>
-<p>Set the password callback for CUPS.
-<p>Pass NULL to restore the default (console) password callback.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsSetPasswordCB(
-    <a href='#cups_password_cb_t'>cups_password_cb_t</a> cb);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>cb</tt></td><td>Callback function</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsSetServer'>cupsSetServer()</a></h3>
-<h4>Description</h4>
-<p>Set the default server name.
-<p>The &quot;server&quot; string can be a fully-qualified hostname, a numeric
-IPv4 or IPv6 address, or a domain socket pathname. Pass NULL to
-restore the default server name.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsSetServer(
-    const char * server);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>server</tt></td><td>Server name</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsSetUser'>cupsSetUser()</a></h3>
-<h4>Description</h4>
-<p>Set the default user name.
-<p>Pass NULL to restore the default user name.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsSetUser(
-    const char * user);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>user</tt></td><td>User name</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsTempFd'>cupsTempFd()</a></h3>
-<h4>Description</h4>
-<p>Creates a temporary file.
-<p>The temporary filename is returned in the filename buffer.
-The temporary file is opened for reading and writing.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsTempFd(
-    char * filename,
-    int len);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>filename</tt></td><td>Pointer to buffer</td></tr>
-<tr><td><tt>len</tt></td><td>Size of buffer</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New file descriptor or -1 on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;DEPRECATED&nbsp;</span><a name='cupsTempFile'>cupsTempFile()</a></h3>
-<h4>Description</h4>
-<p>Generates a temporary filename.
-<p>The temporary filename is returned in the filename buffer.
-This function is deprecated - use cupsTempFd() or cupsTempFile2()
-instead.
-
-
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-cupsTempFile(
-    char * filename,
-    int len);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>filename</tt></td><td>Pointer to buffer</td></tr>
-<tr><td><tt>len</tt></td><td>Size of buffer</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Filename or NULL on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cupsTempFile2'>cupsTempFile2()</a></h3>
-<h4>Description</h4>
-<p>Creates a temporary CUPS file.
-<p>The temporary filename is returned in the filename buffer.
-The temporary file is opened for writing.
+</p>
+<h3 class="function"><a name="cupsTempFd">cupsTempFd</a></h3>
+<p class="description">Creates a temporary file.</p>
+<p class="code">
+int cupsTempFd (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *filename,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int len<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>filename</dt>
+<dd class="description">Pointer to buffer</dd>
+<dt>len</dt>
+<dd class="description">Size of buffer</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New file descriptor or -1 on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The temporary filename is returned in the filename buffer.
+The temporary file is opened for reading and writing.</p>
+<h3 class="function"><span class="info">&nbsp;DEPRECATED&nbsp;</span><a name="cupsTempFile">cupsTempFile</a></h3>
+<p class="description">Generates a temporary filename.</p>
+<p class="code">
+char *cupsTempFile (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *filename,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int len<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>filename</dt>
+<dd class="description">Pointer to buffer</dd>
+<dt>len</dt>
+<dd class="description">Size of buffer</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Filename or NULL on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The temporary filename is returned in the filename buffer.
+This function is deprecated - use <a href="#cupsTempFd"><code>cupsTempFd</code></a> or
+<a href="#cupsTempFile2"><code>cupsTempFile2</code></a> instead.
 
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsTempFile2">cupsTempFile2</a></h3>
+<p class="description">Creates a temporary CUPS file.</p>
+<p class="code">
+cups_file_t *cupsTempFile2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *filename,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int len<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>filename</dt>
+<dd class="description">Pointer to buffer</dd>
+<dt>len</dt>
+<dd class="description">Size of buffer</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">CUPS file or NULL on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The temporary filename is returned in the filename buffer.
+The temporary file is opened for writing.
 
-<h4>Syntax</h4>
-<p><tt>
-cups_file_t *<br>
-cupsTempFile2(
-    char * filename,
-    int len);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>filename</tt></td><td>Pointer to buffer</td></tr>
-<tr><td><tt>len</tt></td><td>Size of buffer</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>CUPS file or NULL on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsUser'>cupsUser()</a></h3>
-<h4>Description</h4>
-<p>Return the current user's name.
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-cupsUser(void);
-</tt></p>
-<h4>Arguments</h4>
-<p>None.</p>
-<h4>Returns</h4>
-<p>User name</p>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='STRUCTURES'>Structures</a></h2>
-<ul>
-       <li><a href='#cups_dest_s'><tt>cups_dest_s</tt></a> </li>
-       <li><a href='#cups_job_s'><tt>cups_job_s</tt></a> </li>
-       <li><a href='#cups_option_s'><tt>cups_option_s</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_dest_s'>cups_dest_s</a></h3>
-<h4>Description</h4>
-<p>Destination
-<h4>Definition</h4>
-<p><tt>
-struct cups_dest_s<br>
-{<br>
-&nbsp;&nbsp;char *name, * instance;<br>
-&nbsp;&nbsp;int is_default;<br>
-&nbsp;&nbsp;int num_options;<br>
-&nbsp;&nbsp;<a href='#cups_option_t'>cups_option_t</a> * options;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>instance</tt> </td><td>Local instance name or NULL
-</td></tr>
-<tr><td><tt>is_default</tt> </td><td>Is this printer the default?
-</td></tr>
-<tr><td><tt>num_options</tt> </td><td>Number of options
-</td></tr>
-<tr><td><tt>options</tt> </td><td>Options
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_job_s'>cups_job_s</a></h3>
-<h4>Description</h4>
-<p>Job
-<h4>Definition</h4>
-<p><tt>
-struct cups_job_s<br>
-{<br>
-&nbsp;&nbsp;time_t completed_time;<br>
-&nbsp;&nbsp;time_t creation_time;<br>
-&nbsp;&nbsp;char * dest;<br>
-&nbsp;&nbsp;char * format;<br>
-&nbsp;&nbsp;int id;<br>
-&nbsp;&nbsp;int priority;<br>
-&nbsp;&nbsp;time_t processing_time;<br>
-&nbsp;&nbsp;int size;<br>
-&nbsp;&nbsp;ipp_jstate_t state;<br>
-&nbsp;&nbsp;char * title;<br>
-&nbsp;&nbsp;char * user;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>completed_time</tt> </td><td>Time the job was completed
-</td></tr>
-<tr><td><tt>creation_time</tt> </td><td>Time the job was created
-</td></tr>
-<tr><td><tt>dest</tt> </td><td>Printer or class name
-</td></tr>
-<tr><td><tt>format</tt> </td><td>Document format
-</td></tr>
-<tr><td><tt>id</tt> </td><td>The job ID
-</td></tr>
-<tr><td><tt>priority</tt> </td><td>Priority (1-100)
-</td></tr>
-<tr><td><tt>processing_time</tt> </td><td>Time the job was processed
-</td></tr>
-<tr><td><tt>size</tt> </td><td>Size in kilobytes
-</td></tr>
-<tr><td><tt>state</tt> </td><td>Job state
-</td></tr>
-<tr><td><tt>title</tt> </td><td>Title/job name
-</td></tr>
-<tr><td><tt>user</tt> </td><td>User the submitted the job
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_option_s'>cups_option_s</a></h3>
-<h4>Description</h4>
-<p>Printer Options
-<h4>Definition</h4>
-<p><tt>
-struct cups_option_s<br>
-{<br>
-&nbsp;&nbsp;char * name;<br>
-&nbsp;&nbsp;char * value;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name</tt> </td><td>Name of option
-</td></tr>
-<tr><td><tt>value</tt> </td><td>Value of option
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='TYPES'>Types</a></h2>
-<ul>
-       <li><a href='#cups_dest_t'><tt>cups_dest_t</tt></a> </li>
-       <li><a href='#cups_job_t'><tt>cups_job_t</tt></a> </li>
-       <li><a href='#cups_option_t'><tt>cups_option_t</tt></a> </li>
-       <li><a href='#cups_password_cb_t'><tt>cups_password_cb_t</tt></a> </li>
-       <li><a href='#cups_ptype_t'><tt>cups_ptype_t</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_dest_t'>cups_dest_t</a></h3>
-<h4>Description</h4>
-<p>Destination
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#cups_dest_s'>cups_dest_s</a> cups_dest_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_job_t'>cups_job_t</a></h3>
-<h4>Description</h4>
-<p>Job
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#cups_job_s'>cups_job_s</a> cups_job_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_option_t'>cups_option_t</a></h3>
-<h4>Description</h4>
-<p>Printer Options
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#cups_option_s'>cups_option_s</a> cups_option_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_password_cb_t'>cups_password_cb_t</a></h3>
-<h4>Description</h4>
-<p>Password callback
-<h4>Definition</h4>
-<p><tt>
-typedef const char * (*cups_password_cb_t)(const char *);
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_ptype_t'>cups_ptype_t</a></h3>
-<h4>Description</h4>
-<p>Printer Type/Capability Bits
-<h4>Definition</h4>
-<p><tt>
+</p>
+<h3 class="function"><a name="cupsUser">cupsUser</a></h3>
+<p class="description">Return the current user's name.</p>
+<p class="code">
+const char *cupsUser (void);</p>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">User name</p>
+<h2 class="title"><a name="TYPES">Data Types</a></h2>
+<h3 class="typedef"><a name="cups_dest_t">cups_dest_t</a></h3>
+<p class="description">Destination</p>
+<p class="code">
+typedef struct <a href="#cups_dest_s">cups_dest_s</a> cups_dest_t;
+</p>
+<h3 class="typedef"><a name="cups_job_t">cups_job_t</a></h3>
+<p class="description">Job</p>
+<p class="code">
+typedef struct <a href="#cups_job_s">cups_job_s</a> cups_job_t;
+</p>
+<h3 class="typedef"><a name="cups_option_t">cups_option_t</a></h3>
+<p class="description">Printer Options</p>
+<p class="code">
+typedef struct <a href="#cups_option_s">cups_option_s</a> cups_option_t;
+</p>
+<h3 class="typedef"><a name="cups_password_cb_t">cups_password_cb_t</a></h3>
+<p class="description">Password callback</p>
+<p class="code">
+typedef const char *(*cups_password_cb_t)(const char *);
+</p>
+<h3 class="typedef"><a name="cups_ptype_t">cups_ptype_t</a></h3>
+<p class="description">Printer type/capability bits</p>
+<p class="code">
 typedef unsigned cups_ptype_t;
-</tt></p>
+</p>
+<h2 class="title"><a name="STRUCTURES">Structures</a></h2>
+<h3 class="struct"><a name="cups_dest_s">cups_dest_s</a></h3>
+<p class="description">Destination</p>
+<p class="code">struct cups_dest_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *name, *instance;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int is_default;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_options;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_option_t">cups_option_t</a> *options;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>instance </dt>
+<dd class="description">Local instance name or NULL</dd>
+<dt>is_default </dt>
+<dd class="description">Is this printer the default?</dd>
+<dt>num_options </dt>
+<dd class="description">Number of options</dd>
+<dt>options </dt>
+<dd class="description">Options</dd>
+</dl>
+<h3 class="struct"><a name="cups_job_s">cups_job_s</a></h3>
+<p class="description">Job</p>
+<p class="code">struct cups_job_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;time_t completed_time;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;time_t creation_time;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *dest;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *format;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int id;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int priority;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;time_t processing_time;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int size;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_jstate_t state;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *title;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *user;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>completed_time </dt>
+<dd class="description">Time the job was completed</dd>
+<dt>creation_time </dt>
+<dd class="description">Time the job was created</dd>
+<dt>dest </dt>
+<dd class="description">Printer or class name</dd>
+<dt>format </dt>
+<dd class="description">Document format</dd>
+<dt>id </dt>
+<dd class="description">The job ID</dd>
+<dt>priority </dt>
+<dd class="description">Priority (1-100)</dd>
+<dt>processing_time </dt>
+<dd class="description">Time the job was processed</dd>
+<dt>size </dt>
+<dd class="description">Size in kilobytes</dd>
+<dt>state </dt>
+<dd class="description">Job state</dd>
+<dt>title </dt>
+<dd class="description">Title/job name</dd>
+<dt>user </dt>
+<dd class="description">User the submitted the job</dd>
+</dl>
+<h3 class="struct"><a name="cups_option_s">cups_option_s</a></h3>
+<p class="description">Printer Options</p>
+<p class="code">struct cups_option_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *name;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *value;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>name </dt>
+<dd class="description">Name of option</dd>
+<dt>value </dt>
+<dd class="description">Value of option</dd>
+</dl>
+<h2 class="title"><a name="ENUMERATIONS">Constants</a></h2>
+<h3 class="enumeration"><a name="cups_ptype_e">cups_ptype_e</a></h3>
+<p class="description">Printer type/capability bit constants</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_PRINTER_AUTHENTICATED <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Printer requires authentication </dd>
+<dt>CUPS_PRINTER_BIND </dt>
+<dd class="description">Can bind output</dd>
+<dt>CUPS_PRINTER_BW </dt>
+<dd class="description">Can do B&amp;W printing</dd>
+<dt>CUPS_PRINTER_CLASS </dt>
+<dd class="description">Printer class</dd>
+<dt>CUPS_PRINTER_COLLATE </dt>
+<dd class="description">Can collage copies</dd>
+<dt>CUPS_PRINTER_COLOR </dt>
+<dd class="description">Can do color printing</dd>
+<dt>CUPS_PRINTER_COMMANDS <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Printer supports maintenance commands </dd>
+<dt>CUPS_PRINTER_COPIES </dt>
+<dd class="description">Can do copies</dd>
+<dt>CUPS_PRINTER_COVER </dt>
+<dd class="description">Can cover output</dd>
+<dt>CUPS_PRINTER_DEFAULT </dt>
+<dd class="description">Default printer on network</dd>
+<dt>CUPS_PRINTER_DELETE <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Delete printer </dd>
+<dt>CUPS_PRINTER_DISCOVERED <span class="info">&nbsp;CUPS 1.3&nbsp;</span></dt>
+<dd class="description">Printer was automatically discovered and added </dd>
+<dt>CUPS_PRINTER_DUPLEX </dt>
+<dd class="description">Can do duplexing</dd>
+<dt>CUPS_PRINTER_FAX </dt>
+<dd class="description">Fax queue</dd>
+<dt>CUPS_PRINTER_IMPLICIT </dt>
+<dd class="description">Implicit class</dd>
+<dt>CUPS_PRINTER_LARGE </dt>
+<dd class="description">Can do D/E/A1/A0</dd>
+<dt>CUPS_PRINTER_LOCAL </dt>
+<dd class="description">Local printer or class</dd>
+<dt>CUPS_PRINTER_MEDIUM </dt>
+<dd class="description">Can do Tabloid/B/C/A3/A2</dd>
+<dt>CUPS_PRINTER_NOT_SHARED <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Printer is not shared </dd>
+<dt>CUPS_PRINTER_PUNCH </dt>
+<dd class="description">Can punch output</dd>
+<dt>CUPS_PRINTER_REJECTING </dt>
+<dd class="description">Printer is rejecting jobs</dd>
+<dt>CUPS_PRINTER_REMOTE </dt>
+<dd class="description">Remote printer or class</dd>
+<dt>CUPS_PRINTER_SMALL </dt>
+<dd class="description">Can do Letter/Legal/A4</dd>
+<dt>CUPS_PRINTER_SORT </dt>
+<dd class="description">Can sort output</dd>
+<dt>CUPS_PRINTER_STAPLE </dt>
+<dd class="description">Can staple output</dd>
+<dt>CUPS_PRINTER_VARIABLE </dt>
+<dd class="description">Can do variable sizes</dd>
+</dl>
+</div>
 </body>
 </html>
index b4c6c43ad7f423f592fe40564a771c0e24dff3e7..8c35624ce613d1d245aa25322fa83eed26bb9296 100644 (file)
 <html>
 <!-- SECTION: Programming -->
 <head>
-       <title>File and Directory APIs</title>
-       <meta name='keywords' content='Programming'>
-       <meta name='creator' content='Mini-XML v2.4'>
-       <style type='text/css'><!--
-       h1, h2, h3, p { font-family: sans-serif; text-align: justify; }
-       tt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }
-       pre { font-weight: bold; color: #7f0000; margin-left: 2em; }
-       span.info { background: #000000; border: solid thin #000000; color: #ffffff; font-size: 80%; font-style: italic; font-weight: bold; white-space: nowrap; }
-       h3 span.info { float: right; font-size: 100%; }
-       h1.title, h2.title, h3.title { border-bottom: solid 2px #000000; }
-       --></style>
+<title>File and Directory APIs</title>
+<meta name="keywords" content="Programming">
+<meta name="creator" content="Mini-XML v2.5">
+<style type="text/css"><!--
+BODY {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+H1, H2, H3, H4, H5, H6, P, TD, TH {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+KBD {
+  font-family: monaco, courier, monospace;
+  font-weight: bold;
+}
+
+PRE {
+  font-family: monaco, courier, monospace;
+}
+
+PRE.command {
+  margin-left: 36pt;
+}
+
+PRE.example {
+  background: #eeeeee;
+  border: dotted thin #999999;
+  margin-left: 36pt;
+  padding: 10px;
+}
+
+PRE.command EM, PRE.example EM {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+P.command {
+  font-family: monaco, courier, monospace;
+  margin-left: 36pt;
+}
+
+P.formula {
+  font-style: italic;
+  margin-left: 36pt;
+}
+
+BLOCKQUOTE {
+  background: #cccccc;
+  border: solid thin #999999;
+  padding: 10pt;
+}
+
+A:link, A:visited {
+  text-decoration: none;
+  font-weight: bold;
+}
+
+A:link:hover, A:visited:hover, A:active {
+  text-decoration: underline;
+  font-weight: bold;
+}
+
+SUB, SUP {
+  font-size: 50%;
+}
+
+DIV.table TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.table CAPTION {
+  caption-side: top;
+  font-size: 120%;
+  font-style: italic;
+  font-weight: bold;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.table TABLE TD {
+  border: solid thin #cccccc;
+  padding-top: 5pt;
+}
+
+DIV.table TABLE TH {
+  background: #cccccc;
+  border: none;
+  border-bottom: solid thin #999999;
+}
+
+DIV.figure TABLE {
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.figure CAPTION {
+  caption-side: bottom;
+  font-size: 120%;
+  font-style: italic;
+  font-weight: bold;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+TH.label {
+  padding-top: 5pt;
+  text-align: right;
+  vertical-align: top;
+}
+
+HR {
+  border: solid thin;
+}
+
+SPAN.info {
+  background: #000000;
+  border: thin solid #000000;
+  color: #ffffff;
+  font-size: 80%;
+  font-style: italic;
+  font-weight: bold;
+  white-space: nowrap;
+}
+
+H2 SPAN.info, H3 SPAN.info, H4 SPAN.info {
+  float: right;
+  font-size: 100%;
+}
+
+H2.title, H3.title {
+  border-bottom: solid 2pt #000000;
+}
+
+DT {
+  margin-left: 36pt;
+  margin-top: 12pt;
+}
+
+DD {
+  margin-left: 54pt;
+}
+
+DL.category DT {
+  font-weight: bold;
+}
+
+P.summary {
+  margin-left: 36pt;
+  font-family: monaco, courier, monospace;
+}
+
+SPAN.message {
+  font-style: italic;
+  font-size: smaller;
+}
+
+DIV.summary TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin: 10px;
+}
+
+DIV.summary TABLE TD, DIV.summary TABLE TH {
+  border: solid thin #999999;
+  padding: 5px;
+  text-align: left;
+  vertical-align: top;
+}
+
+DIV.summary TABLE THEAD TH {
+  background: #eeeeee;
+}
+
+/* API documentation styles... */
+div.body h1 {
+  margin: 0;
+}
+div.body h2 {
+  margin-top: 1.5em;
+}
+div.body h3, div.body h4, div.body h5 {
+  margin-bottom: 0.5em;
+  margin-top: 1.5em;
+}
+.class, .enumeration, .function, .struct, .typedef, .union {
+  border-bottom: solid thin #999999;
+  margin-bottom: 0;
+  margin-top: 2em;
+}
+.description {
+  margin-top: 0.5em;
+}
+code, p.code, pre, ul.code li {
+  font-family: monaco, courier, monospace;
+  font-size: 90%;
+}
+ul.code, ul.contents, ul.subcontents {
+  list-style-type: none;
+  margin: 0;
+  padding-left: 0;
+}
+ul.code li {
+  margin: 0;
+}
+ul.contents > li {
+  margin-top: 1em;
+}
+ul.contents li ul.code, ul.contents li ul.subcontents {
+  padding-left: 2em;
+}
+div.body dl {
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dt {
+  font-style: italic;
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dd {
+  margin-bottom: 0.5em;
+}
+
+/* This is just for the HTML files generated with the framedhelp target */
+div.contents {
+  background: #e8e8e8;
+  border: solid thin black;
+  padding: 10px;
+}
+div.contents h1 {
+  font-size: 110%;
+}
+div.contents h2 {
+  font-size: 100%;
+}
+div.contents ul.contents {
+  font-size: 80%;
+}
+--></style>
 </head>
 <body>
+<div class='body'>
+<!--
+  "$Id: api-filedir.header 7279 2008-01-31 01:50:44Z mike $"
+
+  File and Directory API header for the Common UNIX Printing System (CUPS).
+
+  Copyright 2008 by Apple Inc.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">File and Directory APIs</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+       <th>Headers</th>
+       <th>cups/file.h<br>
+       cups/dir.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <th>Library</th>
+       <td>-lcups</td>
+</tr>
+<tr>
+       <th>See Also</th>
+       <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
+       Programming: <a href='api-cups.html' target='_top'>CUPS API</a></td>
+</tr>
+</tbody>
+</table></div>
+<h2 class="title">Contents</h2>
+<ul class="contents">
+</li>
+<li><a href="#OVERVIEW">Overview</a></li>
+<li><a href="#FUNCTIONS">Functions</a><ul class="code">
+<li><a href="#cupsDirClose" title="Close a directory.">cupsDirClose</a></li>
+<li><a href="#cupsDirOpen" title="Open a directory.">cupsDirOpen</a></li>
+<li><a href="#cupsDirRead" title="Read the next directory entry.">cupsDirRead</a></li>
+<li><a href="#cupsDirRewind" title="Rewind to the start of the directory.">cupsDirRewind</a></li>
+<li><a href="#cupsFileClose" title="Close a CUPS file.">cupsFileClose</a></li>
+<li><a href="#cupsFileCompression" title="Return whether a file is compressed.">cupsFileCompression</a></li>
+<li><a href="#cupsFileEOF" title="Return the end-of-file status.">cupsFileEOF</a></li>
+<li><a href="#cupsFileFind" title="Find a file using the specified path.">cupsFileFind</a></li>
+<li><a href="#cupsFileFlush" title="Flush pending output.">cupsFileFlush</a></li>
+<li><a href="#cupsFileGetChar" title="Get a single character from a file.">cupsFileGetChar</a></li>
+<li><a href="#cupsFileGetConf" title="Get a line from a configuration file...">cupsFileGetConf</a></li>
+<li><a href="#cupsFileGetLine" title="Get a CR and/or LF-terminated line that may
+contain binary data.">cupsFileGetLine</a></li>
+<li><a href="#cupsFileGets" title="Get a CR and/or LF-terminated line.">cupsFileGets</a></li>
+<li><a href="#cupsFileLock" title="Temporarily lock access to a file.">cupsFileLock</a></li>
+<li><a href="#cupsFileNumber" title="Return the file descriptor associated with a CUPS file.">cupsFileNumber</a></li>
+<li><a href="#cupsFileOpen" title="Open a CUPS file.">cupsFileOpen</a></li>
+<li><a href="#cupsFileOpenFd" title="Open a CUPS file using a file descriptor.">cupsFileOpenFd</a></li>
+<li><a href="#cupsFilePeekChar" title="Peek at the next character from a file.">cupsFilePeekChar</a></li>
+<li><a href="#cupsFilePrintf" title="Write a formatted string.">cupsFilePrintf</a></li>
+<li><a href="#cupsFilePutChar" title="Write a character.">cupsFilePutChar</a></li>
+<li><a href="#cupsFilePuts" title="Write a string.">cupsFilePuts</a></li>
+<li><a href="#cupsFileRead" title="Read from a file.">cupsFileRead</a></li>
+<li><a href="#cupsFileRewind" title="Set the current file position to the beginning of the
+file.">cupsFileRewind</a></li>
+<li><a href="#cupsFileSeek" title="Seek in a file.">cupsFileSeek</a></li>
+<li><a href="#cupsFileStderr" title="Return a CUPS file associated with stderr.">cupsFileStderr</a></li>
+<li><a href="#cupsFileStdin" title="Return a CUPS file associated with stdin.">cupsFileStdin</a></li>
+<li><a href="#cupsFileStdout" title="Return a CUPS file associated with stdout.">cupsFileStdout</a></li>
+<li><a href="#cupsFileTell" title="Return the current file position.">cupsFileTell</a></li>
+<li><a href="#cupsFileUnlock" title="Unlock access to a file.">cupsFileUnlock</a></li>
+<li><a href="#cupsFileWrite" title="Write to a file.">cupsFileWrite</a></li>
+</ul>
+<li><a href="#TYPES">Data Types</a><ul class="code">
+       <li><a href="#cups_dentry_t" title="Directory entry type">cups_dentry_t</a></li>
+       <li><a href="#cups_dir_t" title="Directory type">cups_dir_t</a></li>
+       <li><a href="#cups_file_t" title="CUPS file type">cups_file_t</a></li>
+</ul></li>
+<li><a href="#STRUCTURES">Structures</a><ul class="code">
+       <li><a href="#cups_dentry_s" title="Directory entry type">cups_dentry_s</a></li>
+</ul></li>
+</ul>
 <!--
-  "$Id: api-filedir.shtml 6649 2007-07-11 21:46:42Z mike $"
+  "$Id: api-filedir.shtml 7279 2008-01-31 01:50:44Z mike $"
 
   File and directory API introduction for the Common UNIX Printing System (CUPS).
 
-  Copyright 2007 by Apple Inc.
+  Copyright 2007-2008 by Apple Inc.
   Copyright 1997-2005 by Easy Software Products, all rights reserved.
 
   These coded instructions, statements, and computer programs are the
   file is missing or damaged, see the license at "http://www.cups.org/".
 -->
 
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name="OVERVIEW">Overview</a></h2>
 
 <p>The CUPS file and directory APIs provide portable interfaces
 for manipulating files and listing files and directories. Unlike
-stdio <tt>FILE</tt> streams, the <tt>cupsFile</tt> functions
+stdio <code>FILE</code> streams, the <code>cupsFile</code> functions
 allow you to open more than 256 files at any given time. They
 also manage the platform-specific details of locking, large file
 support, line endings (CR, LF, or CR LF), and reading and writing
 files using Flate ("gzip") compression. Finally, you can also
 connect, read from, and write to network connections using the
-<tt>cupsFile</tt> functions.</p>
+<code>cupsFile</code> functions.</p>
 
-<p>The <tt>cupsDir</tt> functions manage the platform-specific
+<p>The <code>cupsDir</code> functions manage the platform-specific
 details of directory access/listing and provide a convenient way
 to get both a list of files and the information (permissions,
 size, timestamp, etc.) for each of those files.</p>
+<h2 class="title"><a name="FUNCTIONS">Functions</a></h2>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsDirClose">cupsDirClose</a></h3>
+<p class="description">Close a directory.</p>
+<p class="code">
+void cupsDirClose (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dir_t">cups_dir_t</a> *dp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>dp</dt>
+<dd class="description">Directory pointer</dd>
+</dl>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsDirOpen">cupsDirOpen</a></h3>
+<p class="description">Open a directory.</p>
+<p class="code">
+<a href="#cups_dir_t">cups_dir_t</a> *cupsDirOpen (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *directory<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>directory</dt>
+<dd class="description">Directory name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Directory pointer or <code>NULL</code> if the directory could not be opened.</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsDirRead">cupsDirRead</a></h3>
+<p class="description">Read the next directory entry.</p>
+<p class="code">
+<a href="#cups_dentry_t">cups_dentry_t</a> *cupsDirRead (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dir_t">cups_dir_t</a> *dp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>dp</dt>
+<dd class="description">Directory pointer</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Directory entry or <code>NULL</code> when there are no more</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsDirRewind">cupsDirRewind</a></h3>
+<p class="description">Rewind to the start of the directory.</p>
+<p class="code">
+void cupsDirRewind (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dir_t">cups_dir_t</a> *dp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>dp</dt>
+<dd class="description">Directory pointer</dd>
+</dl>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileClose">cupsFileClose</a></h3>
+<p class="description">Close a CUPS file.</p>
+<p class="code">
+int cupsFileClose (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, -1 on error</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileCompression">cupsFileCompression</a></h3>
+<p class="description">Return whether a file is compressed.</p>
+<p class="code">
+int cupsFileCompression (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description"><code>CUPS_FILE_NONE</code> or <code>CUPS_FILE_GZIP</code></p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileEOF">cupsFileEOF</a></h3>
+<p class="description">Return the end-of-file status.</p>
+<p class="code">
+int cupsFileEOF (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 on end of file, 0 otherwise</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileFind">cupsFileFind</a></h3>
+<p class="description">Find a file using the specified path.</p>
+<p class="code">
+const char *cupsFileFind (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *filename,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *path,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int executable,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *buffer,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int bufsize<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>filename</dt>
+<dd class="description">File to find</dd>
+<dt>path</dt>
+<dd class="description">Colon/semicolon-separated path</dd>
+<dt>executable</dt>
+<dd class="description">1 = executable files, 0 = any file/dir</dd>
+<dt>buffer</dt>
+<dd class="description">Filename buffer</dd>
+<dt>bufsize</dt>
+<dd class="description">Size of filename buffer</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Full path to file or <code>NULL</code> if not found</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function allows the paths in the path string to be separated by
+colons (UNIX standard) or semicolons (Windows standard) and stores the
+result in the buffer supplied.  If the file cannot be found in any of
+the supplied paths, <code>NULL</code> is returned. A <code>NULL</code> path only
+matches the current directory.
 
-<p>The CUPS scheduler (<tt>cupsd</tt>), <tt>mailto</tt> notifier,
-and many of the CUPS API functions use these functions for
-everything except console (stdin, stdout, stderr) I/O.</p>
-
-<h2 class='title'>General Usage</h2>
-
-<p>The <var>&lt;cups/dir.h&gt;</var> and
-<var>&lt;cups/file.h&gt;</var> header files must be included to
-use the <tt>cupsDir</tt> and <tt>cupsFile</tt> functions,
-respectively.</p>
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileFlush">cupsFileFlush</a></h3>
+<p class="description">Flush pending output.</p>
+<p class="code">
+int cupsFileFlush (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, -1 on error</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileGetChar">cupsFileGetChar</a></h3>
+<p class="description">Get a single character from a file.</p>
+<p class="code">
+int cupsFileGetChar (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Character or -1 on end of file</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileGetConf">cupsFileGetConf</a></h3>
+<p class="description">Get a line from a configuration file...</p>
+<p class="code">
+char *cupsFileGetConf (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *buf,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t buflen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char **value,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *linenum<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+<dt>buf</dt>
+<dd class="description">String buffer</dd>
+<dt>buflen</dt>
+<dd class="description">Size of string buffer</dd>
+<dt>value</dt>
+<dd class="description">Pointer to value</dd>
+<dt>linenum</dt>
+<dd class="description">Current line number</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Line read or <code>NULL</code> on end of file or error</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileGetLine">cupsFileGetLine</a></h3>
+<p class="description">Get a CR and/or LF-terminated line that may
+contain binary data.</p>
+<p class="code">
+size_t cupsFileGetLine (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *buf,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t buflen<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">File to read from</dd>
+<dt>buf</dt>
+<dd class="description">Buffer</dd>
+<dt>buflen</dt>
+<dd class="description">Size of buffer</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of bytes on line or 0 on end of file</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function differs from <a href="#cupsFileGets"><code>cupsFileGets</code></a> in that the trailing CR
+and LF are preserved, as is any binary data on the line. The buffer is
+nul-terminated, however you should use the returned length to determine
+the number of bytes on the line.
 
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileGets">cupsFileGets</a></h3>
+<p class="description">Get a CR and/or LF-terminated line.</p>
+<p class="code">
+char *cupsFileGets (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *buf,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t buflen<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+<dt>buf</dt>
+<dd class="description">String buffer</dd>
+<dt>buflen</dt>
+<dd class="description">Size of string buffer</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Line read or <code>NULL</code> on end of file or error</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileLock">cupsFileLock</a></h3>
+<p class="description">Temporarily lock access to a file.</p>
+<p class="code">
+int cupsFileLock (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int block<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+<dt>block</dt>
+<dd class="description">1 to wait for the lock, 0 to fail right away</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, -1 on error</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileNumber">cupsFileNumber</a></h3>
+<p class="description">Return the file descriptor associated with a CUPS file.</p>
+<p class="code">
+int cupsFileNumber (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">File descriptor</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileOpen">cupsFileOpen</a></h3>
+<p class="description">Open a CUPS file.</p>
+<p class="code">
+<a href="#cups_file_t">cups_file_t</a> *cupsFileOpen (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *filename,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *mode<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>filename</dt>
+<dd class="description">Name of file</dd>
+<dt>mode</dt>
+<dd class="description">Open mode</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">CUPS file or <code>NULL</code> if the file or socket cannot be opened</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The &quot;mode&quot; parameter can be &quot;r&quot; to read, &quot;w&quot; to write, overwriting any
+existing file, &quot;a&quot; to append to an existing file or create a new file,
+or &quot;s&quot; to open a socket connection.<br>
+<br>
+When opening for writing (&quot;w&quot;) or appending (&quot;a&quot;), an optional number from
+1 to 9 can be supplied which enables Flate compression of the file.<br>
+<br>
+When opening a socket connection, the filename is a string of the form
+&quot;address:port&quot; or &quot;hostname:port&quot;. The socket will make an IPv4 or IPv6
+connection as needed, generally preferring IPv6 connections when there is
+a choice.
 
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
-</pre>
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileOpenFd">cupsFileOpenFd</a></h3>
+<p class="description">Open a CUPS file using a file descriptor.</p>
+<p class="code">
+<a href="#cups_file_t">cups_file_t</a> *cupsFileOpenFd (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int fd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *mode<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fd</dt>
+<dd class="description">File descriptor</dd>
+<dt>mode</dt>
+<dd class="description">Open mode</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">CUPS file or <code>NULL</code> if the file could not be opened</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The &quot;mode&quot; parameter can be &quot;r&quot; to read, &quot;a&quot; or &quot;w&quot; to write, or &quot;s&quot;
+to treat the file descriptor as a bidirectional socket connection.<br>
+<br>
+When opening for writing (&quot;w&quot;) or appending (&quot;a&quot;), an optional number from
+1 to 9 can be supplied which enables Flate compression of the file.
 
-<h2 class='title'>Compatibility</h2>
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFilePeekChar">cupsFilePeekChar</a></h3>
+<p class="description">Peek at the next character from a file.</p>
+<p class="code">
+int cupsFilePeekChar (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Character or -1 on end of file</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFilePrintf">cupsFilePrintf</a></h3>
+<p class="description">Write a formatted string.</p>
+<p class="code">
+int cupsFilePrintf (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *format,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;...<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+<dt>format</dt>
+<dd class="description">Printf-style format string</dd>
+<dt>...</dt>
+<dd class="description">Additional args as necessary</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of bytes written or -1 on error</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFilePutChar">cupsFilePutChar</a></h3>
+<p class="description">Write a character.</p>
+<p class="code">
+int cupsFilePutChar (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int c<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+<dt>c</dt>
+<dd class="description">Character to write</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, -1 on error</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFilePuts">cupsFilePuts</a></h3>
+<p class="description">Write a string.</p>
+<p class="code">
+int cupsFilePuts (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *s<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+<dt>s</dt>
+<dd class="description">String to write</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of bytes written or -1 on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Like the <code>fputs</code> function, no newline is appended to the string.
 
-<p>All of these functions require CUPS 1.2 or higher.</p>
-<h2 class='title'>Contents</h2>
-<ul>
-       <li><a href='#FUNCTIONS'>Functions</a></li>
-       <li><a href='#STRUCTURES'>Structures</a></li>
-       <li><a href='#TYPES'>Types</a></li>
-</ul>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='FUNCTIONS'>Functions</a></h2>
-<ul>
-       <li><a href='#cupsDirClose'><tt>cupsDirClose()</tt></a> </li>
-       <li><a href='#cupsDirOpen'><tt>cupsDirOpen()</tt></a> </li>
-       <li><a href='#cupsDirRead'><tt>cupsDirRead()</tt></a> </li>
-       <li><a href='#cupsDirRewind'><tt>cupsDirRewind()</tt></a> </li>
-       <li><a href='#cupsFileClose'><tt>cupsFileClose()</tt></a> </li>
-       <li><a href='#cupsFileCompression'><tt>cupsFileCompression()</tt></a> </li>
-       <li><a href='#cupsFileEOF'><tt>cupsFileEOF()</tt></a> </li>
-       <li><a href='#cupsFileFind'><tt>cupsFileFind()</tt></a> </li>
-       <li><a href='#cupsFileFlush'><tt>cupsFileFlush()</tt></a> </li>
-       <li><a href='#cupsFileGetChar'><tt>cupsFileGetChar()</tt></a> </li>
-       <li><a href='#cupsFileGetConf'><tt>cupsFileGetConf()</tt></a> </li>
-       <li><a href='#cupsFileGetLine'><tt>cupsFileGetLine()</tt></a> </li>
-       <li><a href='#cupsFileGets'><tt>cupsFileGets()</tt></a> </li>
-       <li><a href='#cupsFileLock'><tt>cupsFileLock()</tt></a> </li>
-       <li><a href='#cupsFileNumber'><tt>cupsFileNumber()</tt></a> </li>
-       <li><a href='#cupsFileOpen'><tt>cupsFileOpen()</tt></a> </li>
-       <li><a href='#cupsFileOpenFd'><tt>cupsFileOpenFd()</tt></a> </li>
-       <li><a href='#cupsFilePeekChar'><tt>cupsFilePeekChar()</tt></a> </li>
-       <li><a href='#cupsFilePrintf'><tt>cupsFilePrintf()</tt></a> </li>
-       <li><a href='#cupsFilePutChar'><tt>cupsFilePutChar()</tt></a> </li>
-       <li><a href='#cupsFilePuts'><tt>cupsFilePuts()</tt></a> </li>
-       <li><a href='#cupsFileRead'><tt>cupsFileRead()</tt></a> </li>
-       <li><a href='#cupsFileRewind'><tt>cupsFileRewind()</tt></a> </li>
-       <li><a href='#cupsFileSeek'><tt>cupsFileSeek()</tt></a> </li>
-       <li><a href='#cupsFileStderr'><tt>cupsFileStderr()</tt></a> </li>
-       <li><a href='#cupsFileStdin'><tt>cupsFileStdin()</tt></a> </li>
-       <li><a href='#cupsFileStdout'><tt>cupsFileStdout()</tt></a> </li>
-       <li><a href='#cupsFileTell'><tt>cupsFileTell()</tt></a> </li>
-       <li><a href='#cupsFileUnlock'><tt>cupsFileUnlock()</tt></a> </li>
-       <li><a href='#cupsFileWrite'><tt>cupsFileWrite()</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsDirClose'>cupsDirClose()</a></h3>
-<h4>Description</h4>
-<p>Close a directory.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsDirClose(
-    <a href='#cups_dir_t'>cups_dir_t</a> * dp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>dp</tt></td><td>Directory</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsDirOpen'>cupsDirOpen()</a></h3>
-<h4>Description</h4>
-<p>Open a directory.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#cups_dir_t'>cups_dir_t</a> *<br>
-cupsDirOpen(
-    const char * directory);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>directory</tt></td><td>Directory name</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Directory</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsDirRead'>cupsDirRead()</a></h3>
-<h4>Description</h4>
-<p>Read the next directory entry.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#cups_dentry_t'>cups_dentry_t</a> *<br>
-cupsDirRead(
-    <a href='#cups_dir_t'>cups_dir_t</a> * dp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>dp</tt></td><td>Directory</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Directory entry</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsDirRewind'>cupsDirRewind()</a></h3>
-<h4>Description</h4>
-<p>Rewind to the start of the directory.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsDirRewind(
-    <a href='#cups_dir_t'>cups_dir_t</a> * dp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>dp</tt></td><td>Directory</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileClose'>cupsFileClose()</a></h3>
-<h4>Description</h4>
-<p>Close a CUPS file.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsFileClose(
-    <a href='#cups_file_t'>cups_file_t</a> * fp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, -1 on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileCompression'>cupsFileCompression()</a></h3>
-<h4>Description</h4>
-<p>Return whether a file is compressed.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsFileCompression(
-    <a href='#cups_file_t'>cups_file_t</a> * fp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>CUPS_FILE_NONE or CUPS_FILE_GZIP</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileEOF'>cupsFileEOF()</a></h3>
-<h4>Description</h4>
-<p>Return the end-of-file status.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsFileEOF(
-    <a href='#cups_file_t'>cups_file_t</a> * fp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>1 on EOF, 0 otherwise</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileFind'>cupsFileFind()</a></h3>
-<h4>Description</h4>
-<p>Find a file using the specified path.
-<p>This function allows the paths in the path string to be separated by
-colons (UNIX standard) or semicolons (Windows standard) and stores the
-result in the buffer supplied.  If the file cannot be found in any of
-the supplied paths, NULL is returned. A NULL path only matches the
-current directory.
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-cupsFileFind(
-    const char * filename,
-    const char * path,
-    int executable,
-    char * buffer,
-    int bufsize);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>filename</tt></td><td>File to find</td></tr>
-<tr><td><tt>path</tt></td><td>Colon/semicolon-separated path</td></tr>
-<tr><td><tt>executable</tt></td><td>1 = executable files, 0 = any file/dir</td></tr>
-<tr><td><tt>buffer</tt></td><td>Filename buffer</td></tr>
-<tr><td><tt>bufsize</tt></td><td>Size of filename buffer</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Full path to file or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileFlush'>cupsFileFlush()</a></h3>
-<h4>Description</h4>
-<p>Flush pending output.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsFileFlush(
-    <a href='#cups_file_t'>cups_file_t</a> * fp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, -1 on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileGetChar'>cupsFileGetChar()</a></h3>
-<h4>Description</h4>
-<p>Get a single character from a file.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsFileGetChar(
-    <a href='#cups_file_t'>cups_file_t</a> * fp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Character or -1 on EOF</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileGetConf'>cupsFileGetConf()</a></h3>
-<h4>Description</h4>
-<p>Get a line from a configuration file...
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-cupsFileGetConf(
-    <a href='#cups_file_t'>cups_file_t</a> * fp,
-    char * buf,
-    size_t buflen,
-    char ** value,
-    int * linenum);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-<tr><td><tt>buf</tt></td><td>String buffer</td></tr>
-<tr><td><tt>buflen</tt></td><td>Size of string buffer</td></tr>
-<tr><td><tt>value</tt></td><td>Pointer to value</td></tr>
-<tr><td><tt>linenum</tt></td><td>Current line number</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Line read or NULL on eof/error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileGetLine'>cupsFileGetLine()</a></h3>
-<h4>Description</h4>
-<p>Get a CR and/or LF-terminated line that may
-contain binary data.
-<p>This function differs from cupsFileGets() in that the trailing CR and LF
-are preserved, as is any binary data on the line. The buffer is nul-
-terminated, however you should use the returned length to determine
-the number of bytes on the line.
-<h4>Syntax</h4>
-<p><tt>
-size_t<br>
-cupsFileGetLine(
-    <a href='#cups_file_t'>cups_file_t</a> * fp,
-    char * buf,
-    size_t buflen);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>File to read from</td></tr>
-<tr><td><tt>buf</tt></td><td>Buffer</td></tr>
-<tr><td><tt>buflen</tt></td><td>Size of buffer</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of bytes on line or 0 on EOF</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileGets'>cupsFileGets()</a></h3>
-<h4>Description</h4>
-<p>Get a CR and/or LF-terminated line.
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-cupsFileGets(
-    <a href='#cups_file_t'>cups_file_t</a> * fp,
-    char * buf,
-    size_t buflen);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-<tr><td><tt>buf</tt></td><td>String buffer</td></tr>
-<tr><td><tt>buflen</tt></td><td>Size of string buffer</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Line read or NULL on eof/error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileLock'>cupsFileLock()</a></h3>
-<h4>Description</h4>
-<p>Temporarily lock access to a file.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsFileLock(
-    <a href='#cups_file_t'>cups_file_t</a> * fp,
-    int block);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>File to lock</td></tr>
-<tr><td><tt>block</tt></td><td>1 to wait for the lock, 0 to fail right away</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, -1 on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileNumber'>cupsFileNumber()</a></h3>
-<h4>Description</h4>
-<p>Return the file descriptor associated with a CUPS file.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsFileNumber(
-    <a href='#cups_file_t'>cups_file_t</a> * fp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>File descriptor</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileOpen'>cupsFileOpen()</a></h3>
-<h4>Description</h4>
-<p>Open a CUPS file.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#cups_file_t'>cups_file_t</a> *<br>
-cupsFileOpen(
-    const char * filename,
-    const char * mode);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>filename</tt></td><td>Name of file</td></tr>
-<tr><td><tt>mode</tt></td><td>Open mode</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>CUPS file or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileOpenFd'>cupsFileOpenFd()</a></h3>
-<h4>Description</h4>
-<p>Open a CUPS file using a file descriptor.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#cups_file_t'>cups_file_t</a> *<br>
-cupsFileOpenFd(
-    int fd,
-    const char * mode);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fd</tt></td><td>File descriptor</td></tr>
-<tr><td><tt>mode</tt></td><td>Open mode</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>CUPS file or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFilePeekChar'>cupsFilePeekChar()</a></h3>
-<h4>Description</h4>
-<p>Peek at the next character from a file.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsFilePeekChar(
-    <a href='#cups_file_t'>cups_file_t</a> * fp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Character or -1 on EOF</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFilePrintf'>cupsFilePrintf()</a></h3>
-<h4>Description</h4>
-<p>Write a formatted string.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsFilePrintf(
-    <a href='#cups_file_t'>cups_file_t</a> * fp,
-    const char * format,
-    ...);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-<tr><td><tt>format</tt></td><td>Printf-style format string</td></tr>
-<tr><td><tt>...</tt></td><td>Additional args as necessary</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of bytes written or -1</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFilePutChar'>cupsFilePutChar()</a></h3>
-<h4>Description</h4>
-<p>Write a character.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsFilePutChar(
-    <a href='#cups_file_t'>cups_file_t</a> * fp,
-    int c);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-<tr><td><tt>c</tt></td><td>Character to write</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, -1 on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFilePuts'>cupsFilePuts()</a></h3>
-<h4>Description</h4>
-<p>Write a string.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsFilePuts(
-    <a href='#cups_file_t'>cups_file_t</a> * fp,
-    const char * s);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-<tr><td><tt>s</tt></td><td>String to write</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of bytes written or -1</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileRead'>cupsFileRead()</a></h3>
-<h4>Description</h4>
-<p>Read from a file.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ssize_t'>ssize_t</a><br>
-cupsFileRead(
-    <a href='#cups_file_t'>cups_file_t</a> * fp,
-    char * buf,
-    size_t bytes);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-<tr><td><tt>buf</tt></td><td>Buffer</td></tr>
-<tr><td><tt>bytes</tt></td><td>Number of bytes to read</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of bytes read or -1</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileRewind'>cupsFileRewind()</a></h3>
-<h4>Description</h4>
-<p>Rewind a file.
-<h4>Syntax</h4>
-<p><tt>
-off_t<br>
-cupsFileRewind(
-    <a href='#cups_file_t'>cups_file_t</a> * fp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New file position or -1</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileSeek'>cupsFileSeek()</a></h3>
-<h4>Description</h4>
-<p>Seek in a file.
-<h4>Syntax</h4>
-<p><tt>
-off_t<br>
-cupsFileSeek(
-    <a href='#cups_file_t'>cups_file_t</a> * fp,
-    off_t pos);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-<tr><td><tt>pos</tt></td><td>Position in file</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New file position or -1</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileStderr'>cupsFileStderr()</a></h3>
-<h4>Description</h4>
-<p>Just reposition the current pointer, since we have the right
-range...
-<h4>Syntax</h4>
-<p><tt>
-<a href='#cups_file_t'>cups_file_t</a> *<br>
-cupsFileStderr(void);
-</tt></p>
-<h4>Arguments</h4>
-<p>None.</p>
-<h4>Returns</h4>
-<p>Return a CUPS file associated with stderr.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileStdin'>cupsFileStdin()</a></h3>
-<h4>Description</h4>
-<p>Open file descriptor 2...
-<h4>Syntax</h4>
-<p><tt>
-<a href='#cups_file_t'>cups_file_t</a> *<br>
-cupsFileStdin(void);
-</tt></p>
-<h4>Arguments</h4>
-<p>None.</p>
-<h4>Returns</h4>
-<p>Return a CUPS file associated with stdin.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileStdout'>cupsFileStdout()</a></h3>
-<h4>Description</h4>
-<p>Open file descriptor 0...
-<h4>Syntax</h4>
-<p><tt>
-<a href='#cups_file_t'>cups_file_t</a> *<br>
-cupsFileStdout(void);
-</tt></p>
-<h4>Arguments</h4>
-<p>None.</p>
-<h4>Returns</h4>
-<p>Return a CUPS file associated with stdout.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileTell'>cupsFileTell()</a></h3>
-<h4>Description</h4>
-<p>Return the current file position.
-<h4>Syntax</h4>
-<p><tt>
-off_t<br>
-cupsFileTell(
-    <a href='#cups_file_t'>cups_file_t</a> * fp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>File position</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileUnlock'>cupsFileUnlock()</a></h3>
-<h4>Description</h4>
-<p>Unlock access to a file.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsFileUnlock(
-    <a href='#cups_file_t'>cups_file_t</a> * fp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>File to lock</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, -1 on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsFileWrite'>cupsFileWrite()</a></h3>
-<h4>Description</h4>
-<p>Write to a file.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ssize_t'>ssize_t</a><br>
-cupsFileWrite(
-    <a href='#cups_file_t'>cups_file_t</a> * fp,
-    const char * buf,
-    size_t bytes);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>CUPS file</td></tr>
-<tr><td><tt>buf</tt></td><td>Buffer</td></tr>
-<tr><td><tt>bytes</tt></td><td>Number of bytes to write</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of bytes written</p>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='STRUCTURES'>Structures</a></h2>
-<ul>
-       <li><a href='#cups_dentry_s'><tt>cups_dentry_s</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_dentry_s'>cups_dentry_s</a></h3>
-<h4>Description</h4>
-<p>Directory entry type
-<h4>Definition</h4>
-<p><tt>
-struct cups_dentry_s<br>
-{<br>
-&nbsp;&nbsp;struct stat fileinfo;<br>
-&nbsp;&nbsp;char filename[260];<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fileinfo</tt> </td><td>File information
-</td></tr>
-<tr><td><tt>filename[260]</tt> </td><td>File name
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='TYPES'>Types</a></h2>
-<ul>
-       <li><a href='#cups_dentry_t'><tt>cups_dentry_t</tt></a> </li>
-       <li><a href='#cups_dir_t'><tt>cups_dir_t</tt></a> </li>
-       <li><a href='#cups_file_t'><tt>cups_file_t</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_dentry_t'>cups_dentry_t</a></h3>
-<h4>Description</h4>
-<p>Directory entry type
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#cups_dentry_s'>cups_dentry_s</a> cups_dentry_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_dir_t'>cups_dir_t</a></h3>
-<h4>Description</h4>
-<p>Directory type
-<h4>Definition</h4>
-<p><tt>
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileRead">cupsFileRead</a></h3>
+<p class="description">Read from a file.</p>
+<p class="code">
+ssize_t cupsFileRead (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *buf,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t bytes<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+<dt>buf</dt>
+<dd class="description">Buffer</dd>
+<dt>bytes</dt>
+<dd class="description">Number of bytes to read</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of bytes read or -1 on error</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileRewind">cupsFileRewind</a></h3>
+<p class="description">Set the current file position to the beginning of the
+file.</p>
+<p class="code">
+off_t cupsFileRewind (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New file position or -1 on error</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileSeek">cupsFileSeek</a></h3>
+<p class="description">Seek in a file.</p>
+<p class="code">
+off_t cupsFileSeek (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;off_t pos<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+<dt>pos</dt>
+<dd class="description">Position in file</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New file position or -1 on error</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileStderr">cupsFileStderr</a></h3>
+<p class="description">Return a CUPS file associated with stderr.</p>
+<p class="code">
+<a href="#cups_file_t">cups_file_t</a> *cupsFileStderr (void);</p>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">CUPS file</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileStdin">cupsFileStdin</a></h3>
+<p class="description">Return a CUPS file associated with stdin.</p>
+<p class="code">
+<a href="#cups_file_t">cups_file_t</a> *cupsFileStdin (void);</p>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">CUPS file</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileStdout">cupsFileStdout</a></h3>
+<p class="description">Return a CUPS file associated with stdout.</p>
+<p class="code">
+<a href="#cups_file_t">cups_file_t</a> *cupsFileStdout (void);</p>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">CUPS file</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileTell">cupsFileTell</a></h3>
+<p class="description">Return the current file position.</p>
+<p class="code">
+off_t cupsFileTell (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">File position</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileUnlock">cupsFileUnlock</a></h3>
+<p class="description">Unlock access to a file.</p>
+<p class="code">
+int cupsFileUnlock (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, -1 on error</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsFileWrite">cupsFileWrite</a></h3>
+<p class="description">Write to a file.</p>
+<p class="code">
+ssize_t cupsFileWrite (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_file_t">cups_file_t</a> *fp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *buf,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t bytes<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">CUPS file</dd>
+<dt>buf</dt>
+<dd class="description">Buffer</dd>
+<dt>bytes</dt>
+<dd class="description">Number of bytes to write</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of bytes written or -1 on error</p>
+<h2 class="title"><a name="TYPES">Data Types</a></h2>
+<h3 class="typedef"><a name="cups_dentry_t">cups_dentry_t</a></h3>
+<p class="description">Directory entry type</p>
+<p class="code">
+typedef struct <a href="#cups_dentry_s">cups_dentry_s</a> cups_dentry_t;
+</p>
+<h3 class="typedef"><a name="cups_dir_t">cups_dir_t</a></h3>
+<p class="description">Directory type</p>
+<p class="code">
 typedef struct _cups_dir_s cups_dir_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_file_t'>cups_file_t</a></h3>
-<h4>Description</h4>
-<p>CUPS file type
-<h4>Definition</h4>
-<p><tt>
+</p>
+<h3 class="typedef"><a name="cups_file_t">cups_file_t</a></h3>
+<p class="description">CUPS file type</p>
+<p class="code">
 typedef struct _cups_file_s cups_file_t;
-</tt></p>
+</p>
+<h2 class="title"><a name="STRUCTURES">Structures</a></h2>
+<h3 class="struct"><a name="cups_dentry_s">cups_dentry_s</a></h3>
+<p class="description">Directory entry type</p>
+<p class="code">struct cups_dentry_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;struct stat fileinfo;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char filename[260];<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>fileinfo </dt>
+<dd class="description">File information</dd>
+<dt>filename[260] </dt>
+<dd class="description">File name</dd>
+</dl>
+</div>
 </body>
 </html>
index 492f1b2d499526e083479ac37724acc18b11fef4..62ae4ac3a963f8a0381d1bf0a8aa37f40ed023c3 100644 (file)
 <html>
 <!-- SECTION: Programming -->
 <head>
-       <title>Filter and Backend APIs</title>
-       <meta name='keywords' content='Programming'>
-       <meta name='creator' content='Mini-XML v2.4'>
-       <style type='text/css'><!--
-       h1, h2, h3, p { font-family: sans-serif; text-align: justify; }
-       tt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }
-       pre { font-weight: bold; color: #7f0000; margin-left: 2em; }
-       span.info { background: #000000; border: solid thin #000000; color: #ffffff; font-size: 80%; font-style: italic; font-weight: bold; white-space: nowrap; }
-       h3 span.info { float: right; font-size: 100%; }
-       h1.title, h2.title, h3.title { border-bottom: solid 2px #000000; }
-       --></style>
+<title>Filter and Backend Programming</title>
+<meta name="keywords" content="Programming">
+<meta name="creator" content="Mini-XML v2.5">
+<style type="text/css"><!--
+BODY {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+H1, H2, H3, H4, H5, H6, P, TD, TH {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+KBD {
+  font-family: monaco, courier, monospace;
+  font-weight: bold;
+}
+
+PRE {
+  font-family: monaco, courier, monospace;
+}
+
+PRE.command {
+  margin-left: 36pt;
+}
+
+PRE.example {
+  background: #eeeeee;
+  border: dotted thin #999999;
+  margin-left: 36pt;
+  padding: 10px;
+}
+
+PRE.command EM, PRE.example EM {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+P.command {
+  font-family: monaco, courier, monospace;
+  margin-left: 36pt;
+}
+
+P.formula {
+  font-style: italic;
+  margin-left: 36pt;
+}
+
+BLOCKQUOTE {
+  background: #cccccc;
+  border: solid thin #999999;
+  padding: 10pt;
+}
+
+A:link, A:visited {
+  text-decoration: none;
+  font-weight: bold;
+}
+
+A:link:hover, A:visited:hover, A:active {
+  text-decoration: underline;
+  font-weight: bold;
+}
+
+SUB, SUP {
+  font-size: 50%;
+}
+
+DIV.table TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.table CAPTION {
+  caption-side: top;
+  font-size: 120%;
+  font-style: italic;
+  font-weight: bold;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.table TABLE TD {
+  border: solid thin #cccccc;
+  padding-top: 5pt;
+}
+
+DIV.table TABLE TH {
+  background: #cccccc;
+  border: none;
+  border-bottom: solid thin #999999;
+}
+
+DIV.figure TABLE {
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.figure CAPTION {
+  caption-side: bottom;
+  font-size: 120%;
+  font-style: italic;
+  font-weight: bold;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+TH.label {
+  padding-top: 5pt;
+  text-align: right;
+  vertical-align: top;
+}
+
+HR {
+  border: solid thin;
+}
+
+SPAN.info {
+  background: #000000;
+  border: thin solid #000000;
+  color: #ffffff;
+  font-size: 80%;
+  font-style: italic;
+  font-weight: bold;
+  white-space: nowrap;
+}
+
+H2 SPAN.info, H3 SPAN.info, H4 SPAN.info {
+  float: right;
+  font-size: 100%;
+}
+
+H2.title, H3.title {
+  border-bottom: solid 2pt #000000;
+}
+
+DT {
+  margin-left: 36pt;
+  margin-top: 12pt;
+}
+
+DD {
+  margin-left: 54pt;
+}
+
+DL.category DT {
+  font-weight: bold;
+}
+
+P.summary {
+  margin-left: 36pt;
+  font-family: monaco, courier, monospace;
+}
+
+SPAN.message {
+  font-style: italic;
+  font-size: smaller;
+}
+
+DIV.summary TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin: 10px;
+}
+
+DIV.summary TABLE TD, DIV.summary TABLE TH {
+  border: solid thin #999999;
+  padding: 5px;
+  text-align: left;
+  vertical-align: top;
+}
+
+DIV.summary TABLE THEAD TH {
+  background: #eeeeee;
+}
+
+/* API documentation styles... */
+div.body h1 {
+  margin: 0;
+}
+div.body h2 {
+  margin-top: 1.5em;
+}
+div.body h3, div.body h4, div.body h5 {
+  margin-bottom: 0.5em;
+  margin-top: 1.5em;
+}
+.class, .enumeration, .function, .struct, .typedef, .union {
+  border-bottom: solid thin #999999;
+  margin-bottom: 0;
+  margin-top: 2em;
+}
+.description {
+  margin-top: 0.5em;
+}
+code, p.code, pre, ul.code li {
+  font-family: monaco, courier, monospace;
+  font-size: 90%;
+}
+ul.code, ul.contents, ul.subcontents {
+  list-style-type: none;
+  margin: 0;
+  padding-left: 0;
+}
+ul.code li {
+  margin: 0;
+}
+ul.contents > li {
+  margin-top: 1em;
+}
+ul.contents li ul.code, ul.contents li ul.subcontents {
+  padding-left: 2em;
+}
+div.body dl {
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dt {
+  font-style: italic;
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dd {
+  margin-bottom: 0.5em;
+}
+
+/* This is just for the HTML files generated with the framedhelp target */
+div.contents {
+  background: #e8e8e8;
+  border: solid thin black;
+  padding: 10px;
+}
+div.contents h1 {
+  font-size: 110%;
+}
+div.contents h2 {
+  font-size: 100%;
+}
+div.contents ul.contents {
+  font-size: 80%;
+}
+--></style>
 </head>
 <body>
+<div class='body'>
 <!--
-  "$Id: api-filter.shtml 6649 2007-07-11 21:46:42Z mike $"
+  "$Id: api-cups.header 7279 2008-01-31 01:50:44Z mike $"
 
-  Filter and backend API introduction for the Common UNIX Printing System (CUPS).
+  Filter and backend programming header for the Common UNIX Printing System
+  (CUPS).
 
-  Copyright 2007 by Apple Inc.
-  Copyright 1997-2006 by Easy Software Products, all rights reserved.
+  Copyright 2008 by Apple Inc.
 
   These coded instructions, statements, and computer programs are the
   property of Apple Inc. and are protected by Federal copyright
   file is missing or damaged, see the license at "http://www.cups.org/".
 -->
 
-<h2 class='title'>Introduction</h2>
+<h1 class="title">Filter and Backend Programming</h1>
 
-<p>The CUPS filter and backend APIs define standard exit codes
-and provide access to the backchannel data stream. They are only
-used when writing backends, filters, and port monitors.</p>
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+       <th>Header</th>
+       <th>cups/backend.h<br>
+       cups/sidechannel.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <th>Library</th>
+       <td>-lcups</td>
+</tr>
+<tr>
+       <th>See Also</th>
+       <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
+       Programming: <a href='api-cups.html' target='_top'>CUPS API</a><br>
+       Programming: <a href='api-ppd.html' target='_top'>PPD API</a><br>
+       Programming: <a href='api-raster.html' target='_top'>Raster API</a></td>
+</tr>
+</tbody>
+</table></div>
+<h2 class="title">Contents</h2>
+<ul class="contents">
+</li>
+<li><a href="#OVERVIEW">Overview</a><ul class="subcontents">
+<li><a href="#EXITCODES">Exit Codes</a></li>
+<li><a href="#ENVIRONMENT">Environment Variables</a></li>
+<li><a href="#MESSAGES">Communicating with the Scheduler</a></li>
+<li><a href="#COMMUNICATING">Communicating with the Backend</a></li>
+</ul></li>
+<li><a href="#FUNCTIONS">Functions</a><ul class="code">
+<li><a href="#cupsBackChannelRead" title="Read data from the backchannel.">cupsBackChannelRead</a></li>
+<li><a href="#cupsBackChannelWrite" title="Write data to the backchannel.">cupsBackChannelWrite</a></li>
+<li><a href="#cupsSideChannelDoRequest" title="Send a side-channel command to a backend and wait for a response.">cupsSideChannelDoRequest</a></li>
+<li><a href="#cupsSideChannelRead" title="Read a side-channel message.">cupsSideChannelRead</a></li>
+<li><a href="#cupsSideChannelWrite" title="Write a side-channel message.">cupsSideChannelWrite</a></li>
+</ul>
+<li><a href="#TYPES">Data Types</a><ul class="code">
+       <li><a href="#cups_backend_t" title="Backend exit codes">cups_backend_t</a></li>
+       <li><a href="#cups_sc_bidi_t" title="Bidirectional capabilities">cups_sc_bidi_t</a></li>
+       <li><a href="#cups_sc_command_t" title="Request command codes">cups_sc_command_t</a></li>
+       <li><a href="#cups_sc_state_t" title="Printer state bits">cups_sc_state_t</a></li>
+       <li><a href="#cups_sc_status_t" title="Response status codes">cups_sc_status_t</a></li>
+</ul></li>
+<li><a href="#ENUMERATIONS">Constants</a><ul class="code">
+       <li><a href="#cups_backend_e" title="Backend exit codes">cups_backend_e</a></li>
+       <li><a href="#cups_sc_bidi_e" title="Bidirectional capabilities">cups_sc_bidi_e</a></li>
+       <li><a href="#cups_sc_command_e" title="Request command codes">cups_sc_command_e</a></li>
+       <li><a href="#cups_sc_state_e" title="Printer state bits">cups_sc_state_e</a></li>
+       <li><a href="#cups_sc_status_e" title="Response status codes">cups_sc_status_e</a></li>
+</ul></li>
+</ul>
+<!--
+  "$Id: api-filter.shtml 6649 2007-07-11 21:46:42Z mike $"
 
-<h2 class='title'>General Usage</h2>
+  Filter and backend programming introduction for the Common UNIX Printing
+  System (CUPS).
 
-<p>The <var>&lt;cups/backend.h&gt;</var> and
-<var>&lt;cups/cups.h&gt;</var> header files must be included to
-use the <tt>CUPS_BACKEND_</tt> constants and
-<tt>cupsBackChannel</tt> functions, respectively.</p>
+  Copyright 2007-2008 by Apple Inc.
+  Copyright 1997-2006 by Easy Software Products, all rights reserved.
 
-<p>The <var>&lt;cups/sidechannel.h&gt;</var> header file must be
-included to use the <tt>CUPS_SC_</tt> constants and <tt>cupsSideChannel</tt> functions.</p>
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
 
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+<h2 class='title'><a name="OVERVIEW">Overview</a></h2>
 
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
-</pre>
+<p>Filters, printer drivers, port monitors, and backends use a common interface
+for processing print jobs and communicating status information to the scheduler.
+Each filter is run with a standard set of command-line arguments:<p>
 
+<dl class="code">
 
-<h2 class='title'>Compatibility</h2>
+       <dt>argv[1]</dt>
+       <dd>The job ID</dd>
 
-<p>The <tt>cupsBackChannel</tt> functions require CUPS 1.2 or higher. The <tt>cupsSideChannel</tt> functions require CUPS 1.3 or higher.</p>
+       <dt>argv[2]</dt>
+       <dd>The user printing the job</dd>
 
+       <dt>argv[3]</dt>
+       <dd>The job name/title</dd>
 
-<h2 class='title'>Using the cupsBackChannel APIs</h2>
+       <dt>argv[4]</dt>
+       <dd>The number of copies to print</dd>
 
-<p>The <tt>cupsBackChannel</tt> APIs allow your filters, drivers, and port monitors to read data back from a printer and your backends to send data from a printer to the filters, drivers, and port monitors associated with the current job. Back-channel data is normally sent by the printer in response to a command sent from your program to the printer via <tt>stdout</tt>.</p>
+       <dt>argv[5]</dt>
+       <dd>The options that were provided when the job was submitted</dd>
 
-<p>The <tt>cupsBackChannelRead()</tt> function reads data from the printer via the backend. You provide a timeout in seconds along with a buffer pointer and the size of that buffer. It returns the number of bytes or -1 if there was an error. The following code example shows how to poll for back-channel data in your program:</p>
+       <dt>argv[6]</dt>
+       <dd>The file to print (first filter only)</dd>
+</dl>
 
-<pre class='command'>
-#include &lt;cups/cups.h&gt;
+<p>The scheduler runs one or more of these programs to print any given job. The
+first filter reads from the print file and writes to the standard output, while
+the remaining filters read from the standard input and write to the standard
+output. The backend is the last filter in the chain and writes to the
+device.</p>
 
-char buffer[8192];
-ssize_t bytes;
+<h3><a name="EXITCODES">Exit Codes</a></h3>
 
-/* Use a timeout of 0.0 seconds to poll for back-channel data */
-bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0);
-</pre>
+<p>Filters must exit with status 0 when they successfully generate print data
+or 1 when they encounter an error. Backends can return any of the
+<a href="#cups_backend_t"><code>cups_backend_t</code></a> constants.</p>
 
-<p>If you are writing a backend, the <tt>cupsBackChannelWrite()</tt> function sends any back-channel data you have received from the printer to upstream filters in the print filter chain. We recommend using a timeout of 1.0 seconds:</p>
+<h3><a name="ENVIRONMENT">Environment Variables</a></h3>
 
-<pre class='command'>
-#include &lt;cups/cups.h&gt;
+<p>The following environment variables are defined by the printing system:</p>
 
-char buffer[8192];
-ssize_t bytes;
+<dl class="code">
 
-/* Use a timeout of 1.0 seconds to give filters a chance to read */
-cupsBackChannelWrite(buffer, bytes, 1.0);
-</pre>
+       <dt>APPLE_LANGUAGES</dt>
+       <dd>The Apple language identifier associated with the job
+       (Mac OS X only).</dd>
 
+       <dt>CHARSET</dt>
+       <dd>The job character set, typically "utf-8".</dd>
 
-<h2 class='title'>Using the cupsSideChannel APIs</h2>
+       <dt>CLASS</dt>
+       <dd>When a job is submitted to a printer class, contains the name of
+       the destination printer class. Otherwise this environment
+       variable will not be set.</dd>
 
-<p>The <tt>cupsSideChannel</tt> APIs allow your filters, drivers, port monitors, and backend to send and receive the following out-of-band commands:</p>
+       <dt>CONTENT_TYPE</dt>
+       <dd>The MIME type associated with the file (e.g.
+       application/postscript).</dd>
 
-<ul>
+       <dt>CUPS_CACHEDIR</dt>
+       <dd>The directory where cache files can be stored.</dd>
 
-       <li><tt>CUPS_SC_CMD_SOFT_RESET</tt> -  Do a soft reset</li>
-       <li><tt>CUPS_SC_CMD_DRAIN_OUTPUT</tt> -  Drain all pending output</li>
-       <li><tt>CUPS_SC_CMD_GET_BIDI</tt> -  Return bidirectional capabilities</li>
-       <li><tt>CUPS_SC_CMD_GET_DEVICE_ID</tt> -  Return the IEEE-1284 device ID</li>
-       <li><tt>CUPS_SC_CMD_GET_STATE</tt> - Return the device state</li>
+       <dt>CUPS_DATADIR</dt>
+       <dd>The directory where data files can be found.</dd>
 
-</ul>
+       <dt>CUPS_SERVERROOT</dt>
+       <dd>The root directory of the server.</dd>
 
+       <dt>DEVICE_URI</dt>
+       <dd>The device-uri associated with the printer.</dd>
 
-<h3>Sending Commands from a Filter, Driver, or Port Monitor</h3>
+       <dt>FINAL_CONTENT_TYPE</dt>
+       <dd>The MIME type associated with the printer (e.g.
+       application/vnd.cups-postscript).</dd>
 
-<p>The <tt>cupsSideChannelDoRequest()</tt> function is used by filters, drivers, and port monitors to send a command to the backend and read back a response:</p>
+       <dt>LANG</dt>
+       <dd>The language locale associated with the job.</dd>
 
-<pre class='command'>
-cups_sc_status_t cupsSideChannelDoRequest(cups_sc_command_t command,
-                                          char *data, int *datalen,
-                                          double timeout);
-</pre>
+       <dt>PPD</dt>
+       <dd>The full pathname of the PostScript Printer Description (PPD)
+       file for this printer.</dd>
 
-<p>The <tt>CUPS_SC_CMD_SOFT_RESET</tt> and <tt>CUPS_SC_CMD_DRAIN_OUTPUT</tt> commands do not return any data values, while the others return one or more bytes. The <tt>timeout</tt> parameter allows your program to poll or wait for the command to complete - use a timeout of 30 seconds for <tt>CUPS_SC_CMD_SOFT_RESET</tt> and <tt>CUPS_SC_CMD_DRAIN_OUTPUT</tt> and a timeout of 1 second for all other commands.</p>
+       <dt>PRINTER</dt>
+       <dd>The name of the printer.</dd>
 
-<p><tt>CUPS_SC_CMD_GET_BIDI</tt> returns a single <tt>char</tt> value that tells you whether the backend supports bidirectional communications:</p>
+       <dt>RIP_CACHE</dt>
+       <dd>The recommended amount of memory to use for Raster Image
+       Processors (RIPs).</dd>
 
-<pre class='command'>
-#include &lt;cups/sidechannel.h&gt;
+</dl>
 
-char data;
-int datalen;
-cups_sc_bidi_t bidi;
-cups_sc_status_t status;
+<h3><a name="MESSAGES">Communicating with the Scheduler</a></h3>
 
-/* Tell cupsSideChannelDoRequest() how big our buffer is... */
-datalen = 1;
+<p>Filters and backends communicate wih the scheduler by writing messages
+to the standard error file. For example, the following code sets the current
+printer state message to "Printing page 5":</p>
 
-/* Get the bidirectional capabilities, waiting for up to 1 second */
-status  = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_BIDI, &amp;data, &amp;datalen, 1.0);
+<pre class="example">
+int page = 5;
 
-/* Use the returned value if OK was returned and the length is still 1 */
-if (status == CUPS_SC_STATUS_OK && datalen == 1)
-  bidi = (cups_sc_bidi_t)data;
-else
-  bidi = CUPS_SC_BIDI_NOT_SUPPORTED;
+fprintf(stderr, "INFO: Printing page %d\n", page);
 </pre>
 
-<p><tt>CUPS_SC_CMD_GET_DEVICE_ID</tt> returns a string of characters containing the IEEE-1284 device ID for the connected printer:</p>
+<p>Each message is a single line of text starting with one of the following
+prefix strings:</p>
+
+<dl class="code">
+
+       <dt>ALERT: message</dt>
+       <dd>Sets the printer-state-message attribute and adds the specified
+       message to the current error log file using the "alert" log level.</dd>
+
+       <dt>ATTR: attribute=value [attribute=value]</dt>
+       <dd>Sets the named printer or job attribute(s). Typically this is used
+       to set the <code>marker-colors</code>, <code>marker-levels</code>,
+       <code>marker-names</code>, <code>marker-types</code>,
+       <code>printer-alert</code>, and <code>printer-alert-description</code>
+       printer attributes.</dd>
+
+       <dt>CRIT: message</dt>
+       <dd>Sets the printer-state-message attribute and adds the specified
+       message to the current error log file using the "critical" log
+       level.</dd>
+
+       <dt>DEBUG: message</dt>
+       <dd>Sets the printer-state-message attribute and adds the specified
+       message to the current error log file using the "debug" log level.</dd>
+
+       <dt>DEBUG2: message</dt>
+       <dd>Sets the printer-state-message attribute and adds the specified
+       message to the current error log file using the "debug2" log level.</dd>
+
+       <dt>EMERG: message</dt>
+       <dd>Sets the printer-state-message attribute and adds the specified
+       message to the current error log file using the "emergency" log
+       level.</dd>
+
+       <dt>ERROR: message</dt>
+       <dd>Sets the printer-state-message attribute and adds the specified
+       message to the current error log file using the "error" log level.</dd>
+
+       <dt>INFO: message</dt>
+       <dd>Sets the printer-state-message attribute. If the current log level
+       is set to "debug2", also adds the specified message to the current error
+       log file using the "info" log level.</dd>
+
+       <dt>NOTICE: message</dt>
+       <dd>Sets the printer-state-message attribute and adds the specified
+       message to the current error log file using the "notice" log level.</dd>
+
+       <dt>PAGE: page-number #-copies</dt>
+       <dt>PAGE: total #-pages</dt>
+       <dd>Adds an entry to the current page log file. The first form adds
+       #-copies to the job-media-sheets-completed attribute. The second
+       form sets the job-media-sheets-completed attribute to #-pages.</dd>
+
+       <dt>STATE: printer-state-reason [printer-state-reason ...]</dt>
+       <dt>STATE: + printer-state-reason [printer-state-reason ...]</dt>
+       <dt>STATE: - printer-state-reason [printer-state-reason ...]</dt>
+       <dd>Sets, adds, or removes printer-state-reason keywords to the
+       current queue. Typically this is used to indicate media, ink, and
+       toner conditions on a printer.</dd>
+
+       <dt>WARNING: message</dt>
+       <dd>Sets the printer-state-message attribute and adds the specified
+       message to the current error log file using the "warning" log
+       level.</dd>
+
+</dl>
+
+<p>Messages without one of these prefixes are treated as if they began with
+the "DEBUG:" prefix string.</p>
+
+<h3><a name="COMMUNICATING">Communicating with the Backend</a></h3>
+
+<p>Filters can communicate with the backend via the
+<a href="#cupsBackChannelRead"><code>cupsBackChannelRead</code></a> and
+<a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a>
+functions. The 
+<a href="#cupsBackChannelRead"><code>cupsBackChannelRead</code></a> function
+reads data that has been sent back from the device and is typically used to
+obtain status and configuration information. For example, the following code
+polls the backend for back-channel data:</p>
+
+<pre class="example">
+#include &lt;cups/cups.h&gt;
+
+char buffer[8192];
+ssize_t bytes;
+
+/* Use a timeout of 0.0 seconds to poll for back-channel data */
+bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0);
+</pre>
 
-<pre class='command'>
+The
+<a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a>
+function allows you to get out-of-band status information and do synchronization
+with the device. For example, the following code gets the current IEEE-1284
+device ID string from the backend:</p>
+
+<pre class="example">
 #include &lt;cups/sidechannel.h&gt;
 
 char data[2049];
 int datalen;
-cups_sc_status_t status;
+<a href="#cups_sc_status_t">cups_sc_status_t</a> status;
 
 /* Tell cupsSideChannelDoRequest() how big our buffer is, less 1 byte for nul-termination... */
 datalen = sizeof(data) - 1;
 
 /* Get the IEEE-1284 device ID, waiting for up to 1 second */
-status  = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_DEVICE_ID, data, &amp;datalen, 1.0);
+status = <a href="#cupsSideChannelDoRequest">cupsSideChannelDoRequest</a>(CUPS_SC_CMD_GET_DEVICE_ID, data, &amp;datalen, 1.0);
 
 /* Use the returned value if OK was returned and the length is non-zero */
 if (status == CUPS_SC_STATUS_OK && datalen > 0)
@@ -164,59 +557,53 @@ else
   data[0] = '\0';
 </pre>
 
-<p><tt>CUPS_SC_CMD_GET_STATE</tt> returns a single <tt>char</tt> value that tells you the current device state:</p>
-
-<pre class='command'>
-#include &lt;cups/sidechannel.h&gt;
-
-char data;
-int datalen;
-cups_sc_state_t state;
-cups_sc_status_t status;
-
-/* Tell cupsSideChannelDoRequest() how big our buffer is... */
-datalen = 1;
-
-/* Get the bidirectional capabilities, waiting for up to 1 second */
-status  = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_STATE, &amp;data, &amp;datalen, 1.0);
-
-/* Use the returned value if OK was returned and the length is still 1 */
-if (status == CUPS_SC_STATUS_OK && datalen == 1)
-  state = (cups_sc_state_t)data;
-else
-  state = CUPS_SC_STATE_OFFLINE;
-</pre>
-
+<p>Backends communicate with filters using the reciprocal functions
+<a href="#cupsBackChannelWrite"><code>cupsBackChannelWrite</code></a>,
+<a href="#cupsSideChannelRead"><code>cupsSideChannelRead</code></a>, and
+<a href="#cupsSideChannelWrite"><code>cupsSideChannelWrite</code></a>. We
+recommend writing back-channel data using a timeout of 1.0 seconds:</p>
 
-<h3>Handling Commands in your Backend</h3>
+<pre class="example">
+#include &lt;cups/cups.h&gt;
 
-<p>The <tt>cupsSideChannelRead()</tt> function is used by backends to read a command from a filter, driver, or port monitor:</p>
+char buffer[8192];
+ssize_t bytes;
 
-<pre class='command'>
-int cupsSideChannelRead(cups_sc_command_t &amp;command,
-                        cups_sc_status_t  &amp;status,
-                        char *data, int *datalen, double timeout);
+/* Use a timeout of 1.0 seconds to give filters a chance to read */
+cupsBackChannelWrite(buffer, bytes, 1.0);
 </pre>
 
-<p>Backends can either poll for commands using a <tt>timeout</tt> of 0.0, wait indefinitely for commands using a <tt>timeout</tt> of -1.0 (probably in a separate thread for that purpose), or use <tt>select()</tt> or <tt>poll()</tt> on the <tt>CUPS_SC_FD</tt> file descriptor (4) to handle input and output on several file descriptors at the same time. Backends can pass <tt>NULL</tt> for the <tt>data</tt> and <tt>datalen</tt> parameters, since none of the commands sent by upstream filters contain any data at this time.</p>
-
-<p>Once a command is processed, the backend uses the <tt>cupsSideChannelWrite()</tt> function to send its response:</p>
-
-<pre class='command'>
+<p>The <a href="#cupsSideChannelRead"><code>cupsSideChannelRead</code></a>
+function reads a side-channel command from a filter, driver, or port monitor.
+Backends can either poll for commands using a <code>timeout</code> of 0.0, wait
+indefinitely for commands using a <code>timeout</code> of -1.0 (probably in a
+separate thread for that purpose), or use <code>select</code> or
+<code>poll</code> on the <code>CUPS_SC_FD</code> file descriptor (4) to handle
+input and output on several file descriptors at the same time. Backends can pass
+<code>NULL</code> for the <code>data</code> and <code>datalen</code> parameters
+since none of the commands sent by upstream filters contain any data at this
+time.</p>
+
+<p>Once a command is processed, the backend uses the
+<a href="#cupsSideChannelWrite"><code>cupsSideChannelWrite</code></a> function
+to send its response. For example, the following code shows how to poll for a
+side-channel command and respond to it:</p>
+
+<pre class="example">
 #include &lt;cups/sidechannel.h&gt;
 
-cups_sc_command_t command;
-cups_sc_status_t status;
+<a href="#cups_sc_command_t">cups_sc_command_t</a> command;
+<a href="#cups_sc_status_t">cups_sc_status_t</a> status;
 
 /* Poll for a command... */
-if (!cupsSideChannelRead(&amp;command, &amp;status, NULL, NULL, 0.0))
+if (!<a href="#cupsSideChannelRead">cupsSideChannelRead</a>(&amp;command, &amp;status, NULL, NULL, 0.0))
 {
   char data[2048];
   int datalen;
 
   switch (command)
   {
-    ... handle supported commands, file data/datalen/status with values as needed ...
+    /* handle supported commands, file data/datalen/status with values as needed */
 
     default :
         status  = CUPS_SC_STATUS_NOT_IMPLEMENTED;
@@ -225,176 +612,272 @@ if (!cupsSideChannelRead(&amp;command, &amp;status, NULL, NULL, 0.0))
   }
 
   /* Send a response... */
-  cupsSideChannelWrite(command, status, data, datalen, 1.0);
+  <a href="#cupsSideChannelWrite">cupsSideChannelWrite</a>(command, status, data, datalen, 1.0);
 }
 </pre>
-<h2 class='title'>Contents</h2>
-<ul>
-       <li><a href='#FUNCTIONS'>Functions</a></li>
-</ul>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='FUNCTIONS'>Functions</a></h2>
-<ul>
-       <li><a href='#cupsBackChannelRead'><tt>cupsBackChannelRead()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#cupsBackChannelWrite'><tt>cupsBackChannelWrite()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#cupsSideChannelDoRequest'><tt>cupsSideChannelDoRequest()</tt></a> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></li>
-       <li><a href='#cupsSideChannelRead'><tt>cupsSideChannelRead()</tt></a> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></li>
-       <li><a href='#cupsSideChannelWrite'><tt>cupsSideChannelWrite()</tt></a> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cupsBackChannelRead'>cupsBackChannelRead()</a></h3>
-<h4>Description</h4>
-<p>Read data from the backchannel.
-<p>Reads up to &quot;bytes&quot; bytes from the backchannel. The &quot;timeout&quot;
+<h2 class="title"><a name="FUNCTIONS">Functions</a></h2>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsBackChannelRead">cupsBackChannelRead</a></h3>
+<p class="description">Read data from the backchannel.</p>
+<p class="code">
+ssize_t cupsBackChannelRead (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *buffer,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t bytes,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;double timeout<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>buffer</dt>
+<dd class="description">Buffer to read</dd>
+<dt>bytes</dt>
+<dd class="description">Bytes to read</dd>
+<dt>timeout</dt>
+<dd class="description">Timeout in seconds</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Bytes read or -1 on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Reads up to &quot;bytes&quot; bytes from the backchannel. The &quot;timeout&quot;
 parameter controls how many seconds to wait for the data - use
 0.0 to return immediately if there is no data, -1.0 to wait
 for data indefinitely.
 
-
-<h4>Syntax</h4>
-<p><tt>
-ssize_t<br>
-cupsBackChannelRead(
-    char * buffer,
-    size_t bytes,
-    double timeout);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>buffer</tt></td><td>Buffer to read</td></tr>
-<tr><td><tt>bytes</tt></td><td>Bytes to read</td></tr>
-<tr><td><tt>timeout</tt></td><td>Timeout in seconds</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Bytes read or -1 on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cupsBackChannelWrite'>cupsBackChannelWrite()</a></h3>
-<h4>Description</h4>
-<p>Write data to the backchannel.
-<p>Writes &quot;bytes&quot; bytes to the backchannel. The &quot;timeout&quot; parameter
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsBackChannelWrite">cupsBackChannelWrite</a></h3>
+<p class="description">Write data to the backchannel.</p>
+<p class="code">
+ssize_t cupsBackChannelWrite (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *buffer,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t bytes,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;double timeout<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>buffer</dt>
+<dd class="description">Buffer to write</dd>
+<dt>bytes</dt>
+<dd class="description">Bytes to write</dd>
+<dt>timeout</dt>
+<dd class="description">Timeout in seconds</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Bytes written or -1 on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Writes &quot;bytes&quot; bytes to the backchannel. The &quot;timeout&quot; parameter
 controls how many seconds to wait for the data to be written - use
 0.0 to return immediately if the data cannot be written, -1.0 to wait
 indefinitely.
 
-
-<h4>Syntax</h4>
-<p><tt>
-ssize_t<br>
-cupsBackChannelWrite(
-    const char * buffer,
-    size_t bytes,
-    double timeout);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>buffer</tt></td><td>Buffer to write</td></tr>
-<tr><td><tt>bytes</tt></td><td>Bytes to write</td></tr>
-<tr><td><tt>timeout</tt></td><td>Timeout in seconds</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Bytes written or -1 on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.3&nbsp;</span><a name='cupsSideChannelDoRequest'>cupsSideChannelDoRequest()</a></h3>
-<h4>Description</h4>
-<p>Send a side-channel command to a backend and wait for a response.
-<p>This function is normally only called by filters, drivers, or port
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.3&nbsp;</span><a name="cupsSideChannelDoRequest">cupsSideChannelDoRequest</a></h3>
+<p class="description">Send a side-channel command to a backend and wait for a response.</p>
+<p class="code">
+<a href="#cups_sc_status_t">cups_sc_status_t</a> cupsSideChannelDoRequest (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_sc_command_t">cups_sc_command_t</a> command,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *data,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *datalen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;double timeout<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>command</dt>
+<dd class="description">Command to send</dd>
+<dt>data</dt>
+<dd class="description">Response data buffer pointer</dd>
+<dt>datalen</dt>
+<dd class="description">Size of data buffer on entry, number of bytes in buffer on return</dd>
+<dt>timeout</dt>
+<dd class="description">Timeout in seconds</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Status of command</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function is normally only called by filters, drivers, or port
 monitors in order to communicate with the backend used by the current
 printer.  Programs must be prepared to handle timeout or &quot;not
 implemented&quot; status codes, which indicate that the backend or device
-do not support the specified side-channel command.
-<p>The &quot;datalen&quot; parameter must be initialized to the size of the buffer
+do not support the specified side-channel command.<br>
+<br>
+The &quot;datalen&quot; parameter must be initialized to the size of the buffer
 pointed to by the &quot;data&quot; parameter.  cupsSideChannelDoRequest() will
 update the value to contain the number of data bytes in the buffer.
 
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#cups_sc_status_t'>cups_sc_status_t</a><br>
-cupsSideChannelDoRequest(
-    cups_sc_command_t command,
-    char * data,
-    int * datalen,
-    double timeout);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>command</tt></td><td>Command to send</td></tr>
-<tr><td><tt>data</tt></td><td>Response data buffer pointer</td></tr>
-<tr><td><tt>datalen</tt></td><td>Size of data buffer on entry, number of bytes in buffer on return</td></tr>
-<tr><td><tt>timeout</tt></td><td>Timeout in seconds</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Status of command</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.3&nbsp;</span><a name='cupsSideChannelRead'>cupsSideChannelRead()</a></h3>
-<h4>Description</h4>
-<p>Read a side-channel message.
-<p>This function is normally only called by backend programs to read
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.3&nbsp;</span><a name="cupsSideChannelRead">cupsSideChannelRead</a></h3>
+<p class="description">Read a side-channel message.</p>
+<p class="code">
+int cupsSideChannelRead (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_sc_command_t">cups_sc_command_t</a> *command,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_sc_status_t">cups_sc_status_t</a> *status,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *data,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *datalen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;double timeout<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>command</dt>
+<dd class="description">Command code</dd>
+<dt>status</dt>
+<dd class="description">Status code</dd>
+<dt>data</dt>
+<dd class="description">Data buffer pointer</dd>
+<dt>datalen</dt>
+<dd class="description">Size of data buffer on entry, number of bytes in buffer on return</dd>
+<dt>timeout</dt>
+<dd class="description">Timeout in seconds</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, -1 on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function is normally only called by backend programs to read
 commands from a filter, driver, or port monitor program.  The
 caller must be prepared to handle incomplete or invalid messages
-and return the corresponding status codes.
-<p>The &quot;datalen&quot; parameter must be initialized to the size of the buffer
+and return the corresponding status codes.<br>
+<br>
+The &quot;datalen&quot; parameter must be initialized to the size of the buffer
 pointed to by the &quot;data&quot; parameter.  cupsSideChannelDoRequest() will
 update the value to contain the number of data bytes in the buffer.
 
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsSideChannelRead(
-    cups_sc_command_t * command,
-    <a href='#cups_sc_status_t'>cups_sc_status_t</a> * status,
-    char * data,
-    int * datalen,
-    double timeout);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>command</tt></td><td>Command code</td></tr>
-<tr><td><tt>status</tt></td><td>Status code</td></tr>
-<tr><td><tt>data</tt></td><td>Data buffer pointer</td></tr>
-<tr><td><tt>datalen</tt></td><td>Size of data buffer on entry, number of bytes in buffer on return</td></tr>
-<tr><td><tt>timeout</tt></td><td>Timeout in seconds</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, -1 on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.3&nbsp;</span><a name='cupsSideChannelWrite'>cupsSideChannelWrite()</a></h3>
-<h4>Description</h4>
-<p>Write a side-channel message.
-<p>This function is normally only called by backend programs to send
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.3&nbsp;</span><a name="cupsSideChannelWrite">cupsSideChannelWrite</a></h3>
+<p class="description">Write a side-channel message.</p>
+<p class="code">
+int cupsSideChannelWrite (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_sc_command_t">cups_sc_command_t</a> command,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_sc_status_t">cups_sc_status_t</a> status,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *data,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int datalen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;double timeout<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>command</dt>
+<dd class="description">Command code</dd>
+<dt>status</dt>
+<dd class="description">Status code</dd>
+<dt>data</dt>
+<dd class="description">Data buffer pointer</dd>
+<dt>datalen</dt>
+<dd class="description">Number of bytes of data</dd>
+<dt>timeout</dt>
+<dd class="description">Timeout in seconds</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, -1 on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function is normally only called by backend programs to send
 responses to a filter, driver, or port monitor program.
 
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsSideChannelWrite(
-    cups_sc_command_t command,
-    <a href='#cups_sc_status_t'>cups_sc_status_t</a> status,
-    const char * data,
-    int datalen,
-    double timeout);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>command</tt></td><td>Command code</td></tr>
-<tr><td><tt>status</tt></td><td>Status code</td></tr>
-<tr><td><tt>data</tt></td><td>Data buffer pointer</td></tr>
-<tr><td><tt>datalen</tt></td><td>Number of bytes of data</td></tr>
-<tr><td><tt>timeout</tt></td><td>Timeout in seconds</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, -1 on error</p>
+</p>
+<h2 class="title"><a name="TYPES">Data Types</a></h2>
+<h3 class="typedef"><a name="cups_backend_t">cups_backend_t</a></h3>
+<p class="description">Backend exit codes</p>
+<p class="code">
+typedef enum <a href="#cups_backend_e">cups_backend_e</a> cups_backend_t;
+</p>
+<h3 class="typedef"><a name="cups_sc_bidi_t">cups_sc_bidi_t</a></h3>
+<p class="description">Bidirectional capabilities</p>
+<p class="code">
+typedef enum <a href="#cups_sc_bidi_e">cups_sc_bidi_e</a> cups_sc_bidi_t;
+</p>
+<h3 class="typedef"><a name="cups_sc_command_t">cups_sc_command_t</a></h3>
+<p class="description">Request command codes</p>
+<p class="code">
+typedef enum <a href="#cups_sc_command_e">cups_sc_command_e</a> cups_sc_command_t;
+</p>
+<h3 class="typedef"><a name="cups_sc_state_t">cups_sc_state_t</a></h3>
+<p class="description">Printer state bits</p>
+<p class="code">
+typedef enum <a href="#cups_sc_state_e">cups_sc_state_e</a> cups_sc_state_t;
+</p>
+<h3 class="typedef"><a name="cups_sc_status_t">cups_sc_status_t</a></h3>
+<p class="description">Response status codes</p>
+<p class="code">
+typedef enum <a href="#cups_sc_status_e">cups_sc_status_e</a> cups_sc_status_t;
+</p>
+<h2 class="title"><a name="ENUMERATIONS">Constants</a></h2>
+<h3 class="enumeration"><a name="cups_backend_e">cups_backend_e</a></h3>
+<p class="description">Backend exit codes</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_BACKEND_AUTH_REQUIRED </dt>
+<dd class="description">Job failed, authentication required</dd>
+<dt>CUPS_BACKEND_CANCEL </dt>
+<dd class="description">Job failed, cancel job</dd>
+<dt>CUPS_BACKEND_FAILED </dt>
+<dd class="description">Job failed, use error-policy</dd>
+<dt>CUPS_BACKEND_HOLD </dt>
+<dd class="description">Job failed, hold job</dd>
+<dt>CUPS_BACKEND_OK </dt>
+<dd class="description">Job completed successfully</dd>
+<dt>CUPS_BACKEND_STOP </dt>
+<dd class="description">Job failed, stop queue</dd>
+</dl>
+<h3 class="enumeration"><a name="cups_sc_bidi_e">cups_sc_bidi_e</a></h3>
+<p class="description">Bidirectional capabilities</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_SC_BIDI_NOT_SUPPORTED </dt>
+<dd class="description">Bidirectional I/O is not supported</dd>
+<dt>CUPS_SC_BIDI_SUPPORTED </dt>
+<dd class="description">Bidirectional I/O is supported</dd>
+</dl>
+<h3 class="enumeration"><a name="cups_sc_command_e">cups_sc_command_e</a></h3>
+<p class="description">Request command codes</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_SC_CMD_DRAIN_OUTPUT </dt>
+<dd class="description">Drain all pending output</dd>
+<dt>CUPS_SC_CMD_GET_BIDI </dt>
+<dd class="description">Return bidirectional capabilities</dd>
+<dt>CUPS_SC_CMD_GET_DEVICE_ID </dt>
+<dd class="description">Return the IEEE-1284 device ID</dd>
+<dt>CUPS_SC_CMD_GET_STATE </dt>
+<dd class="description">Return the device state</dd>
+<dt>CUPS_SC_CMD_SOFT_RESET </dt>
+<dd class="description">Do a soft reset</dd>
+</dl>
+<h3 class="enumeration"><a name="cups_sc_state_e">cups_sc_state_e</a></h3>
+<p class="description">Printer state bits</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_SC_STATE_BUSY </dt>
+<dd class="description">Device is busy</dd>
+<dt>CUPS_SC_STATE_ERROR </dt>
+<dd class="description">Other error condition</dd>
+<dt>CUPS_SC_STATE_MARKER_EMPTY </dt>
+<dd class="description">Toner/ink out condition</dd>
+<dt>CUPS_SC_STATE_MARKER_LOW </dt>
+<dd class="description">Toner/ink low condition</dd>
+<dt>CUPS_SC_STATE_MEDIA_EMPTY </dt>
+<dd class="description">Paper out condition</dd>
+<dt>CUPS_SC_STATE_MEDIA_LOW </dt>
+<dd class="description">Paper low condition</dd>
+<dt>CUPS_SC_STATE_OFFLINE </dt>
+<dd class="description">Device is off-line</dd>
+<dt>CUPS_SC_STATE_ONLINE </dt>
+<dd class="description">Device is on-line</dd>
+</dl>
+<h3 class="enumeration"><a name="cups_sc_status_e">cups_sc_status_e</a></h3>
+<p class="description">Response status codes</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_SC_STATUS_BAD_MESSAGE </dt>
+<dd class="description">The command/response message was invalid</dd>
+<dt>CUPS_SC_STATUS_IO_ERROR </dt>
+<dd class="description">An I/O error occurred</dd>
+<dt>CUPS_SC_STATUS_NONE </dt>
+<dd class="description">No status</dd>
+<dt>CUPS_SC_STATUS_NOT_IMPLEMENTED </dt>
+<dd class="description">Command not implemented</dd>
+<dt>CUPS_SC_STATUS_NO_RESPONSE </dt>
+<dd class="description">The device did not respond</dd>
+<dt>CUPS_SC_STATUS_OK </dt>
+<dd class="description">Operation succeeded</dd>
+<dt>CUPS_SC_STATUS_TIMEOUT </dt>
+<dd class="description">The backend did not respond</dd>
+<dt>CUPS_SC_STATUS_TOO_BIG </dt>
+<dd class="description">Response too big</dd>
+</dl>
+</div>
 </body>
 </html>
index 3f4e2eee8ecaf31c4215380a5b4e453a60af13ac..e8c09e286e8a22cd6105e496029e986f43c0d5a7 100644 (file)
 <html>
 <!-- SECTION: Programming -->
 <head>
-       <title>HTTP and IPP APIs</title>
-       <meta name='keywords' content='Programming'>
-       <meta name='creator' content='Mini-XML v2.4'>
-       <style type='text/css'><!--
-       h1, h2, h3, p { font-family: sans-serif; text-align: justify; }
-       tt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }
-       pre { font-weight: bold; color: #7f0000; margin-left: 2em; }
-       span.info { background: #000000; border: solid thin #000000; color: #ffffff; font-size: 80%; font-style: italic; font-weight: bold; white-space: nowrap; }
-       h3 span.info { float: right; font-size: 100%; }
-       h1.title, h2.title, h3.title { border-bottom: solid 2px #000000; }
-       --></style>
+<title>HTTP and IPP APIs</title>
+<meta name="keywords" content="Programming">
+<meta name="creator" content="Mini-XML v2.5">
+<style type="text/css"><!--
+BODY {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+H1, H2, H3, H4, H5, H6, P, TD, TH {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+KBD {
+  font-family: monaco, courier, monospace;
+  font-weight: bold;
+}
+
+PRE {
+  font-family: monaco, courier, monospace;
+}
+
+PRE.command {
+  margin-left: 36pt;
+}
+
+PRE.example {
+  background: #eeeeee;
+  border: dotted thin #999999;
+  margin-left: 36pt;
+  padding: 10px;
+}
+
+PRE.command EM, PRE.example EM {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+P.command {
+  font-family: monaco, courier, monospace;
+  margin-left: 36pt;
+}
+
+P.formula {
+  font-style: italic;
+  margin-left: 36pt;
+}
+
+BLOCKQUOTE {
+  background: #cccccc;
+  border: solid thin #999999;
+  padding: 10pt;
+}
+
+A:link, A:visited {
+  text-decoration: none;
+  font-weight: bold;
+}
+
+A:link:hover, A:visited:hover, A:active {
+  text-decoration: underline;
+  font-weight: bold;
+}
+
+SUB, SUP {
+  font-size: 50%;
+}
+
+DIV.table TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.table CAPTION {
+  caption-side: top;
+  font-size: 120%;
+  font-style: italic;
+  font-weight: bold;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.table TABLE TD {
+  border: solid thin #cccccc;
+  padding-top: 5pt;
+}
+
+DIV.table TABLE TH {
+  background: #cccccc;
+  border: none;
+  border-bottom: solid thin #999999;
+}
+
+DIV.figure TABLE {
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.figure CAPTION {
+  caption-side: bottom;
+  font-size: 120%;
+  font-style: italic;
+  font-weight: bold;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+TH.label {
+  padding-top: 5pt;
+  text-align: right;
+  vertical-align: top;
+}
+
+HR {
+  border: solid thin;
+}
+
+SPAN.info {
+  background: #000000;
+  border: thin solid #000000;
+  color: #ffffff;
+  font-size: 80%;
+  font-style: italic;
+  font-weight: bold;
+  white-space: nowrap;
+}
+
+H2 SPAN.info, H3 SPAN.info, H4 SPAN.info {
+  float: right;
+  font-size: 100%;
+}
+
+H2.title, H3.title {
+  border-bottom: solid 2pt #000000;
+}
+
+DT {
+  margin-left: 36pt;
+  margin-top: 12pt;
+}
+
+DD {
+  margin-left: 54pt;
+}
+
+DL.category DT {
+  font-weight: bold;
+}
+
+P.summary {
+  margin-left: 36pt;
+  font-family: monaco, courier, monospace;
+}
+
+SPAN.message {
+  font-style: italic;
+  font-size: smaller;
+}
+
+DIV.summary TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin: 10px;
+}
+
+DIV.summary TABLE TD, DIV.summary TABLE TH {
+  border: solid thin #999999;
+  padding: 5px;
+  text-align: left;
+  vertical-align: top;
+}
+
+DIV.summary TABLE THEAD TH {
+  background: #eeeeee;
+}
+
+/* API documentation styles... */
+div.body h1 {
+  margin: 0;
+}
+div.body h2 {
+  margin-top: 1.5em;
+}
+div.body h3, div.body h4, div.body h5 {
+  margin-bottom: 0.5em;
+  margin-top: 1.5em;
+}
+.class, .enumeration, .function, .struct, .typedef, .union {
+  border-bottom: solid thin #999999;
+  margin-bottom: 0;
+  margin-top: 2em;
+}
+.description {
+  margin-top: 0.5em;
+}
+code, p.code, pre, ul.code li {
+  font-family: monaco, courier, monospace;
+  font-size: 90%;
+}
+ul.code, ul.contents, ul.subcontents {
+  list-style-type: none;
+  margin: 0;
+  padding-left: 0;
+}
+ul.code li {
+  margin: 0;
+}
+ul.contents > li {
+  margin-top: 1em;
+}
+ul.contents li ul.code, ul.contents li ul.subcontents {
+  padding-left: 2em;
+}
+div.body dl {
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dt {
+  font-style: italic;
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dd {
+  margin-bottom: 0.5em;
+}
+
+/* This is just for the HTML files generated with the framedhelp target */
+div.contents {
+  background: #e8e8e8;
+  border: solid thin black;
+  padding: 10px;
+}
+div.contents h1 {
+  font-size: 110%;
+}
+div.contents h2 {
+  font-size: 100%;
+}
+div.contents ul.contents {
+  font-size: 80%;
+}
+--></style>
 </head>
 <body>
+<div class='body'>
 <!--
-  "$Id: api-httpipp.shtml 6649 2007-07-11 21:46:42Z mike $"
+  "$Id: api-httpipp.header 7258 2008-01-28 00:15:05Z mike $"
+
+  HTTP and IPP API header for the Common UNIX Printing System (CUPS).
+
+  Copyright 2007-2008 by Apple Inc.
+  Copyright 1997-2006 by Easy Software Products, all rights reserved.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">HTTP and IPP APIs</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+       <th>Header</th>
+       <th>cups/cups.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <th>Library</th>
+       <td>-lcups</td>
+</tr>
+<tr>
+       <th>See Also</th>
+       <td>Programming: <a href='api-overview.html'>Introduction to CUPS Programming</a><br>
+       Programming: <a href='api-cups.html'>CUPS API</a><br>
+       References: <a href='spec-ipp.html'>CUPS Implementation of IPP</a></td>
+</tr>
+</tbody>
+</table></div>
+<h2 class="title">Contents</h2>
+<ul class="contents">
+</li>
+<li><a href="#OVERVIEW">Overview</a><ul class="subcontents">
+<li><a href="#CREATING_URI_STRINGS">Creating URI Strings</a></li>
+<li><a href="#SENDING_REQUESTS_WITH_FILES">Sending Requests with Files</a></li>
+<li><a href="#ASYNCHRONOUS_REQUEST_PROCESSING">Asynchronous Request Processing</a></li>
+</ul></li>
+<li><a href="#FUNCTIONS">Functions</a><ul class="code">
+<li><a href="#cupsDoAuthentication" title="Authenticate a request.">cupsDoAuthentication</a></li>
+<li><a href="#cupsDoFileRequest" title="Do an IPP request with a file.">cupsDoFileRequest</a></li>
+<li><a href="#cupsDoIORequest" title="Do an IPP request with file descriptors.">cupsDoIORequest</a></li>
+<li><a href="#cupsDoRequest" title="Do an IPP request.">cupsDoRequest</a></li>
+<li><a href="#cupsEncodeOptions" title="Encode printer options into IPP attributes.">cupsEncodeOptions</a></li>
+<li><a href="#cupsEncodeOptions2" title="Encode printer options into IPP attributes for a group.">cupsEncodeOptions2</a></li>
+<li><a href="#cupsGetResponse" title="Get a response to an IPP request.">cupsGetResponse</a></li>
+<li><a href="#cupsReadResponseData" title="Read additional data after the IPP response.">cupsReadResponseData</a></li>
+<li><a href="#cupsSendRequest" title="Send an IPP request.">cupsSendRequest</a></li>
+<li><a href="#cupsWriteRequestData" title="Write additional data after an IPP request.">cupsWriteRequestData</a></li>
+<li><a href="#httpAddrAny" title="Check for the &quot;any&quot; address.">httpAddrAny</a></li>
+<li><a href="#httpAddrEqual" title="Compare two addresses.">httpAddrEqual</a></li>
+<li><a href="#httpAddrLength" title="Return the length of the address in bytes.">httpAddrLength</a></li>
+<li><a href="#httpAddrLocalhost" title="Check for the local loopback address.">httpAddrLocalhost</a></li>
+<li><a href="#httpAddrLookup" title="Lookup the hostname associated with the address.">httpAddrLookup</a></li>
+<li><a href="#httpAddrString" title="Convert an address to a numeric string.">httpAddrString</a></li>
+<li><a href="#httpAssembleURI" title="Assemble a uniform resource identifier from its
+components.">httpAssembleURI</a></li>
+<li><a href="#httpAssembleURIf" title="Assemble a uniform resource identifier from its
+components with a formatted resource.">httpAssembleURIf</a></li>
+<li><a href="#httpBlocking" title="Set blocking/non-blocking behavior on a connection.">httpBlocking</a></li>
+<li><a href="#httpCheck" title="Check to see if there is a pending response from the server.">httpCheck</a></li>
+<li><a href="#httpClearCookie" title="Clear the cookie value(s).">httpClearCookie</a></li>
+<li><a href="#httpClearFields" title="Clear HTTP request fields.">httpClearFields</a></li>
+<li><a href="#httpClose" title="Close an HTTP connection...">httpClose</a></li>
+<li><a href="#httpConnect" title="Connect to a HTTP server.">httpConnect</a></li>
+<li><a href="#httpConnectEncrypt" title="Connect to a HTTP server using encryption.">httpConnectEncrypt</a></li>
+<li><a href="#httpDecode64" title="Base64-decode a string.">httpDecode64</a></li>
+<li><a href="#httpDecode64_2" title="Base64-decode a string.">httpDecode64_2</a></li>
+<li><a href="#httpDelete" title="Send a DELETE request to the server.">httpDelete</a></li>
+<li><a href="#httpEncode64" title="Base64-encode a string.">httpEncode64</a></li>
+<li><a href="#httpEncode64_2" title="Base64-encode a string.">httpEncode64_2</a></li>
+<li><a href="#httpEncryption" title="Set the required encryption on the link.">httpEncryption</a></li>
+<li><a href="#httpError" title="Get the last error on a connection.">httpError</a></li>
+<li><a href="#httpFlush" title="Flush data from a HTTP connection.">httpFlush</a></li>
+<li><a href="#httpFlushWrite" title="Flush data in write buffer.">httpFlushWrite</a></li>
+<li><a href="#httpGet" title="Send a GET request to the server.">httpGet</a></li>
+<li><a href="#httpGetAuthString" title="Get the current authorization string.">httpGetAuthString</a></li>
+<li><a href="#httpGetBlocking" title="Get the blocking/non-block state of a connection.">httpGetBlocking</a></li>
+<li><a href="#httpGetCookie" title="Get any cookie data from the response.">httpGetCookie</a></li>
+<li><a href="#httpGetDateString" title="Get a formatted date/time string from a time value.">httpGetDateString</a></li>
+<li><a href="#httpGetDateString2" title="Get a formatted date/time string from a time value.">httpGetDateString2</a></li>
+<li><a href="#httpGetDateTime" title="Get a time value from a formatted date/time string.">httpGetDateTime</a></li>
+<li><a href="#httpGetFd" title="Get the file descriptor associated with a connection.">httpGetFd</a></li>
+<li><a href="#httpGetField" title="Get a field value from a request/response.">httpGetField</a></li>
+<li><a href="#httpGetHostByName" title="Lookup a hostname or IPv4 address, and return
+address records for the specified name.">httpGetHostByName</a></li>
+<li><a href="#httpGetHostname" title="Get the FQDN for the connection or local system.">httpGetHostname</a></li>
+<li><a href="#httpGetLength" title="Get the amount of data remaining from the
+content-length or transfer-encoding fields.">httpGetLength</a></li>
+<li><a href="#httpGetLength2" title="Get the amount of data remaining from the
+content-length or transfer-encoding fields.">httpGetLength2</a></li>
+<li><a href="#httpGetStatus" title="Get the status of the last HTTP request.">httpGetStatus</a></li>
+<li><a href="#httpGetSubField" title="Get a sub-field value.">httpGetSubField</a></li>
+<li><a href="#httpGetSubField2" title="Get a sub-field value.">httpGetSubField2</a></li>
+<li><a href="#httpGets" title="Get a line of text from a HTTP connection.">httpGets</a></li>
+<li><a href="#httpHead" title="Send a HEAD request to the server.">httpHead</a></li>
+<li><a href="#httpInitialize" title="Initialize the HTTP interface library and set the
+default HTTP proxy (if any).">httpInitialize</a></li>
+<li><a href="#httpMD5" title="Compute the MD5 sum of the username:group:password.">httpMD5</a></li>
+<li><a href="#httpMD5Final" title="Combine the MD5 sum of the username, group, and password
+with the server-supplied nonce value, method, and
+request-uri.">httpMD5Final</a></li>
+<li><a href="#httpMD5String" title="Convert an MD5 sum to a character string.">httpMD5String</a></li>
+<li><a href="#httpOptions" title="Send an OPTIONS request to the server.">httpOptions</a></li>
+<li><a href="#httpPost" title="Send a POST request to the server.">httpPost</a></li>
+<li><a href="#httpPut" title="Send a PUT request to the server.">httpPut</a></li>
+<li><a href="#httpRead" title="Read data from a HTTP connection.">httpRead</a></li>
+<li><a href="#httpRead2" title="Read data from a HTTP connection.">httpRead2</a></li>
+<li><a href="#httpReconnect" title="Reconnect to a HTTP server.">httpReconnect</a></li>
+<li><a href="#httpSeparate" title="Separate a Universal Resource Identifier into its
+components.">httpSeparate</a></li>
+<li><a href="#httpSeparate2" title="Separate a Universal Resource Identifier into its
+components.">httpSeparate2</a></li>
+<li><a href="#httpSeparateURI" title="Separate a Universal Resource Identifier into its
+components.">httpSeparateURI</a></li>
+<li><a href="#httpSetAuthString" title="Set the current authorization string.">httpSetAuthString</a></li>
+<li><a href="#httpSetCookie" title="Set the cookie value(s)...">httpSetCookie</a></li>
+<li><a href="#httpSetExpect" title="Set the Expect: header in a request.">httpSetExpect</a></li>
+<li><a href="#httpSetField" title="Set the value of an HTTP header.">httpSetField</a></li>
+<li><a href="#httpSetLength" title="Set the content-length and content-encoding.">httpSetLength</a></li>
+<li><a href="#httpStatus" title="Return a short string describing a HTTP status code.">httpStatus</a></li>
+<li><a href="#httpTrace" title="Send an TRACE request to the server.">httpTrace</a></li>
+<li><a href="#httpUpdate" title="Update the current HTTP state for incoming data.">httpUpdate</a></li>
+<li><a href="#httpWait" title="Wait for data available on a connection.">httpWait</a></li>
+<li><a href="#httpWrite" title="Write data to a HTTP connection.">httpWrite</a></li>
+<li><a href="#httpWrite2" title="Write data to a HTTP connection.">httpWrite2</a></li>
+<li><a href="#ippAddBoolean" title="Add a boolean attribute to an IPP message.">ippAddBoolean</a></li>
+<li><a href="#ippAddBooleans" title="Add an array of boolean values.">ippAddBooleans</a></li>
+<li><a href="#ippAddCollection" title="Add a collection value.">ippAddCollection</a></li>
+<li><a href="#ippAddCollections" title="Add an array of collection values.">ippAddCollections</a></li>
+<li><a href="#ippAddDate" title="Add a date attribute to an IPP message.">ippAddDate</a></li>
+<li><a href="#ippAddInteger" title="Add a integer attribute to an IPP message.">ippAddInteger</a></li>
+<li><a href="#ippAddIntegers" title="Add an array of integer values.">ippAddIntegers</a></li>
+<li><a href="#ippAddOctetString" title="Add an octetString value to an IPP message.">ippAddOctetString</a></li>
+<li><a href="#ippAddRange" title="Add a range of values to an IPP message.">ippAddRange</a></li>
+<li><a href="#ippAddRanges" title="Add ranges of values to an IPP message.">ippAddRanges</a></li>
+<li><a href="#ippAddResolution" title="Add a resolution value to an IPP message.">ippAddResolution</a></li>
+<li><a href="#ippAddResolutions" title="Add resolution values to an IPP message.">ippAddResolutions</a></li>
+<li><a href="#ippAddSeparator" title="Add a group separator to an IPP message.">ippAddSeparator</a></li>
+<li><a href="#ippAddString" title="Add a language-encoded string to an IPP message.">ippAddString</a></li>
+<li><a href="#ippAddStrings" title="Add language-encoded strings to an IPP message.">ippAddStrings</a></li>
+<li><a href="#ippDateToTime" title="Convert from RFC 1903 Date/Time format to UNIX time
+in seconds.">ippDateToTime</a></li>
+<li><a href="#ippDelete" title="Delete an IPP message.">ippDelete</a></li>
+<li><a href="#ippDeleteAttribute" title="Delete a single attribute in an IPP message.">ippDeleteAttribute</a></li>
+<li><a href="#ippErrorString" title="Return a name for the given status code.">ippErrorString</a></li>
+<li><a href="#ippErrorValue" title="Return a status code for the given name.">ippErrorValue</a></li>
+<li><a href="#ippFindAttribute" title="Find a named attribute in a request...">ippFindAttribute</a></li>
+<li><a href="#ippFindNextAttribute" title="Find the next named attribute in a request...">ippFindNextAttribute</a></li>
+<li><a href="#ippLength" title="Compute the length of an IPP message.">ippLength</a></li>
+<li><a href="#ippNew" title="Allocate a new IPP message.">ippNew</a></li>
+<li><a href="#ippNewRequest" title="Allocate a new IPP request message.">ippNewRequest</a></li>
+<li><a href="#ippOpString" title="Return a name for the given operation id.">ippOpString</a></li>
+<li><a href="#ippOpValue" title="Return an operation id for the given name.">ippOpValue</a></li>
+<li><a href="#ippPort" title="Return the default IPP port number.">ippPort</a></li>
+<li><a href="#ippRead" title="Read data for an IPP message from a HTTP connection.">ippRead</a></li>
+<li><a href="#ippReadFile" title="Read data for an IPP message from a file.">ippReadFile</a></li>
+<li><a href="#ippReadIO" title="Read data for an IPP message.">ippReadIO</a></li>
+<li><a href="#ippSetPort" title="Set the default port number.">ippSetPort</a></li>
+<li><a href="#ippTimeToDate" title="Convert from UNIX time to RFC 1903 format.">ippTimeToDate</a></li>
+<li><a href="#ippWrite" title="Write data for an IPP message to a HTTP connection.">ippWrite</a></li>
+<li><a href="#ippWriteFile" title="Write data for an IPP message to a file.">ippWriteFile</a></li>
+<li><a href="#ippWriteIO" title="Write data for an IPP message.">ippWriteIO</a></li>
+</ul>
+<li><a href="#TYPES">Data Types</a><ul class="code">
+       <li><a href="#http_addrlist_t" title="Socket address list, which is
+used to enumerate all of the
+addresses that are associated
+with a hostname. ">http_addrlist_t</a></li>
+       <li><a href="#http_auth_t" title="HTTP authentication types">http_auth_t</a></li>
+       <li><a href="#http_encoding_t" title="HTTP transfer encoding values">http_encoding_t</a></li>
+       <li><a href="#http_encryption_t" title="HTTP encryption values">http_encryption_t</a></li>
+       <li><a href="#http_t" title="HTTP connection type">http_t</a></li>
+       <li><a href="#ipp_attribute_t" title="Attribute">ipp_attribute_t</a></li>
+       <li><a href="#ipp_iocb_t" title="IPP IO Callback Function ">ipp_iocb_t</a></li>
+       <li><a href="#ipp_request_t" title="Request Header">ipp_request_t</a></li>
+       <li><a href="#ipp_t" title="Attribute Value">ipp_t</a></li>
+       <li><a href="#ipp_uchar_t" title="IPP status codes...">ipp_uchar_t</a></li>
+       <li><a href="#ipp_value_t" title="New in CUPS 1.1.19">ipp_value_t</a></li>
+</ul></li>
+<li><a href="#STRUCTURES">Structures</a><ul class="code">
+       <li><a href="#http_addrlist_s" title="Socket address list, which is
+used to enumerate all of the
+addresses that are associated
+with a hostname. ">http_addrlist_s</a></li>
+       <li><a href="#ipp_attribute_s" title="Attribute">ipp_attribute_s</a></li>
+       <li><a href="#ipp_s" title="IPP Request/Response/Notification">ipp_s</a></li>
+</ul></li>
+<li><a href="#UNIONS">Unions</a><ul class="code">
+       <li><a href="#ipp_request_u" title="Request Header">ipp_request_u</a></li>
+       <li><a href="#ipp_value_u" title="New in CUPS 1.1.19">ipp_value_u</a></li>
+</ul></li>
+<li><a href="#ENUMERATIONS">Constants</a><ul class="code">
+       <li><a href="#http_auth_e" title="HTTP authentication types">http_auth_e</a></li>
+       <li><a href="#http_encoding_e" title="HTTP transfer encoding values">http_encoding_e</a></li>
+       <li><a href="#http_encryption_e" title="HTTP encryption values">http_encryption_e</a></li>
+       <li><a href="#http_field_e" title="HTTP field names">http_field_e</a></li>
+       <li><a href="#http_keepalive_e" title="Types and structures...">http_keepalive_e</a></li>
+       <li><a href="#http_state_e" title="">http_state_e</a></li>
+       <li><a href="#http_status_e" title="HTTP status codes">http_status_e</a></li>
+       <li><a href="#http_uri_coding_e" title="">http_uri_coding_e</a></li>
+       <li><a href="#http_uri_status_e" title="">http_uri_status_e</a></li>
+       <li><a href="#http_version_e" title="">http_version_e</a></li>
+       <li><a href="#ipp_finish_e" title="">ipp_finish_e</a></li>
+       <li><a href="#ipp_jstate_e" title="">ipp_jstate_e</a></li>
+       <li><a href="#ipp_op_e" title="">ipp_op_e</a></li>
+       <li><a href="#ipp_orient_e" title="">ipp_orient_e</a></li>
+       <li><a href="#ipp_pstate_e" title="">ipp_pstate_e</a></li>
+       <li><a href="#ipp_quality_e" title="">ipp_quality_e</a></li>
+       <li><a href="#ipp_res_e" title="Types and structures...">ipp_res_e</a></li>
+       <li><a href="#ipp_state_e" title="">ipp_state_e</a></li>
+       <li><a href="#ipp_status_e" title="IPP status codes...">ipp_status_e</a></li>
+       <li><a href="#ipp_tag_e" title="Format tags for attributes...">ipp_tag_e</a></li>
+</ul></li>
+</ul>
+<!--
+  "$Id: api-httpipp.shtml 7258 2008-01-28 00:15:05Z mike $"
 
   HTTP and IPP API introduction for the Common UNIX Printing System (CUPS).
 
-  Copyright 2007 by Apple Inc.
+  Copyright 2007-2008 by Apple Inc.
   Copyright 1997-2006 by Easy Software Products, all rights reserved.
 
   These coded instructions, statements, and computer programs are the
   file is missing or damaged, see the license at "http://www.cups.org/".
 -->
 
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
+
+<p>The CUPS HTTP and IPP APIs provide low-level access to the HTTP and IPP
+protocols and CUPS scheduler. They are typically used by monitoring and
+administration programs to perform specific functions not supported by the
+high-level CUPS API functions.</p>
+
+<p>The HTTP APIs use an opaque structure called
+<a href='#http_t'><code>http_t</code></a> to manage connections to
+a particular HTTP or IPP server. The
+<a href='#httpConnectEncrypt'><code>httpConnectEncrypt</code></a> function is
+used to create an instance of this structure for a particular server.
+The constant <code>CUPS_HTTP_DEFAULT</code> can be used with all of the
+<code>cups</code> functions to refer to the default CUPS server - the functions
+create a per-thread <a href='#http_t'><code>http_t</code></a> as needed.</p>
+
+<p>The IPP APIs use two structures for requests (messages sent to the CUPS
+scheduler) and responses (messages sent back to your application from the
+scheduler). The <a href='#ipp_t'><code>ipp_t</code></a> structure holds a
+complete request or response and is allocated using the
+<a href='#ippNew'><code>ippNew</code></a> or
+<a href='#ippNewRequest'><code>ippNewRequest</code></a> functions and
+freed using the <a href='#ippDelete'><code>ippDelete</code></a> function.</p>
+
+<p>The second structure is called
+<a href='#ipp_attribute_t'><code>ipp_attribute_t</code></a> and holds a
+single IPP attribute which consists of a group tag (<code>group_tag</code>), a
+value type tag (<code>value_tag</code>), the attribute name (<code>name</code>),
+and 1 or more values (<code>values[]</code>). Attributes are added to an
+<a href='#ipp_t'><code>ipp_t</code></a> structure using one of the
+<code>ippAdd</code> functions. For example, use
+<a href='#ippAddString'><code>ippAddString</code></a> to add a
+"requesting-user-name" string attribute to a request:</p>
+
+<pre class='example'>
+<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(IPP_GET_JOBS);
+
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+             NULL, cupsUser());
+</pre>
 
-<p>The CUPS HTTP and IPP APIs provide low-level access to the
-HTTP and IPP protocols and CUPS scheduler. They are typically
-used by monitoring and administration programs to perform
-specific functions not supported by the high-level CUPS API
-functions.</p>
+<p>Once you have created an IPP request, use the <code>cups</code>
+functions to send the request to and read the response from the server.
+For example, the <a href='#cupsDoRequest'><code>cupsDoRequest</code></a>
+function can be used for simple query operations that do not involve files:</p>
 
-<h2 class='title'>General Usage</h2>
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
 
-<p>The <var>&lt;cups/cups.h&gt;</var> header file must be included to
-use the HTTP and IPP functions.</p>
 
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+<a href='#ipp_t'>ipp_t</a> *<a name='get_jobs'>get_jobs</a>(void)
+{
+  <a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(IPP_GET_JOBS);
 
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
+  <a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+               NULL, cupsUser());
+
+  return (<a href='#cupsDoRequest'>cupsDoRequest</a>(CUPS_HTTP_DEFAULT, request, "/"));
+}
 </pre>
 
-<h2 class='title'>Compatibility</h2>
-
-<p>Unless otherwise specified, the HTTP and IPP API functions
-require CUPS 1.1 or higher.</p>
-<h2 class='title'>Contents</h2>
-<ul>
-       <li><a href='#ENUMERATIONS'>Enumerations</a></li>
-       <li><a href='#FUNCTIONS'>Functions</a></li>
-       <li><a href='#STRUCTURES'>Structures</a></li>
-       <li><a href='#TYPES'>Types</a></li>
-       <li><a href='#UNIONS'>Unions</a></li>
-</ul>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='ENUMERATIONS'>Enumerations</a></h2>
-<ul>
-       <li><a href='#http_auth_e'><tt>http_auth_e</tt></a> </li>
-       <li><a href='#http_encoding_e'><tt>http_encoding_e</tt></a> </li>
-       <li><a href='#http_encryption_e'><tt>http_encryption_e</tt></a> </li>
-       <li><a href='#http_field_e'><tt>http_field_e</tt></a> </li>
-       <li><a href='#http_keepalive_e'><tt>http_keepalive_e</tt></a> </li>
-       <li><a href='#http_state_e'><tt>http_state_e</tt></a> </li>
-       <li><a href='#http_status_e'><tt>http_status_e</tt></a> </li>
-       <li><a href='#http_uri_coding_e'><tt>http_uri_coding_e</tt></a> </li>
-       <li><a href='#http_uri_status_e'><tt>http_uri_status_e</tt></a> </li>
-       <li><a href='#http_version_e'><tt>http_version_e</tt></a> </li>
-       <li><a href='#ipp_finish_e'><tt>ipp_finish_e</tt></a> </li>
-       <li><a href='#ipp_jstate_e'><tt>ipp_jstate_e</tt></a> </li>
-       <li><a href='#ipp_op_e'><tt>ipp_op_e</tt></a> </li>
-       <li><a href='#ipp_orient_e'><tt>ipp_orient_e</tt></a> </li>
-       <li><a href='#ipp_pstate_e'><tt>ipp_pstate_e</tt></a> </li>
-       <li><a href='#ipp_quality_e'><tt>ipp_quality_e</tt></a> </li>
-       <li><a href='#ipp_res_e'><tt>ipp_res_e</tt></a> </li>
-       <li><a href='#ipp_state_e'><tt>ipp_state_e</tt></a> </li>
-       <li><a href='#ipp_status_e'><tt>ipp_status_e</tt></a> </li>
-       <li><a href='#ipp_tag_e'><tt>ipp_tag_e</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='http_auth_e'>http_auth_e</a></h3>
-<h4>Description</h4>
-<p>HTTP authentication types
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>HTTP_AUTH_BASIC</tt> </td><td>Basic authentication in use
-</td></tr>
-<tr><td><tt>HTTP_AUTH_MD5</tt> </td><td>Digest authentication in use
-</td></tr>
-<tr><td><tt>HTTP_AUTH_MD5_INT</tt> </td><td>Digest authentication in use for body
-</td></tr>
-<tr><td><tt>HTTP_AUTH_MD5_SESS</tt> </td><td>MD5-session authentication in use
-</td></tr>
-<tr><td><tt>HTTP_AUTH_MD5_SESS_INT</tt> </td><td>MD5-session authentication in use for body
-</td></tr>
-<tr><td><tt>HTTP_AUTH_NEGOTIATE</tt> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></td><td>GSSAPI authentication in use 
-</td></tr>
-<tr><td><tt>HTTP_AUTH_NONE</tt> </td><td>No authentication in use
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='http_encoding_e'>http_encoding_e</a></h3>
-<h4>Description</h4>
-<p>HTTP transfer encoding values
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>HTTP_ENCODE_CHUNKED</tt> </td><td>Data is chunked
-</td></tr>
-<tr><td><tt>HTTP_ENCODE_FIELDS</tt> </td><td>Sending HTTP fields
-</td></tr>
-<tr><td><tt>HTTP_ENCODE_LENGTH</tt> </td><td>Data is sent with Content-Length
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='http_encryption_e'>http_encryption_e</a></h3>
-<h4>Description</h4>
-<p>HTTP encryption values
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>HTTP_ENCRYPT_ALWAYS</tt> </td><td>Always encrypt (SSL)
-</td></tr>
-<tr><td><tt>HTTP_ENCRYPT_IF_REQUESTED</tt> </td><td>Encrypt if requested (TLS upgrade)
-</td></tr>
-<tr><td><tt>HTTP_ENCRYPT_NEVER</tt> </td><td>Never encrypt
-</td></tr>
-<tr><td><tt>HTTP_ENCRYPT_REQUIRED</tt> </td><td>Encryption is required (TLS upgrade)
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='http_field_e'>http_field_e</a></h3>
-<h4>Description</h4>
-<p>HTTP field names
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>HTTP_FIELD_ACCEPT_LANGUAGE</tt> </td><td>Accept-Language field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_ACCEPT_RANGES</tt> </td><td>Accept-Ranges field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_AUTHORIZATION</tt> </td><td>Authorization field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_CONNECTION</tt> </td><td>Connection field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_CONTENT_ENCODING</tt> </td><td>Content-Encoding field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_CONTENT_LANGUAGE</tt> </td><td>Content-Language field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_CONTENT_LENGTH</tt> </td><td>Content-Length field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_CONTENT_LOCATION</tt> </td><td>Content-Location field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_CONTENT_MD5</tt> </td><td>Content-MD5 field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_CONTENT_RANGE</tt> </td><td>Content-Range field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_CONTENT_TYPE</tt> </td><td>Content-Type field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_CONTENT_VERSION</tt> </td><td>Content-Version field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_DATE</tt> </td><td>Date field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_HOST</tt> </td><td>Host field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_IF_MODIFIED_SINCE</tt> </td><td>If-Modified-Since field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_IF_UNMODIFIED_SINCE</tt> </td><td>If-Unmodified-Since field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_KEEP_ALIVE</tt> </td><td>Keep-Alive field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_LAST_MODIFIED</tt> </td><td>Last-Modified field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_LINK</tt> </td><td>Link field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_LOCATION</tt> </td><td>Location field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_MAX</tt> </td><td>Maximum field index
-</td></tr>
-<tr><td><tt>HTTP_FIELD_RANGE</tt> </td><td>Range field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_REFERER</tt> </td><td>Referer field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_RETRY_AFTER</tt> </td><td>Retry-After field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_TRANSFER_ENCODING</tt> </td><td>Transfer-Encoding field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_UNKNOWN</tt> </td><td>Unknown field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_UPGRADE</tt> </td><td>Upgrade field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_USER_AGENT</tt> </td><td>User-Agent field
-</td></tr>
-<tr><td><tt>HTTP_FIELD_WWW_AUTHENTICATE</tt> </td><td>WWW-Authenticate field
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='http_keepalive_e'>http_keepalive_e</a></h3>
-<h4>Description</h4>
-<p>Types and structures...
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>HTTP_KEEPALIVE_OFF</tt> </td><td>No keep alive support
-</td></tr>
-<tr><td><tt>HTTP_KEEPALIVE_ON</tt> </td><td>Use keep alive
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='http_state_e'>http_state_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>HTTP_CLOSE</tt> </td><td>CLOSE command, waiting for blank line
-</td></tr>
-<tr><td><tt>HTTP_DELETE</tt> </td><td>DELETE command, waiting for blank line
-</td></tr>
-<tr><td><tt>HTTP_GET</tt> </td><td>GET command, waiting for blank line
-</td></tr>
-<tr><td><tt>HTTP_GET_SEND</tt> </td><td>GET command, sending data
-</td></tr>
-<tr><td><tt>HTTP_HEAD</tt> </td><td>HEAD command, waiting for blank line
-</td></tr>
-<tr><td><tt>HTTP_OPTIONS</tt> </td><td>OPTIONS command, waiting for blank line
-</td></tr>
-<tr><td><tt>HTTP_POST</tt> </td><td>POST command, waiting for blank line
-</td></tr>
-<tr><td><tt>HTTP_POST_RECV</tt> </td><td>POST command, receiving data
-</td></tr>
-<tr><td><tt>HTTP_POST_SEND</tt> </td><td>POST command, sending data
-</td></tr>
-<tr><td><tt>HTTP_PUT</tt> </td><td>PUT command, waiting for blank line
-</td></tr>
-<tr><td><tt>HTTP_PUT_RECV</tt> </td><td>PUT command, receiving data
-</td></tr>
-<tr><td><tt>HTTP_STATUS</tt> </td><td>Command complete, sending status
-</td></tr>
-<tr><td><tt>HTTP_TRACE</tt> </td><td>TRACE command, waiting for blank line
-</td></tr>
-<tr><td><tt>HTTP_WAITING</tt> </td><td>Waiting for command
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='http_status_e'>http_status_e</a></h3>
-<h4>Description</h4>
-<p>HTTP status codes
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>HTTP_ACCEPTED</tt> </td><td>DELETE command was successful
-</td></tr>
-<tr><td><tt>HTTP_BAD_GATEWAY</tt> </td><td>Bad gateway
-</td></tr>
-<tr><td><tt>HTTP_BAD_REQUEST</tt> </td><td>Bad request
-</td></tr>
-<tr><td><tt>HTTP_CONFLICT</tt> </td><td>Request is self-conflicting
-</td></tr>
-<tr><td><tt>HTTP_CONTINUE</tt> </td><td>Everything OK, keep going...
-</td></tr>
-<tr><td><tt>HTTP_CREATED</tt> </td><td>PUT command was successful
-</td></tr>
-<tr><td><tt>HTTP_ERROR</tt> </td><td>An error response from httpXxxx()
-</td></tr>
-<tr><td><tt>HTTP_EXPECTATION_FAILED</tt> </td><td>The expectation given in an Expect header field was not met
-</td></tr>
-<tr><td><tt>HTTP_FORBIDDEN</tt> </td><td>Forbidden to access this URI
-</td></tr>
-<tr><td><tt>HTTP_GATEWAY_TIMEOUT</tt> </td><td>Gateway connection timed out
-</td></tr>
-<tr><td><tt>HTTP_GONE</tt> </td><td>Server has gone away
-</td></tr>
-<tr><td><tt>HTTP_LENGTH_REQUIRED</tt> </td><td>A content length or encoding is required
-</td></tr>
-<tr><td><tt>HTTP_METHOD_NOT_ALLOWED</tt> </td><td>Method is not allowed
-</td></tr>
-<tr><td><tt>HTTP_MOVED_PERMANENTLY</tt> </td><td>Document has moved permanently
-</td></tr>
-<tr><td><tt>HTTP_MOVED_TEMPORARILY</tt> </td><td>Document has moved temporarily
-</td></tr>
-<tr><td><tt>HTTP_MULTIPLE_CHOICES</tt> </td><td>Multiple files match request
-</td></tr>
-<tr><td><tt>HTTP_NOT_ACCEPTABLE</tt> </td><td>Not Acceptable
-</td></tr>
-<tr><td><tt>HTTP_NOT_AUTHORITATIVE</tt> </td><td>Information isn't authoritative
-</td></tr>
-<tr><td><tt>HTTP_NOT_FOUND</tt> </td><td>URI was not found
-</td></tr>
-<tr><td><tt>HTTP_NOT_IMPLEMENTED</tt> </td><td>Feature not implemented
-</td></tr>
-<tr><td><tt>HTTP_NOT_MODIFIED</tt> </td><td>File not modified
-</td></tr>
-<tr><td><tt>HTTP_NOT_SUPPORTED</tt> </td><td>HTTP version not supported
-</td></tr>
-<tr><td><tt>HTTP_NO_CONTENT</tt> </td><td>Successful command, no new data
-</td></tr>
-<tr><td><tt>HTTP_OK</tt> </td><td>OPTIONS/GET/HEAD/POST/TRACE command was successful
-</td></tr>
-<tr><td><tt>HTTP_PARTIAL_CONTENT</tt> </td><td>Only a partial file was recieved/sent
-</td></tr>
-<tr><td><tt>HTTP_PAYMENT_REQUIRED</tt> </td><td>Payment required
-</td></tr>
-<tr><td><tt>HTTP_PRECONDITION</tt> </td><td>Precondition failed
-</td></tr>
-<tr><td><tt>HTTP_PROXY_AUTHENTICATION</tt> </td><td>Proxy Authentication is Required
-</td></tr>
-<tr><td><tt>HTTP_REQUESTED_RANGE</tt> </td><td>The requested range is not satisfiable
-</td></tr>
-<tr><td><tt>HTTP_REQUEST_TIMEOUT</tt> </td><td>Request timed out
-</td></tr>
-<tr><td><tt>HTTP_REQUEST_TOO_LARGE</tt> </td><td>Request entity too large
-</td></tr>
-<tr><td><tt>HTTP_RESET_CONTENT</tt> </td><td>Content was reset/recreated
-</td></tr>
-<tr><td><tt>HTTP_SEE_OTHER</tt> </td><td>See this other link...
-</td></tr>
-<tr><td><tt>HTTP_SERVER_ERROR</tt> </td><td>Internal server error
-</td></tr>
-<tr><td><tt>HTTP_SERVICE_UNAVAILABLE</tt> </td><td>Service is unavailable
-</td></tr>
-<tr><td><tt>HTTP_SWITCHING_PROTOCOLS</tt> </td><td>HTTP upgrade to TLS/SSL
-</td></tr>
-<tr><td><tt>HTTP_UNAUTHORIZED</tt> </td><td>Unauthorized to access host
-</td></tr>
-<tr><td><tt>HTTP_UNSUPPORTED_MEDIATYPE</tt> </td><td>The requested media type is unsupported
-</td></tr>
-<tr><td><tt>HTTP_UPGRADE_REQUIRED</tt> </td><td>Upgrade to SSL/TLS required
-</td></tr>
-<tr><td><tt>HTTP_URI_TOO_LONG</tt> </td><td>URI too long
-</td></tr>
-<tr><td><tt>HTTP_USE_PROXY</tt> </td><td>Must use a proxy to access this URI
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='http_uri_coding_e'>http_uri_coding_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>HTTP_URI_CODING_ALL</tt> </td><td>En/decode everything
-</td></tr>
-<tr><td><tt>HTTP_URI_CODING_HOSTNAME</tt> </td><td>En/decode the hostname portion
-</td></tr>
-<tr><td><tt>HTTP_URI_CODING_MOST</tt> </td><td>En/decode all but the query
-</td></tr>
-<tr><td><tt>HTTP_URI_CODING_NONE</tt> </td><td>Don't en/decode anything
-</td></tr>
-<tr><td><tt>HTTP_URI_CODING_QUERY</tt> </td><td>En/decode the query portion
-</td></tr>
-<tr><td><tt>HTTP_URI_CODING_RESOURCE</tt> </td><td>En/decode the resource portion
-</td></tr>
-<tr><td><tt>HTTP_URI_CODING_USERNAME</tt> </td><td>En/decode the username portion
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='http_uri_status_e'>http_uri_status_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>HTTP_URI_BAD_ARGUMENTS</tt> </td><td>Bad arguments to function (error)
-</td></tr>
-<tr><td><tt>HTTP_URI_BAD_HOSTNAME</tt> </td><td>Bad hostname in URI (error)
-</td></tr>
-<tr><td><tt>HTTP_URI_BAD_PORT</tt> </td><td>Bad port number in URI (error)
-</td></tr>
-<tr><td><tt>HTTP_URI_BAD_RESOURCE</tt> </td><td>Bad resource in URI (error)
-</td></tr>
-<tr><td><tt>HTTP_URI_BAD_SCHEME</tt> </td><td>Bad scheme in URI (error)
-</td></tr>
-<tr><td><tt>HTTP_URI_BAD_URI</tt> </td><td>Bad/empty URI (error)
-</td></tr>
-<tr><td><tt>HTTP_URI_BAD_USERNAME</tt> </td><td>Bad username in URI (error)
-</td></tr>
-<tr><td><tt>HTTP_URI_MISSING_RESOURCE</tt> </td><td>Missing resource in URI (warning)
-</td></tr>
-<tr><td><tt>HTTP_URI_MISSING_SCHEME</tt> </td><td>Missing scheme in URI (warning)
-</td></tr>
-<tr><td><tt>HTTP_URI_OK</tt> </td><td>URI decoded OK
-</td></tr>
-<tr><td><tt>HTTP_URI_OVERFLOW</tt> </td><td>URI buffer for httpAssembleURI is too small
-</td></tr>
-<tr><td><tt>HTTP_URI_UNKNOWN_SCHEME</tt> </td><td>Unknown scheme in URI (warning)
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='http_version_e'>http_version_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>HTTP_0_9</tt> </td><td>HTTP/0.9
-</td></tr>
-<tr><td><tt>HTTP_1_0</tt> </td><td>HTTP/1.0
-</td></tr>
-<tr><td><tt>HTTP_1_1</tt> </td><td>HTTP/1.1
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_finish_e'>ipp_finish_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>IPP_FINISHINGS_BALE</tt> </td><td>Bale (any type)
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_BIND</tt> </td><td>Bind
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_BIND_BOTTOM</tt> </td><td>Bind on bottom
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_BIND_LEFT</tt> </td><td>Bind on left
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_BIND_RIGHT</tt> </td><td>Bind on right
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_BIND_TOP</tt> </td><td>Bind on top
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_BOOKLET_MAKER</tt> </td><td>Fold to make booklet
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_COVER</tt> </td><td>Add cover
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_EDGE_STITCH</tt> </td><td>Stitch along any side
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_EDGE_STITCH_BOTTOM</tt> </td><td>Stitch along bottom edge
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_EDGE_STITCH_LEFT</tt> </td><td>Stitch along left side
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_EDGE_STITCH_RIGHT</tt> </td><td>Stitch along right side
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_EDGE_STITCH_TOP</tt> </td><td>Stitch along top edge
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_FOLD</tt> </td><td>Fold (any type)
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_JOB_OFFSET</tt> </td><td>Offset for binding (any type)
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_NONE</tt> </td><td>No finishing
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_PUNCH</tt> </td><td>Punch (any location/count)
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_SADDLE_STITCH</tt> </td><td>Staple interior
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_STAPLE</tt> </td><td>Staple (any location)
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_STAPLE_BOTTOM_LEFT</tt> </td><td>Staple bottom left corner
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_STAPLE_BOTTOM_RIGHT</tt> </td><td>Staple bottom right corner
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_STAPLE_DUAL_BOTTOM</tt> </td><td>Two staples on bottom
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_STAPLE_DUAL_LEFT</tt> </td><td>Two staples on left
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_STAPLE_DUAL_RIGHT</tt> </td><td>Two staples on right
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_STAPLE_DUAL_TOP</tt> </td><td>Two staples on top
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_STAPLE_TOP_LEFT</tt> </td><td>Staple top left corner
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_STAPLE_TOP_RIGHT</tt> </td><td>Staple top right corner
-</td></tr>
-<tr><td><tt>IPP_FINISHINGS_TRIM</tt> </td><td>Trim (any type)
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_jstate_e'>ipp_jstate_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>IPP_JOB_ABORTED</tt> </td><td>Job has aborted due to error
-</td></tr>
-<tr><td><tt>IPP_JOB_CANCELED</tt> </td><td>Job has been canceled
-</td></tr>
-<tr><td><tt>IPP_JOB_COMPLETED</tt> </td><td>Job has completed successfully
-</td></tr>
-<tr><td><tt>IPP_JOB_HELD</tt> </td><td>Job is held for printing
-</td></tr>
-<tr><td><tt>IPP_JOB_PENDING</tt> </td><td>Job is waiting to be printed
-</td></tr>
-<tr><td><tt>IPP_JOB_PROCESSING</tt> </td><td>Job is currently printing
-</td></tr>
-<tr><td><tt>IPP_JOB_STOPPED</tt> </td><td>Job has been stopped
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_op_e'>ipp_op_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>CUPS_ACCEPT_JOBS</tt> </td><td>Accept new jobs on a printer
-</td></tr>
-<tr><td><tt>CUPS_ADD_MODIFY_CLASS</tt> </td><td>Add or modify a class
-</td></tr>
-<tr><td><tt>CUPS_ADD_MODIFY_PRINTER</tt> </td><td>Add or modify a printer
-</td></tr>
-<tr><td><tt>CUPS_AUTHENTICATE_JOB</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Authenticate a job 
-</td></tr>
-<tr><td><tt>CUPS_DELETE_CLASS</tt> </td><td>Delete a class
-</td></tr>
-<tr><td><tt>CUPS_DELETE_PRINTER</tt> </td><td>Delete a printer
-</td></tr>
-<tr><td><tt>CUPS_GET_CLASSES</tt> <span class='info'>&nbsp;DEPRECATED&nbsp;</span></td><td>Get a list of classes 
-</td></tr>
-<tr><td><tt>CUPS_GET_DEFAULT</tt> </td><td>Get the default printer
-</td></tr>
-<tr><td><tt>CUPS_GET_DEVICES</tt> </td><td>Get a list of supported devices
-</td></tr>
-<tr><td><tt>CUPS_GET_DOCUMENT</tt> <span class='info'>&nbsp;CUPS 1.4&nbsp;</span></td><td>Get a document file 
-</td></tr>
-<tr><td><tt>CUPS_GET_PPD</tt> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></td><td>Get a PPD file 
-</td></tr>
-<tr><td><tt>CUPS_GET_PPDS</tt> </td><td>Get a list of supported drivers
-</td></tr>
-<tr><td><tt>CUPS_GET_PRINTERS</tt> </td><td>Get a list of printers and/or classes
-</td></tr>
-<tr><td><tt>CUPS_MOVE_JOB</tt> </td><td>Move a job to a different printer
-</td></tr>
-<tr><td><tt>CUPS_REJECT_JOBS</tt> </td><td>Reject new jobs on a printer
-</td></tr>
-<tr><td><tt>CUPS_SET_DEFAULT</tt> </td><td>Set the default printer
-</td></tr>
-<tr><td><tt>IPP_ACTIVATE_PRINTER</tt> </td><td>Start a printer @private@
-</td></tr>
-<tr><td><tt>IPP_CANCEL_CURRENT_JOB</tt> </td><td>Cancel the current job @private@
-</td></tr>
-<tr><td><tt>IPP_CANCEL_JOB</tt> </td><td>Cancel a job
-</td></tr>
-<tr><td><tt>IPP_CANCEL_SUBSCRIPTION</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Cancel a subscription 
-</td></tr>
-<tr><td><tt>IPP_CREATE_JOB</tt> </td><td>Create an empty print job
-</td></tr>
-<tr><td><tt>IPP_CREATE_JOB_SUBSCRIPTION</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Create a job subscription 
-</td></tr>
-<tr><td><tt>IPP_CREATE_PRINTER_SUBSCRIPTION</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Create a printer subscription 
-</td></tr>
-<tr><td><tt>IPP_DEACTIVATE_PRINTER</tt> </td><td>Stop a printer @private@
-</td></tr>
-<tr><td><tt>IPP_DISABLE_PRINTER</tt> </td><td>Stop a printer
-</td></tr>
-<tr><td><tt>IPP_ENABLE_PRINTER</tt> </td><td>Start a printer
-</td></tr>
-<tr><td><tt>IPP_GET_JOBS</tt> </td><td>Get a list of jobs
-</td></tr>
-<tr><td><tt>IPP_GET_JOB_ATTRIBUTES</tt> </td><td>Get job attributes
-</td></tr>
-<tr><td><tt>IPP_GET_NOTIFICATIONS</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Get notification events 
-</td></tr>
-<tr><td><tt>IPP_GET_PRINTER_ATTRIBUTES</tt> </td><td>Get printer attributes
-</td></tr>
-<tr><td><tt>IPP_GET_PRINTER_SUPPORTED_VALUES</tt> </td><td>Get supported attribute values
-</td></tr>
-<tr><td><tt>IPP_GET_PRINT_SUPPORT_FILES</tt> </td><td>Get printer support files @private@
-</td></tr>
-<tr><td><tt>IPP_GET_SUBSCRIPTIONS</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Get list of subscriptions 
-</td></tr>
-<tr><td><tt>IPP_GET_SUBSCRIPTION_ATTRIBUTES</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Get subscription attributes 
-</td></tr>
-<tr><td><tt>IPP_HOLD_JOB</tt> </td><td>Hold a job for printing
-</td></tr>
-<tr><td><tt>IPP_HOLD_NEW_JOBS</tt> </td><td>Hold new jobs @private@
-</td></tr>
-<tr><td><tt>IPP_PAUSE_PRINTER</tt> </td><td>Stop a printer
-</td></tr>
-<tr><td><tt>IPP_PAUSE_PRINTER_AFTER_CURRENT_JOB</tt> </td><td>Stop printer after the current job @private@
-</td></tr>
-<tr><td><tt>IPP_PRINT_JOB</tt> </td><td>Print a single file
-</td></tr>
-<tr><td><tt>IPP_PRINT_URI</tt> </td><td>Print a single URL @private@
-</td></tr>
-<tr><td><tt>IPP_PRIVATE</tt> </td><td>Reserved @private@
-</td></tr>
-<tr><td><tt>IPP_PROMOTE_JOB</tt> </td><td>Promote a job to print sooner @private@
-</td></tr>
-<tr><td><tt>IPP_PURGE_JOBS</tt> </td><td>Cancel all jobs
-</td></tr>
-<tr><td><tt>IPP_RELEASE_HELD_NEW_JOBS</tt> </td><td>Release new jobs @private@
-</td></tr>
-<tr><td><tt>IPP_RELEASE_JOB</tt> </td><td>Release a job for printing
-</td></tr>
-<tr><td><tt>IPP_RENEW_SUBSCRIPTION</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Renew a printer subscription 
-</td></tr>
-<tr><td><tt>IPP_REPROCESS_JOB</tt> </td><td>Reprint a job @private@
-</td></tr>
-<tr><td><tt>IPP_RESTART_JOB</tt> </td><td>Reprint a job
-</td></tr>
-<tr><td><tt>IPP_RESTART_PRINTER</tt> </td><td>Restart a printer @private@
-</td></tr>
-<tr><td><tt>IPP_RESUME_JOB</tt> </td><td>Resume the current job @private@
-</td></tr>
-<tr><td><tt>IPP_RESUME_PRINTER</tt> </td><td>Start a printer
-</td></tr>
-<tr><td><tt>IPP_SCHEDULE_JOB_AFTER</tt> </td><td>Schedule a job to print after another @private@
-</td></tr>
-<tr><td><tt>IPP_SEND_DOCUMENT</tt> </td><td>Add a file to a job
-</td></tr>
-<tr><td><tt>IPP_SEND_NOTIFICATIONS</tt> </td><td>Send notification events @private@
-</td></tr>
-<tr><td><tt>IPP_SEND_URI</tt> </td><td>Add a URL to a job @private@
-</td></tr>
-<tr><td><tt>IPP_SET_JOB_ATTRIBUTES</tt> </td><td>Set job attributes
-</td></tr>
-<tr><td><tt>IPP_SET_PRINTER_ATTRIBUTES</tt> </td><td>Set printer attributes @private@
-</td></tr>
-<tr><td><tt>IPP_SHUTDOWN_PRINTER</tt> </td><td>Turn a printer off @private@
-</td></tr>
-<tr><td><tt>IPP_STARTUP_PRINTER</tt> </td><td>Turn a printer on @private@
-</td></tr>
-<tr><td><tt>IPP_SUSPEND_CURRENT_JOB</tt> </td><td>Suspend the current job @private@
-</td></tr>
-<tr><td><tt>IPP_VALIDATE_JOB</tt> </td><td>Validate job options
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_orient_e'>ipp_orient_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>IPP_LANDSCAPE</tt> </td><td>90 degrees counter-clockwise
-</td></tr>
-<tr><td><tt>IPP_PORTRAIT</tt> </td><td>No rotation
-</td></tr>
-<tr><td><tt>IPP_REVERSE_LANDSCAPE</tt> </td><td>90 degrees clockwise
-</td></tr>
-<tr><td><tt>IPP_REVERSE_PORTRAIT</tt> </td><td>180 degrees
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_pstate_e'>ipp_pstate_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>IPP_PRINTER_IDLE</tt> </td><td>Printer is idle
-</td></tr>
-<tr><td><tt>IPP_PRINTER_PROCESSING</tt> </td><td>Printer is working
-</td></tr>
-<tr><td><tt>IPP_PRINTER_STOPPED</tt> </td><td>Printer is stopped
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_quality_e'>ipp_quality_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>IPP_QUALITY_DRAFT</tt> </td><td>Draft quality
-</td></tr>
-<tr><td><tt>IPP_QUALITY_HIGH</tt> </td><td>High quality
-</td></tr>
-<tr><td><tt>IPP_QUALITY_NORMAL</tt> </td><td>Normal quality
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_res_e'>ipp_res_e</a></h3>
-<h4>Description</h4>
-<p>Types and structures...
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>IPP_RES_PER_CM</tt> </td><td>Pixels per centimeter
-</td></tr>
-<tr><td><tt>IPP_RES_PER_INCH</tt> </td><td>Pixels per inch
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_state_e'>ipp_state_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>IPP_ATTRIBUTE</tt> </td><td>One or more attributes need to be sent/received
-</td></tr>
-<tr><td><tt>IPP_DATA</tt> </td><td>IPP request data needs to be sent/received
-</td></tr>
-<tr><td><tt>IPP_ERROR</tt> </td><td>An error occurred
-</td></tr>
-<tr><td><tt>IPP_HEADER</tt> </td><td>The request header needs to be sent/received
-</td></tr>
-<tr><td><tt>IPP_IDLE</tt> </td><td>Nothing is happening/request completed
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_status_e'>ipp_status_e</a></h3>
-<h4>Description</h4>
-<p>IPP status codes...
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>CUPS_SEE_OTHER</tt> </td><td>cups-see-other
-</td></tr>
-<tr><td><tt>IPP_ATTRIBUTES</tt> </td><td>client-error-attributes-or-values-not-supported
-</td></tr>
-<tr><td><tt>IPP_ATTRIBUTES_NOT_SETTABLE</tt> </td><td>client-error-attributes-not-settable
-</td></tr>
-<tr><td><tt>IPP_BAD_REQUEST</tt> </td><td>client-error-bad-request
-</td></tr>
-<tr><td><tt>IPP_CHARSET</tt> </td><td>client-error-charset-not-supported
-</td></tr>
-<tr><td><tt>IPP_COMPRESSION_ERROR</tt> </td><td>client-error-compression-error
-</td></tr>
-<tr><td><tt>IPP_COMPRESSION_NOT_SUPPORTED</tt> </td><td>client-error-compression-not-supported
-</td></tr>
-<tr><td><tt>IPP_CONFLICT</tt> </td><td>client-error-conflicting-attributes
-</td></tr>
-<tr><td><tt>IPP_DEVICE_ERROR</tt> </td><td>server-error-device-error
-</td></tr>
-<tr><td><tt>IPP_DOCUMENT_ACCESS_ERROR</tt> </td><td>client-error-document-access-error
-</td></tr>
-<tr><td><tt>IPP_DOCUMENT_FORMAT</tt> </td><td>client-error-document-format-not-supported
-</td></tr>
-<tr><td><tt>IPP_DOCUMENT_FORMAT_ERROR</tt> </td><td>client-error-document-format-error
-</td></tr>
-<tr><td><tt>IPP_ERROR_JOB_CANCELED</tt> </td><td>server-error-job-canceled
-</td></tr>
-<tr><td><tt>IPP_FORBIDDEN</tt> </td><td>client-error-forbidden
-</td></tr>
-<tr><td><tt>IPP_GONE</tt> </td><td>client-error-gone
-</td></tr>
-<tr><td><tt>IPP_IGNORED_ALL_NOTIFICATIONS</tt> </td><td>client-error-ignored-all-notifications
-</td></tr>
-<tr><td><tt>IPP_IGNORED_ALL_SUBSCRIPTIONS</tt> </td><td>client-error-ignored-all-subscriptions
-</td></tr>
-<tr><td><tt>IPP_INTERNAL_ERROR</tt> </td><td>server-error-internal-error
-</td></tr>
-<tr><td><tt>IPP_MULTIPLE_JOBS_NOT_SUPPORTED</tt> </td><td>server-error-multiple-document-jobs-not-supported
-</td></tr>
-<tr><td><tt>IPP_NOT_ACCEPTING</tt> </td><td>server-error-not-accepting-jobs
-</td></tr>
-<tr><td><tt>IPP_NOT_AUTHENTICATED</tt> </td><td>client-error-not-authenticated
-</td></tr>
-<tr><td><tt>IPP_NOT_AUTHORIZED</tt> </td><td>client-error-not-authorized
-</td></tr>
-<tr><td><tt>IPP_NOT_FOUND</tt> </td><td>client-error-not-found
-</td></tr>
-<tr><td><tt>IPP_NOT_POSSIBLE</tt> </td><td>client-error-not-possible
-</td></tr>
-<tr><td><tt>IPP_OK</tt> </td><td>successful-ok
-</td></tr>
-<tr><td><tt>IPP_OK_BUT_CANCEL_SUBSCRIPTION</tt> </td><td>successful-ok-but-cancel-subscription
-</td></tr>
-<tr><td><tt>IPP_OK_CONFLICT</tt> </td><td>successful-ok-conflicting-attributes
-</td></tr>
-<tr><td><tt>IPP_OK_EVENTS_COMPLETE</tt> </td><td>successful-ok-events-complete
-</td></tr>
-<tr><td><tt>IPP_OK_IGNORED_NOTIFICATIONS</tt> </td><td>successful-ok-ignored-notifications
-</td></tr>
-<tr><td><tt>IPP_OK_IGNORED_SUBSCRIPTIONS</tt> </td><td>successful-ok-ignored-subscriptions
-</td></tr>
-<tr><td><tt>IPP_OK_SUBST</tt> </td><td>successful-ok-ignored-or-substituted-attributes
-</td></tr>
-<tr><td><tt>IPP_OK_TOO_MANY_EVENTS</tt> </td><td>successful-ok-too-many-events
-</td></tr>
-<tr><td><tt>IPP_OPERATION_NOT_SUPPORTED</tt> </td><td>server-error-operation-not-supported
-</td></tr>
-<tr><td><tt>IPP_PRINTER_BUSY</tt> </td><td>server-error-busy
-</td></tr>
-<tr><td><tt>IPP_PRINTER_IS_DEACTIVATED</tt> </td><td>server-error-printer-is-deactivated
-</td></tr>
-<tr><td><tt>IPP_PRINT_SUPPORT_FILE_NOT_FOUND</tt> </td><td>client-error-print-support-file-not-found
-</td></tr>
-<tr><td><tt>IPP_REDIRECTION_OTHER_SITE</tt> </td><td>
-</td></tr>
-<tr><td><tt>IPP_REQUEST_ENTITY</tt> </td><td>client-error-request-entity-too-large
-</td></tr>
-<tr><td><tt>IPP_REQUEST_VALUE</tt> </td><td>client-error-request-value-too-long
-</td></tr>
-<tr><td><tt>IPP_SERVICE_UNAVAILABLE</tt> </td><td>server-error-service-unavailable
-</td></tr>
-<tr><td><tt>IPP_TEMPORARY_ERROR</tt> </td><td>server-error-temporary-error
-</td></tr>
-<tr><td><tt>IPP_TIMEOUT</tt> </td><td>client-error-timeout
-</td></tr>
-<tr><td><tt>IPP_TOO_MANY_SUBSCRIPTIONS</tt> </td><td>client-error-too-many-subscriptions
-</td></tr>
-<tr><td><tt>IPP_URI_SCHEME</tt> </td><td>client-error-uri-scheme-not-supported
-</td></tr>
-<tr><td><tt>IPP_VERSION_NOT_SUPPORTED</tt> </td><td>server-error-version-not-supported
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_tag_e'>ipp_tag_e</a></h3>
-<h4>Description</h4>
-<p>Format tags for attributes...
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>IPP_TAG_ADMINDEFINE</tt> </td><td>Admin-defined value
-</td></tr>
-<tr><td><tt>IPP_TAG_BEGIN_COLLECTION</tt> </td><td>Beginning of collection value
-</td></tr>
-<tr><td><tt>IPP_TAG_BOOLEAN</tt> </td><td>Boolean value
-</td></tr>
-<tr><td><tt>IPP_TAG_CHARSET</tt> </td><td>Character set value
-</td></tr>
-<tr><td><tt>IPP_TAG_COPY</tt> </td><td>Bitflag for copied attribute values
-</td></tr>
-<tr><td><tt>IPP_TAG_DATE</tt> </td><td>Date/time value
-</td></tr>
-<tr><td><tt>IPP_TAG_DEFAULT</tt> </td><td>Default value
-</td></tr>
-<tr><td><tt>IPP_TAG_DELETEATTR</tt> </td><td>Delete-attribute value
-</td></tr>
-<tr><td><tt>IPP_TAG_END</tt> </td><td>End-of-attributes
-</td></tr>
-<tr><td><tt>IPP_TAG_END_COLLECTION</tt> </td><td>End of collection value
-</td></tr>
-<tr><td><tt>IPP_TAG_ENUM</tt> </td><td>Enumeration value
-</td></tr>
-<tr><td><tt>IPP_TAG_EVENT_NOTIFICATION</tt> </td><td>Event group
-</td></tr>
-<tr><td><tt>IPP_TAG_INTEGER</tt> </td><td>Integer value
-</td></tr>
-<tr><td><tt>IPP_TAG_JOB</tt> </td><td>Job group
-</td></tr>
-<tr><td><tt>IPP_TAG_KEYWORD</tt> </td><td>Keyword value
-</td></tr>
-<tr><td><tt>IPP_TAG_LANGUAGE</tt> </td><td>Language value
-</td></tr>
-<tr><td><tt>IPP_TAG_MASK</tt> </td><td>Mask for copied attribute values
-</td></tr>
-<tr><td><tt>IPP_TAG_MEMBERNAME</tt> </td><td>Collection member name value
-</td></tr>
-<tr><td><tt>IPP_TAG_MIMETYPE</tt> </td><td>MIME media type value
-</td></tr>
-<tr><td><tt>IPP_TAG_NAME</tt> </td><td>Name value
-</td></tr>
-<tr><td><tt>IPP_TAG_NAMELANG</tt> </td><td>Name-with-language value
-</td></tr>
-<tr><td><tt>IPP_TAG_NOTSETTABLE</tt> </td><td>Not-settable value
-</td></tr>
-<tr><td><tt>IPP_TAG_NOVALUE</tt> </td><td>No-value value
-</td></tr>
-<tr><td><tt>IPP_TAG_OPERATION</tt> </td><td>Operation group
-</td></tr>
-<tr><td><tt>IPP_TAG_PRINTER</tt> </td><td>Printer group
-</td></tr>
-<tr><td><tt>IPP_TAG_RANGE</tt> </td><td>Range value
-</td></tr>
-<tr><td><tt>IPP_TAG_RESOLUTION</tt> </td><td>Resolution value
-</td></tr>
-<tr><td><tt>IPP_TAG_STRING</tt> </td><td>Octet string value
-</td></tr>
-<tr><td><tt>IPP_TAG_SUBSCRIPTION</tt> </td><td>Subscription group
-</td></tr>
-<tr><td><tt>IPP_TAG_TEXT</tt> </td><td>Text value
-</td></tr>
-<tr><td><tt>IPP_TAG_TEXTLANG</tt> </td><td>Text-with-language value
-</td></tr>
-<tr><td><tt>IPP_TAG_UNKNOWN</tt> </td><td>Unknown value
-</td></tr>
-<tr><td><tt>IPP_TAG_UNSUPPORTED_GROUP</tt> </td><td>Unsupported attributes group
-</td></tr>
-<tr><td><tt>IPP_TAG_UNSUPPORTED_VALUE</tt> </td><td>Unsupported value
-</td></tr>
-<tr><td><tt>IPP_TAG_URI</tt> </td><td>URI value
-</td></tr>
-<tr><td><tt>IPP_TAG_URISCHEME</tt> </td><td>URI scheme value
-</td></tr>
-<tr><td><tt>IPP_TAG_ZERO</tt> </td><td>Zero tag - used for separators
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='FUNCTIONS'>Functions</a></h2>
-<ul>
-       <li><a href='#cupsDoAuthentication'><tt>cupsDoAuthentication()</tt></a> <span class='info'>&nbsp;CUPS 1.1.20&nbsp;</span></li>
-       <li><a href='#cupsDoFileRequest'><tt>cupsDoFileRequest()</tt></a> </li>
-       <li><a href='#cupsDoIORequest'><tt>cupsDoIORequest()</tt></a> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></li>
-       <li><a href='#cupsDoRequest'><tt>cupsDoRequest()</tt></a> </li>
-       <li><a href='#cupsEncodeOptions'><tt>cupsEncodeOptions()</tt></a> </li>
-       <li><a href='#cupsEncodeOptions2'><tt>cupsEncodeOptions2()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpAddrAny'><tt>httpAddrAny()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpAddrEqual'><tt>httpAddrEqual()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpAddrLength'><tt>httpAddrLength()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpAddrLocalhost'><tt>httpAddrLocalhost()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpAddrLookup'><tt>httpAddrLookup()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpAddrString'><tt>httpAddrString()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpAssembleURI'><tt>httpAssembleURI()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpAssembleURIf'><tt>httpAssembleURIf()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpBlocking'><tt>httpBlocking()</tt></a> </li>
-       <li><a href='#httpCheck'><tt>httpCheck()</tt></a> </li>
-       <li><a href='#httpClearCookie'><tt>httpClearCookie()</tt></a> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></li>
-       <li><a href='#httpClearFields'><tt>httpClearFields()</tt></a> </li>
-       <li><a href='#httpClose'><tt>httpClose()</tt></a> </li>
-       <li><a href='#httpConnect'><tt>httpConnect()</tt></a> </li>
-       <li><a href='#httpConnectEncrypt'><tt>httpConnectEncrypt()</tt></a> </li>
-       <li><a href='#httpDecode64'><tt>httpDecode64()</tt></a> <span class='info'>&nbsp;DEPRECATED&nbsp;</span></li>
-       <li><a href='#httpDecode64_2'><tt>httpDecode64_2()</tt></a> <span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span></li>
-       <li><a href='#httpDelete'><tt>httpDelete()</tt></a> </li>
-       <li><a href='#httpEncode64'><tt>httpEncode64()</tt></a> <span class='info'>&nbsp;DEPRECATED&nbsp;</span></li>
-       <li><a href='#httpEncode64_2'><tt>httpEncode64_2()</tt></a> <span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span></li>
-       <li><a href='#httpEncryption'><tt>httpEncryption()</tt></a> </li>
-       <li><a href='#httpError'><tt>httpError()</tt></a> </li>
-       <li><a href='#httpFlush'><tt>httpFlush()</tt></a> </li>
-       <li><a href='#httpFlushWrite'><tt>httpFlushWrite()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpGet'><tt>httpGet()</tt></a> </li>
-       <li><a href='#httpGetAuthString'><tt>httpGetAuthString()</tt></a> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></li>
-       <li><a href='#httpGetBlocking'><tt>httpGetBlocking()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpGetCookie'><tt>httpGetCookie()</tt></a> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></li>
-       <li><a href='#httpGetDateString'><tt>httpGetDateString()</tt></a> <span class='info'>&nbsp;DEPRECATED&nbsp;</span></li>
-       <li><a href='#httpGetDateString2'><tt>httpGetDateString2()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpGetDateTime'><tt>httpGetDateTime()</tt></a> </li>
-       <li><a href='#httpGetFd'><tt>httpGetFd()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpGetField'><tt>httpGetField()</tt></a> </li>
-       <li><a href='#httpGetHostByName'><tt>httpGetHostByName()</tt></a> <span class='info'>&nbsp;DEPRECATED&nbsp;</span></li>
-       <li><a href='#httpGetHostname'><tt>httpGetHostname()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpGetLength'><tt>httpGetLength()</tt></a> <span class='info'>&nbsp;DEPRECATED&nbsp;</span></li>
-       <li><a href='#httpGetLength2'><tt>httpGetLength2()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpGetStatus'><tt>httpGetStatus()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpGetSubField'><tt>httpGetSubField()</tt></a> <span class='info'>&nbsp;DEPRECATED&nbsp;</span></li>
-       <li><a href='#httpGetSubField2'><tt>httpGetSubField2()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpGets'><tt>httpGets()</tt></a> </li>
-       <li><a href='#httpHead'><tt>httpHead()</tt></a> </li>
-       <li><a href='#httpInitialize'><tt>httpInitialize()</tt></a> </li>
-       <li><a href='#httpMD5'><tt>httpMD5()</tt></a> </li>
-       <li><a href='#httpMD5Final'><tt>httpMD5Final()</tt></a> </li>
-       <li><a href='#httpMD5String'><tt>httpMD5String()</tt></a> </li>
-       <li><a href='#httpOptions'><tt>httpOptions()</tt></a> </li>
-       <li><a href='#httpPost'><tt>httpPost()</tt></a> </li>
-       <li><a href='#httpPut'><tt>httpPut()</tt></a> </li>
-       <li><a href='#httpRead'><tt>httpRead()</tt></a> <span class='info'>&nbsp;DEPRECATED&nbsp;</span></li>
-       <li><a href='#httpRead2'><tt>httpRead2()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpReconnect'><tt>httpReconnect()</tt></a> </li>
-       <li><a href='#httpSeparate'><tt>httpSeparate()</tt></a> <span class='info'>&nbsp;DEPRECATED&nbsp;</span></li>
-       <li><a href='#httpSeparate2'><tt>httpSeparate2()</tt></a> <span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span></li>
-       <li><a href='#httpSeparateURI'><tt>httpSeparateURI()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpSetAuthString'><tt>httpSetAuthString()</tt></a> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></li>
-       <li><a href='#httpSetCookie'><tt>httpSetCookie()</tt></a> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></li>
-       <li><a href='#httpSetExpect'><tt>httpSetExpect()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpSetField'><tt>httpSetField()</tt></a> </li>
-       <li><a href='#httpSetLength'><tt>httpSetLength()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#httpStatus'><tt>httpStatus()</tt></a> </li>
-       <li><a href='#httpTrace'><tt>httpTrace()</tt></a> </li>
-       <li><a href='#httpUpdate'><tt>httpUpdate()</tt></a> </li>
-       <li><a href='#httpWait'><tt>httpWait()</tt></a> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></li>
-       <li><a href='#httpWrite'><tt>httpWrite()</tt></a> <span class='info'>&nbsp;DEPRECATED&nbsp;</span></li>
-       <li><a href='#httpWrite2'><tt>httpWrite2()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ippAddBoolean'><tt>ippAddBoolean()</tt></a> </li>
-       <li><a href='#ippAddBooleans'><tt>ippAddBooleans()</tt></a> </li>
-       <li><a href='#ippAddCollection'><tt>ippAddCollection()</tt></a> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></li>
-       <li><a href='#ippAddCollections'><tt>ippAddCollections()</tt></a> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></li>
-       <li><a href='#ippAddDate'><tt>ippAddDate()</tt></a> </li>
-       <li><a href='#ippAddInteger'><tt>ippAddInteger()</tt></a> </li>
-       <li><a href='#ippAddIntegers'><tt>ippAddIntegers()</tt></a> </li>
-       <li><a href='#ippAddOctetString'><tt>ippAddOctetString()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ippAddRange'><tt>ippAddRange()</tt></a> </li>
-       <li><a href='#ippAddRanges'><tt>ippAddRanges()</tt></a> </li>
-       <li><a href='#ippAddResolution'><tt>ippAddResolution()</tt></a> </li>
-       <li><a href='#ippAddResolutions'><tt>ippAddResolutions()</tt></a> </li>
-       <li><a href='#ippAddSeparator'><tt>ippAddSeparator()</tt></a> </li>
-       <li><a href='#ippAddString'><tt>ippAddString()</tt></a> </li>
-       <li><a href='#ippAddStrings'><tt>ippAddStrings()</tt></a> </li>
-       <li><a href='#ippDateToTime'><tt>ippDateToTime()</tt></a> </li>
-       <li><a href='#ippDelete'><tt>ippDelete()</tt></a> </li>
-       <li><a href='#ippDeleteAttribute'><tt>ippDeleteAttribute()</tt></a> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></li>
-       <li><a href='#ippErrorString'><tt>ippErrorString()</tt></a> </li>
-       <li><a href='#ippErrorValue'><tt>ippErrorValue()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ippFindAttribute'><tt>ippFindAttribute()</tt></a> </li>
-       <li><a href='#ippFindNextAttribute'><tt>ippFindNextAttribute()</tt></a> </li>
-       <li><a href='#ippLength'><tt>ippLength()</tt></a> </li>
-       <li><a href='#ippNew'><tt>ippNew()</tt></a> </li>
-       <li><a href='#ippNewRequest'><tt>ippNewRequest()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ippOpString'><tt>ippOpString()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ippOpValue'><tt>ippOpValue()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ippPort'><tt>ippPort()</tt></a> </li>
-       <li><a href='#ippRead'><tt>ippRead()</tt></a> </li>
-       <li><a href='#ippReadFile'><tt>ippReadFile()</tt></a> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></li>
-       <li><a href='#ippReadIO'><tt>ippReadIO()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ippSetPort'><tt>ippSetPort()</tt></a> </li>
-       <li><a href='#ippTimeToDate'><tt>ippTimeToDate()</tt></a> </li>
-       <li><a href='#ippWrite'><tt>ippWrite()</tt></a> </li>
-       <li><a href='#ippWriteFile'><tt>ippWriteFile()</tt></a> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></li>
-       <li><a href='#ippWriteIO'><tt>ippWriteIO()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.20&nbsp;</span><a name='cupsDoAuthentication'>cupsDoAuthentication()</a></h3>
-<h4>Description</h4>
-<p>Authenticate a request.
-<p>This function should be called in response to a HTTP_UNAUTHORIZED
-status, prior to resubmitting your request.
+<p>The <a href='#cupsDoRequest'><code>cupsDoRequest</code></a> function frees
+the request structure and returns an IPP response structure or NULL pointer if
+the request could not be sent to the server. Once you have a response from
+the server, you can either use the
+<a href='#ippFindAttribute'><code>ippFindAttribute</code></a> and
+<a href='#ippFindNextAttribute'><code>ippFindNextAttribute</code></a> functions
+to find specific attributes, for example:</p>
 
+<pre class='example'>
+<a href='#ipp_t'>ipp_t</a> *response;
+<a href='#ipp_attribute_t'>ipp_attribute_t</a> *attr;
 
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsDoAuthentication(
-    <a href='#http_t'>http_t</a> * http,
-    const char * method,
-    const char * resource);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection to server</td></tr>
-<tr><td><tt>method</tt></td><td>Request method (GET, POST, PUT)</td></tr>
-<tr><td><tt>resource</tt></td><td>Resource path</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, -1 on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsDoFileRequest'>cupsDoFileRequest()</a></h3>
-<h4>Description</h4>
-<p>Do an IPP request with a file.
-<p>This function sends the IPP request to the specified server, retrying
+attr = <a href='#ippFindAttribute'>ippFindAttribute</a>(response, "printer-state", IPP_TAG_ENUM);
+</pre>
+
+<p>You can also walk the list of attributes with a simple <code>for</code> loop
+like this:</p>
+
+<pre class='example'>
+<a href='#ipp_t'>ipp_t</a> *response;
+<a href='#ipp_attribute_t'>ipp_attribute_t</a> *attr;
+
+for (attr = response->attrs; attr != NULL; attr = attr->next)
+  if (attr->name == NULL)
+    puts("--SEPARATOR--");
+  else
+    puts(attr->name);
+</pre>
+
+<p>The <code>for</code> loop approach is normally used when collecting
+attributes for multiple objects (jobs, printers, etc.) in a response. Attributes
+with <code>NULL</code> names indicate a separator between the attributes of
+each object. For example, the following code will list the jobs returned from
+our previous <a href='#get_jobs'><code>get_jobs</code></a> example code:</p>
+
+<pre class='example'>
+<a href='#ipp_t'>ipp_t</a> *response = <a href='#get_jobs'>get_jobs</a>();
+
+if (response != NULL)
+{
+  <a href='#ipp_attribute_t'>ipp_attribute_t</a> *attr;
+  int job_id = 0;
+  char *job_name = NULL;
+  char *job_originating_user_name = NULL;
+
+  puts("Job ID  Owner             Title");
+  puts("------  ----------------  ---------------------------------");
+
+  for (attr = response->attrs; attr != NULL; attr = attr->next)
+  {
+   /* Attributes without names are separators between jobs */
+    if (attr->name == NULL)
+    {
+      if (job_id > 0 &amp;&amp; job_name != NULL &amp;&amp; job_originating_user_name != NULL)
+        printf("%5d  %-16s  %s\n", job_id, job_originating_user_name, job_name);
+
+      job_id = 0;
+      job_name = NULL;
+      job_originating_user_name = NULL;
+      continue;
+    }
+    else if (!strcmp(attr->name, "job-id") &amp;&amp; attr->value_tag == IPP_TAG_INTEGER)
+      job_id = attr->values[0].integer;
+    else if (!strcmp(attr->name, "job-name") &amp;&amp; attr->value_tag == IPP_TAG_NAME)
+      job_name = attr->values[0].string.text;
+    else if (!strcmp(attr->name, "job-originating-user-name") &amp;&amp;
+             attr->value_tag == IPP_TAG_NAME)
+      job_originating_user_name = attr->values[0].string.text;
+  }
+
+  if (job_id > 0 &amp;&amp; job_name != NULL &amp;&amp; job_originating_user_name != NULL)
+    printf("%5d  %-16s  %s\n", job_id, job_originating_user_name, job_name);
+}
+</pre>
+
+<h3><a name='CREATING_URI_STRINGS'>Creating URI Strings</a></h3>
+
+<p>To ensure proper encoding, the
+<a href='#httpAssembleURIf'><code>httpAssembleURIf</code></a> function must be
+used to format a "printer-uri" string for all printer-based requests:</p>
+
+<pre class='example'>
+const char *name = "Foo";
+char uri[1024];
+<a href='#ipp_t'>ipp_t</a> *request;
+
+<a href='#httpAssembleURIf'>httpAssembleURIf</a>(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, cupsServer(),
+                 ippPort(), "/printers/%s", name);
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
+</pre>
+
+<h3><a name='SENDING_REQUESTS_WITH_FILES'>Sending Requests with Files</a></h3>
+
+<p>The <a href='#cupsDoFileRequest'><code>cupsDoFileRequest</code></a> and
+<a href='#cupsDoIORequest'><code>cupsDoIORequest</code></a> functions are
+used for requests involving files. The
+<a href='#cupsDoFileRequest'><code>cupsDoFileRequest</code></a> function
+attaches the named file to a request and is typically used when sending a print
+file or changing a printer's PPD file:</p>
+
+<pre class='example'>
+const char *filename = "/usr/share/cups/data/testprint.ps";
+const char *name = "Foo";
+char uri[1024];
+char resource[1024];
+<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(IPP_PRINT_JOB);
+<a href='#ipp_t'>ipp_t</a> *response;
+
+/* Use httpAssembleURIf for the printer-uri string */
+<a href='#httpAssembleURIf'>httpAssembleURIf</a>(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, cupsServer(),
+                 ippPort(), "/printers/%s", name);
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+             NULL, cupsUser());
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
+             NULL, "testprint.ps");
+
+/* Use snprintf for the resource path */
+snprintf(resource, sizeof(resource), "/printers/%s", name);
+
+response = <a href='#cupsDoFileRequest'>cupsDoFileRequest</a>(CUPS_HTTP_DEFAULT, request, resource, filename);
+</pre>
+
+<p>The <a href='#cupsDoIORequest'><code>cupsDoIORequest</code></a> function
+optionally attaches a file to the request and optionally saves a file in the
+response from the server. It is used when using a pipe for the request
+attachment or when using a request that returns a file, currently only
+<code>CUPS_GET_DOCUMENT</code> and <code>CUPS_GET_PPD</code>. For example,
+the following code will download the PPD file for the sample HP LaserJet
+printer driver:</p>
+
+<pre class='example'>
+char tempfile[1024];
+int tempfd;
+<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(CUPS_GET_PPD);
+<a href='#ipp_t'>ipp_t</a> *response;
+
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
+             NULL, "laserjet.ppd");
+
+tempfd = cupsTempFd(tempfile, sizeof(tempfile));
+
+response = <a href='#cupsDoIORequest'>cupsDoIORequest</a>(CUPS_HTTP_DEFAULT, request, "/", -1, tempfd);
+</pre>
+
+<p>The example passes <code>-1</code> for the input file descriptor to specify
+that no file is to be attached to the request. The PPD file attached to the
+response is written to the temporary file descriptor we created using the
+<code>cupsTempFd</code> function.</p>
+
+<h3><a name='ASYNCHRONOUS_REQUEST_PROCESSING'>Asynchronous Request Processing</a></h3>
+
+<p>The <a href='#cupsSendRequest'><code>cupsSendRequest</code></a> and
+<a href='#cupsGetResponse'><code>cupsGetResponse</code></a> support
+asynchronous communications with the server. Unlike the other request
+functions, the IPP request is not automatically freed, so remember to
+free your request with the <a href='#ippDelete'><code>ippDelete</code></a>
+function.</p>
+
+<p>File data is attached to the request using the
+<a href='#cupsWriteRequestData'><code>cupsWriteRequestData</code></a>
+function, while file data returned from the server is read using the
+<a href='#cupsReadResponseData'><code>cupsReadResponseData</code></a>
+function. We can rewrite the previous <code>CUPS_GET_PPD</code> example
+to use the asynchronous functions quite easily:</p>
+
+<pre class='example'>
+char tempfile[1024];
+int tempfd;
+<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(CUPS_GET_PPD);
+<a href='#ipp_t'>ipp_t</a> *response;
+
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
+             NULL, "laserjet.ppd");
+
+tempfd = cupsTempFd(tempfile, sizeof(tempfile));
+
+if (<a href='#cupsSendRequest'>cupsSendRequest</a>(CUPS_HTTP_DEFAULT, request, "/") == HTTP_CONTINUE)
+{
+  response = <a href='#cupsGetResponse'>cupsGetResponse</a>(CUPS_HTTP_DEFAULT, "/");
+
+  if (response != NULL)
+  {
+    ssize_t bytes;
+    char buffer[8192];
+
+    while ((bytes = <a href='#cupsReadResponseData'>cupsReadResponseData</a>(CUPS_HTTP_DEFAULT, buffer, sizeof(buffer))) > 0)
+      write(tempfd, buffer, bytes);
+  }
+}
+
+/* Free the request! */
+<a href='#ippDelete'>ippDelete</a>(request);
+</pre>
+
+<p>The <a href='#cupsSendRequest'><code>cupsSendRequest</code></a> function
+returns the initial HTTP request status, typically either
+<code>HTTP_CONTINUE</code> or <code>HTTP_UNAUTHORIZED</code>. The latter status
+is returned when the request requires authentication of some sort. The
+<a href='#cupsDoAuthentication'><code>cupsDoAuthentication</code></a> function
+must be called when your see <code>HTTP_UNAUTHORIZED</code> and the request
+re-sent. We can add authentication support to our example code by using a
+<code>do ... while</code> loop:</p>
+
+<pre class='example'>
+char tempfile[1024];
+int tempfd;
+<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(CUPS_GET_PPD);
+<a href='#ipp_t'>ipp_t</a> *response;
+http_status_t status;
+
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
+             NULL, "laserjet.ppd");
+
+tempfd = cupsTempFd(tempfile, sizeof(tempfile));
+
+/* Loop for authentication */
+do
+{
+  status = a href='#cupsSendRequest'>cupsSendRequest</a>(CUPS_HTTP_DEFAULT, request, "/");
+
+  if (status == HTTP_UNAUTHORIZED)
+  {
+    /* Try to authenticate, break out of the loop if that fails */
+    if (<a href='#cupsDoAuthentication'>cupsDoAuthentication</a>(CUPS_HTTP_DEFAULT, "POST", "/"))
+      break;
+  }
+}
+while (status != HTTP_CONTINUE &amp;&amp; status != HTTP_UNAUTHORIZED);
+
+if (status == HTTP_CONTINUE)
+{
+  response = <a href='#cupsGetResponse'>cupsGetResponse</a>(CUPS_HTTP_DEFAULT, "/");
+
+  if (response != NULL)
+  {
+    ssize_t bytes;
+    char buffer[8192];
+
+    while ((bytes = <a href='#cupsReadResponseData'>cupsReadResponseData</a>(CUPS_HTTP_DEFAULT, buffer, sizeof(buffer))) > 0)
+      write(tempfd, buffer, bytes);
+  }
+}
+
+/* Free the request! */
+<a href='#ippDelete'>ippDelete</a>(request);
+</pre>
+<h2 class="title"><a name="FUNCTIONS">Functions</a></h2>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.20&nbsp;</span><a name="cupsDoAuthentication">cupsDoAuthentication</a></h3>
+<p class="description">Authenticate a request.</p>
+<p class="code">
+int cupsDoAuthentication (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *method,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *resource<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection to server</dd>
+<dt>method</dt>
+<dd class="description">Request method (&quot;GET&quot;, &quot;POST&quot;, &quot;PUT&quot;)</dd>
+<dt>resource</dt>
+<dd class="description">Resource path</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, -1 on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function should be called in response to a <code>HTTP_UNAUTHORIZED</code>
+status, prior to resubmitting your request.
+
+</p>
+<h3 class="function"><a name="cupsDoFileRequest">cupsDoFileRequest</a></h3>
+<p class="description">Do an IPP request with a file.</p>
+<p class="code">
+<a href="#ipp_t">ipp_t</a> *cupsDoFileRequest (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *request,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *resource,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *filename<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or CUPS_HTTP_DEFAULT</dd>
+<dt>request</dt>
+<dd class="description">IPP request</dd>
+<dt>resource</dt>
+<dd class="description">HTTP resource for POST</dd>
+<dt>filename</dt>
+<dd class="description">File to send or NULL for none</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Response data</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function sends the IPP request to the specified server, retrying
 and authenticating as necessary.  The request is freed with ippDelete()
-after receiving a valid IPP response.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_t'>ipp_t</a> *<br>
-cupsDoFileRequest(
-    <a href='#http_t'>http_t</a> * http,
-    <a href='#ipp_t'>ipp_t</a> * request,
-    const char * resource,
-    const char * filename);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection to server</td></tr>
-<tr><td><tt>request</tt></td><td>IPP request</td></tr>
-<tr><td><tt>resource</tt></td><td>HTTP resource for POST</td></tr>
-<tr><td><tt>filename</tt></td><td>File to send or NULL for none</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Response data</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.3&nbsp;</span><a name='cupsDoIORequest'>cupsDoIORequest()</a></h3>
-<h4>Description</h4>
-<p>Do an IPP request with file descriptors.
-<p>This function sends the IPP request to the specified server, retrying
+after receiving a valid IPP response.</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.3&nbsp;</span><a name="cupsDoIORequest">cupsDoIORequest</a></h3>
+<p class="description">Do an IPP request with file descriptors.</p>
+<p class="code">
+<a href="#ipp_t">ipp_t</a> *cupsDoIORequest (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *request,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *resource,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int infile,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int outfile<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or CUPS_HTTP_DEFAULT</dd>
+<dt>request</dt>
+<dd class="description">IPP request</dd>
+<dt>resource</dt>
+<dd class="description">HTTP resource for POST</dd>
+<dt>infile</dt>
+<dd class="description">File to read from or -1 for none</dd>
+<dt>outfile</dt>
+<dd class="description">File to write to or -1 for none</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Response data</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function sends the IPP request to the specified server, retrying
 and authenticating as necessary.  The request is freed with ippDelete()
-after receiving a valid IPP response.
-<p>If &quot;infile&quot; is a valid file descriptor, cupsDoIORequest() copies
-all of the data from the file after the IPP request message.
-<p>If &quot;outfile&quot; is a valid file descriptor, cupsDoIORequest() copies
+after receiving a valid IPP response.<br>
+<br>
+If &quot;infile&quot; is a valid file descriptor, cupsDoIORequest() copies
+all of the data from the file after the IPP request message.<br>
+<br>
+If &quot;outfile&quot; is a valid file descriptor, cupsDoIORequest() copies
 all of the data after the IPP response message to the file.
 
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_t'>ipp_t</a> *<br>
-cupsDoIORequest(
-    <a href='#http_t'>http_t</a> * http,
-    <a href='#ipp_t'>ipp_t</a> * request,
-    const char * resource,
-    int infile,
-    int outfile);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection to server</td></tr>
-<tr><td><tt>request</tt></td><td>IPP request</td></tr>
-<tr><td><tt>resource</tt></td><td>HTTP resource for POST</td></tr>
-<tr><td><tt>infile</tt></td><td>File to read from or -1 for none</td></tr>
-<tr><td><tt>outfile</tt></td><td>File to write to or -1 for none</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Response data</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsDoRequest'>cupsDoRequest()</a></h3>
-<h4>Description</h4>
-<p>Do an IPP request.
-<p>This function sends the IPP request to the specified server, retrying
+</p>
+<h3 class="function"><a name="cupsDoRequest">cupsDoRequest</a></h3>
+<p class="description">Do an IPP request.</p>
+<p class="code">
+<a href="#ipp_t">ipp_t</a> *cupsDoRequest (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *request,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *resource<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or CUPS_HTTP_DEFAULT</dd>
+<dt>request</dt>
+<dd class="description">IPP request</dd>
+<dt>resource</dt>
+<dd class="description">HTTP resource for POST</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Response data</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function sends the IPP request to the specified server, retrying
 and authenticating as necessary.  The request is freed with ippDelete()
-after receiving a valid IPP response.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_t'>ipp_t</a> *<br>
-cupsDoRequest(
-    <a href='#http_t'>http_t</a> * http,
-    <a href='#ipp_t'>ipp_t</a> * request,
-    const char * resource);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection to server</td></tr>
-<tr><td><tt>request</tt></td><td>IPP request</td></tr>
-<tr><td><tt>resource</tt></td><td>HTTP resource for POST</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Response data</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsEncodeOptions'>cupsEncodeOptions()</a></h3>
-<h4>Description</h4>
-<p>Encode printer options into IPP attributes.
-<p>This function adds operation, job, and then subscription attributes,
+after receiving a valid IPP response.</p>
+<h3 class="function"><a name="cupsEncodeOptions">cupsEncodeOptions</a></h3>
+<p class="description">Encode printer options into IPP attributes.</p>
+<p class="code">
+void cupsEncodeOptions (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_options,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_option_t *options<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">Request to add to</dd>
+<dt>num_options</dt>
+<dd class="description">Number of options</dd>
+<dt>options</dt>
+<dd class="description">Options</dd>
+</dl>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function adds operation, job, and then subscription attributes,
 in that order. Use the cupsEncodeOptions2() function to add attributes
-for a single group.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsEncodeOptions(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    int num_options,
-    cups_option_t * options);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>Request to add to</td></tr>
-<tr><td><tt>num_options</tt></td><td>Number of options</td></tr>
-<tr><td><tt>options</tt></td><td>Options</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cupsEncodeOptions2'>cupsEncodeOptions2()</a></h3>
-<h4>Description</h4>
-<p>Encode printer options into IPP attributes for a group.
-<p>This function only adds attributes for a single group. Call this
+for a single group.</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsEncodeOptions2">cupsEncodeOptions2</a></h3>
+<p class="description">Encode printer options into IPP attributes for a group.</p>
+<p class="code">
+void cupsEncodeOptions2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_options,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_option_t *options,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t group_tag<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">Request to add to</dd>
+<dt>num_options</dt>
+<dd class="description">Number of options</dd>
+<dt>options</dt>
+<dd class="description">Options</dd>
+<dt>group_tag</dt>
+<dd class="description">Group to encode</dd>
+</dl>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function only adds attributes for a single group. Call this
 function multiple times for each group, or use cupsEncodeOptions()
 to add the standard groups.
 
-
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsEncodeOptions2(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    int num_options,
-    cups_option_t * options,
-    ipp_tag_t group_tag);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>Request to add to</td></tr>
-<tr><td><tt>num_options</tt></td><td>Number of options</td></tr>
-<tr><td><tt>options</tt></td><td>Options</td></tr>
-<tr><td><tt>group_tag</tt></td><td>Group to encode</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpAddrAny'>httpAddrAny()</a></h3>
-<h4>Description</h4>
-<p>Check for the &quot;any&quot; address.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpAddrAny(
-    const <a href='#http_addr_t'>http_addr_t</a> * addr);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>addr</tt></td><td>Address to check</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>1 if &quot;any&quot;, 0 otherwise</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpAddrEqual'>httpAddrEqual()</a></h3>
-<h4>Description</h4>
-<p>Compare two addresses.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpAddrEqual(
-    const <a href='#http_addr_t'>http_addr_t</a> * addr1,
-    const <a href='#http_addr_t'>http_addr_t</a> * addr2);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>addr1</tt></td><td>First address</td></tr>
-<tr><td><tt>addr2</tt></td><td>Second address</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>1 if equal, 0 if not</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpAddrLength'>httpAddrLength()</a></h3>
-<h4>Description</h4>
-<p>Return the length of the address in bytes.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpAddrLength(
-    const <a href='#http_addr_t'>http_addr_t</a> * addr);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>addr</tt></td><td>Address</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Length in bytes</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpAddrLocalhost'>httpAddrLocalhost()</a></h3>
-<h4>Description</h4>
-<p>Check for the local loopback address.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpAddrLocalhost(
-    const <a href='#http_addr_t'>http_addr_t</a> * addr);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>addr</tt></td><td>Address to check</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>1 if local host, 0 otherwise</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpAddrLookup'>httpAddrLookup()</a></h3>
-<h4>Description</h4>
-<p>Lookup the hostname associated with the address.
-
-
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-httpAddrLookup(
-    const <a href='#http_addr_t'>http_addr_t</a> * addr,
-    char * name,
-    int namelen);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>addr</tt></td><td>Address to lookup</td></tr>
-<tr><td><tt>name</tt></td><td>Host name buffer</td></tr>
-<tr><td><tt>namelen</tt></td><td>Size of name buffer</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Host name</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpAddrString'>httpAddrString()</a></h3>
-<h4>Description</h4>
-<p>Convert an address to a numeric string.
-
-
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-httpAddrString(
-    const <a href='#http_addr_t'>http_addr_t</a> * addr,
-    char * s,
-    int slen);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>addr</tt></td><td>Address to convert</td></tr>
-<tr><td><tt>s</tt></td><td>String buffer</td></tr>
-<tr><td><tt>slen</tt></td><td>Length of string</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Numeric address string</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpAssembleURI'>httpAssembleURI()</a></h3>
-<h4>Description</h4>
-<p>Assemble a uniform resource identifier from its
-components.
-<p>This function escapes reserved characters in the URI depending on the
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsGetResponse">cupsGetResponse</a></h3>
+<p class="description">Get a response to an IPP request.</p>
+<p class="code">
+<a href="#ipp_t">ipp_t</a> *cupsGetResponse (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *resource<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or CUPS_HTTP_DEFAULT</dd>
+<dt>resource</dt>
+<dd class="description">HTTP resource for POST</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Response or NULL on HTTP error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Use this function to get the response for an IPP request sent using
+cupsSendDocument() or cupsSendRequest(). For requests that return
+additional data, use httpRead() after getting a successful response.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsReadResponseData">cupsReadResponseData</a></h3>
+<p class="description">Read additional data after the IPP response.</p>
+<p class="code">
+ssize_t cupsReadResponseData (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *buffer,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t length<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or CUPS_HTTP_DEFAULT</dd>
+<dt>buffer</dt>
+<dd class="description">Buffer to use</dd>
+<dt>length</dt>
+<dd class="description">Number of bytes to read</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Bytes read, 0 on EOF, -1 on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function is used after cupsGetResponse() to read the PPD or document
+files for CUPS_GET_PPD and CUPS_GET_DOCUMENT requests, respectively.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsSendRequest">cupsSendRequest</a></h3>
+<p class="description">Send an IPP request.</p>
+<p class="code">
+http_status_t cupsSendRequest (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *request,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *resource,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t length<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or CUPS_HTTP_DEFAULT</dd>
+<dt>request</dt>
+<dd class="description">IPP request</dd>
+<dt>resource</dt>
+<dd class="description">Resource path</dd>
+<dt>length</dt>
+<dd class="description">Length of data to follow or CUPS_LENGTH_VARIABLE</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Initial HTTP status</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Use httpWrite() to write any additional data (document, PPD file, etc.)
+for the request, cupsGetResponse() to get the IPP response, and httpRead()
+to read any additional data following the response. Only one request can be 
+sent/queued at a time.<br>
+<br>
+Unlike cupsDoFileRequest(), cupsDoIORequest(), and cupsDoRequest(), the
+request is not freed.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsWriteRequestData">cupsWriteRequestData</a></h3>
+<p class="description">Write additional data after an IPP request.</p>
+<p class="code">
+http_status_t cupsWriteRequestData (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *buffer,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t length<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or CUPS_HTTP_DEFAULT</dd>
+<dt>buffer</dt>
+<dd class="description">Bytes to write</dd>
+<dt>length</dt>
+<dd class="description">Number of bytes to write</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">HTTP_CONTINUE if OK or HTTP status on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function is used after cupsSendRequest() or cupsStartDocument()
+to provide a PPD or document file as needed.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpAddrAny">httpAddrAny</a></h3>
+<p class="description">Check for the &quot;any&quot; address.</p>
+<p class="code">
+int httpAddrAny (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const <a href="#http_addr_t">http_addr_t</a> *addr<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>addr</dt>
+<dd class="description">Address to check</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 if &quot;any&quot;, 0 otherwise</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpAddrEqual">httpAddrEqual</a></h3>
+<p class="description">Compare two addresses.</p>
+<p class="code">
+int httpAddrEqual (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const <a href="#http_addr_t">http_addr_t</a> *addr1,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const <a href="#http_addr_t">http_addr_t</a> *addr2<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>addr1</dt>
+<dd class="description">First address</dd>
+<dt>addr2</dt>
+<dd class="description">Second address</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 if equal, 0 if not</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpAddrLength">httpAddrLength</a></h3>
+<p class="description">Return the length of the address in bytes.</p>
+<p class="code">
+int httpAddrLength (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const <a href="#http_addr_t">http_addr_t</a> *addr<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>addr</dt>
+<dd class="description">Address</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Length in bytes</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpAddrLocalhost">httpAddrLocalhost</a></h3>
+<p class="description">Check for the local loopback address.</p>
+<p class="code">
+int httpAddrLocalhost (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const <a href="#http_addr_t">http_addr_t</a> *addr<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>addr</dt>
+<dd class="description">Address to check</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 if local host, 0 otherwise</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpAddrLookup">httpAddrLookup</a></h3>
+<p class="description">Lookup the hostname associated with the address.</p>
+<p class="code">
+char *httpAddrLookup (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const <a href="#http_addr_t">http_addr_t</a> *addr,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int namelen<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>addr</dt>
+<dd class="description">Address to lookup</dd>
+<dt>name</dt>
+<dd class="description">Host name buffer</dd>
+<dt>namelen</dt>
+<dd class="description">Size of name buffer</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Host name</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpAddrString">httpAddrString</a></h3>
+<p class="description">Convert an address to a numeric string.</p>
+<p class="code">
+char *httpAddrString (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const <a href="#http_addr_t">http_addr_t</a> *addr,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *s,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int slen<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>addr</dt>
+<dd class="description">Address to convert</dd>
+<dt>s</dt>
+<dd class="description">String buffer</dd>
+<dt>slen</dt>
+<dd class="description">Length of string</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Numeric address string</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpAssembleURI">httpAssembleURI</a></h3>
+<p class="description">Assemble a uniform resource identifier from its
+components.</p>
+<p class="code">
+http_uri_status_t httpAssembleURI (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_uri_coding_t encoding,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *uri,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int urilen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *scheme,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *username,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *host,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int port,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *resource<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>encoding</dt>
+<dd class="description">Encoding flags</dd>
+<dt>uri</dt>
+<dd class="description">URI buffer</dd>
+<dt>urilen</dt>
+<dd class="description">Size of URI buffer</dd>
+<dt>scheme</dt>
+<dd class="description">Scheme name</dd>
+<dt>username</dt>
+<dd class="description">Username</dd>
+<dt>host</dt>
+<dd class="description">Hostname or address</dd>
+<dt>port</dt>
+<dd class="description">Port number</dd>
+<dt>resource</dt>
+<dd class="description">Resource</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">URI status</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function escapes reserved characters in the URI depending on the
 value of the &quot;encoding&quot; argument.  You should use this function in
 place of traditional string functions whenever you need to create a
 URI string.
 
-
-<h4>Syntax</h4>
-<p><tt>
-http_uri_status_t<br>
-httpAssembleURI(
-    http_uri_coding_t encoding,
-    char * uri,
-    int urilen,
-    const char * scheme,
-    const char * username,
-    const char * host,
-    int port,
-    const char * resource);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>encoding</tt></td><td>Encoding flags</td></tr>
-<tr><td><tt>uri</tt></td><td>URI buffer</td></tr>
-<tr><td><tt>urilen</tt></td><td>Size of URI buffer</td></tr>
-<tr><td><tt>scheme</tt></td><td>Scheme name</td></tr>
-<tr><td><tt>username</tt></td><td>Username</td></tr>
-<tr><td><tt>host</tt></td><td>Hostname or address</td></tr>
-<tr><td><tt>port</tt></td><td>Port number</td></tr>
-<tr><td><tt>resource</tt></td><td>Resource</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>URI status</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpAssembleURIf'>httpAssembleURIf()</a></h3>
-<h4>Description</h4>
-<p>Assemble a uniform resource identifier from its
-components with a formatted resource.
-<p>This function creates a formatted version of the resource string
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpAssembleURIf">httpAssembleURIf</a></h3>
+<p class="description">Assemble a uniform resource identifier from its
+components with a formatted resource.</p>
+<p class="code">
+http_uri_status_t httpAssembleURIf (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_uri_coding_t encoding,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *uri,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int urilen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *scheme,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *username,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *host,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int port,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *resourcef,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;...<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>encoding</dt>
+<dd class="description">Encoding flags</dd>
+<dt>uri</dt>
+<dd class="description">URI buffer</dd>
+<dt>urilen</dt>
+<dd class="description">Size of URI buffer</dd>
+<dt>scheme</dt>
+<dd class="description">Scheme name</dd>
+<dt>username</dt>
+<dd class="description">Username</dd>
+<dt>host</dt>
+<dd class="description">Hostname or address</dd>
+<dt>port</dt>
+<dd class="description">Port number</dd>
+<dt>resourcef</dt>
+<dd class="description">Printf-style resource</dd>
+<dt>...</dt>
+<dd class="description">Additional arguments as needed</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">URI status</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function creates a formatted version of the resource string
 argument &quot;resourcef&quot; and escapes reserved characters in the URI
 depending on the value of the &quot;encoding&quot; argument.  You should use
 this function in place of traditional string functions whenever
 you need to create a URI string.
 
-
-<h4>Syntax</h4>
-<p><tt>
-http_uri_status_t<br>
-httpAssembleURIf(
-    http_uri_coding_t encoding,
-    char * uri,
-    int urilen,
-    const char * scheme,
-    const char * username,
-    const char * host,
-    int port,
-    const char * resourcef,
-    ...);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>encoding</tt></td><td>Encoding flags</td></tr>
-<tr><td><tt>uri</tt></td><td>URI buffer</td></tr>
-<tr><td><tt>urilen</tt></td><td>Size of URI buffer</td></tr>
-<tr><td><tt>scheme</tt></td><td>Scheme name</td></tr>
-<tr><td><tt>username</tt></td><td>Username</td></tr>
-<tr><td><tt>host</tt></td><td>Hostname or address</td></tr>
-<tr><td><tt>port</tt></td><td>Port number</td></tr>
-<tr><td><tt>resourcef</tt></td><td>Printf-style resource</td></tr>
-<tr><td><tt>...</tt></td><td>Additional arguments as needed</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>URI status</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpBlocking'>httpBlocking()</a></h3>
-<h4>Description</h4>
-<p>Set blocking/non-blocking behavior on a connection.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-httpBlocking(
-    <a href='#http_t'>http_t</a> * http,
-    int b);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>b</tt></td><td>1 = blocking, 0 = non-blocking</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpCheck'>httpCheck()</a></h3>
-<h4>Description</h4>
-<p>Check to see if there is a pending response from the server.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpCheck(
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 = no data, 1 = data available</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span><a name='httpClearCookie'>httpClearCookie()</a></h3>
-<h4>Description</h4>
-<p>Clear the cookie value(s).
-
-
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-httpClearCookie(
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpClearFields'>httpClearFields()</a></h3>
-<h4>Description</h4>
-<p>Clear HTTP request fields.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-httpClearFields(
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpClose'>httpClose()</a></h3>
-<h4>Description</h4>
-<p>Close an HTTP connection...
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-httpClose(
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpConnect'>httpConnect()</a></h3>
-<h4>Description</h4>
-<p>Connect to a HTTP server.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#http_t'>http_t</a> *<br>
-httpConnect(
-    const char * host,
-    int port);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>host</tt></td><td>Host to connect to</td></tr>
-<tr><td><tt>port</tt></td><td>Port number</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New HTTP connection</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpConnectEncrypt'>httpConnectEncrypt()</a></h3>
-<h4>Description</h4>
-<p>Connect to a HTTP server using encryption.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#http_t'>http_t</a> *<br>
-httpConnectEncrypt(
-    const char * host,
-    int port,
-    <a href='#http_encryption_t'>http_encryption_t</a> encryption);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>host</tt></td><td>Host to connect to</td></tr>
-<tr><td><tt>port</tt></td><td>Port number</td></tr>
-<tr><td><tt>encryption</tt></td><td>Type of encryption to use</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New HTTP connection</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;DEPRECATED&nbsp;</span><a name='httpDecode64'>httpDecode64()</a></h3>
-<h4>Description</h4>
-<p>Base64-decode a string.
-<p>This function is deprecated. Use the httpDecode64_2() function instead
+</p>
+<h3 class="function"><a name="httpBlocking">httpBlocking</a></h3>
+<p class="description">Set blocking/non-blocking behavior on a connection.</p>
+<p class="code">
+void httpBlocking (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int b<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>b</dt>
+<dd class="description">1 = blocking, 0 = non-blocking</dd>
+</dl>
+<h3 class="function"><a name="httpCheck">httpCheck</a></h3>
+<p class="description">Check to see if there is a pending response from the server.</p>
+<p class="code">
+int httpCheck (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 = no data, 1 = data available</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.19&nbsp;</span><a name="httpClearCookie">httpClearCookie</a></h3>
+<p class="description">Clear the cookie value(s).</p>
+<p class="code">
+void httpClearCookie (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+</dl>
+<h3 class="function"><a name="httpClearFields">httpClearFields</a></h3>
+<p class="description">Clear HTTP request fields.</p>
+<p class="code">
+void httpClearFields (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+</dl>
+<h3 class="function"><a name="httpClose">httpClose</a></h3>
+<p class="description">Close an HTTP connection...</p>
+<p class="code">
+void httpClose (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+</dl>
+<h3 class="function"><a name="httpConnect">httpConnect</a></h3>
+<p class="description">Connect to a HTTP server.</p>
+<p class="code">
+<a href="#http_t">http_t</a> *httpConnect (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *host,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int port<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>host</dt>
+<dd class="description">Host to connect to</dd>
+<dt>port</dt>
+<dd class="description">Port number</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New HTTP connection</p>
+<h3 class="function"><a name="httpConnectEncrypt">httpConnectEncrypt</a></h3>
+<p class="description">Connect to a HTTP server using encryption.</p>
+<p class="code">
+<a href="#http_t">http_t</a> *httpConnectEncrypt (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *host,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int port,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_encryption_t">http_encryption_t</a> encryption<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>host</dt>
+<dd class="description">Host to connect to</dd>
+<dt>port</dt>
+<dd class="description">Port number</dd>
+<dt>encryption</dt>
+<dd class="description">Type of encryption to use</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New HTTP connection</p>
+<h3 class="function"><span class="info">&nbsp;DEPRECATED&nbsp;</span><a name="httpDecode64">httpDecode64</a></h3>
+<p class="description">Base64-decode a string.</p>
+<p class="code">
+char *httpDecode64 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *out,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *in<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>out</dt>
+<dd class="description">String to write to</dd>
+<dt>in</dt>
+<dd class="description">String to read from</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Decoded string</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function is deprecated. Use the httpDecode64_2() function instead
 which provides buffer length arguments.
 
-
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-httpDecode64(
-    char * out,
-    const char * in);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>out</tt></td><td>String to write to</td></tr>
-<tr><td><tt>in</tt></td><td>String to read from</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Decoded string</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span><a name='httpDecode64_2'>httpDecode64_2()</a></h3>
-<h4>Description</h4>
-<p>Base64-decode a string.
-
-
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-httpDecode64_2(
-    char * out,
-    int * outlen,
-    const char * in);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>out</tt></td><td>String to write to</td></tr>
-<tr><td><tt>outlen</tt></td><td>Size of output string</td></tr>
-<tr><td><tt>in</tt></td><td>String to read from</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Decoded string</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpDelete'>httpDelete()</a></h3>
-<h4>Description</h4>
-<p>Send a DELETE request to the server.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpDelete(
-    <a href='#http_t'>http_t</a> * http,
-    const char * uri);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>uri</tt></td><td>URI to delete</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Status of call (0 = success)</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;DEPRECATED&nbsp;</span><a name='httpEncode64'>httpEncode64()</a></h3>
-<h4>Description</h4>
-<p>Base64-encode a string.
-<p>This function is deprecated. Use the httpEncode64_2() function instead
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.21&nbsp;</span><a name="httpDecode64_2">httpDecode64_2</a></h3>
+<p class="description">Base64-decode a string.</p>
+<p class="code">
+char *httpDecode64_2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *out,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *outlen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *in<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>out</dt>
+<dd class="description">String to write to</dd>
+<dt>outlen</dt>
+<dd class="description">Size of output string</dd>
+<dt>in</dt>
+<dd class="description">String to read from</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Decoded string</p>
+<h3 class="function"><a name="httpDelete">httpDelete</a></h3>
+<p class="description">Send a DELETE request to the server.</p>
+<p class="code">
+int httpDelete (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *uri<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>uri</dt>
+<dd class="description">URI to delete</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Status of call (0 = success)</p>
+<h3 class="function"><span class="info">&nbsp;DEPRECATED&nbsp;</span><a name="httpEncode64">httpEncode64</a></h3>
+<p class="description">Base64-encode a string.</p>
+<p class="code">
+char *httpEncode64 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *out,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *in<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>out</dt>
+<dd class="description">String to write to</dd>
+<dt>in</dt>
+<dd class="description">String to read from</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Encoded string</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function is deprecated. Use the httpEncode64_2() function instead
 which provides buffer length arguments.
 
-
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-httpEncode64(
-    char * out,
-    const char * in);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>out</tt></td><td>String to write to</td></tr>
-<tr><td><tt>in</tt></td><td>String to read from</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Encoded string</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span><a name='httpEncode64_2'>httpEncode64_2()</a></h3>
-<h4>Description</h4>
-<p>Base64-encode a string.
-
-
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-httpEncode64_2(
-    char * out,
-    int outlen,
-    const char * in,
-    int inlen);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>out</tt></td><td>String to write to</td></tr>
-<tr><td><tt>outlen</tt></td><td>Size of output string</td></tr>
-<tr><td><tt>in</tt></td><td>String to read from</td></tr>
-<tr><td><tt>inlen</tt></td><td>Size of input string</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Encoded string</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpEncryption'>httpEncryption()</a></h3>
-<h4>Description</h4>
-<p>Set the required encryption on the link.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpEncryption(
-    <a href='#http_t'>http_t</a> * http,
-    <a href='#http_encryption_t'>http_encryption_t</a> e);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>e</tt></td><td>New encryption preference</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>-1 on error, 0 on success</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpError'>httpError()</a></h3>
-<h4>Description</h4>
-<p>Get the last error on a connection.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpError(
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Error code (errno) value</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpFlush'>httpFlush()</a></h3>
-<h4>Description</h4>
-<p>Flush data from a HTTP connection.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-httpFlush(
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpFlushWrite'>httpFlushWrite()</a></h3>
-<h4>Description</h4>
-<p>Flush data in write buffer.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpFlushWrite(
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Bytes written or -1 on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpGet'>httpGet()</a></h3>
-<h4>Description</h4>
-<p>Send a GET request to the server.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpGet(
-    <a href='#http_t'>http_t</a> * http,
-    const char * uri);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>uri</tt></td><td>URI to get</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Status of call (0 = success)</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.3&nbsp;</span><a name='httpGetAuthString'>httpGetAuthString()</a></h3>
-<h4>Description</h4>
-<p>Get the current authorization string.
-<p>The authorization string is set by cupsDoAuthentication() and
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.21&nbsp;</span><a name="httpEncode64_2">httpEncode64_2</a></h3>
+<p class="description">Base64-encode a string.</p>
+<p class="code">
+char *httpEncode64_2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *out,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int outlen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *in,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int inlen<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>out</dt>
+<dd class="description">String to write to</dd>
+<dt>outlen</dt>
+<dd class="description">Size of output string</dd>
+<dt>in</dt>
+<dd class="description">String to read from</dd>
+<dt>inlen</dt>
+<dd class="description">Size of input string</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Encoded string</p>
+<h3 class="function"><a name="httpEncryption">httpEncryption</a></h3>
+<p class="description">Set the required encryption on the link.</p>
+<p class="code">
+int httpEncryption (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_encryption_t">http_encryption_t</a> e<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>e</dt>
+<dd class="description">New encryption preference</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">-1 on error, 0 on success</p>
+<h3 class="function"><a name="httpError">httpError</a></h3>
+<p class="description">Get the last error on a connection.</p>
+<p class="code">
+int httpError (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Error code (errno) value</p>
+<h3 class="function"><a name="httpFlush">httpFlush</a></h3>
+<p class="description">Flush data from a HTTP connection.</p>
+<p class="code">
+void httpFlush (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+</dl>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpFlushWrite">httpFlushWrite</a></h3>
+<p class="description">Flush data in write buffer.</p>
+<p class="code">
+int httpFlushWrite (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Bytes written or -1 on error</p>
+<h3 class="function"><a name="httpGet">httpGet</a></h3>
+<p class="description">Send a GET request to the server.</p>
+<p class="code">
+int httpGet (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *uri<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>uri</dt>
+<dd class="description">URI to get</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Status of call (0 = success)</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.3&nbsp;</span><a name="httpGetAuthString">httpGetAuthString</a></h3>
+<p class="description">Get the current authorization string.</p>
+<p class="code">
+char *httpGetAuthString (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Authorization string</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The authorization string is set by cupsDoAuthentication() and
 httpSetAuthString().  Use httpGetAuthString() to retrieve the
 string to use with httpSetField() for the HTTP_FIELD_AUTHORIZATION
 value.
 
-
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-httpGetAuthString(
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Authorization string</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpGetBlocking'>httpGetBlocking()</a></h3>
-<h4>Description</h4>
-<p>Get the blocking/non-block state of a connection.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpGetBlocking(
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>1 if blocking, 0 if non-blocking</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span><a name='httpGetCookie'>httpGetCookie()</a></h3>
-<h4>Description</h4>
-<p>Get any cookie data from the response.
-
-
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-httpGetCookie(
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connecion</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Cookie data or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;DEPRECATED&nbsp;</span><a name='httpGetDateString'>httpGetDateString()</a></h3>
-<h4>Description</h4>
-<p>Get a formatted date/time string from a time value.
-
-
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-httpGetDateString(
-    time_t t);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>t</tt></td><td>UNIX time</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Date/time string</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpGetDateString2'>httpGetDateString2()</a></h3>
-<h4>Description</h4>
-<p>Get a formatted date/time string from a time value.
-
-
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-httpGetDateString2(
-    time_t t,
-    char * s,
-    int slen);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>t</tt></td><td>UNIX time</td></tr>
-<tr><td><tt>s</tt></td><td>String buffer</td></tr>
-<tr><td><tt>slen</tt></td><td>Size of string buffer</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Date/time string</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpGetDateTime'>httpGetDateTime()</a></h3>
-<h4>Description</h4>
-<p>Get a time value from a formatted date/time string.
-<h4>Syntax</h4>
-<p><tt>
-time_t<br>
-httpGetDateTime(
-    const char * s);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>s</tt></td><td>Date/time string</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>UNIX time</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpGetFd'>httpGetFd()</a></h3>
-<h4>Description</h4>
-<p>Get the file descriptor associated with a connection.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpGetFd(
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>File descriptor or -1 if none</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpGetField'>httpGetField()</a></h3>
-<h4>Description</h4>
-<p>Get a field value from a request/response.
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-httpGetField(
-    <a href='#http_t'>http_t</a> * http,
-    http_field_t field);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>field</tt></td><td>Field to get</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Field value</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;DEPRECATED&nbsp;</span><a name='httpGetHostByName'>httpGetHostByName()</a></h3>
-<h4>Description</h4>
-<p>Lookup a hostname or IPv4 address, and return
-address records for the specified name.
-
-
-<h4>Syntax</h4>
-<p><tt>
-struct hostent *<br>
-httpGetHostByName(
-    const char * name);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name</tt></td><td>Hostname or IP address</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Host entry</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpGetHostname'>httpGetHostname()</a></h3>
-<h4>Description</h4>
-<p>Get the FQDN for the connection or local system.
-<p>When &quot;http&quot; points to a connected socket, return the hostname or
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpGetBlocking">httpGetBlocking</a></h3>
+<p class="description">Get the blocking/non-block state of a connection.</p>
+<p class="code">
+int httpGetBlocking (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 if blocking, 0 if non-blocking</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.19&nbsp;</span><a name="httpGetCookie">httpGetCookie</a></h3>
+<p class="description">Get any cookie data from the response.</p>
+<p class="code">
+const char *httpGetCookie (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connecion</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Cookie data or NULL</p>
+<h3 class="function"><span class="info">&nbsp;DEPRECATED&nbsp;</span><a name="httpGetDateString">httpGetDateString</a></h3>
+<p class="description">Get a formatted date/time string from a time value.</p>
+<p class="code">
+const char *httpGetDateString (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;time_t t<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>t</dt>
+<dd class="description">UNIX time</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Date/time string</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpGetDateString2">httpGetDateString2</a></h3>
+<p class="description">Get a formatted date/time string from a time value.</p>
+<p class="code">
+const char *httpGetDateString2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;time_t t,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *s,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int slen<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>t</dt>
+<dd class="description">UNIX time</dd>
+<dt>s</dt>
+<dd class="description">String buffer</dd>
+<dt>slen</dt>
+<dd class="description">Size of string buffer</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Date/time string</p>
+<h3 class="function"><a name="httpGetDateTime">httpGetDateTime</a></h3>
+<p class="description">Get a time value from a formatted date/time string.</p>
+<p class="code">
+time_t httpGetDateTime (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *s<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>s</dt>
+<dd class="description">Date/time string</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">UNIX time</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpGetFd">httpGetFd</a></h3>
+<p class="description">Get the file descriptor associated with a connection.</p>
+<p class="code">
+int httpGetFd (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">File descriptor or -1 if none</p>
+<h3 class="function"><a name="httpGetField">httpGetField</a></h3>
+<p class="description">Get a field value from a request/response.</p>
+<p class="code">
+const char *httpGetField (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_field_t field<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>field</dt>
+<dd class="description">Field to get</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Field value</p>
+<h3 class="function"><span class="info">&nbsp;DEPRECATED&nbsp;</span><a name="httpGetHostByName">httpGetHostByName</a></h3>
+<p class="description">Lookup a hostname or IPv4 address, and return
+address records for the specified name.</p>
+<p class="code">
+struct hostent *httpGetHostByName (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>name</dt>
+<dd class="description">Hostname or IP address</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Host entry</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpGetHostname">httpGetHostname</a></h3>
+<p class="description">Get the FQDN for the connection or local system.</p>
+<p class="code">
+const char *httpGetHostname (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *s,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int slen<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection or NULL</dd>
+<dt>s</dt>
+<dd class="description">String buffer for name</dd>
+<dt>slen</dt>
+<dd class="description">Size of buffer</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">FQDN for connection or system</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">When &quot;http&quot; points to a connected socket, return the hostname or
 address that was used in the call to httpConnect() or httpConnectEncrypt().
 Otherwise, return the FQDN for the local system using both gethostname()
 and gethostbyname() to get the local hostname with domain.
 
-
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-httpGetHostname(
-    <a href='#http_t'>http_t</a> * http,
-    char * s,
-    int slen);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection or NULL</td></tr>
-<tr><td><tt>s</tt></td><td>String buffer for name</td></tr>
-<tr><td><tt>slen</tt></td><td>Size of buffer</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>FQDN for connection or system</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;DEPRECATED&nbsp;</span><a name='httpGetLength'>httpGetLength()</a></h3>
-<h4>Description</h4>
-<p>Get the amount of data remaining from the
-content-length or transfer-encoding fields.
-<p>This function is deprecated and will not return lengths larger than
+</p>
+<h3 class="function"><span class="info">&nbsp;DEPRECATED&nbsp;</span><a name="httpGetLength">httpGetLength</a></h3>
+<p class="description">Get the amount of data remaining from the
+content-length or transfer-encoding fields.</p>
+<p class="code">
+int httpGetLength (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Content length</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function is deprecated and will not return lengths larger than
 2^31 - 1; use httpGetLength2() instead.
 
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpGetLength(
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Content length</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpGetLength2'>httpGetLength2()</a></h3>
-<h4>Description</h4>
-<p>Get the amount of data remaining from the
-content-length or transfer-encoding fields.
-<p>This function returns the complete content length, even for
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpGetLength2">httpGetLength2</a></h3>
+<p class="description">Get the amount of data remaining from the
+content-length or transfer-encoding fields.</p>
+<p class="code">
+off_t httpGetLength2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Content length</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function returns the complete content length, even for
 content larger than 2^31 - 1.
 
-
-<h4>Syntax</h4>
-<p><tt>
-off_t<br>
-httpGetLength2(
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Content length</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpGetStatus'>httpGetStatus()</a></h3>
-<h4>Description</h4>
-<p>Get the status of the last HTTP request.
-
-
-<h4>Syntax</h4>
-<p><tt>
-http_status_t<br>
-httpGetStatus(
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>HTTP status</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;DEPRECATED&nbsp;</span><a name='httpGetSubField'>httpGetSubField()</a></h3>
-<h4>Description</h4>
-<p>Get a sub-field value.
-
-
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-httpGetSubField(
-    <a href='#http_t'>http_t</a> * http,
-    http_field_t field,
-    const char * name,
-    char * value);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>field</tt></td><td>Field index</td></tr>
-<tr><td><tt>name</tt></td><td>Name of sub-field</td></tr>
-<tr><td><tt>value</tt></td><td>Value string</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Value or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpGetSubField2'>httpGetSubField2()</a></h3>
-<h4>Description</h4>
-<p>Get a sub-field value.
-
-
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-httpGetSubField2(
-    <a href='#http_t'>http_t</a> * http,
-    http_field_t field,
-    const char * name,
-    char * value,
-    int valuelen);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>field</tt></td><td>Field index</td></tr>
-<tr><td><tt>name</tt></td><td>Name of sub-field</td></tr>
-<tr><td><tt>value</tt></td><td>Value string</td></tr>
-<tr><td><tt>valuelen</tt></td><td>Size of value buffer</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Value or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpGets'>httpGets()</a></h3>
-<h4>Description</h4>
-<p>Get a line of text from a HTTP connection.
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-httpGets(
-    char * line,
-    int length,
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>line</tt></td><td>Line to read into</td></tr>
-<tr><td><tt>length</tt></td><td>Max length of buffer</td></tr>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Line or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpHead'>httpHead()</a></h3>
-<h4>Description</h4>
-<p>Send a HEAD request to the server.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpHead(
-    <a href='#http_t'>http_t</a> * http,
-    const char * uri);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>uri</tt></td><td>URI for head</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Status of call (0 = success)</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpInitialize'>httpInitialize()</a></h3>
-<h4>Description</h4>
-<p>Initialize the HTTP interface library and set the
-default HTTP proxy (if any).
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-httpInitialize(void);
-</tt></p>
-<h4>Arguments</h4>
-<p>None.</p>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpMD5'>httpMD5()</a></h3>
-<h4>Description</h4>
-<p>Compute the MD5 sum of the username:group:password.
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-httpMD5(
-    const char * username,
-    const char * realm,
-    const char * passwd,
-    char md5[33]);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>username</tt></td><td>User name</td></tr>
-<tr><td><tt>realm</tt></td><td>Realm name</td></tr>
-<tr><td><tt>passwd</tt></td><td>Password string</td></tr>
-<tr><td><tt>md5[33]</tt></td><td>MD5 string</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>MD5 sum</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpMD5Final'>httpMD5Final()</a></h3>
-<h4>Description</h4>
-<p>Combine the MD5 sum of the username, group, and password
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpGetStatus">httpGetStatus</a></h3>
+<p class="description">Get the status of the last HTTP request.</p>
+<p class="code">
+http_status_t httpGetStatus (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">HTTP status</p>
+<h3 class="function"><span class="info">&nbsp;DEPRECATED&nbsp;</span><a name="httpGetSubField">httpGetSubField</a></h3>
+<p class="description">Get a sub-field value.</p>
+<p class="code">
+char *httpGetSubField (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_field_t field,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *value<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>field</dt>
+<dd class="description">Field index</dd>
+<dt>name</dt>
+<dd class="description">Name of sub-field</dd>
+<dt>value</dt>
+<dd class="description">Value string</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Value or NULL</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpGetSubField2">httpGetSubField2</a></h3>
+<p class="description">Get a sub-field value.</p>
+<p class="code">
+char *httpGetSubField2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_field_t field,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *value,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int valuelen<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>field</dt>
+<dd class="description">Field index</dd>
+<dt>name</dt>
+<dd class="description">Name of sub-field</dd>
+<dt>value</dt>
+<dd class="description">Value string</dd>
+<dt>valuelen</dt>
+<dd class="description">Size of value buffer</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Value or NULL</p>
+<h3 class="function"><a name="httpGets">httpGets</a></h3>
+<p class="description">Get a line of text from a HTTP connection.</p>
+<p class="code">
+char *httpGets (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *line,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int length,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>line</dt>
+<dd class="description">Line to read into</dd>
+<dt>length</dt>
+<dd class="description">Max length of buffer</dd>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Line or NULL</p>
+<h3 class="function"><a name="httpHead">httpHead</a></h3>
+<p class="description">Send a HEAD request to the server.</p>
+<p class="code">
+int httpHead (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *uri<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>uri</dt>
+<dd class="description">URI for head</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Status of call (0 = success)</p>
+<h3 class="function"><a name="httpInitialize">httpInitialize</a></h3>
+<p class="description">Initialize the HTTP interface library and set the
+default HTTP proxy (if any).</p>
+<p class="code">
+void httpInitialize (void);</p>
+<h3 class="function"><a name="httpMD5">httpMD5</a></h3>
+<p class="description">Compute the MD5 sum of the username:group:password.</p>
+<p class="code">
+char *httpMD5 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *username,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *realm,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *passwd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char md5[33]<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>username</dt>
+<dd class="description">User name</dd>
+<dt>realm</dt>
+<dd class="description">Realm name</dd>
+<dt>passwd</dt>
+<dd class="description">Password string</dd>
+<dt>md5[33]</dt>
+<dd class="description">MD5 string</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">MD5 sum</p>
+<h3 class="function"><a name="httpMD5Final">httpMD5Final</a></h3>
+<p class="description">Combine the MD5 sum of the username, group, and password
 with the server-supplied nonce value, method, and
-request-uri.
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-httpMD5Final(
-    const char * nonce,
-    const char * method,
-    const char * resource,
-    char md5[33]);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>nonce</tt></td><td>Server nonce value</td></tr>
-<tr><td><tt>method</tt></td><td>METHOD (GET, POST, etc.)</td></tr>
-<tr><td><tt>resource</tt></td><td>Resource path</td></tr>
-<tr><td><tt>md5[33]</tt></td><td>MD5 sum</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New sum</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpMD5String'>httpMD5String()</a></h3>
-<h4>Description</h4>
-<p>Convert an MD5 sum to a character string.
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-httpMD5String(
-    const unsigned char * sum,
-    char md5[33]);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>sum</tt></td><td>MD5 sum data</td></tr>
-<tr><td><tt>md5[33]</tt></td><td>MD5 sum in hex</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>MD5 sum in hex</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpOptions'>httpOptions()</a></h3>
-<h4>Description</h4>
-<p>Send an OPTIONS request to the server.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpOptions(
-    <a href='#http_t'>http_t</a> * http,
-    const char * uri);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>uri</tt></td><td>URI for options</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Status of call (0 = success)</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpPost'>httpPost()</a></h3>
-<h4>Description</h4>
-<p>Send a POST request to the server.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpPost(
-    <a href='#http_t'>http_t</a> * http,
-    const char * uri);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>uri</tt></td><td>URI for post</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Status of call (0 = success)</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpPut'>httpPut()</a></h3>
-<h4>Description</h4>
-<p>Send a PUT request to the server.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpPut(
-    <a href='#http_t'>http_t</a> * http,
-    const char * uri);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>uri</tt></td><td>URI to put</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Status of call (0 = success)</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;DEPRECATED&nbsp;</span><a name='httpRead'>httpRead()</a></h3>
-<h4>Description</h4>
-<p>Read data from a HTTP connection.
-<p>This function is deprecated. Use the httpRead2() function which can
+request-uri.</p>
+<p class="code">
+char *httpMD5Final (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *nonce,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *method,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *resource,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char md5[33]<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>nonce</dt>
+<dd class="description">Server nonce value</dd>
+<dt>method</dt>
+<dd class="description">METHOD (GET, POST, etc.)</dd>
+<dt>resource</dt>
+<dd class="description">Resource path</dd>
+<dt>md5[33]</dt>
+<dd class="description">MD5 sum</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New sum</p>
+<h3 class="function"><a name="httpMD5String">httpMD5String</a></h3>
+<p class="description">Convert an MD5 sum to a character string.</p>
+<p class="code">
+char *httpMD5String (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const unsigned char *sum,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char md5[33]<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>sum</dt>
+<dd class="description">MD5 sum data</dd>
+<dt>md5[33]</dt>
+<dd class="description">MD5 sum in hex</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">MD5 sum in hex</p>
+<h3 class="function"><a name="httpOptions">httpOptions</a></h3>
+<p class="description">Send an OPTIONS request to the server.</p>
+<p class="code">
+int httpOptions (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *uri<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>uri</dt>
+<dd class="description">URI for options</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Status of call (0 = success)</p>
+<h3 class="function"><a name="httpPost">httpPost</a></h3>
+<p class="description">Send a POST request to the server.</p>
+<p class="code">
+int httpPost (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *uri<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>uri</dt>
+<dd class="description">URI for post</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Status of call (0 = success)</p>
+<h3 class="function"><a name="httpPut">httpPut</a></h3>
+<p class="description">Send a PUT request to the server.</p>
+<p class="code">
+int httpPut (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *uri<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>uri</dt>
+<dd class="description">URI to put</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Status of call (0 = success)</p>
+<h3 class="function"><span class="info">&nbsp;DEPRECATED&nbsp;</span><a name="httpRead">httpRead</a></h3>
+<p class="description">Read data from a HTTP connection.</p>
+<p class="code">
+int httpRead (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *buffer,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int length<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>buffer</dt>
+<dd class="description">Buffer for data</dd>
+<dt>length</dt>
+<dd class="description">Maximum number of bytes</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of bytes read</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function is deprecated. Use the httpRead2() function which can
 read more than 2GB of data.
 
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpRead(
-    <a href='#http_t'>http_t</a> * http,
-    char * buffer,
-    int length);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>buffer</tt></td><td>Buffer for data</td></tr>
-<tr><td><tt>length</tt></td><td>Maximum number of bytes</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of bytes read</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpRead2'>httpRead2()</a></h3>
-<h4>Description</h4>
-<p>Read data from a HTTP connection.
-
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ssize_t'>ssize_t</a><br>
-httpRead2(
-    <a href='#http_t'>http_t</a> * http,
-    char * buffer,
-    size_t length);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>buffer</tt></td><td>Buffer for data</td></tr>
-<tr><td><tt>length</tt></td><td>Maximum number of bytes</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of bytes read</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpReconnect'>httpReconnect()</a></h3>
-<h4>Description</h4>
-<p>Reconnect to a HTTP server.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpReconnect(
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, non-zero on failure</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;DEPRECATED&nbsp;</span><a name='httpSeparate'>httpSeparate()</a></h3>
-<h4>Description</h4>
-<p>Separate a Universal Resource Identifier into its
-components.
-<p>This function is deprecated; use the httpSeparateURI() function instead.
-
-
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-httpSeparate(
-    const char * uri,
-    char * scheme,
-    char * username,
-    char * host,
-    int * port,
-    char * resource);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>uri</tt></td><td>Universal Resource Identifier</td></tr>
-<tr><td><tt>scheme</tt></td><td>Scheme [32] (http, https, etc.)</td></tr>
-<tr><td><tt>username</tt></td><td>Username [1024]</td></tr>
-<tr><td><tt>host</tt></td><td>Hostname [1024]</td></tr>
-<tr><td><tt>port</tt></td><td>Port number to use</td></tr>
-<tr><td><tt>resource</tt></td><td>Resource/filename [1024]</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.21&nbsp;</span><a name='httpSeparate2'>httpSeparate2()</a></h3>
-<h4>Description</h4>
-<p>Separate a Universal Resource Identifier into its
-components.
-<p>This function is deprecated; use the httpSeparateURI() function instead.
-
-
-
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-httpSeparate2(
-    const char * uri,
-    char * scheme,
-    int schemelen,
-    char * username,
-    int usernamelen,
-    char * host,
-    int hostlen,
-    int * port,
-    char * resource,
-    int resourcelen);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>uri</tt></td><td>Universal Resource Identifier</td></tr>
-<tr><td><tt>scheme</tt></td><td>Scheme (http, https, etc.)</td></tr>
-<tr><td><tt>schemelen</tt></td><td>Size of scheme buffer</td></tr>
-<tr><td><tt>username</tt></td><td>Username</td></tr>
-<tr><td><tt>usernamelen</tt></td><td>Size of username buffer</td></tr>
-<tr><td><tt>host</tt></td><td>Hostname</td></tr>
-<tr><td><tt>hostlen</tt></td><td>Size of hostname buffer</td></tr>
-<tr><td><tt>port</tt></td><td>Port number to use</td></tr>
-<tr><td><tt>resource</tt></td><td>Resource/filename</td></tr>
-<tr><td><tt>resourcelen</tt></td><td>Size of resource buffer</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpSeparateURI'>httpSeparateURI()</a></h3>
-<h4>Description</h4>
-<p>Separate a Universal Resource Identifier into its
-components.
-
-
-<h4>Syntax</h4>
-<p><tt>
-http_uri_status_t<br>
-httpSeparateURI(
-    http_uri_coding_t decoding,
-    const char * uri,
-    char * scheme,
-    int schemelen,
-    char * username,
-    int usernamelen,
-    char * host,
-    int hostlen,
-    int * port,
-    char * resource,
-    int resourcelen);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>decoding</tt></td><td>Decoding flags</td></tr>
-<tr><td><tt>uri</tt></td><td>Universal Resource Identifier</td></tr>
-<tr><td><tt>scheme</tt></td><td>Scheme (http, https, etc.)</td></tr>
-<tr><td><tt>schemelen</tt></td><td>Size of scheme buffer</td></tr>
-<tr><td><tt>username</tt></td><td>Username</td></tr>
-<tr><td><tt>usernamelen</tt></td><td>Size of username buffer</td></tr>
-<tr><td><tt>host</tt></td><td>Hostname</td></tr>
-<tr><td><tt>hostlen</tt></td><td>Size of hostname buffer</td></tr>
-<tr><td><tt>port</tt></td><td>Port number to use</td></tr>
-<tr><td><tt>resource</tt></td><td>Resource/filename</td></tr>
-<tr><td><tt>resourcelen</tt></td><td>Size of resource buffer</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Result of separation</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.3&nbsp;</span><a name='httpSetAuthString'>httpSetAuthString()</a></h3>
-<h4>Description</h4>
-<p>Set the current authorization string.
-<p>This function just stores a copy of the current authorization string in
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpRead2">httpRead2</a></h3>
+<p class="description">Read data from a HTTP connection.</p>
+<p class="code">
+ssize_t httpRead2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *buffer,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t length<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>buffer</dt>
+<dd class="description">Buffer for data</dd>
+<dt>length</dt>
+<dd class="description">Maximum number of bytes</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of bytes read</p>
+<h3 class="function"><a name="httpReconnect">httpReconnect</a></h3>
+<p class="description">Reconnect to a HTTP server.</p>
+<p class="code">
+int httpReconnect (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, non-zero on failure</p>
+<h3 class="function"><span class="info">&nbsp;DEPRECATED&nbsp;</span><a name="httpSeparate">httpSeparate</a></h3>
+<p class="description">Separate a Universal Resource Identifier into its
+components.</p>
+<p class="code">
+void httpSeparate (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *uri,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *scheme,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *username,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *host,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *port,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *resource<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>uri</dt>
+<dd class="description">Universal Resource Identifier</dd>
+<dt>scheme</dt>
+<dd class="description">Scheme [32] (http, https, etc.)</dd>
+<dt>username</dt>
+<dd class="description">Username [1024]</dd>
+<dt>host</dt>
+<dd class="description">Hostname [1024]</dd>
+<dt>port</dt>
+<dd class="description">Port number to use</dd>
+<dt>resource</dt>
+<dd class="description">Resource/filename [1024]</dd>
+</dl>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function is deprecated; use the httpSeparateURI() function instead.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.21&nbsp;</span><a name="httpSeparate2">httpSeparate2</a></h3>
+<p class="description">Separate a Universal Resource Identifier into its
+components.</p>
+<p class="code">
+void httpSeparate2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *uri,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *scheme,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int schemelen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *username,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int usernamelen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *host,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int hostlen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *port,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *resource,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int resourcelen<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>uri</dt>
+<dd class="description">Universal Resource Identifier</dd>
+<dt>scheme</dt>
+<dd class="description">Scheme (http, https, etc.)</dd>
+<dt>schemelen</dt>
+<dd class="description">Size of scheme buffer</dd>
+<dt>username</dt>
+<dd class="description">Username</dd>
+<dt>usernamelen</dt>
+<dd class="description">Size of username buffer</dd>
+<dt>host</dt>
+<dd class="description">Hostname</dd>
+<dt>hostlen</dt>
+<dd class="description">Size of hostname buffer</dd>
+<dt>port</dt>
+<dd class="description">Port number to use</dd>
+<dt>resource</dt>
+<dd class="description">Resource/filename</dd>
+<dt>resourcelen</dt>
+<dd class="description">Size of resource buffer</dd>
+</dl>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function is deprecated; use the httpSeparateURI() function instead.
+
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpSeparateURI">httpSeparateURI</a></h3>
+<p class="description">Separate a Universal Resource Identifier into its
+components.</p>
+<p class="code">
+http_uri_status_t httpSeparateURI (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_uri_coding_t decoding,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *uri,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *scheme,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int schemelen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *username,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int usernamelen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *host,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int hostlen,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *port,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *resource,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int resourcelen<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>decoding</dt>
+<dd class="description">Decoding flags</dd>
+<dt>uri</dt>
+<dd class="description">Universal Resource Identifier</dd>
+<dt>scheme</dt>
+<dd class="description">Scheme (http, https, etc.)</dd>
+<dt>schemelen</dt>
+<dd class="description">Size of scheme buffer</dd>
+<dt>username</dt>
+<dd class="description">Username</dd>
+<dt>usernamelen</dt>
+<dd class="description">Size of username buffer</dd>
+<dt>host</dt>
+<dd class="description">Hostname</dd>
+<dt>hostlen</dt>
+<dd class="description">Size of hostname buffer</dd>
+<dt>port</dt>
+<dd class="description">Port number to use</dd>
+<dt>resource</dt>
+<dd class="description">Resource/filename</dd>
+<dt>resourcelen</dt>
+<dd class="description">Size of resource buffer</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Result of separation</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.3&nbsp;</span><a name="httpSetAuthString">httpSetAuthString</a></h3>
+<p class="description">Set the current authorization string.</p>
+<p class="code">
+void httpSetAuthString (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *scheme,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *data<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>scheme</dt>
+<dd class="description">Auth scheme (NULL to clear it)</dd>
+<dt>data</dt>
+<dd class="description">Auth data (NULL for none)</dd>
+</dl>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function just stores a copy of the current authorization string in
 the HTTP connection object.  You must still call httpSetField() to set
 HTTP_FIELD_AUTHORIZATION prior to issuing a HTTP request using httpGet(),
 httpHead(), httpOptions(), httpPost, or httpPut().
 
-
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-httpSetAuthString(
-    <a href='#http_t'>http_t</a> * http,
-    const char * scheme,
-    const char * data);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>scheme</tt></td><td>Auth scheme (NULL to clear it)</td></tr>
-<tr><td><tt>data</tt></td><td>Auth data (NULL for none)</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span><a name='httpSetCookie'>httpSetCookie()</a></h3>
-<h4>Description</h4>
-<p>Set the cookie value(s)...
-
-
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-httpSetCookie(
-    <a href='#http_t'>http_t</a> * http,
-    const char * cookie);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>Connection</td></tr>
-<tr><td><tt>cookie</tt></td><td>Cookie string</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpSetExpect'>httpSetExpect()</a></h3>
-<h4>Description</h4>
-<p>Set the Expect: header in a request.
-<p>Currently only HTTP_CONTINUE is supported for the &quot;expect&quot; argument.
-
-
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-httpSetExpect(
-    <a href='#http_t'>http_t</a> * http,
-    http_status_t expect);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>expect</tt></td><td>HTTP status to expect (HTTP_CONTINUE)</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpSetField'>httpSetField()</a></h3>
-<h4>Description</h4>
-<p>Set the value of an HTTP header.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-httpSetField(
-    <a href='#http_t'>http_t</a> * http,
-    http_field_t field,
-    const char * value);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>field</tt></td><td>Field index</td></tr>
-<tr><td><tt>value</tt></td><td>Value</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpSetLength'>httpSetLength()</a></h3>
-<h4>Description</h4>
-<p>Set the content-length and content-encoding.
-
-
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-httpSetLength(
-    <a href='#http_t'>http_t</a> * http,
-    size_t length);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>length</tt></td><td>Length (0 for chunked)</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpStatus'>httpStatus()</a></h3>
-<h4>Description</h4>
-<p>Return a short string describing a HTTP status code.
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-httpStatus(
-    http_status_t status);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>status</tt></td><td>HTTP status code</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>String or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpTrace'>httpTrace()</a></h3>
-<h4>Description</h4>
-<p>Send an TRACE request to the server.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpTrace(
-    <a href='#http_t'>http_t</a> * http,
-    const char * uri);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>uri</tt></td><td>URI for trace</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Status of call (0 = success)</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='httpUpdate'>httpUpdate()</a></h3>
-<h4>Description</h4>
-<p>Update the current HTTP state for incoming data.
-<h4>Syntax</h4>
-<p><tt>
-http_status_t<br>
-httpUpdate(
-    <a href='#http_t'>http_t</a> * http);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>HTTP status</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span><a name='httpWait'>httpWait()</a></h3>
-<h4>Description</h4>
-<p>Wait for data available on a connection.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpWait(
-    <a href='#http_t'>http_t</a> * http,
-    int msec);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>msec</tt></td><td>Milliseconds to wait</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>1 if data is available, 0 otherwise</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;DEPRECATED&nbsp;</span><a name='httpWrite'>httpWrite()</a></h3>
-<h4>Description</h4>
-<p>Write data to a HTTP connection.
-<p>This function is deprecated. Use the httpWrite2() function which can
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.19&nbsp;</span><a name="httpSetCookie">httpSetCookie</a></h3>
+<p class="description">Set the cookie value(s)...</p>
+<p class="code">
+void httpSetCookie (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *cookie<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">Connection</dd>
+<dt>cookie</dt>
+<dd class="description">Cookie string</dd>
+</dl>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpSetExpect">httpSetExpect</a></h3>
+<p class="description">Set the Expect: header in a request.</p>
+<p class="code">
+void httpSetExpect (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_status_t expect<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>expect</dt>
+<dd class="description">HTTP status to expect (HTTP_CONTINUE)</dd>
+</dl>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Currently only HTTP_CONTINUE is supported for the &quot;expect&quot; argument.
+
+</p>
+<h3 class="function"><a name="httpSetField">httpSetField</a></h3>
+<p class="description">Set the value of an HTTP header.</p>
+<p class="code">
+void httpSetField (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_field_t field,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *value<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>field</dt>
+<dd class="description">Field index</dd>
+<dt>value</dt>
+<dd class="description">Value</dd>
+</dl>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpSetLength">httpSetLength</a></h3>
+<p class="description">Set the content-length and content-encoding.</p>
+<p class="code">
+void httpSetLength (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t length<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>length</dt>
+<dd class="description">Length (0 for chunked)</dd>
+</dl>
+<h3 class="function"><a name="httpStatus">httpStatus</a></h3>
+<p class="description">Return a short string describing a HTTP status code.</p>
+<p class="code">
+const char *httpStatus (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_status_t status<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>status</dt>
+<dd class="description">HTTP status code</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">String or NULL</p>
+<h3 class="function"><a name="httpTrace">httpTrace</a></h3>
+<p class="description">Send an TRACE request to the server.</p>
+<p class="code">
+int httpTrace (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *uri<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>uri</dt>
+<dd class="description">URI for trace</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Status of call (0 = success)</p>
+<h3 class="function"><a name="httpUpdate">httpUpdate</a></h3>
+<p class="description">Update the current HTTP state for incoming data.</p>
+<p class="code">
+http_status_t httpUpdate (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">HTTP status</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.19&nbsp;</span><a name="httpWait">httpWait</a></h3>
+<p class="description">Wait for data available on a connection.</p>
+<p class="code">
+int httpWait (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int msec<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>msec</dt>
+<dd class="description">Milliseconds to wait</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 if data is available, 0 otherwise</p>
+<h3 class="function"><span class="info">&nbsp;DEPRECATED&nbsp;</span><a name="httpWrite">httpWrite</a></h3>
+<p class="description">Write data to a HTTP connection.</p>
+<p class="code">
+int httpWrite (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *buffer,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int length<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>buffer</dt>
+<dd class="description">Buffer for data</dd>
+<dt>length</dt>
+<dd class="description">Number of bytes to write</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of bytes written</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function is deprecated. Use the httpWrite2() function which can
 write more than 2GB of data.
 
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-httpWrite(
-    <a href='#http_t'>http_t</a> * http,
-    const char * buffer,
-    int length);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>buffer</tt></td><td>Buffer for data</td></tr>
-<tr><td><tt>length</tt></td><td>Number of bytes to write</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of bytes written</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='httpWrite2'>httpWrite2()</a></h3>
-<h4>Description</h4>
-<p>Write data to a HTTP connection.
-
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ssize_t'>ssize_t</a><br>
-httpWrite2(
-    <a href='#http_t'>http_t</a> * http,
-    const char * buffer,
-    size_t length);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>buffer</tt></td><td>Buffer for data</td></tr>
-<tr><td><tt>length</tt></td><td>Number of bytes to write</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of bytes written</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippAddBoolean'>ippAddBoolean()</a></h3>
-<h4>Description</h4>
-<p>Add a boolean attribute to an IPP message.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippAddBoolean(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    ipp_tag_t group,
-    const char * name,
-    char value);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>group</tt></td><td>IPP group</td></tr>
-<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
-<tr><td><tt>value</tt></td><td>Value of attribute</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippAddBooleans'>ippAddBooleans()</a></h3>
-<h4>Description</h4>
-<p>Add an array of boolean values.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippAddBooleans(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    ipp_tag_t group,
-    const char * name,
-    int num_values,
-    const char * values);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>group</tt></td><td>IPP group</td></tr>
-<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
-<tr><td><tt>num_values</tt></td><td>Number of values</td></tr>
-<tr><td><tt>values</tt></td><td>Values</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span><a name='ippAddCollection'>ippAddCollection()</a></h3>
-<h4>Description</h4>
-<p>Add a collection value.
-
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippAddCollection(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    ipp_tag_t group,
-    const char * name,
-    <a href='#ipp_t'>ipp_t</a> * value);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>group</tt></td><td>IPP group</td></tr>
-<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
-<tr><td><tt>value</tt></td><td>Value</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span><a name='ippAddCollections'>ippAddCollections()</a></h3>
-<h4>Description</h4>
-<p>Add an array of collection values.
-
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippAddCollections(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    ipp_tag_t group,
-    const char * name,
-    int num_values,
-    const <a href='#ipp_t'>ipp_t</a> ** values);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>group</tt></td><td>IPP group</td></tr>
-<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
-<tr><td><tt>num_values</tt></td><td>Number of values</td></tr>
-<tr><td><tt>values</tt></td><td>Values</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippAddDate'>ippAddDate()</a></h3>
-<h4>Description</h4>
-<p>Add a date attribute to an IPP message.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippAddDate(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    ipp_tag_t group,
-    const char * name,
-    const <a href='#ipp_uchar_t'>ipp_uchar_t</a> * value);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>group</tt></td><td>IPP group</td></tr>
-<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
-<tr><td><tt>value</tt></td><td>Value</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippAddInteger'>ippAddInteger()</a></h3>
-<h4>Description</h4>
-<p>Add a integer attribute to an IPP message.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippAddInteger(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    ipp_tag_t group,
-    ipp_tag_t type,
-    const char * name,
-    int value);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>group</tt></td><td>IPP group</td></tr>
-<tr><td><tt>type</tt></td><td>Type of attribute</td></tr>
-<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
-<tr><td><tt>value</tt></td><td>Value of attribute</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippAddIntegers'>ippAddIntegers()</a></h3>
-<h4>Description</h4>
-<p>Add an array of integer values.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippAddIntegers(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    ipp_tag_t group,
-    ipp_tag_t type,
-    const char * name,
-    int num_values,
-    const int * values);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>group</tt></td><td>IPP group</td></tr>
-<tr><td><tt>type</tt></td><td>Type of attribute</td></tr>
-<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
-<tr><td><tt>num_values</tt></td><td>Number of values</td></tr>
-<tr><td><tt>values</tt></td><td>Values</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ippAddOctetString'>ippAddOctetString()</a></h3>
-<h4>Description</h4>
-<p>Add an octetString value to an IPP message.
-
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippAddOctetString(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    ipp_tag_t group,
-    const char * name,
-    const void * data,
-    int datalen);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>group</tt></td><td>IPP group</td></tr>
-<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
-<tr><td><tt>data</tt></td><td>octetString data</td></tr>
-<tr><td><tt>datalen</tt></td><td>Length of data in bytes</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippAddRange'>ippAddRange()</a></h3>
-<h4>Description</h4>
-<p>Add a range of values to an IPP message.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippAddRange(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    ipp_tag_t group,
-    const char * name,
-    int lower,
-    int upper);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>group</tt></td><td>IPP group</td></tr>
-<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
-<tr><td><tt>lower</tt></td><td>Lower value</td></tr>
-<tr><td><tt>upper</tt></td><td>Upper value</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippAddRanges'>ippAddRanges()</a></h3>
-<h4>Description</h4>
-<p>Add ranges of values to an IPP message.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippAddRanges(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    ipp_tag_t group,
-    const char * name,
-    int num_values,
-    const int * lower,
-    const int * upper);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>group</tt></td><td>IPP group</td></tr>
-<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
-<tr><td><tt>num_values</tt></td><td>Number of values</td></tr>
-<tr><td><tt>lower</tt></td><td>Lower values</td></tr>
-<tr><td><tt>upper</tt></td><td>Upper values</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippAddResolution'>ippAddResolution()</a></h3>
-<h4>Description</h4>
-<p>Add a resolution value to an IPP message.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippAddResolution(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    ipp_tag_t group,
-    const char * name,
-    ipp_res_t units,
-    int xres,
-    int yres);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>group</tt></td><td>IPP group</td></tr>
-<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
-<tr><td><tt>units</tt></td><td>Units for resolution</td></tr>
-<tr><td><tt>xres</tt></td><td>X resolution</td></tr>
-<tr><td><tt>yres</tt></td><td>Y resolution</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippAddResolutions'>ippAddResolutions()</a></h3>
-<h4>Description</h4>
-<p>Add resolution values to an IPP message.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippAddResolutions(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    ipp_tag_t group,
-    const char * name,
-    int num_values,
-    ipp_res_t units,
-    const int * xres,
-    const int * yres);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>group</tt></td><td>IPP group</td></tr>
-<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
-<tr><td><tt>num_values</tt></td><td>Number of values</td></tr>
-<tr><td><tt>units</tt></td><td>Units for resolution</td></tr>
-<tr><td><tt>xres</tt></td><td>X resolutions</td></tr>
-<tr><td><tt>yres</tt></td><td>Y resolutions</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippAddSeparator'>ippAddSeparator()</a></h3>
-<h4>Description</h4>
-<p>Add a group separator to an IPP message.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippAddSeparator(
-    <a href='#ipp_t'>ipp_t</a> * ipp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippAddString'>ippAddString()</a></h3>
-<h4>Description</h4>
-<p>Add a language-encoded string to an IPP message.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippAddString(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    ipp_tag_t group,
-    ipp_tag_t type,
-    const char * name,
-    const char * charset,
-    const char * value);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>group</tt></td><td>IPP group</td></tr>
-<tr><td><tt>type</tt></td><td>Type of attribute</td></tr>
-<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
-<tr><td><tt>charset</tt></td><td>Character set</td></tr>
-<tr><td><tt>value</tt></td><td>Value</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippAddStrings'>ippAddStrings()</a></h3>
-<h4>Description</h4>
-<p>Add language-encoded strings to an IPP message.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippAddStrings(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    ipp_tag_t group,
-    ipp_tag_t type,
-    const char * name,
-    int num_values,
-    const char * charset,
-    const char *const * values);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>group</tt></td><td>IPP group</td></tr>
-<tr><td><tt>type</tt></td><td>Type of attribute</td></tr>
-<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
-<tr><td><tt>num_values</tt></td><td>Number of values</td></tr>
-<tr><td><tt>charset</tt></td><td>Character set</td></tr>
-<tr><td><tt>values</tt></td><td>Values</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippDateToTime'>ippDateToTime()</a></h3>
-<h4>Description</h4>
-<p>Convert from RFC 1903 Date/Time format to UNIX time
-in seconds.
-<h4>Syntax</h4>
-<p><tt>
-time_t<br>
-ippDateToTime(
-    const <a href='#ipp_uchar_t'>ipp_uchar_t</a> * date);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>date</tt></td><td>RFC 1903 date info</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>UNIX time value</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippDelete'>ippDelete()</a></h3>
-<h4>Description</h4>
-<p>Delete an IPP message.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-ippDelete(
-    <a href='#ipp_t'>ipp_t</a> * ipp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span><a name='ippDeleteAttribute'>ippDeleteAttribute()</a></h3>
-<h4>Description</h4>
-<p>Delete a single attribute in an IPP message.
-
-
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-ippDeleteAttribute(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    <a href='#ipp_attribute_t'>ipp_attribute_t</a> * attr);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>attr</tt></td><td>Attribute to delete</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippErrorString'>ippErrorString()</a></h3>
-<h4>Description</h4>
-<p>Return a name for the given status code.
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-ippErrorString(
-    ipp_status_t error);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>error</tt></td><td>Error status</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Text string</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ippErrorValue'>ippErrorValue()</a></h3>
-<h4>Description</h4>
-<p>Return a status code for the given name.
-
-
-<h4>Syntax</h4>
-<p><tt>
-ipp_status_t<br>
-ippErrorValue(
-    const char * name);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name</tt></td><td>Name</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>IPP status code</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippFindAttribute'>ippFindAttribute()</a></h3>
-<h4>Description</h4>
-<p>Find a named attribute in a request...
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippFindAttribute(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    const char * name,
-    ipp_tag_t type);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
-<tr><td><tt>type</tt></td><td>Type of attribute</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Matching attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippFindNextAttribute'>ippFindNextAttribute()</a></h3>
-<h4>Description</h4>
-<p>Find the next named attribute in a request...
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_attribute_t'>ipp_attribute_t</a> *<br>
-ippFindNextAttribute(
-    <a href='#ipp_t'>ipp_t</a> * ipp,
-    const char * name,
-    ipp_tag_t type);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
-<tr><td><tt>type</tt></td><td>Type of attribute</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Matching attribute</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippLength'>ippLength()</a></h3>
-<h4>Description</h4>
-<p>Compute the length of an IPP message.
-<h4>Syntax</h4>
-<p><tt>
-size_t<br>
-ippLength(
-    <a href='#ipp_t'>ipp_t</a> * ipp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ipp</tt></td><td>IPP message</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Size of IPP message</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippNew'>ippNew()</a></h3>
-<h4>Description</h4>
-<p>Allocate a new IPP message.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_t'>ipp_t</a> *<br>
-ippNew(void);
-</tt></p>
-<h4>Arguments</h4>
-<p>None.</p>
-<h4>Returns</h4>
-<p>New IPP message</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ippNewRequest'>ippNewRequest()</a></h3>
-<h4>Description</h4>
-<p>Allocate a new IPP request message.
-<p>The new request message is initialized with the attributes-charset and
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="httpWrite2">httpWrite2</a></h3>
+<p class="description">Write data to a HTTP connection.</p>
+<p class="code">
+ssize_t httpWrite2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *buffer,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t length<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>buffer</dt>
+<dd class="description">Buffer for data</dd>
+<dt>length</dt>
+<dd class="description">Number of bytes to write</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of bytes written</p>
+<h3 class="function"><a name="ippAddBoolean">ippAddBoolean</a></h3>
+<p class="description">Add a boolean attribute to an IPP message.</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippAddBoolean (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t group,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char value<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>group</dt>
+<dd class="description">IPP group</dd>
+<dt>name</dt>
+<dd class="description">Name of attribute</dd>
+<dt>value</dt>
+<dd class="description">Value of attribute</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New attribute</p>
+<h3 class="function"><a name="ippAddBooleans">ippAddBooleans</a></h3>
+<p class="description">Add an array of boolean values.</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippAddBooleans (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t group,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_values,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *values<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>group</dt>
+<dd class="description">IPP group</dd>
+<dt>name</dt>
+<dd class="description">Name of attribute</dd>
+<dt>num_values</dt>
+<dd class="description">Number of values</dd>
+<dt>values</dt>
+<dd class="description">Values</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New attribute</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.19&nbsp;</span><a name="ippAddCollection">ippAddCollection</a></h3>
+<p class="description">Add a collection value.</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippAddCollection (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t group,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *value<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>group</dt>
+<dd class="description">IPP group</dd>
+<dt>name</dt>
+<dd class="description">Name of attribute</dd>
+<dt>value</dt>
+<dd class="description">Value</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New attribute</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.19&nbsp;</span><a name="ippAddCollections">ippAddCollections</a></h3>
+<p class="description">Add an array of collection values.</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippAddCollections (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t group,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_values,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const <a href="#ipp_t">ipp_t</a> **values<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>group</dt>
+<dd class="description">IPP group</dd>
+<dt>name</dt>
+<dd class="description">Name of attribute</dd>
+<dt>num_values</dt>
+<dd class="description">Number of values</dd>
+<dt>values</dt>
+<dd class="description">Values</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New attribute</p>
+<h3 class="function"><a name="ippAddDate">ippAddDate</a></h3>
+<p class="description">Add a date attribute to an IPP message.</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippAddDate (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t group,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const <a href="#ipp_uchar_t">ipp_uchar_t</a> *value<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>group</dt>
+<dd class="description">IPP group</dd>
+<dt>name</dt>
+<dd class="description">Name of attribute</dd>
+<dt>value</dt>
+<dd class="description">Value</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New attribute</p>
+<h3 class="function"><a name="ippAddInteger">ippAddInteger</a></h3>
+<p class="description">Add a integer attribute to an IPP message.</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippAddInteger (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t group,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t type,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int value<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>group</dt>
+<dd class="description">IPP group</dd>
+<dt>type</dt>
+<dd class="description">Type of attribute</dd>
+<dt>name</dt>
+<dd class="description">Name of attribute</dd>
+<dt>value</dt>
+<dd class="description">Value of attribute</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New attribute</p>
+<h3 class="function"><a name="ippAddIntegers">ippAddIntegers</a></h3>
+<p class="description">Add an array of integer values.</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippAddIntegers (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t group,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t type,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_values,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const int *values<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>group</dt>
+<dd class="description">IPP group</dd>
+<dt>type</dt>
+<dd class="description">Type of attribute</dd>
+<dt>name</dt>
+<dd class="description">Name of attribute</dd>
+<dt>num_values</dt>
+<dd class="description">Number of values</dd>
+<dt>values</dt>
+<dd class="description">Values</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New attribute</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ippAddOctetString">ippAddOctetString</a></h3>
+<p class="description">Add an octetString value to an IPP message.</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippAddOctetString (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t group,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const void *data,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int datalen<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>group</dt>
+<dd class="description">IPP group</dd>
+<dt>name</dt>
+<dd class="description">Name of attribute</dd>
+<dt>data</dt>
+<dd class="description">octetString data</dd>
+<dt>datalen</dt>
+<dd class="description">Length of data in bytes</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New attribute</p>
+<h3 class="function"><a name="ippAddRange">ippAddRange</a></h3>
+<p class="description">Add a range of values to an IPP message.</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippAddRange (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t group,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int lower,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int upper<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>group</dt>
+<dd class="description">IPP group</dd>
+<dt>name</dt>
+<dd class="description">Name of attribute</dd>
+<dt>lower</dt>
+<dd class="description">Lower value</dd>
+<dt>upper</dt>
+<dd class="description">Upper value</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New attribute</p>
+<h3 class="function"><a name="ippAddRanges">ippAddRanges</a></h3>
+<p class="description">Add ranges of values to an IPP message.</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippAddRanges (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t group,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_values,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const int *lower,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const int *upper<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>group</dt>
+<dd class="description">IPP group</dd>
+<dt>name</dt>
+<dd class="description">Name of attribute</dd>
+<dt>num_values</dt>
+<dd class="description">Number of values</dd>
+<dt>lower</dt>
+<dd class="description">Lower values</dd>
+<dt>upper</dt>
+<dd class="description">Upper values</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New attribute</p>
+<h3 class="function"><a name="ippAddResolution">ippAddResolution</a></h3>
+<p class="description">Add a resolution value to an IPP message.</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippAddResolution (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t group,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_res_t units,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int xres,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int yres<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>group</dt>
+<dd class="description">IPP group</dd>
+<dt>name</dt>
+<dd class="description">Name of attribute</dd>
+<dt>units</dt>
+<dd class="description">Units for resolution</dd>
+<dt>xres</dt>
+<dd class="description">X resolution</dd>
+<dt>yres</dt>
+<dd class="description">Y resolution</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New attribute</p>
+<h3 class="function"><a name="ippAddResolutions">ippAddResolutions</a></h3>
+<p class="description">Add resolution values to an IPP message.</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippAddResolutions (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t group,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_values,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_res_t units,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const int *xres,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const int *yres<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>group</dt>
+<dd class="description">IPP group</dd>
+<dt>name</dt>
+<dd class="description">Name of attribute</dd>
+<dt>num_values</dt>
+<dd class="description">Number of values</dd>
+<dt>units</dt>
+<dd class="description">Units for resolution</dd>
+<dt>xres</dt>
+<dd class="description">X resolutions</dd>
+<dt>yres</dt>
+<dd class="description">Y resolutions</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New attribute</p>
+<h3 class="function"><a name="ippAddSeparator">ippAddSeparator</a></h3>
+<p class="description">Add a group separator to an IPP message.</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippAddSeparator (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New attribute</p>
+<h3 class="function"><a name="ippAddString">ippAddString</a></h3>
+<p class="description">Add a language-encoded string to an IPP message.</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippAddString (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t group,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t type,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *charset,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *value<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>group</dt>
+<dd class="description">IPP group</dd>
+<dt>type</dt>
+<dd class="description">Type of attribute</dd>
+<dt>name</dt>
+<dd class="description">Name of attribute</dd>
+<dt>charset</dt>
+<dd class="description">Character set</dd>
+<dt>value</dt>
+<dd class="description">Value</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New attribute</p>
+<h3 class="function"><a name="ippAddStrings">ippAddStrings</a></h3>
+<p class="description">Add language-encoded strings to an IPP message.</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippAddStrings (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t group,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t type,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_values,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *charset,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *const *values<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>group</dt>
+<dd class="description">IPP group</dd>
+<dt>type</dt>
+<dd class="description">Type of attribute</dd>
+<dt>name</dt>
+<dd class="description">Name of attribute</dd>
+<dt>num_values</dt>
+<dd class="description">Number of values</dd>
+<dt>charset</dt>
+<dd class="description">Character set</dd>
+<dt>values</dt>
+<dd class="description">Values</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New attribute</p>
+<h3 class="function"><a name="ippDateToTime">ippDateToTime</a></h3>
+<p class="description">Convert from RFC 1903 Date/Time format to UNIX time
+in seconds.</p>
+<p class="code">
+time_t ippDateToTime (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const <a href="#ipp_uchar_t">ipp_uchar_t</a> *date<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>date</dt>
+<dd class="description">RFC 1903 date info</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">UNIX time value</p>
+<h3 class="function"><a name="ippDelete">ippDelete</a></h3>
+<p class="description">Delete an IPP message.</p>
+<p class="code">
+void ippDelete (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+</dl>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.19&nbsp;</span><a name="ippDeleteAttribute">ippDeleteAttribute</a></h3>
+<p class="description">Delete a single attribute in an IPP message.</p>
+<p class="code">
+void ippDeleteAttribute (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_attribute_t">ipp_attribute_t</a> *attr<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>attr</dt>
+<dd class="description">Attribute to delete</dd>
+</dl>
+<h3 class="function"><a name="ippErrorString">ippErrorString</a></h3>
+<p class="description">Return a name for the given status code.</p>
+<p class="code">
+const char *ippErrorString (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_status_t error<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>error</dt>
+<dd class="description">Error status</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Text string</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ippErrorValue">ippErrorValue</a></h3>
+<p class="description">Return a status code for the given name.</p>
+<p class="code">
+ipp_status_t ippErrorValue (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>name</dt>
+<dd class="description">Name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">IPP status code</p>
+<h3 class="function"><a name="ippFindAttribute">ippFindAttribute</a></h3>
+<p class="description">Find a named attribute in a request...</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippFindAttribute (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t type<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>name</dt>
+<dd class="description">Name of attribute</dd>
+<dt>type</dt>
+<dd class="description">Type of attribute</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Matching attribute</p>
+<h3 class="function"><a name="ippFindNextAttribute">ippFindNextAttribute</a></h3>
+<p class="description">Find the next named attribute in a request...</p>
+<p class="code">
+<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippFindNextAttribute (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t type<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>name</dt>
+<dd class="description">Name of attribute</dd>
+<dt>type</dt>
+<dd class="description">Type of attribute</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Matching attribute</p>
+<h3 class="function"><a name="ippLength">ippLength</a></h3>
+<p class="description">Compute the length of an IPP message.</p>
+<p class="code">
+size_t ippLength (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Size of IPP message</p>
+<h3 class="function"><a name="ippNew">ippNew</a></h3>
+<p class="description">Allocate a new IPP message.</p>
+<p class="code">
+<a href="#ipp_t">ipp_t</a> *ippNew (void);</p>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New IPP message</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ippNewRequest">ippNewRequest</a></h3>
+<p class="description">Allocate a new IPP request message.</p>
+<p class="code">
+<a href="#ipp_t">ipp_t</a> *ippNewRequest (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_op_t op<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>op</dt>
+<dd class="description">Operation code</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">IPP request message</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The new request message is initialized with the attributes-charset and
 attributes-natural-language attributes added. The
 attributes-natural-language value is derived from the current locale.
 
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ipp_t'>ipp_t</a> *<br>
-ippNewRequest(
-    ipp_op_t op);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>op</tt></td><td>Operation code</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>IPP request message</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ippOpString'>ippOpString()</a></h3>
-<h4>Description</h4>
-<p>Return a name for the given operation id.
-
-
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-ippOpString(
-    ipp_op_t op);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>op</tt></td><td>Operation ID</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Name</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ippOpValue'>ippOpValue()</a></h3>
-<h4>Description</h4>
-<p>Return an operation id for the given name.
-
-
-<h4>Syntax</h4>
-<p><tt>
-ipp_op_t<br>
-ippOpValue(
-    const char * name);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name</tt></td><td>Textual name</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Operation ID</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippPort'>ippPort()</a></h3>
-<h4>Description</h4>
-<p>Return the default IPP port number.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-ippPort(void);
-</tt></p>
-<h4>Arguments</h4>
-<p>None.</p>
-<h4>Returns</h4>
-<p>Port number</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippRead'>ippRead()</a></h3>
-<h4>Description</h4>
-<p>Read data for an IPP message from a HTTP connection.
-<h4>Syntax</h4>
-<p><tt>
-ipp_state_t<br>
-ippRead(
-    <a href='#http_t'>http_t</a> * http,
-    <a href='#ipp_t'>ipp_t</a> * ipp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>ipp</tt></td><td>IPP data</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Current state</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span><a name='ippReadFile'>ippReadFile()</a></h3>
-<h4>Description</h4>
-<p>Read data for an IPP message from a file.
-
-
-<h4>Syntax</h4>
-<p><tt>
-ipp_state_t<br>
-ippReadFile(
-    int fd,
-    <a href='#ipp_t'>ipp_t</a> * ipp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fd</tt></td><td>HTTP data</td></tr>
-<tr><td><tt>ipp</tt></td><td>IPP data</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Current state</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ippReadIO'>ippReadIO()</a></h3>
-<h4>Description</h4>
-<p>Read data for an IPP message.
-
-
-<h4>Syntax</h4>
-<p><tt>
-ipp_state_t<br>
-ippReadIO(
-    void * src,
-    <a href='#ipp_iocb_t'>ipp_iocb_t</a> cb,
-    int blocking,
-    <a href='#ipp_t'>ipp_t</a> * parent,
-    <a href='#ipp_t'>ipp_t</a> * ipp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>src</tt></td><td>Data source</td></tr>
-<tr><td><tt>cb</tt></td><td>Read callback function</td></tr>
-<tr><td><tt>blocking</tt></td><td>Use blocking IO?</td></tr>
-<tr><td><tt>parent</tt></td><td>Parent request, if any</td></tr>
-<tr><td><tt>ipp</tt></td><td>IPP data</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Current state</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippSetPort'>ippSetPort()</a></h3>
-<h4>Description</h4>
-<p>Set the default port number.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-ippSetPort(
-    int p);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>p</tt></td><td>Port number to use</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippTimeToDate'>ippTimeToDate()</a></h3>
-<h4>Description</h4>
-<p>Convert from UNIX time to RFC 1903 format.
-<h4>Syntax</h4>
-<p><tt>
-const <a href='#ipp_uchar_t'>ipp_uchar_t</a> *<br>
-ippTimeToDate(
-    time_t t);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>t</tt></td><td>UNIX time value</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>RFC-1903 date/time data</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ippWrite'>ippWrite()</a></h3>
-<h4>Description</h4>
-<p>Write data for an IPP message to a HTTP connection.
-<h4>Syntax</h4>
-<p><tt>
-ipp_state_t<br>
-ippWrite(
-    <a href='#http_t'>http_t</a> * http,
-    <a href='#ipp_t'>ipp_t</a> * ipp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>http</tt></td><td>HTTP connection</td></tr>
-<tr><td><tt>ipp</tt></td><td>IPP data</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Current state</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span><a name='ippWriteFile'>ippWriteFile()</a></h3>
-<h4>Description</h4>
-<p>Write data for an IPP message to a file.
-
-
-<h4>Syntax</h4>
-<p><tt>
-ipp_state_t<br>
-ippWriteFile(
-    int fd,
-    <a href='#ipp_t'>ipp_t</a> * ipp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fd</tt></td><td>HTTP data</td></tr>
-<tr><td><tt>ipp</tt></td><td>IPP data</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Current state</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ippWriteIO'>ippWriteIO()</a></h3>
-<h4>Description</h4>
-<p>Write data for an IPP message.
-
-
-<h4>Syntax</h4>
-<p><tt>
-ipp_state_t<br>
-ippWriteIO(
-    void * dst,
-    <a href='#ipp_iocb_t'>ipp_iocb_t</a> cb,
-    int blocking,
-    <a href='#ipp_t'>ipp_t</a> * parent,
-    <a href='#ipp_t'>ipp_t</a> * ipp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>dst</tt></td><td>Destination</td></tr>
-<tr><td><tt>cb</tt></td><td>Write callback function</td></tr>
-<tr><td><tt>blocking</tt></td><td>Use blocking IO?</td></tr>
-<tr><td><tt>parent</tt></td><td>Parent IPP message</td></tr>
-<tr><td><tt>ipp</tt></td><td>IPP data</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Current state</p>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='STRUCTURES'>Structures</a></h2>
-<ul>
-       <li><a href='#http_addrlist_s'><tt>http_addrlist_s</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ipp_attribute_s'><tt>ipp_attribute_s</tt></a> </li>
-       <li><a href='#ipp_s'><tt>ipp_s</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='http_addrlist_s'>http_addrlist_s</a></h3>
-<h4>Description</h4>
-<p>Socket address list, which is
-used to enumerate all of the
-addresses that are associated
-with a hostname. 
-<h4>Definition</h4>
-<p><tt>
-struct http_addrlist_s<br>
-{<br>
-&nbsp;&nbsp;<a href='#http_addr_t'>http_addr_t</a> addr;<br>
-&nbsp;&nbsp;struct <a href='#http_addrlist_s'>http_addrlist_s</a> * next;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>addr</tt> </td><td>Address
-</td></tr>
-<tr><td><tt>next</tt> </td><td>Pointer to next address in list
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_attribute_s'>ipp_attribute_s</a></h3>
-<h4>Description</h4>
-<p>Attribute
-<h4>Definition</h4>
-<p><tt>
-struct ipp_attribute_s<br>
-{<br>
-&nbsp;&nbsp;char * name;<br>
-&nbsp;&nbsp;struct <a href='#ipp_attribute_s'>ipp_attribute_s</a> * next;<br>
-&nbsp;&nbsp;int num_values;<br>
-&nbsp;&nbsp;ipp_tag_t group_tag, value_tag;<br>
-&nbsp;&nbsp;<a href='#ipp_value_t'>ipp_value_t</a> values[1];<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name</tt> </td><td>Name of attribute
-</td></tr>
-<tr><td><tt>next</tt> </td><td>Next attribute in list
-</td></tr>
-<tr><td><tt>num_values</tt> </td><td>Number of values
-</td></tr>
-<tr><td><tt>value_tag</tt> </td><td>What type of value is it?
-</td></tr>
-<tr><td><tt>values[1]</tt> </td><td>Values
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_s'>ipp_s</a></h3>
-<h4>Description</h4>
-<p>IPP Request/Response/Notification
-<h4>Definition</h4>
-<p><tt>
-struct ipp_s<br>
-{<br>
-&nbsp;&nbsp;<a href='#ipp_attribute_t'>ipp_attribute_t</a> * attrs;<br>
-&nbsp;&nbsp;<a href='#ipp_attribute_t'>ipp_attribute_t</a> * current;<br>
-&nbsp;&nbsp;ipp_tag_t curtag;<br>
-&nbsp;&nbsp;<a href='#ipp_attribute_t'>ipp_attribute_t</a> * last;<br>
-&nbsp;&nbsp;<a href='#ipp_attribute_t'>ipp_attribute_t</a> * prev;<br>
-&nbsp;&nbsp;<a href='#ipp_request_t'>ipp_request_t</a> request;<br>
-&nbsp;&nbsp;ipp_state_t state;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>attrs</tt> </td><td>Attributes
-</td></tr>
-<tr><td><tt>current</tt> </td><td>Current attribute (for read/write)
-</td></tr>
-<tr><td><tt>curtag</tt> </td><td>Current attribute group tag
-</td></tr>
-<tr><td><tt>last</tt> </td><td>Last attribute in list
-</td></tr>
-<tr><td><tt>prev</tt> </td><td>Previous attribute (for read)
-</td></tr>
-<tr><td><tt>request</tt> </td><td>Request header
-</td></tr>
-<tr><td><tt>state</tt> </td><td>State of request
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='TYPES'>Types</a></h2>
-<ul>
-       <li><a href='#http_addrlist_t'><tt>http_addrlist_t</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#http_auth_t'><tt>http_auth_t</tt></a> </li>
-       <li><a href='#http_encoding_t'><tt>http_encoding_t</tt></a> </li>
-       <li><a href='#http_encryption_t'><tt>http_encryption_t</tt></a> </li>
-       <li><a href='#http_t'><tt>http_t</tt></a> </li>
-       <li><a href='#ipp_attribute_t'><tt>ipp_attribute_t</tt></a> </li>
-       <li><a href='#ipp_iocb_t'><tt>ipp_iocb_t</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ipp_request_t'><tt>ipp_request_t</tt></a> </li>
-       <li><a href='#ipp_t'><tt>ipp_t</tt></a> </li>
-       <li><a href='#ipp_uchar_t'><tt>ipp_uchar_t</tt></a> </li>
-       <li><a href='#ipp_value_t'><tt>ipp_value_t</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='http_addrlist_t'>http_addrlist_t</a></h3>
-<h4>Description</h4>
-<p>Socket address list, which is
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ippOpString">ippOpString</a></h3>
+<p class="description">Return a name for the given operation id.</p>
+<p class="code">
+const char *ippOpString (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_op_t op<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>op</dt>
+<dd class="description">Operation ID</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Name</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ippOpValue">ippOpValue</a></h3>
+<p class="description">Return an operation id for the given name.</p>
+<p class="code">
+ipp_op_t ippOpValue (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>name</dt>
+<dd class="description">Textual name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Operation ID</p>
+<h3 class="function"><a name="ippPort">ippPort</a></h3>
+<p class="description">Return the default IPP port number.</p>
+<p class="code">
+int ippPort (void);</p>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Port number</p>
+<h3 class="function"><a name="ippRead">ippRead</a></h3>
+<p class="description">Read data for an IPP message from a HTTP connection.</p>
+<p class="code">
+ipp_state_t ippRead (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>ipp</dt>
+<dd class="description">IPP data</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Current state</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.19&nbsp;</span><a name="ippReadFile">ippReadFile</a></h3>
+<p class="description">Read data for an IPP message from a file.</p>
+<p class="code">
+ipp_state_t ippReadFile (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int fd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fd</dt>
+<dd class="description">HTTP data</dd>
+<dt>ipp</dt>
+<dd class="description">IPP data</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Current state</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ippReadIO">ippReadIO</a></h3>
+<p class="description">Read data for an IPP message.</p>
+<p class="code">
+ipp_state_t ippReadIO (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;void *src,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_iocb_t">ipp_iocb_t</a> cb,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int blocking,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *parent,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>src</dt>
+<dd class="description">Data source</dd>
+<dt>cb</dt>
+<dd class="description">Read callback function</dd>
+<dt>blocking</dt>
+<dd class="description">Use blocking IO?</dd>
+<dt>parent</dt>
+<dd class="description">Parent request, if any</dd>
+<dt>ipp</dt>
+<dd class="description">IPP data</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Current state</p>
+<h3 class="function"><a name="ippSetPort">ippSetPort</a></h3>
+<p class="description">Set the default port number.</p>
+<p class="code">
+void ippSetPort (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int p<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>p</dt>
+<dd class="description">Port number to use</dd>
+</dl>
+<h3 class="function"><a name="ippTimeToDate">ippTimeToDate</a></h3>
+<p class="description">Convert from UNIX time to RFC 1903 format.</p>
+<p class="code">
+const <a href="#ipp_uchar_t">ipp_uchar_t</a> *ippTimeToDate (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;time_t t<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>t</dt>
+<dd class="description">UNIX time value</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">RFC-1903 date/time data</p>
+<h3 class="function"><a name="ippWrite">ippWrite</a></h3>
+<p class="description">Write data for an IPP message to a HTTP connection.</p>
+<p class="code">
+ipp_state_t ippWrite (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">HTTP connection</dd>
+<dt>ipp</dt>
+<dd class="description">IPP data</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Current state</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.19&nbsp;</span><a name="ippWriteFile">ippWriteFile</a></h3>
+<p class="description">Write data for an IPP message to a file.</p>
+<p class="code">
+ipp_state_t ippWriteFile (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int fd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fd</dt>
+<dd class="description">HTTP data</dd>
+<dt>ipp</dt>
+<dd class="description">IPP data</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Current state</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ippWriteIO">ippWriteIO</a></h3>
+<p class="description">Write data for an IPP message.</p>
+<p class="code">
+ipp_state_t ippWriteIO (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;void *dst,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_iocb_t">ipp_iocb_t</a> cb,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int blocking,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *parent,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>dst</dt>
+<dd class="description">Destination</dd>
+<dt>cb</dt>
+<dd class="description">Write callback function</dd>
+<dt>blocking</dt>
+<dd class="description">Use blocking IO?</dd>
+<dt>parent</dt>
+<dd class="description">Parent IPP message</dd>
+<dt>ipp</dt>
+<dd class="description">IPP data</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Current state</p>
+<h2 class="title"><a name="TYPES">Data Types</a></h2>
+<h3 class="typedef"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="http_addrlist_t">http_addrlist_t</a></h3>
+<p class="description">Socket address list, which is
 used to enumerate all of the
 addresses that are associated
-with a hostname. 
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#http_addrlist_s'>http_addrlist_s</a> / http_addrlist_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='http_auth_t'>http_auth_t</a></h3>
-<h4>Description</h4>
-<p>HTTP authentication types
-<h4>Definition</h4>
-<p><tt>
-typedef enum <a href='#http_auth_e'>http_auth_e</a> http_auth_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='http_encoding_t'>http_encoding_t</a></h3>
-<h4>Description</h4>
-<p>HTTP transfer encoding values
-<h4>Definition</h4>
-<p><tt>
-typedef enum <a href='#http_encoding_e'>http_encoding_e</a> http_encoding_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='http_encryption_t'>http_encryption_t</a></h3>
-<h4>Description</h4>
-<p>HTTP encryption values
-<h4>Definition</h4>
-<p><tt>
-typedef enum <a href='#http_encryption_e'>http_encryption_e</a> http_encryption_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='http_t'>http_t</a></h3>
-<h4>Description</h4>
-<p>HTTP connection type
-<h4>Definition</h4>
-<p><tt>
+with a hostname. </p>
+<p class="code">
+typedef struct <a href="#http_addrlist_s">http_addrlist_s</a> / http_addrlist_t;
+</p>
+<h3 class="typedef"><a name="http_auth_t">http_auth_t</a></h3>
+<p class="description">HTTP authentication types</p>
+<p class="code">
+typedef enum <a href="#http_auth_e">http_auth_e</a> http_auth_t;
+</p>
+<h3 class="typedef"><a name="http_encoding_t">http_encoding_t</a></h3>
+<p class="description">HTTP transfer encoding values</p>
+<p class="code">
+typedef enum <a href="#http_encoding_e">http_encoding_e</a> http_encoding_t;
+</p>
+<h3 class="typedef"><a name="http_encryption_t">http_encryption_t</a></h3>
+<p class="description">HTTP encryption values</p>
+<p class="code">
+typedef enum <a href="#http_encryption_e">http_encryption_e</a> http_encryption_t;
+</p>
+<h3 class="typedef"><a name="http_t">http_t</a></h3>
+<p class="description">HTTP connection type</p>
+<p class="code">
 typedef struct _http_s http_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_attribute_t'>ipp_attribute_t</a></h3>
-<h4>Description</h4>
-<p>Attribute
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#ipp_attribute_s'>ipp_attribute_s</a> ipp_attribute_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ipp_iocb_t'>ipp_iocb_t</a></h3>
-<h4>Description</h4>
-<p>IPP IO Callback Function 
-<h4>Definition</h4>
-<p><tt>
-typedef <a href='#ssize_t'>ssize_t</a> (*ipp_iocb_t)(void *, <a href='#ipp_uchar_t'>ipp_uchar_t</a> *, size_t);
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_request_t'>ipp_request_t</a></h3>
-<h4>Description</h4>
-<p>Request Header
-<h4>Definition</h4>
-<p><tt>
-typedef union <a href='#ipp_request_u'>ipp_request_u</a> ipp_request_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_t'>ipp_t</a></h3>
-<h4>Description</h4>
-<p>Attribute Value
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#ipp_s'>ipp_s</a> ipp_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_uchar_t'>ipp_uchar_t</a></h3>
-<h4>Description</h4>
-<p>IPP status codes...
-<h4>Definition</h4>
-<p><tt>
+</p>
+<h3 class="typedef"><a name="ipp_attribute_t">ipp_attribute_t</a></h3>
+<p class="description">Attribute</p>
+<p class="code">
+typedef struct <a href="#ipp_attribute_s">ipp_attribute_s</a> ipp_attribute_t;
+</p>
+<h3 class="typedef"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ipp_iocb_t">ipp_iocb_t</a></h3>
+<p class="description">IPP IO Callback Function </p>
+<p class="code">
+typedef ssize_t (*ipp_iocb_t)(void *, <a href="#ipp_uchar_t">ipp_uchar_t</a> *, size_t);
+</p>
+<h3 class="typedef"><a name="ipp_request_t">ipp_request_t</a></h3>
+<p class="description">Request Header</p>
+<p class="code">
+typedef union <a href="#ipp_request_u">ipp_request_u</a> ipp_request_t;
+</p>
+<h3 class="typedef"><a name="ipp_t">ipp_t</a></h3>
+<p class="description">Attribute Value</p>
+<p class="code">
+typedef struct <a href="#ipp_s">ipp_s</a> ipp_t;
+</p>
+<h3 class="typedef"><a name="ipp_uchar_t">ipp_uchar_t</a></h3>
+<p class="description">IPP status codes...</p>
+<p class="code">
 typedef typedef unsigned char ipp_uchar_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_value_t'>ipp_value_t</a></h3>
-<h4>Description</h4>
-<p>New in CUPS 1.1.19
-<h4>Definition</h4>
-<p><tt>
-typedef union <a href='#ipp_value_u'>ipp_value_u</a> ipp_value_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='UNIONS'>Unions</a></h2>
-<ul>
-       <li><a href='#ipp_request_u'><tt>ipp_request_u</tt></a> </li>
-       <li><a href='#ipp_value_u'><tt>ipp_value_u</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_request_u'>ipp_request_u</a></h3>
-<h4>Description</h4>
-<p>Request Header
-<h4>Definition</h4>
-<p><tt>
-union ipp_request_u<br>
-{<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ipp_value_u'>ipp_value_u</a></h3>
-<h4>Description</h4>
-<p>New in CUPS 1.1.19
-<h4>Definition</h4>
-<p><tt>
-union ipp_value_u<br>
-{<br>
-&nbsp;&nbsp;char boolean;<br>
-&nbsp;&nbsp;<a href='#ipp_t'>ipp_t</a> * collection;<br>
-&nbsp;&nbsp;<a href='#ipp_uchar_t'>ipp_uchar_t</a> date[11];<br>
-&nbsp;&nbsp;int integer;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>boolean</tt> </td><td>Boolean value
-</td></tr>
-<tr><td><tt>collection</tt> </td><td>Collection value
-</td></tr>
-<tr><td><tt>date[11]</tt> </td><td>Date/time value
-</td></tr>
-<tr><td><tt>integer</tt> </td><td>Integer/enumerated value
-</td></tr>
-</tbody></table></div>
+</p>
+<h3 class="typedef"><a name="ipp_value_t">ipp_value_t</a></h3>
+<p class="description">New in CUPS 1.1.19</p>
+<p class="code">
+typedef union <a href="#ipp_value_u">ipp_value_u</a> ipp_value_t;
+</p>
+<h2 class="title"><a name="STRUCTURES">Structures</a></h2>
+<h3 class="struct"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="http_addrlist_s">http_addrlist_s</a></h3>
+<p class="description">Socket address list, which is
+used to enumerate all of the
+addresses that are associated
+with a hostname. </p>
+<p class="code">struct http_addrlist_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_addr_t">http_addr_t</a> addr;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;struct <a href="#http_addrlist_s">http_addrlist_s</a> *next;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>addr </dt>
+<dd class="description">Address</dd>
+<dt>next </dt>
+<dd class="description">Pointer to next address in list</dd>
+</dl>
+<h3 class="struct"><a name="ipp_attribute_s">ipp_attribute_s</a></h3>
+<p class="description">Attribute</p>
+<p class="code">struct ipp_attribute_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *name;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;struct <a href="#ipp_attribute_s">ipp_attribute_s</a> *next;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_values;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t group_tag, value_tag;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_value_t">ipp_value_t</a> values[1];<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>name </dt>
+<dd class="description">Name of attribute</dd>
+<dt>next </dt>
+<dd class="description">Next attribute in list</dd>
+<dt>num_values </dt>
+<dd class="description">Number of values</dd>
+<dt>value_tag </dt>
+<dd class="description">What type of value is it?</dd>
+<dt>values[1] </dt>
+<dd class="description">Values</dd>
+</dl>
+<h3 class="struct"><a name="ipp_s">ipp_s</a></h3>
+<p class="description">IPP Request/Response/Notification</p>
+<p class="code">struct ipp_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_attribute_t">ipp_attribute_t</a> *attrs;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_attribute_t">ipp_attribute_t</a> *current;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_tag_t curtag;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_attribute_t">ipp_attribute_t</a> *last;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_attribute_t">ipp_attribute_t</a> *prev;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_request_t">ipp_request_t</a> request;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ipp_state_t state;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>attrs </dt>
+<dd class="description">Attributes</dd>
+<dt>current </dt>
+<dd class="description">Current attribute (for read/write)</dd>
+<dt>curtag </dt>
+<dd class="description">Current attribute group tag</dd>
+<dt>last </dt>
+<dd class="description">Last attribute in list</dd>
+<dt>prev </dt>
+<dd class="description">Previous attribute (for read)</dd>
+<dt>request </dt>
+<dd class="description">Request header</dd>
+<dt>state </dt>
+<dd class="description">State of request</dd>
+</dl>
+<h2 class="title"><a name="UNIONS">Unions</a></h2>
+<h3 class="union"><a name="ipp_request_u">ipp_request_u</a></h3>
+<p class="description">Request Header</p>
+<p class="code">union ipp_request_u {<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+</dl>
+<h3 class="union"><a name="ipp_value_u">ipp_value_u</a></h3>
+<p class="description">New in CUPS 1.1.19</p>
+<p class="code">union ipp_value_u {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char boolean;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *collection;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_uchar_t">ipp_uchar_t</a> date[11];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int integer;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>boolean </dt>
+<dd class="description">Boolean value</dd>
+<dt>collection </dt>
+<dd class="description">Collection value</dd>
+<dt>date[11] </dt>
+<dd class="description">Date/time value</dd>
+<dt>integer </dt>
+<dd class="description">Integer/enumerated value</dd>
+</dl>
+<h2 class="title"><a name="ENUMERATIONS">Constants</a></h2>
+<h3 class="enumeration"><a name="http_auth_e">http_auth_e</a></h3>
+<p class="description">HTTP authentication types</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>HTTP_AUTH_BASIC </dt>
+<dd class="description">Basic authentication in use</dd>
+<dt>HTTP_AUTH_MD5 </dt>
+<dd class="description">Digest authentication in use</dd>
+<dt>HTTP_AUTH_MD5_INT </dt>
+<dd class="description">Digest authentication in use for body</dd>
+<dt>HTTP_AUTH_MD5_SESS </dt>
+<dd class="description">MD5-session authentication in use</dd>
+<dt>HTTP_AUTH_MD5_SESS_INT </dt>
+<dd class="description">MD5-session authentication in use for body</dd>
+<dt>HTTP_AUTH_NEGOTIATE <span class="info">&nbsp;CUPS 1.3&nbsp;</span></dt>
+<dd class="description">GSSAPI authentication in use </dd>
+<dt>HTTP_AUTH_NONE </dt>
+<dd class="description">No authentication in use</dd>
+</dl>
+<h3 class="enumeration"><a name="http_encoding_e">http_encoding_e</a></h3>
+<p class="description">HTTP transfer encoding values</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>HTTP_ENCODE_CHUNKED </dt>
+<dd class="description">Data is chunked</dd>
+<dt>HTTP_ENCODE_FIELDS </dt>
+<dd class="description">Sending HTTP fields</dd>
+<dt>HTTP_ENCODE_LENGTH </dt>
+<dd class="description">Data is sent with Content-Length</dd>
+</dl>
+<h3 class="enumeration"><a name="http_encryption_e">http_encryption_e</a></h3>
+<p class="description">HTTP encryption values</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>HTTP_ENCRYPT_ALWAYS </dt>
+<dd class="description">Always encrypt (SSL)</dd>
+<dt>HTTP_ENCRYPT_IF_REQUESTED </dt>
+<dd class="description">Encrypt if requested (TLS upgrade)</dd>
+<dt>HTTP_ENCRYPT_NEVER </dt>
+<dd class="description">Never encrypt</dd>
+<dt>HTTP_ENCRYPT_REQUIRED </dt>
+<dd class="description">Encryption is required (TLS upgrade)</dd>
+</dl>
+<h3 class="enumeration"><a name="http_field_e">http_field_e</a></h3>
+<p class="description">HTTP field names</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>HTTP_FIELD_ACCEPT_LANGUAGE </dt>
+<dd class="description">Accept-Language field</dd>
+<dt>HTTP_FIELD_ACCEPT_RANGES </dt>
+<dd class="description">Accept-Ranges field</dd>
+<dt>HTTP_FIELD_AUTHORIZATION </dt>
+<dd class="description">Authorization field</dd>
+<dt>HTTP_FIELD_CONNECTION </dt>
+<dd class="description">Connection field</dd>
+<dt>HTTP_FIELD_CONTENT_ENCODING </dt>
+<dd class="description">Content-Encoding field</dd>
+<dt>HTTP_FIELD_CONTENT_LANGUAGE </dt>
+<dd class="description">Content-Language field</dd>
+<dt>HTTP_FIELD_CONTENT_LENGTH </dt>
+<dd class="description">Content-Length field</dd>
+<dt>HTTP_FIELD_CONTENT_LOCATION </dt>
+<dd class="description">Content-Location field</dd>
+<dt>HTTP_FIELD_CONTENT_MD5 </dt>
+<dd class="description">Content-MD5 field</dd>
+<dt>HTTP_FIELD_CONTENT_RANGE </dt>
+<dd class="description">Content-Range field</dd>
+<dt>HTTP_FIELD_CONTENT_TYPE </dt>
+<dd class="description">Content-Type field</dd>
+<dt>HTTP_FIELD_CONTENT_VERSION </dt>
+<dd class="description">Content-Version field</dd>
+<dt>HTTP_FIELD_DATE </dt>
+<dd class="description">Date field</dd>
+<dt>HTTP_FIELD_HOST </dt>
+<dd class="description">Host field</dd>
+<dt>HTTP_FIELD_IF_MODIFIED_SINCE </dt>
+<dd class="description">If-Modified-Since field</dd>
+<dt>HTTP_FIELD_IF_UNMODIFIED_SINCE </dt>
+<dd class="description">If-Unmodified-Since field</dd>
+<dt>HTTP_FIELD_KEEP_ALIVE </dt>
+<dd class="description">Keep-Alive field</dd>
+<dt>HTTP_FIELD_LAST_MODIFIED </dt>
+<dd class="description">Last-Modified field</dd>
+<dt>HTTP_FIELD_LINK </dt>
+<dd class="description">Link field</dd>
+<dt>HTTP_FIELD_LOCATION </dt>
+<dd class="description">Location field</dd>
+<dt>HTTP_FIELD_MAX </dt>
+<dd class="description">Maximum field index</dd>
+<dt>HTTP_FIELD_RANGE </dt>
+<dd class="description">Range field</dd>
+<dt>HTTP_FIELD_REFERER </dt>
+<dd class="description">Referer field</dd>
+<dt>HTTP_FIELD_RETRY_AFTER </dt>
+<dd class="description">Retry-After field</dd>
+<dt>HTTP_FIELD_TRANSFER_ENCODING </dt>
+<dd class="description">Transfer-Encoding field</dd>
+<dt>HTTP_FIELD_UNKNOWN </dt>
+<dd class="description">Unknown field</dd>
+<dt>HTTP_FIELD_UPGRADE </dt>
+<dd class="description">Upgrade field</dd>
+<dt>HTTP_FIELD_USER_AGENT </dt>
+<dd class="description">User-Agent field</dd>
+<dt>HTTP_FIELD_WWW_AUTHENTICATE </dt>
+<dd class="description">WWW-Authenticate field</dd>
+</dl>
+<h3 class="enumeration"><a name="http_keepalive_e">http_keepalive_e</a></h3>
+<p class="description">Types and structures...</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>HTTP_KEEPALIVE_OFF </dt>
+<dd class="description">No keep alive support</dd>
+<dt>HTTP_KEEPALIVE_ON </dt>
+<dd class="description">Use keep alive</dd>
+</dl>
+<h3 class="enumeration"><a name="http_state_e">http_state_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>HTTP_CLOSE </dt>
+<dd class="description">CLOSE command, waiting for blank line</dd>
+<dt>HTTP_DELETE </dt>
+<dd class="description">DELETE command, waiting for blank line</dd>
+<dt>HTTP_GET </dt>
+<dd class="description">GET command, waiting for blank line</dd>
+<dt>HTTP_GET_SEND </dt>
+<dd class="description">GET command, sending data</dd>
+<dt>HTTP_HEAD </dt>
+<dd class="description">HEAD command, waiting for blank line</dd>
+<dt>HTTP_OPTIONS </dt>
+<dd class="description">OPTIONS command, waiting for blank line</dd>
+<dt>HTTP_POST </dt>
+<dd class="description">POST command, waiting for blank line</dd>
+<dt>HTTP_POST_RECV </dt>
+<dd class="description">POST command, receiving data</dd>
+<dt>HTTP_POST_SEND </dt>
+<dd class="description">POST command, sending data</dd>
+<dt>HTTP_PUT </dt>
+<dd class="description">PUT command, waiting for blank line</dd>
+<dt>HTTP_PUT_RECV </dt>
+<dd class="description">PUT command, receiving data</dd>
+<dt>HTTP_STATUS </dt>
+<dd class="description">Command complete, sending status</dd>
+<dt>HTTP_TRACE </dt>
+<dd class="description">TRACE command, waiting for blank line</dd>
+<dt>HTTP_WAITING </dt>
+<dd class="description">Waiting for command</dd>
+</dl>
+<h3 class="enumeration"><a name="http_status_e">http_status_e</a></h3>
+<p class="description">HTTP status codes</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>HTTP_ACCEPTED </dt>
+<dd class="description">DELETE command was successful</dd>
+<dt>HTTP_BAD_GATEWAY </dt>
+<dd class="description">Bad gateway</dd>
+<dt>HTTP_BAD_REQUEST </dt>
+<dd class="description">Bad request</dd>
+<dt>HTTP_CONFLICT </dt>
+<dd class="description">Request is self-conflicting</dd>
+<dt>HTTP_CONTINUE </dt>
+<dd class="description">Everything OK, keep going...</dd>
+<dt>HTTP_CREATED </dt>
+<dd class="description">PUT command was successful</dd>
+<dt>HTTP_ERROR </dt>
+<dd class="description">An error response from httpXxxx()</dd>
+<dt>HTTP_EXPECTATION_FAILED </dt>
+<dd class="description">The expectation given in an Expect header field was not met</dd>
+<dt>HTTP_FORBIDDEN </dt>
+<dd class="description">Forbidden to access this URI</dd>
+<dt>HTTP_GATEWAY_TIMEOUT </dt>
+<dd class="description">Gateway connection timed out</dd>
+<dt>HTTP_GONE </dt>
+<dd class="description">Server has gone away</dd>
+<dt>HTTP_LENGTH_REQUIRED </dt>
+<dd class="description">A content length or encoding is required</dd>
+<dt>HTTP_METHOD_NOT_ALLOWED </dt>
+<dd class="description">Method is not allowed</dd>
+<dt>HTTP_MOVED_PERMANENTLY </dt>
+<dd class="description">Document has moved permanently</dd>
+<dt>HTTP_MOVED_TEMPORARILY </dt>
+<dd class="description">Document has moved temporarily</dd>
+<dt>HTTP_MULTIPLE_CHOICES </dt>
+<dd class="description">Multiple files match request</dd>
+<dt>HTTP_NOT_ACCEPTABLE </dt>
+<dd class="description">Not Acceptable</dd>
+<dt>HTTP_NOT_AUTHORITATIVE </dt>
+<dd class="description">Information isn't authoritative</dd>
+<dt>HTTP_NOT_FOUND </dt>
+<dd class="description">URI was not found</dd>
+<dt>HTTP_NOT_IMPLEMENTED </dt>
+<dd class="description">Feature not implemented</dd>
+<dt>HTTP_NOT_MODIFIED </dt>
+<dd class="description">File not modified</dd>
+<dt>HTTP_NOT_SUPPORTED </dt>
+<dd class="description">HTTP version not supported</dd>
+<dt>HTTP_NO_CONTENT </dt>
+<dd class="description">Successful command, no new data</dd>
+<dt>HTTP_OK </dt>
+<dd class="description">OPTIONS/GET/HEAD/POST/TRACE command was successful</dd>
+<dt>HTTP_PARTIAL_CONTENT </dt>
+<dd class="description">Only a partial file was recieved/sent</dd>
+<dt>HTTP_PAYMENT_REQUIRED </dt>
+<dd class="description">Payment required</dd>
+<dt>HTTP_PRECONDITION </dt>
+<dd class="description">Precondition failed</dd>
+<dt>HTTP_PROXY_AUTHENTICATION </dt>
+<dd class="description">Proxy Authentication is Required</dd>
+<dt>HTTP_REQUESTED_RANGE </dt>
+<dd class="description">The requested range is not satisfiable</dd>
+<dt>HTTP_REQUEST_TIMEOUT </dt>
+<dd class="description">Request timed out</dd>
+<dt>HTTP_REQUEST_TOO_LARGE </dt>
+<dd class="description">Request entity too large</dd>
+<dt>HTTP_RESET_CONTENT </dt>
+<dd class="description">Content was reset/recreated</dd>
+<dt>HTTP_SEE_OTHER </dt>
+<dd class="description">See this other link...</dd>
+<dt>HTTP_SERVER_ERROR </dt>
+<dd class="description">Internal server error</dd>
+<dt>HTTP_SERVICE_UNAVAILABLE </dt>
+<dd class="description">Service is unavailable</dd>
+<dt>HTTP_SWITCHING_PROTOCOLS </dt>
+<dd class="description">HTTP upgrade to TLS/SSL</dd>
+<dt>HTTP_UNAUTHORIZED </dt>
+<dd class="description">Unauthorized to access host</dd>
+<dt>HTTP_UNSUPPORTED_MEDIATYPE </dt>
+<dd class="description">The requested media type is unsupported</dd>
+<dt>HTTP_UPGRADE_REQUIRED </dt>
+<dd class="description">Upgrade to SSL/TLS required</dd>
+<dt>HTTP_URI_TOO_LONG </dt>
+<dd class="description">URI too long</dd>
+<dt>HTTP_USE_PROXY </dt>
+<dd class="description">Must use a proxy to access this URI</dd>
+</dl>
+<h3 class="enumeration"><a name="http_uri_coding_e">http_uri_coding_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>HTTP_URI_CODING_ALL </dt>
+<dd class="description">En/decode everything</dd>
+<dt>HTTP_URI_CODING_HOSTNAME </dt>
+<dd class="description">En/decode the hostname portion</dd>
+<dt>HTTP_URI_CODING_MOST </dt>
+<dd class="description">En/decode all but the query</dd>
+<dt>HTTP_URI_CODING_NONE </dt>
+<dd class="description">Don't en/decode anything</dd>
+<dt>HTTP_URI_CODING_QUERY </dt>
+<dd class="description">En/decode the query portion</dd>
+<dt>HTTP_URI_CODING_RESOURCE </dt>
+<dd class="description">En/decode the resource portion</dd>
+<dt>HTTP_URI_CODING_USERNAME </dt>
+<dd class="description">En/decode the username portion</dd>
+</dl>
+<h3 class="enumeration"><a name="http_uri_status_e">http_uri_status_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>HTTP_URI_BAD_ARGUMENTS </dt>
+<dd class="description">Bad arguments to function (error)</dd>
+<dt>HTTP_URI_BAD_HOSTNAME </dt>
+<dd class="description">Bad hostname in URI (error)</dd>
+<dt>HTTP_URI_BAD_PORT </dt>
+<dd class="description">Bad port number in URI (error)</dd>
+<dt>HTTP_URI_BAD_RESOURCE </dt>
+<dd class="description">Bad resource in URI (error)</dd>
+<dt>HTTP_URI_BAD_SCHEME </dt>
+<dd class="description">Bad scheme in URI (error)</dd>
+<dt>HTTP_URI_BAD_URI </dt>
+<dd class="description">Bad/empty URI (error)</dd>
+<dt>HTTP_URI_BAD_USERNAME </dt>
+<dd class="description">Bad username in URI (error)</dd>
+<dt>HTTP_URI_MISSING_RESOURCE </dt>
+<dd class="description">Missing resource in URI (warning)</dd>
+<dt>HTTP_URI_MISSING_SCHEME </dt>
+<dd class="description">Missing scheme in URI (warning)</dd>
+<dt>HTTP_URI_OK </dt>
+<dd class="description">URI decoded OK</dd>
+<dt>HTTP_URI_OVERFLOW </dt>
+<dd class="description">URI buffer for httpAssembleURI is too small</dd>
+<dt>HTTP_URI_UNKNOWN_SCHEME </dt>
+<dd class="description">Unknown scheme in URI (warning)</dd>
+</dl>
+<h3 class="enumeration"><a name="http_version_e">http_version_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>HTTP_0_9 </dt>
+<dd class="description">HTTP/0.9</dd>
+<dt>HTTP_1_0 </dt>
+<dd class="description">HTTP/1.0</dd>
+<dt>HTTP_1_1 </dt>
+<dd class="description">HTTP/1.1</dd>
+</dl>
+<h3 class="enumeration"><a name="ipp_finish_e">ipp_finish_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>IPP_FINISHINGS_BALE </dt>
+<dd class="description">Bale (any type)</dd>
+<dt>IPP_FINISHINGS_BIND </dt>
+<dd class="description">Bind</dd>
+<dt>IPP_FINISHINGS_BIND_BOTTOM </dt>
+<dd class="description">Bind on bottom</dd>
+<dt>IPP_FINISHINGS_BIND_LEFT </dt>
+<dd class="description">Bind on left</dd>
+<dt>IPP_FINISHINGS_BIND_RIGHT </dt>
+<dd class="description">Bind on right</dd>
+<dt>IPP_FINISHINGS_BIND_TOP </dt>
+<dd class="description">Bind on top</dd>
+<dt>IPP_FINISHINGS_BOOKLET_MAKER </dt>
+<dd class="description">Fold to make booklet</dd>
+<dt>IPP_FINISHINGS_COVER </dt>
+<dd class="description">Add cover</dd>
+<dt>IPP_FINISHINGS_EDGE_STITCH </dt>
+<dd class="description">Stitch along any side</dd>
+<dt>IPP_FINISHINGS_EDGE_STITCH_BOTTOM </dt>
+<dd class="description">Stitch along bottom edge</dd>
+<dt>IPP_FINISHINGS_EDGE_STITCH_LEFT </dt>
+<dd class="description">Stitch along left side</dd>
+<dt>IPP_FINISHINGS_EDGE_STITCH_RIGHT </dt>
+<dd class="description">Stitch along right side</dd>
+<dt>IPP_FINISHINGS_EDGE_STITCH_TOP </dt>
+<dd class="description">Stitch along top edge</dd>
+<dt>IPP_FINISHINGS_FOLD </dt>
+<dd class="description">Fold (any type)</dd>
+<dt>IPP_FINISHINGS_JOB_OFFSET </dt>
+<dd class="description">Offset for binding (any type)</dd>
+<dt>IPP_FINISHINGS_NONE </dt>
+<dd class="description">No finishing</dd>
+<dt>IPP_FINISHINGS_PUNCH </dt>
+<dd class="description">Punch (any location/count)</dd>
+<dt>IPP_FINISHINGS_SADDLE_STITCH </dt>
+<dd class="description">Staple interior</dd>
+<dt>IPP_FINISHINGS_STAPLE </dt>
+<dd class="description">Staple (any location)</dd>
+<dt>IPP_FINISHINGS_STAPLE_BOTTOM_LEFT </dt>
+<dd class="description">Staple bottom left corner</dd>
+<dt>IPP_FINISHINGS_STAPLE_BOTTOM_RIGHT </dt>
+<dd class="description">Staple bottom right corner</dd>
+<dt>IPP_FINISHINGS_STAPLE_DUAL_BOTTOM </dt>
+<dd class="description">Two staples on bottom</dd>
+<dt>IPP_FINISHINGS_STAPLE_DUAL_LEFT </dt>
+<dd class="description">Two staples on left</dd>
+<dt>IPP_FINISHINGS_STAPLE_DUAL_RIGHT </dt>
+<dd class="description">Two staples on right</dd>
+<dt>IPP_FINISHINGS_STAPLE_DUAL_TOP </dt>
+<dd class="description">Two staples on top</dd>
+<dt>IPP_FINISHINGS_STAPLE_TOP_LEFT </dt>
+<dd class="description">Staple top left corner</dd>
+<dt>IPP_FINISHINGS_STAPLE_TOP_RIGHT </dt>
+<dd class="description">Staple top right corner</dd>
+<dt>IPP_FINISHINGS_TRIM </dt>
+<dd class="description">Trim (any type)</dd>
+</dl>
+<h3 class="enumeration"><a name="ipp_jstate_e">ipp_jstate_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>IPP_JOB_ABORTED </dt>
+<dd class="description">Job has aborted due to error</dd>
+<dt>IPP_JOB_CANCELED </dt>
+<dd class="description">Job has been canceled</dd>
+<dt>IPP_JOB_COMPLETED </dt>
+<dd class="description">Job has completed successfully</dd>
+<dt>IPP_JOB_HELD </dt>
+<dd class="description">Job is held for printing</dd>
+<dt>IPP_JOB_PENDING </dt>
+<dd class="description">Job is waiting to be printed</dd>
+<dt>IPP_JOB_PROCESSING </dt>
+<dd class="description">Job is currently printing</dd>
+<dt>IPP_JOB_STOPPED </dt>
+<dd class="description">Job has been stopped</dd>
+</dl>
+<h3 class="enumeration"><a name="ipp_op_e">ipp_op_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_ACCEPT_JOBS </dt>
+<dd class="description">Accept new jobs on a printer</dd>
+<dt>CUPS_ADD_MODIFY_CLASS </dt>
+<dd class="description">Add or modify a class</dd>
+<dt>CUPS_ADD_MODIFY_PRINTER </dt>
+<dd class="description">Add or modify a printer</dd>
+<dt>CUPS_AUTHENTICATE_JOB <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Authenticate a job </dd>
+<dt>CUPS_DELETE_CLASS </dt>
+<dd class="description">Delete a class</dd>
+<dt>CUPS_DELETE_PRINTER </dt>
+<dd class="description">Delete a printer</dd>
+<dt>CUPS_GET_CLASSES <span class="info">&nbsp;DEPRECATED&nbsp;</span></dt>
+<dd class="description">Get a list of classes </dd>
+<dt>CUPS_GET_DEFAULT </dt>
+<dd class="description">Get the default printer</dd>
+<dt>CUPS_GET_DEVICES </dt>
+<dd class="description">Get a list of supported devices</dd>
+<dt>CUPS_GET_DOCUMENT <span class="info">&nbsp;CUPS 1.4&nbsp;</span></dt>
+<dd class="description">Get a document file </dd>
+<dt>CUPS_GET_PPD <span class="info">&nbsp;CUPS 1.3&nbsp;</span></dt>
+<dd class="description">Get a PPD file </dd>
+<dt>CUPS_GET_PPDS </dt>
+<dd class="description">Get a list of supported drivers</dd>
+<dt>CUPS_GET_PRINTERS </dt>
+<dd class="description">Get a list of printers and/or classes</dd>
+<dt>CUPS_MOVE_JOB </dt>
+<dd class="description">Move a job to a different printer</dd>
+<dt>CUPS_REJECT_JOBS </dt>
+<dd class="description">Reject new jobs on a printer</dd>
+<dt>CUPS_SET_DEFAULT </dt>
+<dd class="description">Set the default printer</dd>
+<dt>IPP_CANCEL_JOB </dt>
+<dd class="description">Cancel a job</dd>
+<dt>IPP_CANCEL_SUBSCRIPTION <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Cancel a subscription </dd>
+<dt>IPP_CREATE_JOB </dt>
+<dd class="description">Create an empty print job</dd>
+<dt>IPP_CREATE_JOB_SUBSCRIPTION <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Create a job subscription </dd>
+<dt>IPP_CREATE_PRINTER_SUBSCRIPTION <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Create a printer subscription </dd>
+<dt>IPP_DISABLE_PRINTER </dt>
+<dd class="description">Stop a printer</dd>
+<dt>IPP_ENABLE_PRINTER </dt>
+<dd class="description">Start a printer</dd>
+<dt>IPP_GET_JOBS </dt>
+<dd class="description">Get a list of jobs</dd>
+<dt>IPP_GET_JOB_ATTRIBUTES </dt>
+<dd class="description">Get job attributes</dd>
+<dt>IPP_GET_NOTIFICATIONS <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Get notification events </dd>
+<dt>IPP_GET_PRINTER_ATTRIBUTES </dt>
+<dd class="description">Get printer attributes</dd>
+<dt>IPP_GET_PRINTER_SUPPORTED_VALUES </dt>
+<dd class="description">Get supported attribute values</dd>
+<dt>IPP_GET_SUBSCRIPTIONS <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Get list of subscriptions </dd>
+<dt>IPP_GET_SUBSCRIPTION_ATTRIBUTES <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Get subscription attributes </dd>
+<dt>IPP_HOLD_JOB </dt>
+<dd class="description">Hold a job for printing</dd>
+<dt>IPP_PAUSE_PRINTER </dt>
+<dd class="description">Stop a printer</dd>
+<dt>IPP_PRINT_JOB </dt>
+<dd class="description">Print a single file</dd>
+<dt>IPP_PURGE_JOBS </dt>
+<dd class="description">Cancel all jobs</dd>
+<dt>IPP_RELEASE_JOB </dt>
+<dd class="description">Release a job for printing</dd>
+<dt>IPP_RENEW_SUBSCRIPTION <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Renew a printer subscription </dd>
+<dt>IPP_RESTART_JOB </dt>
+<dd class="description">Reprint a job</dd>
+<dt>IPP_RESUME_PRINTER </dt>
+<dd class="description">Start a printer</dd>
+<dt>IPP_SEND_DOCUMENT </dt>
+<dd class="description">Add a file to a job</dd>
+<dt>IPP_SET_JOB_ATTRIBUTES </dt>
+<dd class="description">Set job attributes</dd>
+<dt>IPP_VALIDATE_JOB </dt>
+<dd class="description">Validate job options</dd>
+</dl>
+<h3 class="enumeration"><a name="ipp_orient_e">ipp_orient_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>IPP_LANDSCAPE </dt>
+<dd class="description">90 degrees counter-clockwise</dd>
+<dt>IPP_PORTRAIT </dt>
+<dd class="description">No rotation</dd>
+<dt>IPP_REVERSE_LANDSCAPE </dt>
+<dd class="description">90 degrees clockwise</dd>
+<dt>IPP_REVERSE_PORTRAIT </dt>
+<dd class="description">180 degrees</dd>
+</dl>
+<h3 class="enumeration"><a name="ipp_pstate_e">ipp_pstate_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>IPP_PRINTER_IDLE </dt>
+<dd class="description">Printer is idle</dd>
+<dt>IPP_PRINTER_PROCESSING </dt>
+<dd class="description">Printer is working</dd>
+<dt>IPP_PRINTER_STOPPED </dt>
+<dd class="description">Printer is stopped</dd>
+</dl>
+<h3 class="enumeration"><a name="ipp_quality_e">ipp_quality_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>IPP_QUALITY_DRAFT </dt>
+<dd class="description">Draft quality</dd>
+<dt>IPP_QUALITY_HIGH </dt>
+<dd class="description">High quality</dd>
+<dt>IPP_QUALITY_NORMAL </dt>
+<dd class="description">Normal quality</dd>
+</dl>
+<h3 class="enumeration"><a name="ipp_res_e">ipp_res_e</a></h3>
+<p class="description">Types and structures...</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>IPP_RES_PER_CM </dt>
+<dd class="description">Pixels per centimeter</dd>
+<dt>IPP_RES_PER_INCH </dt>
+<dd class="description">Pixels per inch</dd>
+</dl>
+<h3 class="enumeration"><a name="ipp_state_e">ipp_state_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>IPP_ATTRIBUTE </dt>
+<dd class="description">One or more attributes need to be sent/received</dd>
+<dt>IPP_DATA </dt>
+<dd class="description">IPP request data needs to be sent/received</dd>
+<dt>IPP_ERROR </dt>
+<dd class="description">An error occurred</dd>
+<dt>IPP_HEADER </dt>
+<dd class="description">The request header needs to be sent/received</dd>
+<dt>IPP_IDLE </dt>
+<dd class="description">Nothing is happening/request completed</dd>
+</dl>
+<h3 class="enumeration"><a name="ipp_status_e">ipp_status_e</a></h3>
+<p class="description">IPP status codes...</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_SEE_OTHER </dt>
+<dd class="description">cups-see-other</dd>
+<dt>IPP_ATTRIBUTES </dt>
+<dd class="description">client-error-attributes-or-values-not-supported</dd>
+<dt>IPP_ATTRIBUTES_NOT_SETTABLE </dt>
+<dd class="description">client-error-attributes-not-settable</dd>
+<dt>IPP_BAD_REQUEST </dt>
+<dd class="description">client-error-bad-request</dd>
+<dt>IPP_CHARSET </dt>
+<dd class="description">client-error-charset-not-supported</dd>
+<dt>IPP_COMPRESSION_ERROR </dt>
+<dd class="description">client-error-compression-error</dd>
+<dt>IPP_COMPRESSION_NOT_SUPPORTED </dt>
+<dd class="description">client-error-compression-not-supported</dd>
+<dt>IPP_CONFLICT </dt>
+<dd class="description">client-error-conflicting-attributes</dd>
+<dt>IPP_DEVICE_ERROR </dt>
+<dd class="description">server-error-device-error</dd>
+<dt>IPP_DOCUMENT_ACCESS_ERROR </dt>
+<dd class="description">client-error-document-access-error</dd>
+<dt>IPP_DOCUMENT_FORMAT </dt>
+<dd class="description">client-error-document-format-not-supported</dd>
+<dt>IPP_DOCUMENT_FORMAT_ERROR </dt>
+<dd class="description">client-error-document-format-error</dd>
+<dt>IPP_ERROR_JOB_CANCELED </dt>
+<dd class="description">server-error-job-canceled</dd>
+<dt>IPP_FORBIDDEN </dt>
+<dd class="description">client-error-forbidden</dd>
+<dt>IPP_GONE </dt>
+<dd class="description">client-error-gone</dd>
+<dt>IPP_IGNORED_ALL_NOTIFICATIONS </dt>
+<dd class="description">client-error-ignored-all-notifications</dd>
+<dt>IPP_IGNORED_ALL_SUBSCRIPTIONS </dt>
+<dd class="description">client-error-ignored-all-subscriptions</dd>
+<dt>IPP_INTERNAL_ERROR </dt>
+<dd class="description">server-error-internal-error</dd>
+<dt>IPP_MULTIPLE_JOBS_NOT_SUPPORTED </dt>
+<dd class="description">server-error-multiple-document-jobs-not-supported</dd>
+<dt>IPP_NOT_ACCEPTING </dt>
+<dd class="description">server-error-not-accepting-jobs</dd>
+<dt>IPP_NOT_AUTHENTICATED </dt>
+<dd class="description">client-error-not-authenticated</dd>
+<dt>IPP_NOT_AUTHORIZED </dt>
+<dd class="description">client-error-not-authorized</dd>
+<dt>IPP_NOT_FOUND </dt>
+<dd class="description">client-error-not-found</dd>
+<dt>IPP_NOT_POSSIBLE </dt>
+<dd class="description">client-error-not-possible</dd>
+<dt>IPP_OK </dt>
+<dd class="description">successful-ok</dd>
+<dt>IPP_OK_BUT_CANCEL_SUBSCRIPTION </dt>
+<dd class="description">successful-ok-but-cancel-subscription</dd>
+<dt>IPP_OK_CONFLICT </dt>
+<dd class="description">successful-ok-conflicting-attributes</dd>
+<dt>IPP_OK_EVENTS_COMPLETE </dt>
+<dd class="description">successful-ok-events-complete</dd>
+<dt>IPP_OK_IGNORED_NOTIFICATIONS </dt>
+<dd class="description">successful-ok-ignored-notifications</dd>
+<dt>IPP_OK_IGNORED_SUBSCRIPTIONS </dt>
+<dd class="description">successful-ok-ignored-subscriptions</dd>
+<dt>IPP_OK_SUBST </dt>
+<dd class="description">successful-ok-ignored-or-substituted-attributes</dd>
+<dt>IPP_OK_TOO_MANY_EVENTS </dt>
+<dd class="description">successful-ok-too-many-events</dd>
+<dt>IPP_OPERATION_NOT_SUPPORTED </dt>
+<dd class="description">server-error-operation-not-supported</dd>
+<dt>IPP_PRINTER_BUSY </dt>
+<dd class="description">server-error-busy</dd>
+<dt>IPP_PRINTER_IS_DEACTIVATED </dt>
+<dd class="description">server-error-printer-is-deactivated</dd>
+<dt>IPP_PRINT_SUPPORT_FILE_NOT_FOUND </dt>
+<dd class="description">client-error-print-support-file-not-found</dd>
+<dt>IPP_REQUEST_ENTITY </dt>
+<dd class="description">client-error-request-entity-too-large</dd>
+<dt>IPP_REQUEST_VALUE </dt>
+<dd class="description">client-error-request-value-too-long</dd>
+<dt>IPP_SERVICE_UNAVAILABLE </dt>
+<dd class="description">server-error-service-unavailable</dd>
+<dt>IPP_TEMPORARY_ERROR </dt>
+<dd class="description">server-error-temporary-error</dd>
+<dt>IPP_TIMEOUT </dt>
+<dd class="description">client-error-timeout</dd>
+<dt>IPP_TOO_MANY_SUBSCRIPTIONS </dt>
+<dd class="description">client-error-too-many-subscriptions</dd>
+<dt>IPP_URI_SCHEME </dt>
+<dd class="description">client-error-uri-scheme-not-supported</dd>
+<dt>IPP_VERSION_NOT_SUPPORTED </dt>
+<dd class="description">server-error-version-not-supported</dd>
+</dl>
+<h3 class="enumeration"><a name="ipp_tag_e">ipp_tag_e</a></h3>
+<p class="description">Format tags for attributes...</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>IPP_TAG_ADMINDEFINE </dt>
+<dd class="description">Admin-defined value</dd>
+<dt>IPP_TAG_BEGIN_COLLECTION </dt>
+<dd class="description">Beginning of collection value</dd>
+<dt>IPP_TAG_BOOLEAN </dt>
+<dd class="description">Boolean value</dd>
+<dt>IPP_TAG_CHARSET </dt>
+<dd class="description">Character set value</dd>
+<dt>IPP_TAG_COPY </dt>
+<dd class="description">Bitflag for copied attribute values</dd>
+<dt>IPP_TAG_DATE </dt>
+<dd class="description">Date/time value</dd>
+<dt>IPP_TAG_DEFAULT </dt>
+<dd class="description">Default value</dd>
+<dt>IPP_TAG_DELETEATTR </dt>
+<dd class="description">Delete-attribute value</dd>
+<dt>IPP_TAG_END </dt>
+<dd class="description">End-of-attributes</dd>
+<dt>IPP_TAG_END_COLLECTION </dt>
+<dd class="description">End of collection value</dd>
+<dt>IPP_TAG_ENUM </dt>
+<dd class="description">Enumeration value</dd>
+<dt>IPP_TAG_EVENT_NOTIFICATION </dt>
+<dd class="description">Event group</dd>
+<dt>IPP_TAG_INTEGER </dt>
+<dd class="description">Integer value</dd>
+<dt>IPP_TAG_JOB </dt>
+<dd class="description">Job group</dd>
+<dt>IPP_TAG_KEYWORD </dt>
+<dd class="description">Keyword value</dd>
+<dt>IPP_TAG_LANGUAGE </dt>
+<dd class="description">Language value</dd>
+<dt>IPP_TAG_MASK </dt>
+<dd class="description">Mask for copied attribute values</dd>
+<dt>IPP_TAG_MEMBERNAME </dt>
+<dd class="description">Collection member name value</dd>
+<dt>IPP_TAG_MIMETYPE </dt>
+<dd class="description">MIME media type value</dd>
+<dt>IPP_TAG_NAME </dt>
+<dd class="description">Name value</dd>
+<dt>IPP_TAG_NAMELANG </dt>
+<dd class="description">Name-with-language value</dd>
+<dt>IPP_TAG_NOTSETTABLE </dt>
+<dd class="description">Not-settable value</dd>
+<dt>IPP_TAG_NOVALUE </dt>
+<dd class="description">No-value value</dd>
+<dt>IPP_TAG_OPERATION </dt>
+<dd class="description">Operation group</dd>
+<dt>IPP_TAG_PRINTER </dt>
+<dd class="description">Printer group</dd>
+<dt>IPP_TAG_RANGE </dt>
+<dd class="description">Range value</dd>
+<dt>IPP_TAG_RESOLUTION </dt>
+<dd class="description">Resolution value</dd>
+<dt>IPP_TAG_STRING </dt>
+<dd class="description">Octet string value</dd>
+<dt>IPP_TAG_SUBSCRIPTION </dt>
+<dd class="description">Subscription group</dd>
+<dt>IPP_TAG_TEXT </dt>
+<dd class="description">Text value</dd>
+<dt>IPP_TAG_TEXTLANG </dt>
+<dd class="description">Text-with-language value</dd>
+<dt>IPP_TAG_UNKNOWN </dt>
+<dd class="description">Unknown value</dd>
+<dt>IPP_TAG_UNSUPPORTED_GROUP </dt>
+<dd class="description">Unsupported attributes group</dd>
+<dt>IPP_TAG_UNSUPPORTED_VALUE </dt>
+<dd class="description">Unsupported value</dd>
+<dt>IPP_TAG_URI </dt>
+<dd class="description">URI value</dd>
+<dt>IPP_TAG_URISCHEME </dt>
+<dd class="description">URI scheme value</dd>
+<dt>IPP_TAG_ZERO </dt>
+<dd class="description">Zero tag - used for separators</dd>
+</dl>
+</div>
 </body>
 </html>
diff --git a/doc/help/api-overview.html b/doc/help/api-overview.html
new file mode 100644 (file)
index 0000000..151f3c9
--- /dev/null
@@ -0,0 +1,408 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html>
+<!-- SECTION: Programming -->
+<head>
+<title>Introduction to CUPS Programming</title>
+<meta name="keywords" content="Programming">
+<meta name="creator" content="Mini-XML v2.5">
+<style type="text/css"><!--
+BODY {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+H1, H2, H3, H4, H5, H6, P, TD, TH {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+KBD {
+  font-family: monaco, courier, monospace;
+  font-weight: bold;
+}
+
+PRE {
+  font-family: monaco, courier, monospace;
+}
+
+PRE.command {
+  margin-left: 36pt;
+}
+
+PRE.example {
+  background: #eeeeee;
+  border: dotted thin #999999;
+  margin-left: 36pt;
+  padding: 10px;
+}
+
+PRE.command EM, PRE.example EM {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+P.command {
+  font-family: monaco, courier, monospace;
+  margin-left: 36pt;
+}
+
+P.formula {
+  font-style: italic;
+  margin-left: 36pt;
+}
+
+BLOCKQUOTE {
+  background: #cccccc;
+  border: solid thin #999999;
+  padding: 10pt;
+}
+
+A:link, A:visited {
+  text-decoration: none;
+  font-weight: bold;
+}
+
+A:link:hover, A:visited:hover, A:active {
+  text-decoration: underline;
+  font-weight: bold;
+}
+
+SUB, SUP {
+  font-size: 50%;
+}
+
+DIV.table TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.table CAPTION {
+  caption-side: top;
+  font-size: 120%;
+  font-style: italic;
+  font-weight: bold;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.table TABLE TD {
+  border: solid thin #cccccc;
+  padding-top: 5pt;
+}
+
+DIV.table TABLE TH {
+  background: #cccccc;
+  border: none;
+  border-bottom: solid thin #999999;
+}
+
+DIV.figure TABLE {
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.figure CAPTION {
+  caption-side: bottom;
+  font-size: 120%;
+  font-style: italic;
+  font-weight: bold;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+TH.label {
+  padding-top: 5pt;
+  text-align: right;
+  vertical-align: top;
+}
+
+HR {
+  border: solid thin;
+}
+
+SPAN.info {
+  background: #000000;
+  border: thin solid #000000;
+  color: #ffffff;
+  font-size: 80%;
+  font-style: italic;
+  font-weight: bold;
+  white-space: nowrap;
+}
+
+H2 SPAN.info, H3 SPAN.info, H4 SPAN.info {
+  float: right;
+  font-size: 100%;
+}
+
+H2.title, H3.title {
+  border-bottom: solid 2pt #000000;
+}
+
+DT {
+  margin-left: 36pt;
+  margin-top: 12pt;
+}
+
+DD {
+  margin-left: 54pt;
+}
+
+DL.category DT {
+  font-weight: bold;
+}
+
+P.summary {
+  margin-left: 36pt;
+  font-family: monaco, courier, monospace;
+}
+
+SPAN.message {
+  font-style: italic;
+  font-size: smaller;
+}
+
+DIV.summary TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin: 10px;
+}
+
+DIV.summary TABLE TD, DIV.summary TABLE TH {
+  border: solid thin #999999;
+  padding: 5px;
+  text-align: left;
+  vertical-align: top;
+}
+
+DIV.summary TABLE THEAD TH {
+  background: #eeeeee;
+}
+
+/* API documentation styles... */
+div.body h1 {
+  margin: 0;
+}
+div.body h2 {
+  margin-top: 1.5em;
+}
+div.body h3, div.body h4, div.body h5 {
+  margin-bottom: 0.5em;
+  margin-top: 1.5em;
+}
+.class, .enumeration, .function, .struct, .typedef, .union {
+  border-bottom: solid thin #999999;
+  margin-bottom: 0;
+  margin-top: 2em;
+}
+.description {
+  margin-top: 0.5em;
+}
+code, p.code, pre, ul.code li {
+  font-family: monaco, courier, monospace;
+  font-size: 90%;
+}
+ul.code, ul.contents, ul.subcontents {
+  list-style-type: none;
+  margin: 0;
+  padding-left: 0;
+}
+ul.code li {
+  margin: 0;
+}
+ul.contents > li {
+  margin-top: 1em;
+}
+ul.contents li ul.code, ul.contents li ul.subcontents {
+  padding-left: 2em;
+}
+div.body dl {
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dt {
+  font-style: italic;
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dd {
+  margin-bottom: 0.5em;
+}
+
+/* This is just for the HTML files generated with the framedhelp target */
+div.contents {
+  background: #e8e8e8;
+  border: solid thin black;
+  padding: 10px;
+}
+div.contents h1 {
+  font-size: 110%;
+}
+div.contents h2 {
+  font-size: 100%;
+}
+div.contents ul.contents {
+  font-size: 80%;
+}
+--></style>
+</head>
+<body>
+<div class='body'>
+<!--
+  "$Id: api-cups.header 7279 2008-01-31 01:50:44Z mike $"
+
+  Introduction to CUPS programming header for the Common UNIX Printing System
+  (CUPS).
+
+  Copyright 2008 by Apple Inc.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">Introduction to CUPS Programming</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+       <th>Headers</th>
+       <th>cups/cups.h<br>
+       cups/array.h<br>
+       cups/backend.h<br>
+       cups/dir.h<br>
+       cups/file.h<br>
+       cups/ppd.h<br>
+       cups/raster.h<br>
+       cups/sidechannel.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <th>Libraries</th>
+       <td>-lcups<br>
+       -lcupsimage</td>
+</tr>
+<tr>
+       <th>See Also</th>
+       <td>Programming: <a href='api-cups.html' target='_top'>CUPS API</a><br>
+       Programming: <a href='api-array.html' target='_top'>Array API</a><br>
+       Programming: <a href='api-filedir.html' target='_top'>File and Directory APIs</a><br>
+       Programming: <a href='api-filter.html' target='_top'>Filter and Backend Programming</a><br>
+       Programming: <a href='api-httpipp.html' target='_top'>HTTP and IPP APIs</a><br>
+       Programming: <a href='api-ppd.html' target='_top'>PPD API</a><br>
+       Programming: <a href='api-raster.html' target='_top'>Raster API</a></td>
+</tr>
+</tbody>
+</table></div>
+<h2 class="title">Contents</h2>
+<ul class="contents">
+</li>
+<li><a href="#OVERVIEW">Overview</a></li>
+<li><a href="#COMPILING">Compiling Programs</a><ul class="subcontents">
+<li><a href="#XCODE">Compiling with Xcode</a></li>
+<li><a href="#COMMANDLINE">Compiling with GCC</a></li>
+</ul class="subcontents"></li>
+<li><a href="#WHERETOGO">Where to Go Next</a></li>
+</ul>
+<!--
+  "$Id: api-cups.header 7279 2008-01-31 01:50:44Z mike $"
+
+  Introduction to CUPS programming content for the Common UNIX Printing System
+  (CUPS).
+
+  Copyright 2008 by Apple Inc.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h2 class="title"><a name="OVERVIEW">Overview</a></h2>
+
+<p>CUPS provides two libraries that interface with the different parts of the
+printing system. The "cups" library provides all of the common application and
+filter functions while the "cupsimage" library provides all of the imaging
+functions used in raster printer drivers. The "cups" library functions are
+accessed by including the <var>&lt;cups/cups.h&gt;</var> header, while
+"cupsimage" functions are found in the <var>&lt;cups/raster.h&gt;</var>
+header.</p>
+
+<h2 class="title"><a name="COMPILING">Compiling Programs</a></h2>
+
+<p>The CUPS libraries can be used from any C, C++, or Objective C program.
+The method of compiling against the libraries varies depending on the
+operating system and installation of CUPS. The following sections show how
+to compile a simple program (shown below) in two common environments.</p>
+
+<p>The following simple program lists the available printers on the system:</p>
+
+<pre class="example">
+#include &lt;stdio.h&gt;
+#include &lt;cups/cups.h&gt;
+
+int main(void)
+{
+  int i;
+  cups_dest_t *dests, *dest;
+  int num_dests = cupsGetDests(&amp;dests);
+
+  for (i = num_dests, dest = dests; i &gt; 0; i --, dest ++)
+  {
+    if (dest->instance)
+      printf("%s/%s\n", dest->name, dest->instance);
+    else
+      puts(dest->name);
+  }
+
+  return (0);
+}
+</pre>
+
+<h3><a name="XCODE">Compiling with Xcode</a></h3>
+
+<p>In Xcode, choose <var>New Project...</var> from the <var>File</var> menu,
+then select the <var>Standard Tool</var> project type under <var>Command Line
+Utility</var>. Click <var>Next</var> and choose a project directory. Click
+<var>Next</var> to create the project.</p>
+
+<p>In the project window, double-click on the <var>Targets</var> group and
+control-click on the simple target to show the context menu. Choose
+<var>Existing Framework...</var> from the <var>Add</var> submenu. When the file
+chooser sheet appears, press the <kbd>/</kbd> key and enter "/usr/lib". Scroll
+down the file list and select the <var>libcups.dylib</var> file. Click the
+<var>Add</var> button in the file chooser and attributes sheets.</p>
+
+<p>In the project window, double-click on the <var>main.c</var> source file.
+Replace the template source code with the listing above and save it. Click the
+<var>Build and Go</var> button to build the sample program and run it.</p>
+
+<h3><a name="COMMANDLINE">Compiling with GCC</a></h3>
+
+<p>From the command-line, create a file called <var>sample.c</var> using your
+favorite editor and then run the following command to compile it with GCC and
+run it:</p>
+
+<pre class="command">
+gcc -o simple `cups-config --cflags` simple.c `cups-config --libs`
+./simple
+</pre>
+
+<p>The <code>cups-config</code> command provides the compiler flags
+("cups-config --cflags") and libraries ("cups-config --libs") needed for the
+local system.</p>
+
+<h2 class="title"><a name="WHERETOGO">Where to Go Next</a></h2>
+
+<p>If you are developing a print filter, driver, or backend, see the
+<a href="api-filter.html" target="_top">Filter and Backend Programming</a>
+guide. Raster printer driver developers should also read the
+<a href="api-raster.html" target="_top">Raster API</a> reference.</p>
+</div>
+</body>
+</html>
index 2fe00be672e2ef176e6730dc235e93cfaa1af520..d8aa110a73c579ccc23eb7f5871b257e789b8eb6 100644 (file)
 <html>
 <!-- SECTION: Programming -->
 <head>
-       <title>PPD API</title>
-       <meta name='keywords' content='Programming'>
-       <meta name='creator' content='Mini-XML v2.4'>
-       <style type='text/css'><!--
-       h1, h2, h3, p { font-family: sans-serif; text-align: justify; }
-       tt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }
-       pre { font-weight: bold; color: #7f0000; margin-left: 2em; }
-       span.info { background: #000000; border: solid thin #000000; color: #ffffff; font-size: 80%; font-style: italic; font-weight: bold; white-space: nowrap; }
-       h3 span.info { float: right; font-size: 100%; }
-       h1.title, h2.title, h3.title { border-bottom: solid 2px #000000; }
-       --></style>
+<title>PPD API</title>
+<meta name="keywords" content="Programming">
+<meta name="creator" content="Mini-XML v2.5">
+<style type="text/css"><!--
+BODY {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+H1, H2, H3, H4, H5, H6, P, TD, TH {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+KBD {
+  font-family: monaco, courier, monospace;
+  font-weight: bold;
+}
+
+PRE {
+  font-family: monaco, courier, monospace;
+}
+
+PRE.command {
+  margin-left: 36pt;
+}
+
+PRE.example {
+  background: #eeeeee;
+  border: dotted thin #999999;
+  margin-left: 36pt;
+  padding: 10px;
+}
+
+PRE.command EM, PRE.example EM {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+P.command {
+  font-family: monaco, courier, monospace;
+  margin-left: 36pt;
+}
+
+P.formula {
+  font-style: italic;
+  margin-left: 36pt;
+}
+
+BLOCKQUOTE {
+  background: #cccccc;
+  border: solid thin #999999;
+  padding: 10pt;
+}
+
+A:link, A:visited {
+  text-decoration: none;
+  font-weight: bold;
+}
+
+A:link:hover, A:visited:hover, A:active {
+  text-decoration: underline;
+  font-weight: bold;
+}
+
+SUB, SUP {
+  font-size: 50%;
+}
+
+DIV.table TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.table CAPTION {
+  caption-side: top;
+  font-size: 120%;
+  font-style: italic;
+  font-weight: bold;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.table TABLE TD {
+  border: solid thin #cccccc;
+  padding-top: 5pt;
+}
+
+DIV.table TABLE TH {
+  background: #cccccc;
+  border: none;
+  border-bottom: solid thin #999999;
+}
+
+DIV.figure TABLE {
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.figure CAPTION {
+  caption-side: bottom;
+  font-size: 120%;
+  font-style: italic;
+  font-weight: bold;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+TH.label {
+  padding-top: 5pt;
+  text-align: right;
+  vertical-align: top;
+}
+
+HR {
+  border: solid thin;
+}
+
+SPAN.info {
+  background: #000000;
+  border: thin solid #000000;
+  color: #ffffff;
+  font-size: 80%;
+  font-style: italic;
+  font-weight: bold;
+  white-space: nowrap;
+}
+
+H2 SPAN.info, H3 SPAN.info, H4 SPAN.info {
+  float: right;
+  font-size: 100%;
+}
+
+H2.title, H3.title {
+  border-bottom: solid 2pt #000000;
+}
+
+DT {
+  margin-left: 36pt;
+  margin-top: 12pt;
+}
+
+DD {
+  margin-left: 54pt;
+}
+
+DL.category DT {
+  font-weight: bold;
+}
+
+P.summary {
+  margin-left: 36pt;
+  font-family: monaco, courier, monospace;
+}
+
+SPAN.message {
+  font-style: italic;
+  font-size: smaller;
+}
+
+DIV.summary TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin: 10px;
+}
+
+DIV.summary TABLE TD, DIV.summary TABLE TH {
+  border: solid thin #999999;
+  padding: 5px;
+  text-align: left;
+  vertical-align: top;
+}
+
+DIV.summary TABLE THEAD TH {
+  background: #eeeeee;
+}
+
+/* API documentation styles... */
+div.body h1 {
+  margin: 0;
+}
+div.body h2 {
+  margin-top: 1.5em;
+}
+div.body h3, div.body h4, div.body h5 {
+  margin-bottom: 0.5em;
+  margin-top: 1.5em;
+}
+.class, .enumeration, .function, .struct, .typedef, .union {
+  border-bottom: solid thin #999999;
+  margin-bottom: 0;
+  margin-top: 2em;
+}
+.description {
+  margin-top: 0.5em;
+}
+code, p.code, pre, ul.code li {
+  font-family: monaco, courier, monospace;
+  font-size: 90%;
+}
+ul.code, ul.contents, ul.subcontents {
+  list-style-type: none;
+  margin: 0;
+  padding-left: 0;
+}
+ul.code li {
+  margin: 0;
+}
+ul.contents > li {
+  margin-top: 1em;
+}
+ul.contents li ul.code, ul.contents li ul.subcontents {
+  padding-left: 2em;
+}
+div.body dl {
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dt {
+  font-style: italic;
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dd {
+  margin-bottom: 0.5em;
+}
+
+/* This is just for the HTML files generated with the framedhelp target */
+div.contents {
+  background: #e8e8e8;
+  border: solid thin black;
+  padding: 10px;
+}
+div.contents h1 {
+  font-size: 110%;
+}
+div.contents h2 {
+  font-size: 100%;
+}
+div.contents ul.contents {
+  font-size: 80%;
+}
+--></style>
 </head>
 <body>
+<div class='body'>
 <!--
-  "$Id: api-ppd.shtml 6649 2007-07-11 21:46:42Z mike $"
+  "$Id: api-ppd.header 7278 2008-01-31 01:23:09Z mike $"
+
+  PPD API header for the Common UNIX Printing System (CUPS).
+
+  Copyright 2008 by Apple Inc.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">PPD API</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+       <th>Header</th>
+       <th>cups/ppd.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <th>Library</th>
+       <td>-lcups</td>
+</tr>
+<tr>
+       <th>See Also</th>
+       <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
+       Programming: <a href='api-cups.html' target='_top'>CUPS API</a><br>
+       Reference: <a href='spec-ppd.html' target='_top'>CUPS PPD Specification</a></td>
+</tr>
+</tbody>
+</table></div>
+<h2 class="title">Contents</h2>
+<ul class="contents">
+</li>
+<li><a href="#OVERVIEW">Overview</a><ul class="subcontents">
+<li><a href="#LOADING">Loading a PPD File</a></li>
+<li><a href="#OPTIONS_AND_GROUPS">Options and Groups</a></li>
+<li><a href="#CONSTRAINTS">Constraints</a></li>
+<li><a href="#PAGE_SIZES">Page Sizes</a></li>
+<li><a href="#ATTRIBUTES">Attributes</a></li>
+</ul></li>
+<li><a href="#FUNCTIONS">Functions</a><ul class="code">
+<li><a href="#cupsMarkOptions" title="Mark command-line options in a PPD file.">cupsMarkOptions</a></li>
+<li><a href="#ppdClose" title="Free all memory used by the PPD file.">ppdClose</a></li>
+<li><a href="#ppdCollect" title="Collect all marked options that reside in the specified
+section.">ppdCollect</a></li>
+<li><a href="#ppdCollect2" title="Collect all marked options that reside in the
+specified section and minimum order.">ppdCollect2</a></li>
+<li><a href="#ppdConflicts" title="Check to see if there are any conflicts among the
+marked option choices.">ppdConflicts</a></li>
+<li><a href="#ppdEmit" title="Emit code for marked options to a file.">ppdEmit</a></li>
+<li><a href="#ppdEmitAfterOrder" title="Emit a subset of the code for marked options to a file.">ppdEmitAfterOrder</a></li>
+<li><a href="#ppdEmitFd" title="Emit code for marked options to a file.">ppdEmitFd</a></li>
+<li><a href="#ppdEmitJCL" title="Emit code for JCL options to a file.">ppdEmitJCL</a></li>
+<li><a href="#ppdEmitJCLEnd" title="Emit JCLEnd code to a file.">ppdEmitJCLEnd</a></li>
+<li><a href="#ppdEmitString" title="Get a string containing the code for marked options.">ppdEmitString</a></li>
+<li><a href="#ppdErrorString" title="Returns the text assocated with a status.">ppdErrorString</a></li>
+<li><a href="#ppdFindAttr" title="Find the first matching attribute.">ppdFindAttr</a></li>
+<li><a href="#ppdFindChoice" title="Return a pointer to an option choice.">ppdFindChoice</a></li>
+<li><a href="#ppdFindCustomOption" title="Find a custom option.">ppdFindCustomOption</a></li>
+<li><a href="#ppdFindCustomParam" title="Find a parameter for a custom option.">ppdFindCustomParam</a></li>
+<li><a href="#ppdFindMarkedChoice" title="Return the marked choice for the specified option.">ppdFindMarkedChoice</a></li>
+<li><a href="#ppdFindNextAttr" title="Find the next matching attribute.">ppdFindNextAttr</a></li>
+<li><a href="#ppdFindOption" title="Return a pointer to the specified option.">ppdFindOption</a></li>
+<li><a href="#ppdFirstCustomParam" title="Return the first parameter for a custom option.">ppdFirstCustomParam</a></li>
+<li><a href="#ppdFirstOption" title="Return the first option in the PPD file.">ppdFirstOption</a></li>
+<li><a href="#ppdIsMarked" title="Check to see if an option is marked.">ppdIsMarked</a></li>
+<li><a href="#ppdLastError" title="Return the status from the last ppdOpen*().">ppdLastError</a></li>
+<li><a href="#ppdLocalize" title="Localize the PPD file to the current locale.">ppdLocalize</a></li>
+<li><a href="#ppdLocalizeIPPReason" title="Get the localized version of a cupsIPPReason
+attribute.">ppdLocalizeIPPReason</a></li>
+<li><a href="#ppdLocalizeMarkerName" title="Get the localized version of a marker-names
+attribute value.">ppdLocalizeMarkerName</a></li>
+<li><a href="#ppdMarkDefaults" title="Mark all default options in the PPD file.">ppdMarkDefaults</a></li>
+<li><a href="#ppdMarkOption" title="Mark an option in a PPD file.">ppdMarkOption</a></li>
+<li><a href="#ppdNextCustomParam" title="Return the next parameter for a custom option.">ppdNextCustomParam</a></li>
+<li><a href="#ppdNextOption" title="Return the next option in the PPD file.">ppdNextOption</a></li>
+<li><a href="#ppdOpen" title="Read a PPD file into memory.">ppdOpen</a></li>
+<li><a href="#ppdOpen2" title="Read a PPD file into memory.">ppdOpen2</a></li>
+<li><a href="#ppdOpenFd" title="Read a PPD file into memory.">ppdOpenFd</a></li>
+<li><a href="#ppdOpenFile" title="Read a PPD file into memory.">ppdOpenFile</a></li>
+<li><a href="#ppdPageLength" title="Get the page length for the given size.">ppdPageLength</a></li>
+<li><a href="#ppdPageSize" title="Get the page size record for the given size.">ppdPageSize</a></li>
+<li><a href="#ppdPageWidth" title="Get the page width for the given size.">ppdPageWidth</a></li>
+<li><a href="#ppdSetConformance" title="Set the conformance level for PPD files.">ppdSetConformance</a></li>
+</ul>
+<li><a href="#TYPES">Data Types</a><ul class="code">
+       <li><a href="#ppd_attr_t" title="PPD Attribute Structure ">ppd_attr_t</a></li>
+       <li><a href="#ppd_choice_t" title="Option choices">ppd_choice_t</a></li>
+       <li><a href="#ppd_conform_t" title="Conformance Levels ">ppd_conform_t</a></li>
+       <li><a href="#ppd_const_t" title="Constraints">ppd_const_t</a></li>
+       <li><a href="#ppd_coption_t" title="Custom Option ">ppd_coption_t</a></li>
+       <li><a href="#ppd_cparam_t" title="Custom Parameter ">ppd_cparam_t</a></li>
+       <li><a href="#ppd_cplimit_t" title="Custom Parameter Limit ">ppd_cplimit_t</a></li>
+       <li><a href="#ppd_cptype_t" title="Custom Parameter Type ">ppd_cptype_t</a></li>
+       <li><a href="#ppd_cpvalue_t" title="Custom Parameter Value ">ppd_cpvalue_t</a></li>
+       <li><a href="#ppd_emul_t" title="Emulators">ppd_emul_t</a></li>
+       <li><a href="#ppd_file_t" title="PPD File">ppd_file_t</a></li>
+       <li><a href="#ppd_group_t" title="Groups">ppd_group_t</a></li>
+       <li><a href="#ppd_option_t" title="Options">ppd_option_t</a></li>
+       <li><a href="#ppd_profile_t" title="sRGB Color Profiles">ppd_profile_t</a></li>
+       <li><a href="#ppd_section_t" title="Order dependency sections">ppd_section_t</a></li>
+       <li><a href="#ppd_size_t" title="Page Sizes">ppd_size_t</a></li>
+       <li><a href="#ppd_ui_t" title="UI Types">ppd_ui_t</a></li>
+</ul></li>
+<li><a href="#STRUCTURES">Structures</a><ul class="code">
+       <li><a href="#ppd_attr_s" title="PPD Attribute Structure ">ppd_attr_s</a></li>
+       <li><a href="#ppd_choice_s" title="Option choices">ppd_choice_s</a></li>
+       <li><a href="#ppd_const_s" title="Constraints">ppd_const_s</a></li>
+       <li><a href="#ppd_coption_s" title="Custom Option ">ppd_coption_s</a></li>
+       <li><a href="#ppd_cparam_s" title="Custom Parameter ">ppd_cparam_s</a></li>
+       <li><a href="#ppd_emul_s" title="Emulators">ppd_emul_s</a></li>
+       <li><a href="#ppd_file_s" title="PPD File">ppd_file_s</a></li>
+       <li><a href="#ppd_group_s" title="Groups">ppd_group_s</a></li>
+       <li><a href="#ppd_option_s" title="Options">ppd_option_s</a></li>
+       <li><a href="#ppd_profile_s" title="sRGB Color Profiles">ppd_profile_s</a></li>
+       <li><a href="#ppd_size_s" title="Page Sizes">ppd_size_s</a></li>
+</ul></li>
+<li><a href="#UNIONS">Unions</a><ul class="code">
+       <li><a href="#ppd_cplimit_u" title="Custom Parameter Limit ">ppd_cplimit_u</a></li>
+       <li><a href="#ppd_cpvalue_u" title="Custom Parameter Value ">ppd_cpvalue_u</a></li>
+</ul></li>
+<li><a href="#ENUMERATIONS">Constants</a><ul class="code">
+       <li><a href="#ppd_conform_e" title="">ppd_conform_e</a></li>
+       <li><a href="#ppd_cptype_e" title="Custom Parameter Type ">ppd_cptype_e</a></li>
+       <li><a href="#ppd_cs_e" title="Colorspaces">ppd_cs_e</a></li>
+       <li><a href="#ppd_section_e" title="Order dependency sections">ppd_section_e</a></li>
+       <li><a href="#ppd_status_e" title="Types and structures...">ppd_status_e</a></li>
+       <li><a href="#ppd_ui_e" title="UI Types">ppd_ui_e</a></li>
+</ul></li>
+</ul>
+<!--
+  "$Id: api-ppd.shtml 7278 2008-01-31 01:23:09Z mike $"
 
   PPD API introduction for the Common UNIX Printing System (CUPS).
 
   file is missing or damaged, see the license at "http://www.cups.org/".
 -->
 
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
 
-<p>The CUPS PPD API provides read-only access the data in
-PostScript Printer Description ("PPD") files. With it you can
-display printer options to users, mark option choices and check
-for conflicting choices, and output marked choices in PostScript
-output.</p>
+<p>The CUPS PPD API provides read-only access the data in PostScript Printer
+Description ("PPD") files which are used for all printers with a driver. With
+it you can display printer options to users, mark option choices and check for
+conflicting choices, and output marked choices in PostScript output. The
+<a href="#ppd_file_t"><code>ppd_file_t</code></a> structure contains all of
+the information in a PPD file.</p>
 
-<h2 class='title'>General Usage</h2>
+<h3><a name="LOADING">Loading a PPD File</a></h3>
 
-<p>The <var>&lt;cups/ppd.h&gt;</var> header file must be included
-to use the <tt>ppd</tt> functions.</p>
+<p>The <a href="#ppdOpenFile"><code>ppdOpenFile</code></a> function "opens" a
+PPD file and loads it into memory. For example, the following code opens the
+current printer's PPD file in a CUPS filter:</p>
 
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
 
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
+<a href="#ppd_file_t">ppd_file_t</a> *ppd = <a href="#ppdOpenFile">ppdOpenFile</a>(getenv("PPD"));
 </pre>
 
-<h2 class='title'>Compatibility</h2>
-
-<p>Unless otherwise specified, the PPD API functions require CUPS
-1.1 or higher.</p>
-<h2 class='title'>Contents</h2>
-<ul>
-       <li><a href='#ENUMERATIONS'>Enumerations</a></li>
-       <li><a href='#FUNCTIONS'>Functions</a></li>
-       <li><a href='#STRUCTURES'>Structures</a></li>
-       <li><a href='#TYPES'>Types</a></li>
-       <li><a href='#UNIONS'>Unions</a></li>
-</ul>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='ENUMERATIONS'>Enumerations</a></h2>
-<ul>
-       <li><a href='#ppd_conform_e'><tt>ppd_conform_e</tt></a> </li>
-       <li><a href='#ppd_cptype_e'><tt>ppd_cptype_e</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppd_cs_e'><tt>ppd_cs_e</tt></a> </li>
-       <li><a href='#ppd_section_e'><tt>ppd_section_e</tt></a> </li>
-       <li><a href='#ppd_status_e'><tt>ppd_status_e</tt></a> </li>
-       <li><a href='#ppd_ui_e'><tt>ppd_ui_e</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_conform_e'>ppd_conform_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>PPD_CONFORM_RELAXED</tt> </td><td>Relax whitespace and control char
-</td></tr>
-<tr><td><tt>PPD_CONFORM_STRICT</tt> </td><td>Require strict conformance
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppd_cptype_e'>ppd_cptype_e</a></h3>
-<h4>Description</h4>
-<p>Custom Parameter Type 
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>PPD_CUSTOM_CURVE</tt> </td><td>Curve value for f(x) = x^value
-</td></tr>
-<tr><td><tt>PPD_CUSTOM_INT</tt> </td><td>Integer number value
-</td></tr>
-<tr><td><tt>PPD_CUSTOM_INVCURVE</tt> </td><td>Curve value for f(x) = x^(1/value)
-</td></tr>
-<tr><td><tt>PPD_CUSTOM_PASSCODE</tt> </td><td>String of (hidden) numbers
-</td></tr>
-<tr><td><tt>PPD_CUSTOM_PASSWORD</tt> </td><td>String of (hidden) characters
-</td></tr>
-<tr><td><tt>PPD_CUSTOM_POINTS</tt> </td><td>Measurement value in points
-</td></tr>
-<tr><td><tt>PPD_CUSTOM_REAL</tt> </td><td>Real number value
-</td></tr>
-<tr><td><tt>PPD_CUSTOM_STRING</tt> </td><td>String of characters
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_cs_e'>ppd_cs_e</a></h3>
-<h4>Description</h4>
-<p>Colorspaces
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>PPD_CS_CMY</tt> </td><td>CMY colorspace
-</td></tr>
-<tr><td><tt>PPD_CS_CMYK</tt> </td><td>CMYK colorspace
-</td></tr>
-<tr><td><tt>PPD_CS_GRAY</tt> </td><td>Grayscale colorspace
-</td></tr>
-<tr><td><tt>PPD_CS_N</tt> </td><td>DeviceN colorspace
-</td></tr>
-<tr><td><tt>PPD_CS_RGB</tt> </td><td>RGB colorspace
-</td></tr>
-<tr><td><tt>PPD_CS_RGBK</tt> </td><td>RGBK (K = gray) colorspace
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_section_e'>ppd_section_e</a></h3>
-<h4>Description</h4>
-<p>Order dependency sections
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>PPD_ORDER_ANY</tt> </td><td>Option code can be anywhere in the file
-</td></tr>
-<tr><td><tt>PPD_ORDER_DOCUMENT</tt> </td><td>... must be in the DocumentSetup section
-</td></tr>
-<tr><td><tt>PPD_ORDER_EXIT</tt> </td><td>... must be sent prior to the document
-</td></tr>
-<tr><td><tt>PPD_ORDER_JCL</tt> </td><td>... must be sent as a JCL command
-</td></tr>
-<tr><td><tt>PPD_ORDER_PAGE</tt> </td><td>... must be in the PageSetup section
-</td></tr>
-<tr><td><tt>PPD_ORDER_PROLOG</tt> </td><td>... must be in the Prolog section
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_status_e'>ppd_status_e</a></h3>
-<h4>Description</h4>
-<p>Types and structures...
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>PPD_ALLOC_ERROR</tt> </td><td>Memory allocation error
-</td></tr>
-<tr><td><tt>PPD_BAD_CUSTOM_PARAM</tt> </td><td>Bad custom parameter
-</td></tr>
-<tr><td><tt>PPD_BAD_OPEN_GROUP</tt> </td><td>Bad OpenGroup
-</td></tr>
-<tr><td><tt>PPD_BAD_OPEN_UI</tt> </td><td>Bad OpenUI/JCLOpenUI
-</td></tr>
-<tr><td><tt>PPD_BAD_ORDER_DEPENDENCY</tt> </td><td>Bad OrderDependency
-</td></tr>
-<tr><td><tt>PPD_BAD_UI_CONSTRAINTS</tt> </td><td>Bad UIConstraints
-</td></tr>
-<tr><td><tt>PPD_FILE_OPEN_ERROR</tt> </td><td>Unable to open PPD file
-</td></tr>
-<tr><td><tt>PPD_ILLEGAL_CHARACTER</tt> </td><td>Illegal control character
-</td></tr>
-<tr><td><tt>PPD_ILLEGAL_MAIN_KEYWORD</tt> </td><td>Illegal main keyword string
-</td></tr>
-<tr><td><tt>PPD_ILLEGAL_OPTION_KEYWORD</tt> </td><td>Illegal option keyword string
-</td></tr>
-<tr><td><tt>PPD_ILLEGAL_TRANSLATION</tt> </td><td>Illegal translation string
-</td></tr>
-<tr><td><tt>PPD_ILLEGAL_WHITESPACE</tt> </td><td>Illegal whitespace character
-</td></tr>
-<tr><td><tt>PPD_INTERNAL_ERROR</tt> </td><td>Internal error
-</td></tr>
-<tr><td><tt>PPD_LINE_TOO_LONG</tt> </td><td>Line longer than 255 chars
-</td></tr>
-<tr><td><tt>PPD_MISSING_ASTERISK</tt> </td><td>Missing asterisk in column 0
-</td></tr>
-<tr><td><tt>PPD_MISSING_PPDADOBE4</tt> </td><td>Missing PPD-Adobe-4.x header
-</td></tr>
-<tr><td><tt>PPD_MISSING_VALUE</tt> </td><td>Missing value string
-</td></tr>
-<tr><td><tt>PPD_NESTED_OPEN_GROUP</tt> </td><td>OpenGroup without a CloseGroup first
-</td></tr>
-<tr><td><tt>PPD_NESTED_OPEN_UI</tt> </td><td>OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first
-</td></tr>
-<tr><td><tt>PPD_NULL_FILE</tt> </td><td>NULL PPD file pointer
-</td></tr>
-<tr><td><tt>PPD_OK</tt> </td><td>OK
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_ui_e'>ppd_ui_e</a></h3>
-<h4>Description</h4>
-<p>UI Types
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>PPD_UI_BOOLEAN</tt> </td><td>True or False option
-</td></tr>
-<tr><td><tt>PPD_UI_PICKMANY</tt> </td><td>Pick zero or more from a list
-</td></tr>
-<tr><td><tt>PPD_UI_PICKONE</tt> </td><td>Pick one from a list
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='FUNCTIONS'>Functions</a></h2>
-<ul>
-       <li><a href='#ppdClose'><tt>ppdClose()</tt></a> </li>
-       <li><a href='#ppdCollect'><tt>ppdCollect()</tt></a> </li>
-       <li><a href='#ppdCollect2'><tt>ppdCollect2()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppdConflicts'><tt>ppdConflicts()</tt></a> </li>
-       <li><a href='#ppdEmit'><tt>ppdEmit()</tt></a> </li>
-       <li><a href='#ppdEmitAfterOrder'><tt>ppdEmitAfterOrder()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppdEmitFd'><tt>ppdEmitFd()</tt></a> </li>
-       <li><a href='#ppdEmitJCL'><tt>ppdEmitJCL()</tt></a> </li>
-       <li><a href='#ppdEmitJCLEnd'><tt>ppdEmitJCLEnd()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppdEmitString'><tt>ppdEmitString()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppdErrorString'><tt>ppdErrorString()</tt></a> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></li>
-       <li><a href='#ppdFindAttr'><tt>ppdFindAttr()</tt></a> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></li>
-       <li><a href='#ppdFindChoice'><tt>ppdFindChoice()</tt></a> </li>
-       <li><a href='#ppdFindCustomOption'><tt>ppdFindCustomOption()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppdFindCustomParam'><tt>ppdFindCustomParam()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppdFindMarkedChoice'><tt>ppdFindMarkedChoice()</tt></a> </li>
-       <li><a href='#ppdFindNextAttr'><tt>ppdFindNextAttr()</tt></a> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></li>
-       <li><a href='#ppdFindOption'><tt>ppdFindOption()</tt></a> </li>
-       <li><a href='#ppdFirstCustomParam'><tt>ppdFirstCustomParam()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppdFirstOption'><tt>ppdFirstOption()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppdIsMarked'><tt>ppdIsMarked()</tt></a> </li>
-       <li><a href='#ppdLastError'><tt>ppdLastError()</tt></a> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></li>
-       <li><a href='#ppdLocalize'><tt>ppdLocalize()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppdLocalizeIPPReason'><tt>ppdLocalizeIPPReason()</tt></a> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></li>
-       <li><a href='#ppdMarkDefaults'><tt>ppdMarkDefaults()</tt></a> </li>
-       <li><a href='#ppdMarkOption'><tt>ppdMarkOption()</tt></a> </li>
-       <li><a href='#ppdNextCustomParam'><tt>ppdNextCustomParam()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppdNextOption'><tt>ppdNextOption()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppdOpen'><tt>ppdOpen()</tt></a> </li>
-       <li><a href='#ppdOpen2'><tt>ppdOpen2()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppdOpenFd'><tt>ppdOpenFd()</tt></a> </li>
-       <li><a href='#ppdOpenFile'><tt>ppdOpenFile()</tt></a> </li>
-       <li><a href='#ppdPageLength'><tt>ppdPageLength()</tt></a> </li>
-       <li><a href='#ppdPageSize'><tt>ppdPageSize()</tt></a> </li>
-       <li><a href='#ppdPageWidth'><tt>ppdPageWidth()</tt></a> </li>
-       <li><a href='#ppdSetConformance'><tt>ppdSetConformance()</tt></a> <span class='info'>&nbsp;CUPS 1.1.20&nbsp;</span></li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdClose'>ppdClose()</a></h3>
-<h4>Description</h4>
-<p>Free all memory used by the PPD file.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-ppdClose(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file record</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdCollect'>ppdCollect()</a></h3>
-<h4>Description</h4>
-<p>Collect all marked options that reside in the specified
-section.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-ppdCollect(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    <a href='#ppd_section_t'>ppd_section_t</a> section,
-    <a href='#ppd_choice_t'>ppd_choice_t</a> *** choices);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file data</td></tr>
-<tr><td><tt>section</tt></td><td>Section to collect</td></tr>
-<tr><td><tt>choices</tt></td><td>Pointers to choices</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of options marked</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppdCollect2'>ppdCollect2()</a></h3>
-<h4>Description</h4>
-<p>Collect all marked options that reside in the
-specified section and minimum order.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-ppdCollect2(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    <a href='#ppd_section_t'>ppd_section_t</a> section,
-    float min_order,
-    <a href='#ppd_choice_t'>ppd_choice_t</a> *** choices);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file data</td></tr>
-<tr><td><tt>section</tt></td><td>Section to collect</td></tr>
-<tr><td><tt>min_order</tt></td><td>Minimum OrderDependency value</td></tr>
-<tr><td><tt>choices</tt></td><td>Pointers to choices</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of options marked</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdConflicts'>ppdConflicts()</a></h3>
-<h4>Description</h4>
-<p>Check to see if there are any conflicts.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-ppdConflicts(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD to check</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of conflicts found</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdEmit'>ppdEmit()</a></h3>
-<h4>Description</h4>
-<p>Emit code for marked options to a file.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-ppdEmit(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    FILE * fp,
-    <a href='#ppd_section_t'>ppd_section_t</a> section);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file record</td></tr>
-<tr><td><tt>fp</tt></td><td>File to write to</td></tr>
-<tr><td><tt>section</tt></td><td>Section to write</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, -1 on failure</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppdEmitAfterOrder'>ppdEmitAfterOrder()</a></h3>
-<h4>Description</h4>
-<p>Emit a subset of the code for marked options to a file.
-<p>When &quot;limit&quot; is non-zero, this function only emits options whose
-OrderDependency value is greater than or equal to &quot;min_order&quot;.
-<p>When &quot;limit&quot; is zero, this function is identical to ppdEmit().
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-ppdEmitAfterOrder(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    FILE * fp,
-    <a href='#ppd_section_t'>ppd_section_t</a> section,
-    int limit,
-    float min_order);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file record</td></tr>
-<tr><td><tt>fp</tt></td><td>File to write to</td></tr>
-<tr><td><tt>section</tt></td><td>Section to write</td></tr>
-<tr><td><tt>limit</tt></td><td>Non-zero to use min_order</td></tr>
-<tr><td><tt>min_order</tt></td><td>Lowest OrderDependency</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, -1 on failure</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdEmitFd'>ppdEmitFd()</a></h3>
-<h4>Description</h4>
-<p>Emit code for marked options to a file.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-ppdEmitFd(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    int fd,
-    <a href='#ppd_section_t'>ppd_section_t</a> section);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file record</td></tr>
-<tr><td><tt>fd</tt></td><td>File to write to</td></tr>
-<tr><td><tt>section</tt></td><td>Section to write</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, -1 on failure</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdEmitJCL'>ppdEmitJCL()</a></h3>
-<h4>Description</h4>
-<p>Emit code for JCL options to a file.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-ppdEmitJCL(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    FILE * fp,
-    int job_id,
-    const char * user,
-    const char * title);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file record</td></tr>
-<tr><td><tt>fp</tt></td><td>File to write to</td></tr>
-<tr><td><tt>job_id</tt></td><td>Job ID</td></tr>
-<tr><td><tt>user</tt></td><td>Username</td></tr>
-<tr><td><tt>title</tt></td><td>Title</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, -1 on failure</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppdEmitJCLEnd'>ppdEmitJCLEnd()</a></h3>
-<h4>Description</h4>
-<p>Emit JCLEnd code to a file.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-ppdEmitJCLEnd(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    FILE * fp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file record</td></tr>
-<tr><td><tt>fp</tt></td><td>File to write to</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, -1 on failure</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppdEmitString'>ppdEmitString()</a></h3>
-<h4>Description</h4>
-<p>Get a string containing the code for marked options.
-<p>When &quot;min_order&quot; is greater than zero, this function only includes options
+<p>The return value is a pointer to a new
+<a href="#ppd_file_t"><code>ppd_file_t</code></a> structure or <code>NULL</code>
+if the PPD file does not exist or cannot be loaded. The
+<a href="#ppdClose"><code>ppdClose</code></a> function frees the memory used
+by the structure:</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+
+<a href="#ppdClose">ppdClose</a>(ppd);
+</pre>
+
+<h3><a name="OPTIONS_AND_GROUPS">Options and Groups</a></h3>
+
+<p>PPD files support multiple options, which are stored in arrays of
+<a href="#ppd_option_t"><code>ppd_option_t</code></a> and
+<a href="#ppd_choice_t"><code>ppd_choice_t</code></a> structures.</p>
+
+<p>Each option in turn is associated with a group stored in a
+<a href="#ppd_group_t"><code>ppd_group_t</code></a> structure. Groups can be
+specified in the PPD file; if an option is not associated with a group
+then it is put in an automatically-generated "General" group. Groups can also
+have sub-groups, however CUPS currently ignores sub-groups because of past
+abuses of this functionality.</p>
+
+<p>Options are selected by marking them using one of three functions. The
+first is <a href="#ppdMarkDefaults"><code>ppdMarkDefaults</code></a> which
+selects all of the default options in the PPD file:</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+
+<a href="#ppdMarkDefaults">ppdMarkDefaults</a>(ppd);
+</pre>
+
+<p>The second is <a href="#ppdMarkOption"><code>ppdMarkOption</code></a>
+which selects a single option choice in the PPD file. For example, the following
+code selects the manual feed media source:</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+
+<a href="#ppdMarkOption">ppdMarkOption</a>(ppd, "InputSlot", "ManualFeed");
+</pre>
+
+<p>The last function is
+<a href="#cupsMarkOptions"><code>cupsMarkOptions</code></a> which selects
+multiple option choices in the PPD file from an array of CUPS options, mapping
+IPP attributes like "media" and "sides" to their corresponding PPD options. You
+typically use this function in a print filter with
+<code>cupsParseOptions</code> and
+<a href="#ppdMarkDefaults"><code>ppdMarkDefaults</code></a> to select all of
+the option choices needed for the job, for example:</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd = <a href="#ppdOpenFile">ppdOpenFile</a>(getenv("PPD"));
+cups_option_t *options = NULL;
+int num_options = cupsParseOptions(argv[5], 0, &amp;options);
+
+<a href="#ppdMarkDefaults">ppdMarkDefaults</a>(ppd);
+<a href="#cupsMarkOptions">cupsMarkOptions</a>(ppd, num_options, options);
+</pre>
+
+<h3><a name="CONSTRAINTS">Constraints</a></h3>
+
+<p>PPD files support specification of conflict conditions, called
+constraints, between different options. Constraints are stored in an array of
+<a href="#ppd_const_t"><code>ppd_const_t</code></a> structures which specify
+the options and choices that conflict with each other. The
+<a href="#ppdConflicts"><code>ppdConflicts</code></a> function tells you
+how many of the selected options are incompatible.</p>
+
+<h3><a name="PAGE_SIZES">Page Sizes</a></h3>
+
+<p>Page sizes are special options which have physical dimensions and margins
+associated with them. The size information is stored in
+<a href="#ppd_size_t"><code>ppd_size_t</code></a> structures and is available
+by looking up the named size with the
+<a href="#ppdPageSize"><code>ppdPageSize</code></a> function. The page size and
+margins are returned in units called points; there are 72 points per inch. If
+you pass <code>NULL</code> for the size, the currently selected size is
+returned:</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, NULL);
+</pre>
+
+<p>Besides the standard page sizes listed in a PPD file, some printers
+support variable or custom page sizes. Custom page sizes are supported if the
+<code>variables_sizes</code> member of the
+<a href="#ppd_file_t"><code>ppd_file_t</code></a> structure is non-zero.
+The <code>custom_min</code>, <code>custom_max</code>, and
+<code>custom_margins</code> members of the
+<a href="#ppd_file_t"><code>ppd_file_t</code></a> structure define the limits
+of the printable area. To get the resulting media size, use a page size string
+of the form "Custom.<I>width</I>x<I>length</I>", where "width" and "length" are
+in points. Custom page size names can also be specified in inches
+("Custom.<i>width</i>x<i>height</i>in"), centimeters
+("Custom.<i>width</i>x<i>height</i>cm"), or millimeters
+("Custom.<i>width</i>x<i>height</i>mm"):</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+
+/* Get an 576x720 point custom page size */
+<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.576x720");
+
+/* Get an 8x10 inch custom page size */
+<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.8x10in");
+
+/* Get a 100x200 millimeter custom page size */
+<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.100x200mm");
+
+/* Get a 12.7x34.5 centimeter custom page size */
+<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.12.7x34.5cm");
+</pre>
+
+<h3><a name="ATTRIBUTES">Attributes</a></h3>
+
+<p>Every PPD file is composed of one or more attributes. Most of these
+attributes are used to define groups, options, choices, and page sizes,
+however several informations attributes are available which you may need
+to access in your program or filter. Attributes normally look like one of
+the following examples in a PPD file:</p>
+
+<pre class="example">
+*name: "value"
+*name spec: "value"
+*name spec/text: "value"
+</pre>
+
+<p>The <a href="#ppdFindAttr"><code>ppdFindAttr</code></a> and
+<a href="#ppdFindNextAttr"><code>ppdFindNextAttr</code></a> functions find the
+first and next instances, respectively, of the named attribute with the given
+"spec" string and return a <a href="#ppd_attr_t"><code>ppd_attr_t</code></a>
+structure. If you provide a NULL specifier string, all attributes with the
+given name will be returned. For example, the following code lists all of the
+<code>Product</code> attributes in a PPD file:</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+<a href="#ppd_attr_t">ppd_attr_t</a> *attr;
+
+for (attr = <a href="#ppdFindAttr">ppdFindAttr</a>(ppd, "Product", NULL);
+     attr != NULL;
+     attr = <a href="#ppdFindNextAttr">ppdFindNextAttr</a>(ppd, "Product", NULL))
+  puts(attr->value);
+</pre>
+<h2 class="title"><a name="FUNCTIONS">Functions</a></h2>
+<h3 class="function"><a name="cupsMarkOptions">cupsMarkOptions</a></h3>
+<p class="description">Mark command-line options in a PPD file.</p>
+<p class="code">
+int cupsMarkOptions (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_options,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_option_t *options<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file</dd>
+<dt>num_options</dt>
+<dd class="description">Number of options</dd>
+<dt>options</dt>
+<dd class="description">Options</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 if conflicting</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function maps the IPP &quot;finishings&quot;, &quot;media&quot;, &quot;mirror&quot;,
+&quot;multiple-document-handling&quot;, &quot;output-bin&quot;, &quot;printer-resolution&quot;, and
+&quot;sides&quot; attributes to their corresponding PPD options and choices.</p>
+<h3 class="function"><a name="ppdClose">ppdClose</a></h3>
+<p class="description">Free all memory used by the PPD file.</p>
+<p class="code">
+void ppdClose (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file record</dd>
+</dl>
+<h3 class="function"><a name="ppdCollect">ppdCollect</a></h3>
+<p class="description">Collect all marked options that reside in the specified
+section.</p>
+<p class="code">
+int ppdCollect (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_section_t">ppd_section_t</a> section,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_choice_t">ppd_choice_t</a> ***choices<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file data</dd>
+<dt>section</dt>
+<dd class="description">Section to collect</dd>
+<dt>choices</dt>
+<dd class="description">Pointers to choices</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of options marked</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The choices array should be freed using <code>free</code> when you are
+finished with it.</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppdCollect2">ppdCollect2</a></h3>
+<p class="description">Collect all marked options that reside in the
+specified section and minimum order.</p>
+<p class="code">
+int ppdCollect2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_section_t">ppd_section_t</a> section,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float min_order,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_choice_t">ppd_choice_t</a> ***choices<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file data</dd>
+<dt>section</dt>
+<dd class="description">Section to collect</dd>
+<dt>min_order</dt>
+<dd class="description">Minimum OrderDependency value</dd>
+<dt>choices</dt>
+<dd class="description">Pointers to choices</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of options marked</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The choices array should be freed using <code>free</code> when you are
+finished with it.
+
+</p>
+<h3 class="function"><a name="ppdConflicts">ppdConflicts</a></h3>
+<p class="description">Check to see if there are any conflicts among the
+marked option choices.</p>
+<p class="code">
+int ppdConflicts (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD to check</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of conflicts found</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The returned value is the same as returned by <a href="#ppdMarkOption"><code>ppdMarkOption</code></a>.</p>
+<h3 class="function"><a name="ppdEmit">ppdEmit</a></h3>
+<p class="description">Emit code for marked options to a file.</p>
+<p class="code">
+int ppdEmit (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;FILE *fp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_section_t">ppd_section_t</a> section<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file record</dd>
+<dt>fp</dt>
+<dd class="description">File to write to</dd>
+<dt>section</dt>
+<dd class="description">Section to write</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, -1 on failure</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppdEmitAfterOrder">ppdEmitAfterOrder</a></h3>
+<p class="description">Emit a subset of the code for marked options to a file.</p>
+<p class="code">
+int ppdEmitAfterOrder (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;FILE *fp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_section_t">ppd_section_t</a> section,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int limit,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float min_order<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file record</dd>
+<dt>fp</dt>
+<dd class="description">File to write to</dd>
+<dt>section</dt>
+<dd class="description">Section to write</dd>
+<dt>limit</dt>
+<dd class="description">Non-zero to use min_order</dd>
+<dt>min_order</dt>
+<dd class="description">Lowest OrderDependency</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, -1 on failure</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">When &quot;limit&quot; is non-zero, this function only emits options whose
+OrderDependency value is greater than or equal to &quot;min_order&quot;.<br>
+<br>
+When &quot;limit&quot; is zero, this function is identical to ppdEmit().
+
+</p>
+<h3 class="function"><a name="ppdEmitFd">ppdEmitFd</a></h3>
+<p class="description">Emit code for marked options to a file.</p>
+<p class="code">
+int ppdEmitFd (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int fd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_section_t">ppd_section_t</a> section<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file record</dd>
+<dt>fd</dt>
+<dd class="description">File to write to</dd>
+<dt>section</dt>
+<dd class="description">Section to write</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, -1 on failure</p>
+<h3 class="function"><a name="ppdEmitJCL">ppdEmitJCL</a></h3>
+<p class="description">Emit code for JCL options to a file.</p>
+<p class="code">
+int ppdEmitJCL (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;FILE *fp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int job_id,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *user,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *title<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file record</dd>
+<dt>fp</dt>
+<dd class="description">File to write to</dd>
+<dt>job_id</dt>
+<dd class="description">Job ID</dd>
+<dt>user</dt>
+<dd class="description">Username</dd>
+<dt>title</dt>
+<dd class="description">Title</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, -1 on failure</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppdEmitJCLEnd">ppdEmitJCLEnd</a></h3>
+<p class="description">Emit JCLEnd code to a file.</p>
+<p class="code">
+int ppdEmitJCLEnd (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;FILE *fp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file record</dd>
+<dt>fp</dt>
+<dd class="description">File to write to</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, -1 on failure</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppdEmitString">ppdEmitString</a></h3>
+<p class="description">Get a string containing the code for marked options.</p>
+<p class="code">
+char *ppdEmitString (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_section_t">ppd_section_t</a> section,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float min_order<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file record</dd>
+<dt>section</dt>
+<dd class="description">Section to write</dd>
+<dt>min_order</dt>
+<dd class="description">Lowest OrderDependency</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">String containing option code or <code>NULL</code> if there is no option code</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">When &quot;min_order&quot; is greater than zero, this function only includes options
 whose OrderDependency value is greater than or equal to &quot;min_order&quot;.
 Otherwise, all options in the specified section are included in the
-returned string.
-<p>The return string is allocated on the heap and should be freed using
-free() when you are done with it.
-
-
-<h4>Syntax</h4>
-<p><tt>
-char *<br>
-ppdEmitString(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    <a href='#ppd_section_t'>ppd_section_t</a> section,
-    float min_order);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file record</td></tr>
-<tr><td><tt>section</tt></td><td>Section to write</td></tr>
-<tr><td><tt>min_order</tt></td><td>Lowest OrderDependency</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>String containing option code</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span><a name='ppdErrorString'>ppdErrorString()</a></h3>
-<h4>Description</h4>
-<p>Returns the text assocated with a status.
-
-
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-ppdErrorString(
-    ppd_status_t status);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>status</tt></td><td>PPD status</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Status string</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span><a name='ppdFindAttr'>ppdFindAttr()</a></h3>
-<h4>Description</h4>
-<p>Find the first matching attribute...
-
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ppd_attr_t'>ppd_attr_t</a> *<br>
-ppdFindAttr(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    const char * name,
-    const char * spec);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file data</td></tr>
-<tr><td><tt>name</tt></td><td>Attribute name</td></tr>
-<tr><td><tt>spec</tt></td><td>Specifier string or NULL</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Attribute or NULL if not found</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdFindChoice'>ppdFindChoice()</a></h3>
-<h4>Description</h4>
-<p>Return a pointer to an option choice.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ppd_choice_t'>ppd_choice_t</a> *<br>
-ppdFindChoice(
-    <a href='#ppd_option_t'>ppd_option_t</a> * o,
-    const char * choice);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>o</tt></td><td>Pointer to option</td></tr>
-<tr><td><tt>choice</tt></td><td>Name of choice</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Choice pointer or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppdFindCustomOption'>ppdFindCustomOption()</a></h3>
-<h4>Description</h4>
-<p>Find a custom option.
-
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ppd_coption_t'>ppd_coption_t</a> *<br>
-ppdFindCustomOption(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    const char * keyword);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file</td></tr>
-<tr><td><tt>keyword</tt></td><td>Custom option name</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Custom option or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppdFindCustomParam'>ppdFindCustomParam()</a></h3>
-<h4>Description</h4>
-<p>Find a parameter for a custom option.
-
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ppd_cparam_t'>ppd_cparam_t</a> *<br>
-ppdFindCustomParam(
-    <a href='#ppd_coption_t'>ppd_coption_t</a> * opt,
-    const char * name);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>opt</tt></td><td>Custom option</td></tr>
-<tr><td><tt>name</tt></td><td>Parameter name</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Custom parameter or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdFindMarkedChoice'>ppdFindMarkedChoice()</a></h3>
-<h4>Description</h4>
-<p>Return the marked choice for the specified option.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ppd_choice_t'>ppd_choice_t</a> *<br>
-ppdFindMarkedChoice(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    const char * option);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file</td></tr>
-<tr><td><tt>option</tt></td><td>Keyword/option name</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Pointer to choice or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span><a name='ppdFindNextAttr'>ppdFindNextAttr()</a></h3>
-<h4>Description</h4>
-<p>Find the next matching attribute...
-
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ppd_attr_t'>ppd_attr_t</a> *<br>
-ppdFindNextAttr(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    const char * name,
-    const char * spec);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file data</td></tr>
-<tr><td><tt>name</tt></td><td>Attribute name</td></tr>
-<tr><td><tt>spec</tt></td><td>Specifier string or NULL</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Attribute or NULL if not found</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdFindOption'>ppdFindOption()</a></h3>
-<h4>Description</h4>
-<p>Return a pointer to the specified option.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ppd_option_t'>ppd_option_t</a> *<br>
-ppdFindOption(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    const char * option);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file data</td></tr>
-<tr><td><tt>option</tt></td><td>Option/Keyword name</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Pointer to option or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppdFirstCustomParam'>ppdFirstCustomParam()</a></h3>
-<h4>Description</h4>
-<p>Return the first parameter for a custom option.
-
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ppd_cparam_t'>ppd_cparam_t</a> *<br>
-ppdFirstCustomParam(
-    <a href='#ppd_coption_t'>ppd_coption_t</a> * opt);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>opt</tt></td><td>Custom option</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Custom parameter or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppdFirstOption'>ppdFirstOption()</a></h3>
-<h4>Description</h4>
-<p>Return the first option in the PPD file.
-<p>Options are returned from all groups in sorted order.
-
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ppd_option_t'>ppd_option_t</a> *<br>
-ppdFirstOption(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>First option or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdIsMarked'>ppdIsMarked()</a></h3>
-<h4>Description</h4>
-<p>Check to see if an option is marked...
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-ppdIsMarked(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    const char * option,
-    const char * choice);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file data</td></tr>
-<tr><td><tt>option</tt></td><td>Option/Keyword name</td></tr>
-<tr><td><tt>choice</tt></td><td>Choice name</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Non-zero if option is marked</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span><a name='ppdLastError'>ppdLastError()</a></h3>
-<h4>Description</h4>
-<p>Return the status from the last ppdOpen*().
-
-
-<h4>Syntax</h4>
-<p><tt>
-ppd_status_t<br>
-ppdLastError(
-    int * line);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>line</tt></td><td>Line number</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Status code</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppdLocalize'>ppdLocalize()</a></h3>
-<h4>Description</h4>
-<p>Localize the PPD file to the current locale.
-<p>All groups, options, and choices are localized, as are ICC profile
+returned string.<br>
+<br>
+The return string is allocated on the heap and should be freed using
+<code>free</code> when you are done with it.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.19&nbsp;</span><a name="ppdErrorString">ppdErrorString</a></h3>
+<p class="description">Returns the text assocated with a status.</p>
+<p class="code">
+const char *ppdErrorString (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ppd_status_t status<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>status</dt>
+<dd class="description">PPD status</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Status string</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.19&nbsp;</span><a name="ppdFindAttr">ppdFindAttr</a></h3>
+<p class="description">Find the first matching attribute.</p>
+<p class="code">
+<a href="#ppd_attr_t">ppd_attr_t</a> *ppdFindAttr (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *spec<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file data</dd>
+<dt>name</dt>
+<dd class="description">Attribute name</dd>
+<dt>spec</dt>
+<dd class="description">Specifier string or <code>NULL</code></dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Attribute or <code>NULL</code> if not found</p>
+<h3 class="function"><a name="ppdFindChoice">ppdFindChoice</a></h3>
+<p class="description">Return a pointer to an option choice.</p>
+<p class="code">
+<a href="#ppd_choice_t">ppd_choice_t</a> *ppdFindChoice (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_option_t">ppd_option_t</a> *o,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *choice<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>o</dt>
+<dd class="description">Pointer to option</dd>
+<dt>choice</dt>
+<dd class="description">Name of choice</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Choice pointer or <code>NULL</code></p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppdFindCustomOption">ppdFindCustomOption</a></h3>
+<p class="description">Find a custom option.</p>
+<p class="code">
+<a href="#ppd_coption_t">ppd_coption_t</a> *ppdFindCustomOption (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *keyword<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file</dd>
+<dt>keyword</dt>
+<dd class="description">Custom option name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Custom option or NULL</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppdFindCustomParam">ppdFindCustomParam</a></h3>
+<p class="description">Find a parameter for a custom option.</p>
+<p class="code">
+<a href="#ppd_cparam_t">ppd_cparam_t</a> *ppdFindCustomParam (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_coption_t">ppd_coption_t</a> *opt,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>opt</dt>
+<dd class="description">Custom option</dd>
+<dt>name</dt>
+<dd class="description">Parameter name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Custom parameter or NULL</p>
+<h3 class="function"><a name="ppdFindMarkedChoice">ppdFindMarkedChoice</a></h3>
+<p class="description">Return the marked choice for the specified option.</p>
+<p class="code">
+<a href="#ppd_choice_t">ppd_choice_t</a> *ppdFindMarkedChoice (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *option<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file</dd>
+<dt>option</dt>
+<dd class="description">Keyword/option name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Pointer to choice or <code>NULL</code></p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.19&nbsp;</span><a name="ppdFindNextAttr">ppdFindNextAttr</a></h3>
+<p class="description">Find the next matching attribute.</p>
+<p class="code">
+<a href="#ppd_attr_t">ppd_attr_t</a> *ppdFindNextAttr (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *spec<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file data</dd>
+<dt>name</dt>
+<dd class="description">Attribute name</dd>
+<dt>spec</dt>
+<dd class="description">Specifier string or <code>NULL</code></dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Attribute or <code>NULL</code> if not found</p>
+<h3 class="function"><a name="ppdFindOption">ppdFindOption</a></h3>
+<p class="description">Return a pointer to the specified option.</p>
+<p class="code">
+<a href="#ppd_option_t">ppd_option_t</a> *ppdFindOption (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *option<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file data</dd>
+<dt>option</dt>
+<dd class="description">Option/Keyword name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Pointer to option or <code>NULL</code></p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppdFirstCustomParam">ppdFirstCustomParam</a></h3>
+<p class="description">Return the first parameter for a custom option.</p>
+<p class="code">
+<a href="#ppd_cparam_t">ppd_cparam_t</a> *ppdFirstCustomParam (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_coption_t">ppd_coption_t</a> *opt<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>opt</dt>
+<dd class="description">Custom option</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Custom parameter or NULL</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppdFirstOption">ppdFirstOption</a></h3>
+<p class="description">Return the first option in the PPD file.</p>
+<p class="code">
+<a href="#ppd_option_t">ppd_option_t</a> *ppdFirstOption (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">First option or <code>NULL</code></p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Options are returned from all groups in ascending alphanumeric order.
+
+</p>
+<h3 class="function"><a name="ppdIsMarked">ppdIsMarked</a></h3>
+<p class="description">Check to see if an option is marked.</p>
+<p class="code">
+int ppdIsMarked (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *option,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *choice<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file data</dd>
+<dt>option</dt>
+<dd class="description">Option/Keyword name</dd>
+<dt>choice</dt>
+<dd class="description">Choice name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Non-zero if option is marked</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.19&nbsp;</span><a name="ppdLastError">ppdLastError</a></h3>
+<p class="description">Return the status from the last ppdOpen*().</p>
+<p class="code">
+ppd_status_t ppdLastError (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *line<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>line</dt>
+<dd class="description">Line number</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Status code</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppdLocalize">ppdLocalize</a></h3>
+<p class="description">Localize the PPD file to the current locale.</p>
+<p class="code">
+int ppdLocalize (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, -1 on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">All groups, options, and choices are localized, as are ICC profile
 descriptions, printer presets, and custom option parameters.  Each
 localized string uses the UTF-8 character encoding.
 
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-ppdLocalize(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, -1 on error</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.3&nbsp;</span><a name='ppdLocalizeIPPReason'>ppdLocalizeIPPReason()</a></h3>
-<h4>Description</h4>
-<p>Get the localized version of a cupsIPPReason
-attribute.
-<p>This function uses the current locale to find the corresponding reason
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.3&nbsp;</span><a name="ppdLocalizeIPPReason">ppdLocalizeIPPReason</a></h3>
+<p class="description">Get the localized version of a cupsIPPReason
+attribute.</p>
+<p class="code">
+const char *ppdLocalizeIPPReason (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *reason,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *scheme,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *buffer,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t bufsize<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file</dd>
+<dt>reason</dt>
+<dd class="description">IPP reason keyword to look up</dd>
+<dt>scheme</dt>
+<dd class="description">URI scheme or NULL for text</dd>
+<dt>buffer</dt>
+<dd class="description">Value buffer</dd>
+<dt>bufsize</dt>
+<dd class="description">Size of value buffer</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Value or NULL if not found</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function uses the current locale to find the corresponding reason
 text or URI from the attribute value. If &quot;scheme&quot; is NULL or &quot;text&quot;,
 the returned value contains human-readable (UTF-8) text from the translation
-string or attribute value. Otherwise the corresponding URI is returned.
-<p>If no value of the requested scheme can be found, NULL is returned.
-
-
-<h4>Syntax</h4>
-<p><tt>
-const char *<br>
-ppdLocalizeIPPReason(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    const char * reason,
-    const char * scheme,
-    char * buffer,
-    size_t bufsize);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file</td></tr>
-<tr><td><tt>reason</tt></td><td>IPP reason keyword to look up</td></tr>
-<tr><td><tt>scheme</tt></td><td>URI scheme or NULL for text</td></tr>
-<tr><td><tt>buffer</tt></td><td>Value buffer</td></tr>
-<tr><td><tt>bufsize</tt></td><td>Size of value buffer</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Value or NULL if not found</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdMarkDefaults'>ppdMarkDefaults()</a></h3>
-<h4>Description</h4>
-<p>Mark all default options in the PPD file.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-ppdMarkDefaults(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file record</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdMarkOption'>ppdMarkOption()</a></h3>
-<h4>Description</h4>
-<p>Mark an option in a PPD file.
-<p>Notes:
-<p>-1 is returned if the given option would conflict with any currently
-selected option.
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-ppdMarkOption(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    const char * option,
-    const char * choice);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file record</td></tr>
-<tr><td><tt>option</tt></td><td>Keyword</td></tr>
-<tr><td><tt>choice</tt></td><td>Option name</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of conflicts</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppdNextCustomParam'>ppdNextCustomParam()</a></h3>
-<h4>Description</h4>
-<p>Return the next parameter for a custom option.
-
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ppd_cparam_t'>ppd_cparam_t</a> *<br>
-ppdNextCustomParam(
-    <a href='#ppd_coption_t'>ppd_coption_t</a> * opt);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>opt</tt></td><td>Custom option</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Custom parameter or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppdNextOption'>ppdNextOption()</a></h3>
-<h4>Description</h4>
-<p>Return the next option in the PPD file.
-<p>Options are returned from all groups in sorted order.
-
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ppd_option_t'>ppd_option_t</a> *<br>
-ppdNextOption(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Next option or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdOpen'>ppdOpen()</a></h3>
-<h4>Description</h4>
-<p>Read a PPD file into memory.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ppd_file_t'>ppd_file_t</a> *<br>
-ppdOpen(
-    FILE * fp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>File to read from</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>PPD file record</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppdOpen2'>ppdOpen2()</a></h3>
-<h4>Description</h4>
-<p>Read a PPD file into memory.
-
-
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ppd_file_t'>ppd_file_t</a> *<br>
-ppdOpen2(
-    cups_file_t * fp);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fp</tt></td><td>File to read from</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>PPD file record</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdOpenFd'>ppdOpenFd()</a></h3>
-<h4>Description</h4>
-<p>Read a PPD file into memory.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ppd_file_t'>ppd_file_t</a> *<br>
-ppdOpenFd(
-    int fd);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fd</tt></td><td>File to read from</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>PPD file record</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdOpenFile'>ppdOpenFile()</a></h3>
-<h4>Description</h4>
-<p>Read a PPD file into memory.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ppd_file_t'>ppd_file_t</a> *<br>
-ppdOpenFile(
-    const char * filename);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>filename</tt></td><td>File to read from</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>PPD file record</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdPageLength'>ppdPageLength()</a></h3>
-<h4>Description</h4>
-<p>Get the page length for the given size.
-<h4>Syntax</h4>
-<p><tt>
-float<br>
-ppdPageLength(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    const char * name);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file</td></tr>
-<tr><td><tt>name</tt></td><td>Size name</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Length of page in points or 0.0</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdPageSize'>ppdPageSize()</a></h3>
-<h4>Description</h4>
-<p>Get the page size record for the given size.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#ppd_size_t'>ppd_size_t</a> *<br>
-ppdPageSize(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    const char * name);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file record</td></tr>
-<tr><td><tt>name</tt></td><td>Size name</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Size record for page or NULL</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppdPageWidth'>ppdPageWidth()</a></h3>
-<h4>Description</h4>
-<p>Get the page width for the given size.
-<h4>Syntax</h4>
-<p><tt>
-float<br>
-ppdPageWidth(
-    <a href='#ppd_file_t'>ppd_file_t</a> * ppd,
-    const char * name);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>ppd</tt></td><td>PPD file record</td></tr>
-<tr><td><tt>name</tt></td><td>Size name</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Width of page in points or 0.0</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.20&nbsp;</span><a name='ppdSetConformance'>ppdSetConformance()</a></h3>
-<h4>Description</h4>
-<p>Set the conformance level for PPD files.
-
-
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-ppdSetConformance(
-    <a href='#ppd_conform_t'>ppd_conform_t</a> c);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>c</tt></td><td>Conformance level</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='STRUCTURES'>Structures</a></h2>
-<ul>
-       <li><a href='#ppd_attr_s'><tt>ppd_attr_s</tt></a> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></li>
-       <li><a href='#ppd_choice_s'><tt>ppd_choice_s</tt></a> </li>
-       <li><a href='#ppd_coption_s'><tt>ppd_coption_s</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppd_cparam_s'><tt>ppd_cparam_s</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppd_emul_s'><tt>ppd_emul_s</tt></a> </li>
-       <li><a href='#ppd_file_s'><tt>ppd_file_s</tt></a> </li>
-       <li><a href='#ppd_group_s'><tt>ppd_group_s</tt></a> </li>
-       <li><a href='#ppd_option_s'><tt>ppd_option_s</tt></a> </li>
-       <li><a href='#ppd_profile_s'><tt>ppd_profile_s</tt></a> </li>
-       <li><a href='#ppd_size_s'><tt>ppd_size_s</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span><a name='ppd_attr_s'>ppd_attr_s</a></h3>
-<h4>Description</h4>
-<p>PPD Attribute Structure 
-<h4>Definition</h4>
-<p><tt>
-struct ppd_attr_s<br>
-{<br>
-&nbsp;&nbsp;char name[PPD_MAX_NAME];<br>
-&nbsp;&nbsp;char spec[PPD_MAX_NAME];<br>
-&nbsp;&nbsp;char text[PPD_MAX_TEXT];<br>
-&nbsp;&nbsp;char * value;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name[PPD_MAX_NAME]</tt> </td><td>Name of attribute (cupsXYZ)
-</td></tr>
-<tr><td><tt>spec[PPD_MAX_NAME]</tt> </td><td>Specifier string, if any
-</td></tr>
-<tr><td><tt>text[PPD_MAX_TEXT]</tt> </td><td>Human-readable text, if any
-</td></tr>
-<tr><td><tt>value</tt> </td><td>Value string
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_choice_s'>ppd_choice_s</a></h3>
-<h4>Description</h4>
-<p>Option choices
-<h4>Definition</h4>
-<p><tt>
-struct ppd_choice_s<br>
-{<br>
-&nbsp;&nbsp;char choice[PPD_MAX_NAME];<br>
-&nbsp;&nbsp;char * code;<br>
-&nbsp;&nbsp;char marked;<br>
-&nbsp;&nbsp;<a href='#ppd_option_t'>ppd_option_t</a> * option;<br>
-&nbsp;&nbsp;char text[PPD_MAX_TEXT];<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>choice[PPD_MAX_NAME]</tt> </td><td>Computer-readable option name
-</td></tr>
-<tr><td><tt>code</tt> </td><td>Code to send for this option
-</td></tr>
-<tr><td><tt>marked</tt> </td><td>0 if not selected, 1 otherwise
-</td></tr>
-<tr><td><tt>option</tt> </td><td>Pointer to parent option structure
-</td></tr>
-<tr><td><tt>text[PPD_MAX_TEXT]</tt> </td><td>Human-readable option name
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppd_coption_s'>ppd_coption_s</a></h3>
-<h4>Description</h4>
-<p>Custom Option 
-<h4>Definition</h4>
-<p><tt>
-struct ppd_coption_s<br>
-{<br>
-&nbsp;&nbsp;char keyword[PPD_MAX_NAME];<br>
-&nbsp;&nbsp;int marked;<br>
-&nbsp;&nbsp;<a href='#ppd_option_t'>ppd_option_t</a> * option;<br>
-&nbsp;&nbsp;cups_array_t * params;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>keyword[PPD_MAX_NAME]</tt> </td><td>Name of option that is being extended...
-</td></tr>
-<tr><td><tt>marked</tt> </td><td>Extended option is marked
-</td></tr>
-<tr><td><tt>option</tt> </td><td>Option that is being extended...
-</td></tr>
-<tr><td><tt>params</tt> </td><td>Parameters
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppd_cparam_s'>ppd_cparam_s</a></h3>
-<h4>Description</h4>
-<p>Custom Parameter 
-<h4>Definition</h4>
-<p><tt>
-struct ppd_cparam_s<br>
-{<br>
-&nbsp;&nbsp;<a href='#ppd_cpvalue_t'>ppd_cpvalue_t</a> current;<br>
-&nbsp;&nbsp;<a href='#ppd_cplimit_t'>ppd_cplimit_t</a> minimum, maximum;<br>
-&nbsp;&nbsp;char name[PPD_MAX_NAME];<br>
-&nbsp;&nbsp;int order;<br>
-&nbsp;&nbsp;char text[PPD_MAX_TEXT];<br>
-&nbsp;&nbsp;<a href='#ppd_cptype_t'>ppd_cptype_t</a> type;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>current</tt> </td><td>Current value
-</td></tr>
-<tr><td><tt>maximum</tt> </td><td>Maximum value
-</td></tr>
-<tr><td><tt>name[PPD_MAX_NAME]</tt> </td><td>Parameter name
-</td></tr>
-<tr><td><tt>order</tt> </td><td>Order (0 to N)
-</td></tr>
-<tr><td><tt>text[PPD_MAX_TEXT]</tt> </td><td>Human-readable text
-</td></tr>
-<tr><td><tt>type</tt> </td><td>Parameter type
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_emul_s'>ppd_emul_s</a></h3>
-<h4>Description</h4>
-<p>Emulators
-<h4>Definition</h4>
-<p><tt>
-struct ppd_emul_s<br>
-{<br>
-&nbsp;&nbsp;char name[PPD_MAX_NAME];<br>
-&nbsp;&nbsp;char * start;<br>
-&nbsp;&nbsp;char * stop;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>name[PPD_MAX_NAME]</tt> </td><td>Emulator name
-</td></tr>
-<tr><td><tt>start</tt> </td><td>Code to switch to this emulation
-</td></tr>
-<tr><td><tt>stop</tt> </td><td>Code to stop this emulation
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_file_s'>ppd_file_s</a></h3>
-<h4>Description</h4>
-<p>PPD File
-<h4>Definition</h4>
-<p><tt>
-struct ppd_file_s<br>
-{<br>
-&nbsp;&nbsp;int accurate_screens;<br>
-&nbsp;&nbsp;<a href='#ppd_attr_t'>ppd_attr_t</a> ** attrs;<br>
-&nbsp;&nbsp;int color_device;<br>
-&nbsp;&nbsp;ppd_cs_t colorspace;<br>
-&nbsp;&nbsp;<a href='#ppd_const_t'>ppd_const_t</a> * consts;<br>
-&nbsp;&nbsp;int contone_only;<br>
-&nbsp;&nbsp;cups_array_t * coptions;<br>
-&nbsp;&nbsp;int cur_attr;<br>
-&nbsp;&nbsp;float custom_margins[4];<br>
-&nbsp;&nbsp;float custom_max[2];<br>
-&nbsp;&nbsp;float custom_min[2];<br>
-&nbsp;&nbsp;<a href='#ppd_emul_t'>ppd_emul_t</a> * emulations;<br>
-&nbsp;&nbsp;char ** filters;<br>
-&nbsp;&nbsp;int flip_duplex;<br>
-&nbsp;&nbsp;char ** fonts;<br>
-&nbsp;&nbsp;<a href='#ppd_group_t'>ppd_group_t</a> * groups;<br>
-&nbsp;&nbsp;char * jcl_begin;<br>
-&nbsp;&nbsp;char * jcl_end;<br>
-&nbsp;&nbsp;char * jcl_ps;<br>
-&nbsp;&nbsp;int landscape;<br>
-&nbsp;&nbsp;char * lang_encoding;<br>
-&nbsp;&nbsp;char * lang_version;<br>
-&nbsp;&nbsp;int language_level;<br>
-&nbsp;&nbsp;int manual_copies;<br>
-&nbsp;&nbsp;char * manufacturer;<br>
-&nbsp;&nbsp;cups_array_t * marked;<br>
-&nbsp;&nbsp;int model_number;<br>
-&nbsp;&nbsp;char * modelname;<br>
-&nbsp;&nbsp;char * nickname;<br>
-&nbsp;&nbsp;int num_attrs;<br>
-&nbsp;&nbsp;int num_consts;<br>
-&nbsp;&nbsp;int num_emulations;<br>
-&nbsp;&nbsp;int num_filters;<br>
-&nbsp;&nbsp;int num_fonts;<br>
-&nbsp;&nbsp;int num_groups;<br>
-&nbsp;&nbsp;int num_profiles;<br>
-&nbsp;&nbsp;int num_sizes;<br>
-&nbsp;&nbsp;cups_array_t * options;<br>
-&nbsp;&nbsp;char * patches;<br>
-&nbsp;&nbsp;char * pcfilename;<br>
-&nbsp;&nbsp;char * product;<br>
-&nbsp;&nbsp;<a href='#ppd_profile_t'>ppd_profile_t</a> * profiles;<br>
-&nbsp;&nbsp;char * protocols;<br>
-&nbsp;&nbsp;char * shortnickname;<br>
-&nbsp;&nbsp;<a href='#ppd_size_t'>ppd_size_t</a> * sizes;<br>
-&nbsp;&nbsp;cups_array_t * sorted_attrs;<br>
-&nbsp;&nbsp;int throughput;<br>
-&nbsp;&nbsp;char * ttrasterizer;<br>
-&nbsp;&nbsp;int variable_sizes;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>accurate_screens</tt> </td><td>1 = supports accurate screens, 0 = not
-</td></tr>
-<tr><td><tt>attrs</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>Attributes  @private@
-</td></tr>
-<tr><td><tt>color_device</tt> </td><td>1 = color device, 0 = grayscale
-</td></tr>
-<tr><td><tt>colorspace</tt> </td><td>Default colorspace
-</td></tr>
-<tr><td><tt>consts</tt> </td><td>UI/Non-UI constraints
-</td></tr>
-<tr><td><tt>contone_only</tt> </td><td>1 = continuous tone only, 0 = not
-</td></tr>
-<tr><td><tt>coptions</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Custom options array  @private@
-</td></tr>
-<tr><td><tt>cur_attr</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>Current attribute  @private@
-</td></tr>
-<tr><td><tt>custom_margins[4]</tt> </td><td>Margins around page
-</td></tr>
-<tr><td><tt>custom_max[2]</tt> </td><td>Maximum variable page size
-</td></tr>
-<tr><td><tt>custom_min[2]</tt> </td><td>Minimum variable page size
-</td></tr>
-<tr><td><tt>emulations</tt> </td><td>Emulations and the code to invoke them
-</td></tr>
-<tr><td><tt>filters</tt> </td><td>Filter strings...
-</td></tr>
-<tr><td><tt>flip_duplex</tt> <span class='info'>&nbsp;DEPRECATED&nbsp;</span></td><td>1 = Flip page for back sides 
-</td></tr>
-<tr><td><tt>fonts</tt> </td><td>Pre-loaded fonts
-</td></tr>
-<tr><td><tt>groups</tt> </td><td>UI groups
-</td></tr>
-<tr><td><tt>jcl_begin</tt> </td><td>Start JCL commands
-</td></tr>
-<tr><td><tt>jcl_end</tt> </td><td>End JCL commands
-</td></tr>
-<tr><td><tt>jcl_ps</tt> </td><td>Enter PostScript interpreter
-</td></tr>
-<tr><td><tt>landscape</tt> </td><td>-90 or 90
-</td></tr>
-<tr><td><tt>lang_encoding</tt> </td><td>Language encoding
-</td></tr>
-<tr><td><tt>lang_version</tt> </td><td>Language version (English, Spanish, etc.)
-</td></tr>
-<tr><td><tt>language_level</tt> </td><td>Language level of device
-</td></tr>
-<tr><td><tt>manual_copies</tt> </td><td>1 = Copies done manually, 0 = hardware
-</td></tr>
-<tr><td><tt>manufacturer</tt> </td><td>Manufacturer name
-</td></tr>
-<tr><td><tt>marked</tt> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></td><td>Marked choices  @private@
-</td></tr>
-<tr><td><tt>model_number</tt> </td><td>Device-specific model number
-</td></tr>
-<tr><td><tt>modelname</tt> </td><td>Model name (general)
-</td></tr>
-<tr><td><tt>nickname</tt> </td><td>Nickname (specific)
-</td></tr>
-<tr><td><tt>num_attrs</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>Number of attributes  @private@
-</td></tr>
-<tr><td><tt>num_consts</tt> </td><td>Number of UI/Non-UI constraints
-</td></tr>
-<tr><td><tt>num_emulations</tt> </td><td>Number of emulations supported
-</td></tr>
-<tr><td><tt>num_filters</tt> </td><td>Number of filters
-</td></tr>
-<tr><td><tt>num_fonts</tt> </td><td>Number of pre-loaded fonts
-</td></tr>
-<tr><td><tt>num_groups</tt> </td><td>Number of UI groups
-</td></tr>
-<tr><td><tt>num_profiles</tt> </td><td>Number of sRGB color profiles
-</td></tr>
-<tr><td><tt>num_sizes</tt> </td><td>Number of page sizes
-</td></tr>
-<tr><td><tt>options</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Option lookup array  @private@
-</td></tr>
-<tr><td><tt>patches</tt> </td><td>Patch commands to be sent to printer
-</td></tr>
-<tr><td><tt>pcfilename</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>PCFileName string 
-</td></tr>
-<tr><td><tt>product</tt> </td><td>Product name (from PS RIP/interpreter)
-</td></tr>
-<tr><td><tt>profiles</tt> </td><td>sRGB color profiles
-</td></tr>
-<tr><td><tt>protocols</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>Protocols (BCP, TBCP) string 
-</td></tr>
-<tr><td><tt>shortnickname</tt> </td><td>Short version of nickname
-</td></tr>
-<tr><td><tt>sizes</tt> </td><td>Page sizes
-</td></tr>
-<tr><td><tt>sorted_attrs</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Attribute lookup array  @private@
-</td></tr>
-<tr><td><tt>throughput</tt> </td><td>Pages per minute
-</td></tr>
-<tr><td><tt>ttrasterizer</tt> </td><td>Truetype rasterizer
-</td></tr>
-<tr><td><tt>variable_sizes</tt> </td><td>1 = supports variable sizes, 0 = doesn't
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_group_s'>ppd_group_s</a></h3>
-<h4>Description</h4>
-<p>Groups
-<h4>Definition</h4>
-<p><tt>
-struct ppd_group_s<br>
-{<br>
-&nbsp;&nbsp;char text[PPD_MAX_TEXT - PPD_MAX_NAME];<br>
-&nbsp;&nbsp;char name[PPD_MAX_NAME];<br>
-&nbsp;&nbsp;int num_options;<br>
-&nbsp;&nbsp;int num_subgroups;<br>
-&nbsp;&nbsp;<a href='#ppd_option_t'>ppd_option_t</a> * options;<br>
-&nbsp;&nbsp;struct <a href='#ppd_group_s'>ppd_group_s</a> * subgroups;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>PPD_MAX_NAME]</tt> </td><td>Human-readable group name
-</td></tr>
-<tr><td><tt>name[PPD_MAX_NAME]</tt> <span class='info'>&nbsp;CUPS 1.1.18&nbsp;</span></td><td>Group name 
-</td></tr>
-<tr><td><tt>num_options</tt> </td><td>Number of options
-</td></tr>
-<tr><td><tt>num_subgroups</tt> </td><td>Number of sub-groups
-</td></tr>
-<tr><td><tt>options</tt> </td><td>Options
-</td></tr>
-<tr><td><tt>subgroups</tt> </td><td>Sub-groups (max depth = 1)
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_option_s'>ppd_option_s</a></h3>
-<h4>Description</h4>
-<p>Options
-<h4>Definition</h4>
-<p><tt>
-struct ppd_option_s<br>
-{<br>
-&nbsp;&nbsp;<a href='#ppd_choice_t'>ppd_choice_t</a> * choices;<br>
-&nbsp;&nbsp;char conflicted;<br>
-&nbsp;&nbsp;char defchoice[PPD_MAX_NAME];<br>
-&nbsp;&nbsp;char keyword[PPD_MAX_NAME];<br>
-&nbsp;&nbsp;int num_choices;<br>
-&nbsp;&nbsp;float order;<br>
-&nbsp;&nbsp;<a href='#ppd_section_t'>ppd_section_t</a> section;<br>
-&nbsp;&nbsp;char text[PPD_MAX_TEXT];<br>
-&nbsp;&nbsp;<a href='#ppd_ui_t'>ppd_ui_t</a> ui;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>choices</tt> </td><td>Option choices
-</td></tr>
-<tr><td><tt>conflicted</tt> </td><td>0 if no conflicts exist, 1 otherwise
-</td></tr>
-<tr><td><tt>defchoice[PPD_MAX_NAME]</tt> </td><td>Default option choice
-</td></tr>
-<tr><td><tt>keyword[PPD_MAX_NAME]</tt> </td><td>Option keyword name (&quot;PageSize&quot;, etc.)
-</td></tr>
-<tr><td><tt>num_choices</tt> </td><td>Number of option choices
-</td></tr>
-<tr><td><tt>order</tt> </td><td>Order number
-</td></tr>
-<tr><td><tt>section</tt> </td><td>Section for command
-</td></tr>
-<tr><td><tt>text[PPD_MAX_TEXT]</tt> </td><td>Human-readable text
-</td></tr>
-<tr><td><tt>ui</tt> </td><td>Type of UI option
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_profile_s'>ppd_profile_s</a></h3>
-<h4>Description</h4>
-<p>sRGB Color Profiles
-<h4>Definition</h4>
-<p><tt>
-struct ppd_profile_s<br>
-{<br>
-&nbsp;&nbsp;float density;<br>
-&nbsp;&nbsp;float gamma;<br>
-&nbsp;&nbsp;float matrix[3][3];<br>
-&nbsp;&nbsp;char media_type[PPD_MAX_NAME];<br>
-&nbsp;&nbsp;char resolution[PPD_MAX_NAME];<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>density</tt> </td><td>Ink density to use
-</td></tr>
-<tr><td><tt>gamma</tt> </td><td>Gamma correction to use
-</td></tr>
-<tr><td><tt>matrix[3][3]</tt> </td><td>Transform matrix
-</td></tr>
-<tr><td><tt>media_type[PPD_MAX_NAME]</tt> </td><td>Media type or &quot;-&quot;
-</td></tr>
-<tr><td><tt>resolution[PPD_MAX_NAME]</tt> </td><td>Resolution or &quot;-&quot;
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_size_s'>ppd_size_s</a></h3>
-<h4>Description</h4>
-<p>Page Sizes
-<h4>Definition</h4>
-<p><tt>
-struct ppd_size_s<br>
-{<br>
-&nbsp;&nbsp;float bottom;<br>
-&nbsp;&nbsp;float left;<br>
-&nbsp;&nbsp;float length;<br>
-&nbsp;&nbsp;int marked;<br>
-&nbsp;&nbsp;char name[PPD_MAX_NAME];<br>
-&nbsp;&nbsp;float right;<br>
-&nbsp;&nbsp;float top;<br>
-&nbsp;&nbsp;float width;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>bottom</tt> </td><td>Bottom printable margin in points
-</td></tr>
-<tr><td><tt>left</tt> </td><td>Left printable margin in points
-</td></tr>
-<tr><td><tt>length</tt> </td><td>Length of media in points
-</td></tr>
-<tr><td><tt>marked</tt> </td><td>Page size selected?
-</td></tr>
-<tr><td><tt>name[PPD_MAX_NAME]</tt> </td><td>Media size option
-</td></tr>
-<tr><td><tt>right</tt> </td><td>Right printable margin in points
-</td></tr>
-<tr><td><tt>top</tt> </td><td>Top printable margin in points
-</td></tr>
-<tr><td><tt>width</tt> </td><td>Width of media in points
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='TYPES'>Types</a></h2>
-<ul>
-       <li><a href='#ppd_attr_t'><tt>ppd_attr_t</tt></a> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></li>
-       <li><a href='#ppd_choice_t'><tt>ppd_choice_t</tt></a> </li>
-       <li><a href='#ppd_const_t'><tt>ppd_const_t</tt></a> </li>
-       <li><a href='#ppd_coption_t'><tt>ppd_coption_t</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppd_cparam_t'><tt>ppd_cparam_t</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppd_cplimit_t'><tt>ppd_cplimit_t</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppd_cptype_t'><tt>ppd_cptype_t</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppd_cpvalue_t'><tt>ppd_cpvalue_t</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppd_emul_t'><tt>ppd_emul_t</tt></a> </li>
-       <li><a href='#ppd_file_t'><tt>ppd_file_t</tt></a> </li>
-       <li><a href='#ppd_group_t'><tt>ppd_group_t</tt></a> </li>
-       <li><a href='#ppd_option_t'><tt>ppd_option_t</tt></a> </li>
-       <li><a href='#ppd_profile_t'><tt>ppd_profile_t</tt></a> </li>
-       <li><a href='#ppd_section_t'><tt>ppd_section_t</tt></a> </li>
-       <li><a href='#ppd_size_t'><tt>ppd_size_t</tt></a> </li>
-       <li><a href='#ppd_ui_t'><tt>ppd_ui_t</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span><a name='ppd_attr_t'>ppd_attr_t</a></h3>
-<h4>Description</h4>
-<p>PPD Attribute Structure 
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#ppd_attr_s'>ppd_attr_s</a> ppd_attr_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_choice_t'>ppd_choice_t</a></h3>
-<h4>Description</h4>
-<p>Option choices
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#ppd_choice_s'>ppd_choice_s</a> ppd_choice_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_const_t'>ppd_const_t</a></h3>
-<h4>Description</h4>
-<p>Constraints
-<h4>Definition</h4>
-<p><tt>
-typedef struct ppd_const_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppd_coption_t'>ppd_coption_t</a></h3>
-<h4>Description</h4>
-<p>Custom Option 
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#ppd_coption_s'>ppd_coption_s</a> ppd_coption_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppd_cparam_t'>ppd_cparam_t</a></h3>
-<h4>Description</h4>
-<p>Custom Parameter 
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#ppd_cparam_s'>ppd_cparam_s</a> ppd_cparam_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppd_cplimit_t'>ppd_cplimit_t</a></h3>
-<h4>Description</h4>
-<p>Custom Parameter Limit 
-<h4>Definition</h4>
-<p><tt>
-typedef union <a href='#ppd_cplimit_u'>ppd_cplimit_u</a> ppd_cplimit_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppd_cptype_t'>ppd_cptype_t</a></h3>
-<h4>Description</h4>
-<p>Custom Parameter Type 
-<h4>Definition</h4>
-<p><tt>
-typedef enum <a href='#ppd_cptype_e'>ppd_cptype_e</a> ppd_cptype_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppd_cpvalue_t'>ppd_cpvalue_t</a></h3>
-<h4>Description</h4>
-<p>Custom Parameter Value 
-<h4>Definition</h4>
-<p><tt>
-typedef union <a href='#ppd_cpvalue_u'>ppd_cpvalue_u</a> ppd_cpvalue_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_emul_t'>ppd_emul_t</a></h3>
-<h4>Description</h4>
-<p>Emulators
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#ppd_emul_s'>ppd_emul_s</a> ppd_emul_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_file_t'>ppd_file_t</a></h3>
-<h4>Description</h4>
-<p>PPD File
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#ppd_file_s'>ppd_file_s</a> ppd_file_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_group_t'>ppd_group_t</a></h3>
-<h4>Description</h4>
-<p>Groups
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#ppd_group_s'>ppd_group_s</a> ppd_group_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_option_t'>ppd_option_t</a></h3>
-<h4>Description</h4>
-<p>Options
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#ppd_option_s'>ppd_option_s</a> ppd_option_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_profile_t'>ppd_profile_t</a></h3>
-<h4>Description</h4>
-<p>sRGB Color Profiles
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#ppd_profile_s'>ppd_profile_s</a> ppd_profile_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_section_t'>ppd_section_t</a></h3>
-<h4>Description</h4>
-<p>Order dependency sections
-<h4>Definition</h4>
-<p><tt>
-typedef enum <a href='#ppd_section_e'>ppd_section_e</a> ppd_section_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_size_t'>ppd_size_t</a></h3>
-<h4>Description</h4>
-<p>Page Sizes
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#ppd_size_s'>ppd_size_s</a> ppd_size_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='ppd_ui_t'>ppd_ui_t</a></h3>
-<h4>Description</h4>
-<p>UI Types
-<h4>Definition</h4>
-<p><tt>
-typedef enum <a href='#ppd_ui_e'>ppd_ui_e</a> ppd_ui_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='UNIONS'>Unions</a></h2>
-<ul>
-       <li><a href='#ppd_cplimit_u'><tt>ppd_cplimit_u</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#ppd_cpvalue_u'><tt>ppd_cpvalue_u</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppd_cplimit_u'>ppd_cplimit_u</a></h3>
-<h4>Description</h4>
-<p>Custom Parameter Limit 
-<h4>Definition</h4>
-<p><tt>
-union ppd_cplimit_u<br>
-{<br>
-&nbsp;&nbsp;float custom_curve;<br>
-&nbsp;&nbsp;int custom_int;<br>
-&nbsp;&nbsp;float custom_invcurve;<br>
-&nbsp;&nbsp;int custom_passcode;<br>
-&nbsp;&nbsp;int custom_password;<br>
-&nbsp;&nbsp;float custom_points;<br>
-&nbsp;&nbsp;float custom_real;<br>
-&nbsp;&nbsp;int custom_string;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>custom_curve</tt> </td><td>Gamma value
-</td></tr>
-<tr><td><tt>custom_int</tt> </td><td>Integer value
-</td></tr>
-<tr><td><tt>custom_invcurve</tt> </td><td>Gamma value
-</td></tr>
-<tr><td><tt>custom_passcode</tt> </td><td>Passcode length
-</td></tr>
-<tr><td><tt>custom_password</tt> </td><td>Password length
-</td></tr>
-<tr><td><tt>custom_points</tt> </td><td>Measurement value
-</td></tr>
-<tr><td><tt>custom_real</tt> </td><td>Real value
-</td></tr>
-<tr><td><tt>custom_string</tt> </td><td>String length
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='ppd_cpvalue_u'>ppd_cpvalue_u</a></h3>
-<h4>Description</h4>
-<p>Custom Parameter Value 
-<h4>Definition</h4>
-<p><tt>
-union ppd_cpvalue_u<br>
-{<br>
-&nbsp;&nbsp;float custom_curve;<br>
-&nbsp;&nbsp;int custom_int;<br>
-&nbsp;&nbsp;float custom_invcurve;<br>
-&nbsp;&nbsp;char * custom_passcode;<br>
-&nbsp;&nbsp;char * custom_password;<br>
-&nbsp;&nbsp;float custom_points;<br>
-&nbsp;&nbsp;float custom_real;<br>
-&nbsp;&nbsp;char * custom_string;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>custom_curve</tt> </td><td>Gamma value
-</td></tr>
-<tr><td><tt>custom_int</tt> </td><td>Integer value
-</td></tr>
-<tr><td><tt>custom_invcurve</tt> </td><td>Gamma value
-</td></tr>
-<tr><td><tt>custom_passcode</tt> </td><td>Passcode value
-</td></tr>
-<tr><td><tt>custom_password</tt> </td><td>Password value
-</td></tr>
-<tr><td><tt>custom_points</tt> </td><td>Measurement value
-</td></tr>
-<tr><td><tt>custom_real</tt> </td><td>Real value
-</td></tr>
-<tr><td><tt>custom_string</tt> </td><td>String value
-</td></tr>
-</tbody></table></div>
+string or attribute value. Otherwise the corresponding URI is returned.<br>
+<br>
+If no value of the requested scheme can be found, NULL is returned.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="ppdLocalizeMarkerName">ppdLocalizeMarkerName</a></h3>
+<p class="description">Get the localized version of a marker-names
+attribute value.</p>
+<p class="code">
+const char *ppdLocalizeMarkerName (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file</dd>
+<dt>name</dt>
+<dd class="description">Marker name to look up</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Value or <code>NULL</code> if not found</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function uses the current locale to find the corresponding name
+text from the attribute value. If no localized text for the requested
+name can be found, <code>NULL</code> is returned.
+
+</p>
+<h3 class="function"><a name="ppdMarkDefaults">ppdMarkDefaults</a></h3>
+<p class="description">Mark all default options in the PPD file.</p>
+<p class="code">
+void ppdMarkDefaults (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file record</dd>
+</dl>
+<h3 class="function"><a name="ppdMarkOption">ppdMarkOption</a></h3>
+<p class="description">Mark an option in a PPD file.</p>
+<p class="code">
+int ppdMarkOption (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *option,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *choice<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file record</dd>
+<dt>option</dt>
+<dd class="description">Keyword</dd>
+<dt>choice</dt>
+<dd class="description">Option name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of conflicts</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppdNextCustomParam">ppdNextCustomParam</a></h3>
+<p class="description">Return the next parameter for a custom option.</p>
+<p class="code">
+<a href="#ppd_cparam_t">ppd_cparam_t</a> *ppdNextCustomParam (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_coption_t">ppd_coption_t</a> *opt<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>opt</dt>
+<dd class="description">Custom option</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Custom parameter or NULL</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppdNextOption">ppdNextOption</a></h3>
+<p class="description">Return the next option in the PPD file.</p>
+<p class="code">
+<a href="#ppd_option_t">ppd_option_t</a> *ppdNextOption (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Next option or <code>NULL</code></p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Options are returned from all groups in ascending alphanumeric order.
+
+</p>
+<h3 class="function"><a name="ppdOpen">ppdOpen</a></h3>
+<p class="description">Read a PPD file into memory.</p>
+<p class="code">
+<a href="#ppd_file_t">ppd_file_t</a> *ppdOpen (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;FILE *fp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">File to read from</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">PPD file record</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppdOpen2">ppdOpen2</a></h3>
+<p class="description">Read a PPD file into memory.</p>
+<p class="code">
+<a href="#ppd_file_t">ppd_file_t</a> *ppdOpen2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_file_t *fp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fp</dt>
+<dd class="description">File to read from</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">PPD file record or <code>NULL</code> if the PPD file could not be opened.</p>
+<h3 class="function"><a name="ppdOpenFd">ppdOpenFd</a></h3>
+<p class="description">Read a PPD file into memory.</p>
+<p class="code">
+<a href="#ppd_file_t">ppd_file_t</a> *ppdOpenFd (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int fd<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fd</dt>
+<dd class="description">File to read from</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">PPD file record or <code>NULL</code> if the PPD file could not be opened.</p>
+<h3 class="function"><a name="ppdOpenFile">ppdOpenFile</a></h3>
+<p class="description">Read a PPD file into memory.</p>
+<p class="code">
+<a href="#ppd_file_t">ppd_file_t</a> *ppdOpenFile (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *filename<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>filename</dt>
+<dd class="description">File to read from</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">PPD file record or <code>NULL</code> if the PPD file could not be opened.</p>
+<h3 class="function"><a name="ppdPageLength">ppdPageLength</a></h3>
+<p class="description">Get the page length for the given size.</p>
+<p class="code">
+float ppdPageLength (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file</dd>
+<dt>name</dt>
+<dd class="description">Size name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Length of page in points or 0.0</p>
+<h3 class="function"><a name="ppdPageSize">ppdPageSize</a></h3>
+<p class="description">Get the page size record for the given size.</p>
+<p class="code">
+<a href="#ppd_size_t">ppd_size_t</a> *ppdPageSize (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file record</dd>
+<dt>name</dt>
+<dd class="description">Size name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Size record for page or NULL</p>
+<h3 class="function"><a name="ppdPageWidth">ppdPageWidth</a></h3>
+<p class="description">Get the page width for the given size.</p>
+<p class="code">
+float ppdPageWidth (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_file_t">ppd_file_t</a> *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *name<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ppd</dt>
+<dd class="description">PPD file record</dd>
+<dt>name</dt>
+<dd class="description">Size name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Width of page in points or 0.0</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.1.20&nbsp;</span><a name="ppdSetConformance">ppdSetConformance</a></h3>
+<p class="description">Set the conformance level for PPD files.</p>
+<p class="code">
+void ppdSetConformance (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_conform_t">ppd_conform_t</a> c<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>c</dt>
+<dd class="description">Conformance level</dd>
+</dl>
+<h2 class="title"><a name="TYPES">Data Types</a></h2>
+<h3 class="typedef"><span class="info">&nbsp;CUPS 1.1.19&nbsp;</span><a name="ppd_attr_t">ppd_attr_t</a></h3>
+<p class="description">PPD Attribute Structure </p>
+<p class="code">
+typedef struct <a href="#ppd_attr_s">ppd_attr_s</a> ppd_attr_t;
+</p>
+<h3 class="typedef"><a name="ppd_choice_t">ppd_choice_t</a></h3>
+<p class="description">Option choices</p>
+<p class="code">
+typedef struct <a href="#ppd_choice_s">ppd_choice_s</a> ppd_choice_t;
+</p>
+<h3 class="typedef"><span class="info">&nbsp;CUPS 1.1.19&nbsp;</span><a name="ppd_conform_t">ppd_conform_t</a></h3>
+<p class="description">Conformance Levels </p>
+<p class="code">
+typedef enum <a href="#ppd_conform_e">ppd_conform_e</a> ppd_conform_t;
+</p>
+<h3 class="typedef"><a name="ppd_const_t">ppd_const_t</a></h3>
+<p class="description">Constraints</p>
+<p class="code">
+typedef struct <a href="#ppd_const_s">ppd_const_s</a> ppd_const_t;
+</p>
+<h3 class="typedef"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppd_coption_t">ppd_coption_t</a></h3>
+<p class="description">Custom Option </p>
+<p class="code">
+typedef struct <a href="#ppd_coption_s">ppd_coption_s</a> ppd_coption_t;
+</p>
+<h3 class="typedef"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppd_cparam_t">ppd_cparam_t</a></h3>
+<p class="description">Custom Parameter </p>
+<p class="code">
+typedef struct <a href="#ppd_cparam_s">ppd_cparam_s</a> ppd_cparam_t;
+</p>
+<h3 class="typedef"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppd_cplimit_t">ppd_cplimit_t</a></h3>
+<p class="description">Custom Parameter Limit </p>
+<p class="code">
+typedef union <a href="#ppd_cplimit_u">ppd_cplimit_u</a> ppd_cplimit_t;
+</p>
+<h3 class="typedef"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppd_cptype_t">ppd_cptype_t</a></h3>
+<p class="description">Custom Parameter Type </p>
+<p class="code">
+typedef enum <a href="#ppd_cptype_e">ppd_cptype_e</a> ppd_cptype_t;
+</p>
+<h3 class="typedef"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppd_cpvalue_t">ppd_cpvalue_t</a></h3>
+<p class="description">Custom Parameter Value </p>
+<p class="code">
+typedef union <a href="#ppd_cpvalue_u">ppd_cpvalue_u</a> ppd_cpvalue_t;
+</p>
+<h3 class="typedef"><a name="ppd_emul_t">ppd_emul_t</a></h3>
+<p class="description">Emulators</p>
+<p class="code">
+typedef struct <a href="#ppd_emul_s">ppd_emul_s</a> ppd_emul_t;
+</p>
+<h3 class="typedef"><a name="ppd_file_t">ppd_file_t</a></h3>
+<p class="description">PPD File</p>
+<p class="code">
+typedef struct <a href="#ppd_file_s">ppd_file_s</a> ppd_file_t;
+</p>
+<h3 class="typedef"><a name="ppd_group_t">ppd_group_t</a></h3>
+<p class="description">Groups</p>
+<p class="code">
+typedef struct <a href="#ppd_group_s">ppd_group_s</a> ppd_group_t;
+</p>
+<h3 class="typedef"><a name="ppd_option_t">ppd_option_t</a></h3>
+<p class="description">Options</p>
+<p class="code">
+typedef struct <a href="#ppd_option_s">ppd_option_s</a> ppd_option_t;
+</p>
+<h3 class="typedef"><a name="ppd_profile_t">ppd_profile_t</a></h3>
+<p class="description">sRGB Color Profiles</p>
+<p class="code">
+typedef struct <a href="#ppd_profile_s">ppd_profile_s</a> ppd_profile_t;
+</p>
+<h3 class="typedef"><a name="ppd_section_t">ppd_section_t</a></h3>
+<p class="description">Order dependency sections</p>
+<p class="code">
+typedef enum <a href="#ppd_section_e">ppd_section_e</a> ppd_section_t;
+</p>
+<h3 class="typedef"><a name="ppd_size_t">ppd_size_t</a></h3>
+<p class="description">Page Sizes</p>
+<p class="code">
+typedef struct <a href="#ppd_size_s">ppd_size_s</a> ppd_size_t;
+</p>
+<h3 class="typedef"><a name="ppd_ui_t">ppd_ui_t</a></h3>
+<p class="description">UI Types</p>
+<p class="code">
+typedef enum <a href="#ppd_ui_e">ppd_ui_e</a> ppd_ui_t;
+</p>
+<h2 class="title"><a name="STRUCTURES">Structures</a></h2>
+<h3 class="struct"><span class="info">&nbsp;CUPS 1.1.19&nbsp;</span><a name="ppd_attr_s">ppd_attr_s</a></h3>
+<p class="description">PPD Attribute Structure </p>
+<p class="code">struct ppd_attr_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char name[PPD_MAX_NAME];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char spec[PPD_MAX_NAME];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char text[PPD_MAX_TEXT];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *value;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>name[PPD_MAX_NAME] </dt>
+<dd class="description">Name of attribute (cupsXYZ)</dd>
+<dt>spec[PPD_MAX_NAME] </dt>
+<dd class="description">Specifier string, if any</dd>
+<dt>text[PPD_MAX_TEXT] </dt>
+<dd class="description">Human-readable text, if any</dd>
+<dt>value </dt>
+<dd class="description">Value string</dd>
+</dl>
+<h3 class="struct"><a name="ppd_choice_s">ppd_choice_s</a></h3>
+<p class="description">Option choices</p>
+<p class="code">struct ppd_choice_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char choice[PPD_MAX_NAME];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *code;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char marked;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_option_t">ppd_option_t</a> *option;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char text[PPD_MAX_TEXT];<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>choice[PPD_MAX_NAME] </dt>
+<dd class="description">Computer-readable option name</dd>
+<dt>code </dt>
+<dd class="description">Code to send for this option</dd>
+<dt>marked </dt>
+<dd class="description">0 if not selected, 1 otherwise</dd>
+<dt>option </dt>
+<dd class="description">Pointer to parent option structure</dd>
+<dt>text[PPD_MAX_TEXT] </dt>
+<dd class="description">Human-readable option name</dd>
+</dl>
+<h3 class="struct"><a name="ppd_const_s">ppd_const_s</a></h3>
+<p class="description">Constraints</p>
+<p class="code">struct ppd_const_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char choice1[PPD_MAX_NAME];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char choice2[PPD_MAX_NAME];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char option1[PPD_MAX_NAME];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char option2[PPD_MAX_NAME];<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>choice1[PPD_MAX_NAME] </dt>
+<dd class="description">First option/choice (blank for all)</dd>
+<dt>choice2[PPD_MAX_NAME] </dt>
+<dd class="description">Second option/choice (blank for all)</dd>
+<dt>option1[PPD_MAX_NAME] </dt>
+<dd class="description">First keyword</dd>
+<dt>option2[PPD_MAX_NAME] </dt>
+<dd class="description">Second keyword</dd>
+</dl>
+<h3 class="struct"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppd_coption_s">ppd_coption_s</a></h3>
+<p class="description">Custom Option </p>
+<p class="code">struct ppd_coption_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char keyword[PPD_MAX_NAME];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int marked;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_option_t">ppd_option_t</a> *option;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_array_t *params;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>keyword[PPD_MAX_NAME] </dt>
+<dd class="description">Name of option that is being extended...</dd>
+<dt>marked </dt>
+<dd class="description">Extended option is marked</dd>
+<dt>option </dt>
+<dd class="description">Option that is being extended...</dd>
+<dt>params </dt>
+<dd class="description">Parameters</dd>
+</dl>
+<h3 class="struct"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppd_cparam_s">ppd_cparam_s</a></h3>
+<p class="description">Custom Parameter </p>
+<p class="code">struct ppd_cparam_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_cpvalue_t">ppd_cpvalue_t</a> current;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_cplimit_t">ppd_cplimit_t</a> minimum, maximum;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char name[PPD_MAX_NAME];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int order;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char text[PPD_MAX_TEXT];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_cptype_t">ppd_cptype_t</a> type;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>current </dt>
+<dd class="description">Current value</dd>
+<dt>maximum </dt>
+<dd class="description">Maximum value</dd>
+<dt>name[PPD_MAX_NAME] </dt>
+<dd class="description">Parameter name</dd>
+<dt>order </dt>
+<dd class="description">Order (0 to N)</dd>
+<dt>text[PPD_MAX_TEXT] </dt>
+<dd class="description">Human-readable text</dd>
+<dt>type </dt>
+<dd class="description">Parameter type</dd>
+</dl>
+<h3 class="struct"><a name="ppd_emul_s">ppd_emul_s</a></h3>
+<p class="description">Emulators</p>
+<p class="code">struct ppd_emul_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char name[PPD_MAX_NAME];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *start;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *stop;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>name[PPD_MAX_NAME] </dt>
+<dd class="description">Emulator name</dd>
+<dt>start </dt>
+<dd class="description">Code to switch to this emulation</dd>
+<dt>stop </dt>
+<dd class="description">Code to stop this emulation</dd>
+</dl>
+<h3 class="struct"><a name="ppd_file_s">ppd_file_s</a></h3>
+<p class="description">PPD File</p>
+<p class="code">struct ppd_file_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int accurate_screens;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int color_device;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ppd_cs_t colorspace;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_const_t">ppd_const_t</a> *consts;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int contone_only;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float custom_margins[4];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float custom_max[2];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float custom_min[2];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_emul_t">ppd_emul_t</a> *emulations;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char **filters;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int flip_duplex;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char **fonts;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_group_t">ppd_group_t</a> *groups;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *jcl_begin;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *jcl_end;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *jcl_ps;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int landscape;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *lang_encoding;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *lang_version;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int language_level;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int manual_copies;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *manufacturer;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int model_number;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *modelname;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *nickname;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_consts;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_emulations;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_filters;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_fonts;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_groups;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_profiles;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_sizes;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *patches;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *pcfilename;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *product;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_profile_t">ppd_profile_t</a> *profiles;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *protocols;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *shortnickname;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_size_t">ppd_size_t</a> *sizes;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int throughput;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *ttrasterizer;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int variable_sizes;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>accurate_screens </dt>
+<dd class="description">1 = supports accurate screens, 0 = not</dd>
+<dt>color_device </dt>
+<dd class="description">1 = color device, 0 = grayscale</dd>
+<dt>colorspace </dt>
+<dd class="description">Default colorspace</dd>
+<dt>consts </dt>
+<dd class="description">UI/Non-UI constraints</dd>
+<dt>contone_only </dt>
+<dd class="description">1 = continuous tone only, 0 = not</dd>
+<dt>custom_margins[4] </dt>
+<dd class="description">Margins around page</dd>
+<dt>custom_max[2] </dt>
+<dd class="description">Maximum variable page size</dd>
+<dt>custom_min[2] </dt>
+<dd class="description">Minimum variable page size</dd>
+<dt>emulations </dt>
+<dd class="description">Emulations and the code to invoke them</dd>
+<dt>filters </dt>
+<dd class="description">Filter strings...</dd>
+<dt>flip_duplex <span class="info">&nbsp;DEPRECATED&nbsp;</span></dt>
+<dd class="description">1 = Flip page for back sides </dd>
+<dt>fonts </dt>
+<dd class="description">Pre-loaded fonts</dd>
+<dt>groups </dt>
+<dd class="description">UI groups</dd>
+<dt>jcl_begin </dt>
+<dd class="description">Start JCL commands</dd>
+<dt>jcl_end </dt>
+<dd class="description">End JCL commands</dd>
+<dt>jcl_ps </dt>
+<dd class="description">Enter PostScript interpreter</dd>
+<dt>landscape </dt>
+<dd class="description">-90 or 90</dd>
+<dt>lang_encoding </dt>
+<dd class="description">Language encoding</dd>
+<dt>lang_version </dt>
+<dd class="description">Language version (English, Spanish, etc.)</dd>
+<dt>language_level </dt>
+<dd class="description">Language level of device</dd>
+<dt>manual_copies </dt>
+<dd class="description">1 = Copies done manually, 0 = hardware</dd>
+<dt>manufacturer </dt>
+<dd class="description">Manufacturer name</dd>
+<dt>model_number </dt>
+<dd class="description">Device-specific model number</dd>
+<dt>modelname </dt>
+<dd class="description">Model name (general)</dd>
+<dt>nickname </dt>
+<dd class="description">Nickname (specific)</dd>
+<dt>num_consts </dt>
+<dd class="description">Number of UI/Non-UI constraints</dd>
+<dt>num_emulations </dt>
+<dd class="description">Number of emulations supported</dd>
+<dt>num_filters </dt>
+<dd class="description">Number of filters</dd>
+<dt>num_fonts </dt>
+<dd class="description">Number of pre-loaded fonts</dd>
+<dt>num_groups </dt>
+<dd class="description">Number of UI groups</dd>
+<dt>num_profiles </dt>
+<dd class="description">Number of sRGB color profiles</dd>
+<dt>num_sizes </dt>
+<dd class="description">Number of page sizes</dd>
+<dt>patches </dt>
+<dd class="description">Patch commands to be sent to printer</dd>
+<dt>pcfilename <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">PCFileName string </dd>
+<dt>product </dt>
+<dd class="description">Product name (from PS RIP/interpreter)</dd>
+<dt>profiles </dt>
+<dd class="description">sRGB color profiles</dd>
+<dt>protocols <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">Protocols (BCP, TBCP) string </dd>
+<dt>shortnickname </dt>
+<dd class="description">Short version of nickname</dd>
+<dt>sizes </dt>
+<dd class="description">Page sizes</dd>
+<dt>throughput </dt>
+<dd class="description">Pages per minute</dd>
+<dt>ttrasterizer </dt>
+<dd class="description">Truetype rasterizer</dd>
+<dt>variable_sizes </dt>
+<dd class="description">1 = supports variable sizes, 0 = doesn't</dd>
+</dl>
+<h3 class="struct"><a name="ppd_group_s">ppd_group_s</a></h3>
+<p class="description">Groups</p>
+<p class="code">struct ppd_group_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char text[PPD_MAX_TEXT - PPD_MAX_NAME];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char name[PPD_MAX_NAME];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_options;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_subgroups;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_option_t">ppd_option_t</a> *options;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;struct <a href="#ppd_group_s">ppd_group_s</a> *subgroups;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>PPD_MAX_NAME] </dt>
+<dd class="description">Human-readable group name</dd>
+<dt>name[PPD_MAX_NAME] <span class="info">&nbsp;CUPS 1.1.18&nbsp;</span></dt>
+<dd class="description">Group name </dd>
+<dt>num_options </dt>
+<dd class="description">Number of options</dd>
+<dt>num_subgroups </dt>
+<dd class="description">Number of sub-groups</dd>
+<dt>options </dt>
+<dd class="description">Options</dd>
+<dt>subgroups </dt>
+<dd class="description">Sub-groups (max depth = 1)</dd>
+</dl>
+<h3 class="struct"><a name="ppd_option_s">ppd_option_s</a></h3>
+<p class="description">Options</p>
+<p class="code">struct ppd_option_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_choice_t">ppd_choice_t</a> *choices;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char conflicted;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char defchoice[PPD_MAX_NAME];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char keyword[PPD_MAX_NAME];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_choices;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float order;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_section_t">ppd_section_t</a> section;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char text[PPD_MAX_TEXT];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ppd_ui_t">ppd_ui_t</a> ui;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>choices </dt>
+<dd class="description">Option choices</dd>
+<dt>conflicted </dt>
+<dd class="description">0 if no conflicts exist, 1 otherwise</dd>
+<dt>defchoice[PPD_MAX_NAME] </dt>
+<dd class="description">Default option choice</dd>
+<dt>keyword[PPD_MAX_NAME] </dt>
+<dd class="description">Option keyword name (&quot;PageSize&quot;, etc.)</dd>
+<dt>num_choices </dt>
+<dd class="description">Number of option choices</dd>
+<dt>order </dt>
+<dd class="description">Order number</dd>
+<dt>section </dt>
+<dd class="description">Section for command</dd>
+<dt>text[PPD_MAX_TEXT] </dt>
+<dd class="description">Human-readable text</dd>
+<dt>ui </dt>
+<dd class="description">Type of UI option</dd>
+</dl>
+<h3 class="struct"><a name="ppd_profile_s">ppd_profile_s</a></h3>
+<p class="description">sRGB Color Profiles</p>
+<p class="code">struct ppd_profile_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float density;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float gamma;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float matrix[3][3];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char media_type[PPD_MAX_NAME];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char resolution[PPD_MAX_NAME];<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>density </dt>
+<dd class="description">Ink density to use</dd>
+<dt>gamma </dt>
+<dd class="description">Gamma correction to use</dd>
+<dt>matrix[3][3] </dt>
+<dd class="description">Transform matrix</dd>
+<dt>media_type[PPD_MAX_NAME] </dt>
+<dd class="description">Media type or &quot;-&quot;</dd>
+<dt>resolution[PPD_MAX_NAME] </dt>
+<dd class="description">Resolution or &quot;-&quot;</dd>
+</dl>
+<h3 class="struct"><a name="ppd_size_s">ppd_size_s</a></h3>
+<p class="description">Page Sizes</p>
+<p class="code">struct ppd_size_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float bottom;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float left;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float length;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int marked;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char name[PPD_MAX_NAME];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float right;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float top;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float width;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>bottom </dt>
+<dd class="description">Bottom printable margin in points</dd>
+<dt>left </dt>
+<dd class="description">Left printable margin in points</dd>
+<dt>length </dt>
+<dd class="description">Length of media in points</dd>
+<dt>marked </dt>
+<dd class="description">Page size selected?</dd>
+<dt>name[PPD_MAX_NAME] </dt>
+<dd class="description">Media size option</dd>
+<dt>right </dt>
+<dd class="description">Right printable margin in points</dd>
+<dt>top </dt>
+<dd class="description">Top printable margin in points</dd>
+<dt>width </dt>
+<dd class="description">Width of media in points</dd>
+</dl>
+<h2 class="title"><a name="UNIONS">Unions</a></h2>
+<h3 class="union"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppd_cplimit_u">ppd_cplimit_u</a></h3>
+<p class="description">Custom Parameter Limit </p>
+<p class="code">union ppd_cplimit_u {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float custom_curve;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int custom_int;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float custom_invcurve;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int custom_passcode;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int custom_password;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float custom_points;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float custom_real;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int custom_string;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>custom_curve </dt>
+<dd class="description">Gamma value</dd>
+<dt>custom_int </dt>
+<dd class="description">Integer value</dd>
+<dt>custom_invcurve </dt>
+<dd class="description">Gamma value</dd>
+<dt>custom_passcode </dt>
+<dd class="description">Passcode length</dd>
+<dt>custom_password </dt>
+<dd class="description">Password length</dd>
+<dt>custom_points </dt>
+<dd class="description">Measurement value</dd>
+<dt>custom_real </dt>
+<dd class="description">Real value</dd>
+<dt>custom_string </dt>
+<dd class="description">String length</dd>
+</dl>
+<h3 class="union"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppd_cpvalue_u">ppd_cpvalue_u</a></h3>
+<p class="description">Custom Parameter Value </p>
+<p class="code">union ppd_cpvalue_u {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float custom_curve;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int custom_int;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float custom_invcurve;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *custom_passcode;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *custom_password;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float custom_points;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float custom_real;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *custom_string;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>custom_curve </dt>
+<dd class="description">Gamma value</dd>
+<dt>custom_int </dt>
+<dd class="description">Integer value</dd>
+<dt>custom_invcurve </dt>
+<dd class="description">Gamma value</dd>
+<dt>custom_passcode </dt>
+<dd class="description">Passcode value</dd>
+<dt>custom_password </dt>
+<dd class="description">Password value</dd>
+<dt>custom_points </dt>
+<dd class="description">Measurement value</dd>
+<dt>custom_real </dt>
+<dd class="description">Real value</dd>
+<dt>custom_string </dt>
+<dd class="description">String value</dd>
+</dl>
+<h2 class="title"><a name="ENUMERATIONS">Constants</a></h2>
+<h3 class="enumeration"><a name="ppd_conform_e">ppd_conform_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>PPD_CONFORM_RELAXED </dt>
+<dd class="description">Relax whitespace and control char</dd>
+<dt>PPD_CONFORM_STRICT </dt>
+<dd class="description">Require strict conformance</dd>
+</dl>
+<h3 class="enumeration"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="ppd_cptype_e">ppd_cptype_e</a></h3>
+<p class="description">Custom Parameter Type </p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>PPD_CUSTOM_CURVE </dt>
+<dd class="description">Curve value for f(x) = x^value</dd>
+<dt>PPD_CUSTOM_INT </dt>
+<dd class="description">Integer number value</dd>
+<dt>PPD_CUSTOM_INVCURVE </dt>
+<dd class="description">Curve value for f(x) = x^(1/value)</dd>
+<dt>PPD_CUSTOM_PASSCODE </dt>
+<dd class="description">String of (hidden) numbers</dd>
+<dt>PPD_CUSTOM_PASSWORD </dt>
+<dd class="description">String of (hidden) characters</dd>
+<dt>PPD_CUSTOM_POINTS </dt>
+<dd class="description">Measurement value in points</dd>
+<dt>PPD_CUSTOM_REAL </dt>
+<dd class="description">Real number value</dd>
+<dt>PPD_CUSTOM_STRING </dt>
+<dd class="description">String of characters</dd>
+</dl>
+<h3 class="enumeration"><a name="ppd_cs_e">ppd_cs_e</a></h3>
+<p class="description">Colorspaces</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>PPD_CS_CMY </dt>
+<dd class="description">CMY colorspace</dd>
+<dt>PPD_CS_CMYK </dt>
+<dd class="description">CMYK colorspace</dd>
+<dt>PPD_CS_GRAY </dt>
+<dd class="description">Grayscale colorspace</dd>
+<dt>PPD_CS_N </dt>
+<dd class="description">DeviceN colorspace</dd>
+<dt>PPD_CS_RGB </dt>
+<dd class="description">RGB colorspace</dd>
+<dt>PPD_CS_RGBK </dt>
+<dd class="description">RGBK (K = gray) colorspace</dd>
+</dl>
+<h3 class="enumeration"><a name="ppd_section_e">ppd_section_e</a></h3>
+<p class="description">Order dependency sections</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>PPD_ORDER_ANY </dt>
+<dd class="description">Option code can be anywhere in the file</dd>
+<dt>PPD_ORDER_DOCUMENT </dt>
+<dd class="description">... must be in the DocumentSetup section</dd>
+<dt>PPD_ORDER_EXIT </dt>
+<dd class="description">... must be sent prior to the document</dd>
+<dt>PPD_ORDER_JCL </dt>
+<dd class="description">... must be sent as a JCL command</dd>
+<dt>PPD_ORDER_PAGE </dt>
+<dd class="description">... must be in the PageSetup section</dd>
+<dt>PPD_ORDER_PROLOG </dt>
+<dd class="description">... must be in the Prolog section</dd>
+</dl>
+<h3 class="enumeration"><a name="ppd_status_e">ppd_status_e</a></h3>
+<p class="description">Types and structures...</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>PPD_ALLOC_ERROR </dt>
+<dd class="description">Memory allocation error</dd>
+<dt>PPD_BAD_CUSTOM_PARAM </dt>
+<dd class="description">Bad custom parameter</dd>
+<dt>PPD_BAD_OPEN_GROUP </dt>
+<dd class="description">Bad OpenGroup</dd>
+<dt>PPD_BAD_OPEN_UI </dt>
+<dd class="description">Bad OpenUI/JCLOpenUI</dd>
+<dt>PPD_BAD_ORDER_DEPENDENCY </dt>
+<dd class="description">Bad OrderDependency</dd>
+<dt>PPD_BAD_UI_CONSTRAINTS </dt>
+<dd class="description">Bad UIConstraints</dd>
+<dt>PPD_FILE_OPEN_ERROR </dt>
+<dd class="description">Unable to open PPD file</dd>
+<dt>PPD_ILLEGAL_CHARACTER </dt>
+<dd class="description">Illegal control character</dd>
+<dt>PPD_ILLEGAL_MAIN_KEYWORD </dt>
+<dd class="description">Illegal main keyword string</dd>
+<dt>PPD_ILLEGAL_OPTION_KEYWORD </dt>
+<dd class="description">Illegal option keyword string</dd>
+<dt>PPD_ILLEGAL_TRANSLATION </dt>
+<dd class="description">Illegal translation string</dd>
+<dt>PPD_ILLEGAL_WHITESPACE </dt>
+<dd class="description">Illegal whitespace character</dd>
+<dt>PPD_INTERNAL_ERROR </dt>
+<dd class="description">Internal error</dd>
+<dt>PPD_LINE_TOO_LONG </dt>
+<dd class="description">Line longer than 255 chars</dd>
+<dt>PPD_MISSING_ASTERISK </dt>
+<dd class="description">Missing asterisk in column 0</dd>
+<dt>PPD_MISSING_PPDADOBE4 </dt>
+<dd class="description">Missing PPD-Adobe-4.x header</dd>
+<dt>PPD_MISSING_VALUE </dt>
+<dd class="description">Missing value string</dd>
+<dt>PPD_NESTED_OPEN_GROUP </dt>
+<dd class="description">OpenGroup without a CloseGroup first</dd>
+<dt>PPD_NESTED_OPEN_UI </dt>
+<dd class="description">OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first</dd>
+<dt>PPD_NULL_FILE </dt>
+<dd class="description">NULL PPD file pointer</dd>
+<dt>PPD_OK </dt>
+<dd class="description">OK</dd>
+</dl>
+<h3 class="enumeration"><a name="ppd_ui_e">ppd_ui_e</a></h3>
+<p class="description">UI Types</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>PPD_UI_BOOLEAN </dt>
+<dd class="description">True or False option</dd>
+<dt>PPD_UI_PICKMANY </dt>
+<dd class="description">Pick zero or more from a list</dd>
+<dt>PPD_UI_PICKONE </dt>
+<dd class="description">Pick one from a list</dd>
+</dl>
+</div>
 </body>
 </html>
index 4ffde1100d0d538311b43117750d681536fd80d2..f9010c93365976c43afb20d3f9439f37ff914db3 100644 (file)
 <html>
 <!-- SECTION: Programming -->
 <head>
-       <title>Raster API</title>
-       <meta name='keywords' content='Programming'>
-       <meta name='creator' content='Mini-XML v2.3'>
-       <style type='text/css'><!--
-       h1, h2, h3, p { font-family: sans-serif; text-align: justify; }
-       tt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }
-       pre { font-weight: bold; color: #7f0000; margin-left: 2em; }
-       span.info { background: #000000; border: solid thin #000000; color: #ffffff; font-size: 80%; font-style: italic; font-weight: bold; white-space: nowrap; }
-       h3 span.info { float: right; font-size: 100%; }
-       h1.title, h2.title, h3.title { border-bottom: solid 2px #000000; }
-       --></style>
+<title>Raster API</title>
+<meta name="keywords" content="Programming">
+<meta name="creator" content="Mini-XML v2.5">
+<style type="text/css"><!--
+BODY {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+H1, H2, H3, H4, H5, H6, P, TD, TH {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+KBD {
+  font-family: monaco, courier, monospace;
+  font-weight: bold;
+}
+
+PRE {
+  font-family: monaco, courier, monospace;
+}
+
+PRE.command {
+  margin-left: 36pt;
+}
+
+PRE.example {
+  background: #eeeeee;
+  border: dotted thin #999999;
+  margin-left: 36pt;
+  padding: 10px;
+}
+
+PRE.command EM, PRE.example EM {
+  font-family: lucida grande, geneva, helvetica, arial, sans-serif;
+}
+
+P.command {
+  font-family: monaco, courier, monospace;
+  margin-left: 36pt;
+}
+
+P.formula {
+  font-style: italic;
+  margin-left: 36pt;
+}
+
+BLOCKQUOTE {
+  background: #cccccc;
+  border: solid thin #999999;
+  padding: 10pt;
+}
+
+A:link, A:visited {
+  text-decoration: none;
+  font-weight: bold;
+}
+
+A:link:hover, A:visited:hover, A:active {
+  text-decoration: underline;
+  font-weight: bold;
+}
+
+SUB, SUP {
+  font-size: 50%;
+}
+
+DIV.table TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.table CAPTION {
+  caption-side: top;
+  font-size: 120%;
+  font-style: italic;
+  font-weight: bold;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.table TABLE TD {
+  border: solid thin #cccccc;
+  padding-top: 5pt;
+}
+
+DIV.table TABLE TH {
+  background: #cccccc;
+  border: none;
+  border-bottom: solid thin #999999;
+}
+
+DIV.figure TABLE {
+  margin-left: auto;
+  margin-right: auto;
+}
+
+DIV.figure CAPTION {
+  caption-side: bottom;
+  font-size: 120%;
+  font-style: italic;
+  font-weight: bold;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+TH.label {
+  padding-top: 5pt;
+  text-align: right;
+  vertical-align: top;
+}
+
+HR {
+  border: solid thin;
+}
+
+SPAN.info {
+  background: #000000;
+  border: thin solid #000000;
+  color: #ffffff;
+  font-size: 80%;
+  font-style: italic;
+  font-weight: bold;
+  white-space: nowrap;
+}
+
+H2 SPAN.info, H3 SPAN.info, H4 SPAN.info {
+  float: right;
+  font-size: 100%;
+}
+
+H2.title, H3.title {
+  border-bottom: solid 2pt #000000;
+}
+
+DT {
+  margin-left: 36pt;
+  margin-top: 12pt;
+}
+
+DD {
+  margin-left: 54pt;
+}
+
+DL.category DT {
+  font-weight: bold;
+}
+
+P.summary {
+  margin-left: 36pt;
+  font-family: monaco, courier, monospace;
+}
+
+SPAN.message {
+  font-style: italic;
+  font-size: smaller;
+}
+
+DIV.summary TABLE {
+  border: solid thin #999999;
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin: 10px;
+}
+
+DIV.summary TABLE TD, DIV.summary TABLE TH {
+  border: solid thin #999999;
+  padding: 5px;
+  text-align: left;
+  vertical-align: top;
+}
+
+DIV.summary TABLE THEAD TH {
+  background: #eeeeee;
+}
+
+/* API documentation styles... */
+div.body h1 {
+  margin: 0;
+}
+div.body h2 {
+  margin-top: 1.5em;
+}
+div.body h3, div.body h4, div.body h5 {
+  margin-bottom: 0.5em;
+  margin-top: 1.5em;
+}
+.class, .enumeration, .function, .struct, .typedef, .union {
+  border-bottom: solid thin #999999;
+  margin-bottom: 0;
+  margin-top: 2em;
+}
+.description {
+  margin-top: 0.5em;
+}
+code, p.code, pre, ul.code li {
+  font-family: monaco, courier, monospace;
+  font-size: 90%;
+}
+ul.code, ul.contents, ul.subcontents {
+  list-style-type: none;
+  margin: 0;
+  padding-left: 0;
+}
+ul.code li {
+  margin: 0;
+}
+ul.contents > li {
+  margin-top: 1em;
+}
+ul.contents li ul.code, ul.contents li ul.subcontents {
+  padding-left: 2em;
+}
+div.body dl {
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dt {
+  font-style: italic;
+  margin-left: 0;
+  margin-top: 0;
+}
+div.body dd {
+  margin-bottom: 0.5em;
+}
+
+/* This is just for the HTML files generated with the framedhelp target */
+div.contents {
+  background: #e8e8e8;
+  border: solid thin black;
+  padding: 10px;
+}
+div.contents h1 {
+  font-size: 110%;
+}
+div.contents h2 {
+  font-size: 100%;
+}
+div.contents ul.contents {
+  font-size: 80%;
+}
+--></style>
 </head>
 <body>
+<div class='body'>
+<!--
+  "$Id$"
+
+  Raster API header for the Common UNIX Printing System (CUPS).
+
+  Copyright 2008 by Apple Inc.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">Raster API</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+       <th>Header</th>
+       <th>cups/raster.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <th>Library</th>
+       <td>-lcupsimage</td>
+</tr>
+<tr>
+       <th>See Also</th>
+       <td>Programming: <a href='api-overview.html'>Introduction to CUPS Programming</a><br>
+       Programming: <a href='api-cups.html'>CUPS API</a><br>
+       Programming: <a href='api-cups.html'>PPD API</a><br>
+       References: <a href='spec-ppd.html'>CUPS PPD Specification</a></td>
+</tr>
+</tbody>
+</table></div>
+<h2 class="title">Contents</h2>
+<ul class="contents">
+</li>
+<li><a href="#OVERVIEW">Overview</a></li>
+<li><a href="#FUNCTIONS">Functions</a><ul class="code">
+<li><a href="#cupsRasterClose" title="Close a raster stream.">cupsRasterClose</a></li>
+<li><a href="#cupsRasterInterpretPPD" title="Interpret PPD commands to create a page header.">cupsRasterInterpretPPD</a></li>
+<li><a href="#cupsRasterOpen" title="Open a raster stream.">cupsRasterOpen</a></li>
+<li><a href="#cupsRasterReadHeader" title="Read a raster page header and store it in a
+V1 page header structure.">cupsRasterReadHeader</a></li>
+<li><a href="#cupsRasterReadHeader2" title="Read a raster page header and store it in a
+V2 page header structure.">cupsRasterReadHeader2</a></li>
+<li><a href="#cupsRasterReadPixels" title="Read raster pixels.">cupsRasterReadPixels</a></li>
+<li><a href="#cupsRasterWriteHeader" title="Write a raster page header from a V1 page
+header structure.">cupsRasterWriteHeader</a></li>
+<li><a href="#cupsRasterWriteHeader2" title="Write a raster page header from a V2 page
+header structure.">cupsRasterWriteHeader2</a></li>
+<li><a href="#cupsRasterWritePixels" title="Write raster pixels.">cupsRasterWritePixels</a></li>
+</ul>
+<li><a href="#TYPES">Data Types</a><ul class="code">
+       <li><a href="#cups_interpret_cb_t" title="cupsRasterInterpretPPD callback function">cups_interpret_cb_t</a></li>
+       <li><a href="#cups_mode_t" title="cupsRasterOpen modes">cups_mode_t</a></li>
+       <li><a href="#cups_page_header2_t" title="Version 2 page header ">cups_page_header2_t</a></li>
+       <li><a href="#cups_page_header_t" title="Version 1 page header">cups_page_header_t</a></li>
+       <li><a href="#cups_raster_t" title="Raster stream data">cups_raster_t</a></li>
+</ul></li>
+<li><a href="#STRUCTURES">Structures</a><ul class="code">
+       <li><a href="#cups_page_header2_s" title="Version 2 page header ">cups_page_header2_s</a></li>
+       <li><a href="#cups_page_header_s" title="Version 1 page header">cups_page_header_s</a></li>
+</ul></li>
+<li><a href="#ENUMERATIONS">Constants</a><ul class="code">
+       <li><a href="#cups_adv_e" title="AdvanceMedia attribute values">cups_adv_e</a></li>
+       <li><a href="#cups_bool_e" title="Types...">cups_bool_e</a></li>
+       <li><a href="#cups_cspace_e" title="">cups_cspace_e</a></li>
+       <li><a href="#cups_cut_e" title="">cups_cut_e</a></li>
+       <li><a href="#cups_edge_e" title="">cups_edge_e</a></li>
+       <li><a href="#cups_jog_e" title="">cups_jog_e</a></li>
+       <li><a href="#cups_mode_e" title="">cups_mode_e</a></li>
+       <li><a href="#cups_order_e" title="cupsColorOrder attribute values">cups_order_e</a></li>
+       <li><a href="#cups_orient_e" title="">cups_orient_e</a></li>
+</ul></li>
+</ul>
 <!--
   "$Id$"
 
   Raster API introduction for the Common UNIX Printing System (CUPS).
 
-  Copyright 1997-2006 by Easy Software Products.
+  Copyright 2007-2008 by Apple Inc.
+  Copyright 1997-2006 by Easy Software Products, all rights reserved.
 
   These coded instructions, statements, and computer programs are the
-  property of Easy Software Products and are protected by Federal
-  copyright law.  Distribution and use rights are outlined in the file
-  "LICENSE.txt" which should have been included with this file.  If this
-  file is missing or damaged please contact Easy Software Products
-  at:
-
-      Attn: CUPS Licensing Information
-      Easy Software Products
-      44141 Airport View Drive, Suite 204
-      Hollywood, Maryland 20636 USA
-
-      Voice: (301) 373-9600
-      EMail: cups-info@cups.org
-       WWW: http://www.cups.org
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
 -->
 
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name="OVERVIEW">Overview</a></h2>
+
+<p>The CUPS raster API provides a standard interface for reading and writing
+CUPS raster streams which are used for printing to raster printers. Because the
+raster format is updated from time to time, it is important to use this API to
+avoid incompatibilities with newer versions of CUPS.</p>
+
+<p>CUPS raster files (<code>application/vnd.cups-raster</code>) consists of
+a stream of raster page descriptions produced by one of the RIP filters such as
+<var>pstoraster</var>, <var>imagetoraster</var>, or
+<var>cgpdftoraster</var>. CUPS raster files are referred to using the
+<a href='#cups_raster_t'><code>cups_raster_t</code></a> type and are
+opened using the <a href='#cupsRasterOpen'><code>cupsRasterOpen</code></a>
+function. For example, to read raster data from the standard input, open
+file descriptor 0:</p>
+
+<pre class="example">
+#include &lt;cups/raster.h&gt;>
+
+<a href="#cups_raster_t">cups_raster_t</a> *ras = <a href="#cupsRasterOpen">cupsRasterOpen</a>(0, CUPS_RASTER_READ);
+</pre>
 
-<p>The CUPS raster API provides a standard interface for reading
-and writing CUPS raster streams which are used for printing to
-raster printers. Because the raster format is updated from time
-to time, it is important to use this API to avoid
-incompatibilities with newer versions of CUPS.</p>
+<p>Each page of data begins with a page dictionary structure called
+<a href="#cups_page_header2_t"><code>cups_page_header2_t</code></a>. This
+structure contains the colorspace, bits per color, media size, media type,
+hardware resolution, and so forth used for the page. You read the page header
+using the
+<a href="#cupsRasterReadHeader2"><code>cupsRasterReadHeader2</code></a>
+function:</p>
 
-<h2 class='title'>General Usage</h2>
+<pre class="example">
+#include &lt;cups/raster.h&gt;>
 
-<p>The <var>&lt;cups/raster.h&gt;</var> header file must be
-included to use the <tt>cupsRaster</tt> functions.</p>
+<a href="#cups_raster_t">cups_raster_t</a> *ras = <a href="#cupsRasterOpen">cupsRasterOpen</a>(0, CUPS_RASTER_READ);
+<a href="#cups_page_header2_t">cups_page_header2_t</a> header;
 
-<p>Programs using these functions must be linked to the CUPS
-imaging library: <var>libcupsimage.a</var>,
-<var>libcupsimage.so.2</var>, <var>libcupsimage.2.dylib</var>,
-<var>libcupsimage_s.a</var>, or <var>libcupsimage2.lib</var>
-depending on the platform. The following command compiles
-<var>myprogram.c</var> using GCC and the CUPS imaging
-library:</p>
+while (<a href="#cupsRasterReadHeader2">cupsRasterReadHeader2</a>(ras, &amp;header))
+{
+  /* setup this page */
 
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcupsimage</kbd>
+  /* read raster data */
+
+  /* finish this page */
+}
 </pre>
 
-<h2 class='title'>Compatibility</h2>
+<p>After the page dictionary comes the page data which is a full-resolution,
+possibly compressed bitmap representing the page in the printer's output
+colorspace. You read uncompressed raster data using the
+<a href="#cupsRasterReadPixels"><code>cupsRasterReadPixels</code></a>
+function. A <code>for</code> loop is normally used to read the page one line
+at a time:</p>
 
-<p>Unless otherwise specified, the raster API functions require
-CUPS 1.1 or higher.</p>
+<pre class="example">
+#include &lt;cups/raster.h&gt;>
 
-<h2 class='title'>Licensing</h2>
+<a href="#cups_raster_t">cups_raster_t</a> *ras = <a href="#cupsRasterOpen">cupsRasterOpen</a>(0, CUPS_RASTER_READ);
+<a href="#cups_page_header2_t">cups_page_header2_t</a> header;
+int page = 0;
+int y;
+char *buffer;
 
-<p>The CUPS raster API is provided under the terms of the GNU
-Library General Public License, with exceptions for MacOS X-based
-programs. Please see the CUPS license agreement for more
-information.</p>
-<h2 class='title'>Contents</h2>
-<ul>
-       <li><a href='#ENUMERATIONS'>Enumerations</a></li>
-       <li><a href='#FUNCTIONS'>Functions</a></li>
-       <li><a href='#STRUCTURES'>Structures</a></li>
-       <li><a href='#TYPES'>Types</a></li>
-</ul>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='ENUMERATIONS'>Enumerations</a></h2>
-<ul>
-       <li><a href='#cups_adv_e'><tt>cups_adv_e</tt></a> </li>
-       <li><a href='#cups_bool_e'><tt>cups_bool_e</tt></a> </li>
-       <li><a href='#cups_cspace_e'><tt>cups_cspace_e</tt></a> </li>
-       <li><a href='#cups_cut_e'><tt>cups_cut_e</tt></a> </li>
-       <li><a href='#cups_edge_e'><tt>cups_edge_e</tt></a> </li>
-       <li><a href='#cups_jog_e'><tt>cups_jog_e</tt></a> </li>
-       <li><a href='#cups_mode_e'><tt>cups_mode_e</tt></a> </li>
-       <li><a href='#cups_order_e'><tt>cups_order_e</tt></a> </li>
-       <li><a href='#cups_orient_e'><tt>cups_orient_e</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_adv_e'>cups_adv_e</a></h3>
-<h4>Description</h4>
-<p>AdvanceMedia attribute values
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>CUPS_ADVANCE_FILE</tt> </td><td>Advance the roll after this file
-</td></tr>
-<tr><td><tt>CUPS_ADVANCE_JOB</tt> </td><td>Advance the roll after this job
-</td></tr>
-<tr><td><tt>CUPS_ADVANCE_NONE</tt> </td><td>Never advance the roll
-</td></tr>
-<tr><td><tt>CUPS_ADVANCE_PAGE</tt> </td><td>Advance the roll after this page
-</td></tr>
-<tr><td><tt>CUPS_ADVANCE_SET</tt> </td><td>Advance the roll after this set
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_bool_e'>cups_bool_e</a></h3>
-<h4>Description</h4>
-<p>Types...
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>CUPS_FALSE</tt> </td><td>Logical false
-</td></tr>
-<tr><td><tt>CUPS_TRUE</tt> </td><td>Logical true
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_cspace_e'>cups_cspace_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>CUPS_CSPACE_CIELab</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>CIE Lab 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_CIEXYZ</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>CIE XYZ 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_CMY</tt> </td><td>Cyan, magenta, yellow
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_CMYK</tt> </td><td>Cyan, magenta, yellow, black
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_GMCK</tt> </td><td>Gold, magenta, yellow, black
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_GMCS</tt> </td><td>Gold, magenta, yellow, silver
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_GOLD</tt> </td><td>Gold foil
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_ICC1</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>ICC-based, 1 color 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_ICC2</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>ICC-based, 2 colors 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_ICC3</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>ICC-based, 3 colors 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_ICC4</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>ICC-based, 4 colors 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_ICC5</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>ICC-based, 5 colors 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_ICC6</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>ICC-based, 6 colors 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_ICC7</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>ICC-based, 7 colors 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_ICC8</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>ICC-based, 8 colors 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_ICC9</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>ICC-based, 9 colors 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_ICCA</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>ICC-based, 10 colors 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_ICCB</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>ICC-based, 11 colors 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_ICCC</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>ICC-based, 12 colors 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_ICCD</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>ICC-based, 13 colors 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_ICCE</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>ICC-based, 14 colors 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_ICCF</tt> <span class='info'>&nbsp;CUPS 1.1.19&nbsp;</span></td><td>ICC-based, 15 colors 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_K</tt> </td><td>Black
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_KCMY</tt> </td><td>Black, cyan, magenta, yellow
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_KCMYcm</tt> </td><td>Black, cyan, magenta, yellow, *
-light-cyan, light-magenta
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_RGB</tt> </td><td>Red, green, blue
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_RGBA</tt> </td><td>Red, green, blue, alpha
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_RGBW</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Red, green, blue, white 
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_SILVER</tt> </td><td>Silver foil
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_W</tt> </td><td>Luminance
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_WHITE</tt> </td><td>White ink (as black)
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_YMC</tt> </td><td>Yellow, magenta, cyan
-</td></tr>
-<tr><td><tt>CUPS_CSPACE_YMCK</tt> </td><td>Yellow, magenta, cyan, black
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_cut_e'>cups_cut_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>CUPS_CUT_FILE</tt> </td><td>Cut the roll after this file
-</td></tr>
-<tr><td><tt>CUPS_CUT_JOB</tt> </td><td>Cut the roll after this job
-</td></tr>
-<tr><td><tt>CUPS_CUT_NONE</tt> </td><td>Never cut the roll
-</td></tr>
-<tr><td><tt>CUPS_CUT_PAGE</tt> </td><td>Cut the roll after this page
-</td></tr>
-<tr><td><tt>CUPS_CUT_SET</tt> </td><td>Cut the roll after this set
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_edge_e'>cups_edge_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>CUPS_EDGE_BOTTOM</tt> </td><td>Leading edge is the bottom of the page
-</td></tr>
-<tr><td><tt>CUPS_EDGE_LEFT</tt> </td><td>Leading edge is the left of the page
-</td></tr>
-<tr><td><tt>CUPS_EDGE_RIGHT</tt> </td><td>Leading edge is the right of the page
-</td></tr>
-<tr><td><tt>CUPS_EDGE_TOP</tt> </td><td>Leading edge is the top of the page
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_jog_e'>cups_jog_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>CUPS_JOG_FILE</tt> </td><td>Move pages after this file
-</td></tr>
-<tr><td><tt>CUPS_JOG_JOB</tt> </td><td>Move pages after this job
-</td></tr>
-<tr><td><tt>CUPS_JOG_NONE</tt> </td><td>Never move pages
-</td></tr>
-<tr><td><tt>CUPS_JOG_SET</tt> </td><td>Move pages after this set
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_mode_e'>cups_mode_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>CUPS_RASTER_READ</tt> </td><td>Open stream for reading
-</td></tr>
-<tr><td><tt>CUPS_RASTER_WRITE</tt> </td><td>Open stream for writing
-</td></tr>
-<tr><td><tt>CUPS_RASTER_WRITE_COMPRESSED</tt> <span class='info'>&nbsp;CUPS 1.3&nbsp;</span></td><td>Open stream for compressed writing 
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_order_e'>cups_order_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>CUPS_ORDER_BANDED</tt> </td><td>CCC MMM YYY KKK ...
-</td></tr>
-<tr><td><tt>CUPS_ORDER_CHUNKED</tt> </td><td>CMYK CMYK CMYK ...
-</td></tr>
-<tr><td><tt>CUPS_ORDER_PLANAR</tt> </td><td>CCC ... MMM ... YYY ... KKK ...
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_orient_e'>cups_orient_e</a></h3>
-<h4>Description</h4>
-<p>
-<h4>Values</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Values'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>CUPS_ORIENT_0</tt> </td><td>Don't rotate the page
-</td></tr>
-<tr><td><tt>CUPS_ORIENT_180</tt> </td><td>Turn the page upside down
-</td></tr>
-<tr><td><tt>CUPS_ORIENT_270</tt> </td><td>Rotate the page clockwise
-</td></tr>
-<tr><td><tt>CUPS_ORIENT_90</tt> </td><td>Rotate the page counter-clockwise
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='FUNCTIONS'>Functions</a></h2>
-<ul>
-       <li><a href='#cupsRasterClose'><tt>cupsRasterClose()</tt></a> </li>
-       <li><a href='#cupsRasterInterpretPPD'><tt>cupsRasterInterpretPPD()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#cupsRasterOpen'><tt>cupsRasterOpen()</tt></a> </li>
-       <li><a href='#cupsRasterReadHeader'><tt>cupsRasterReadHeader()</tt></a> </li>
-       <li><a href='#cupsRasterReadHeader2'><tt>cupsRasterReadHeader2()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#cupsRasterReadPixels'><tt>cupsRasterReadPixels()</tt></a> </li>
-       <li><a href='#cupsRasterWriteHeader'><tt>cupsRasterWriteHeader()</tt></a> </li>
-       <li><a href='#cupsRasterWriteHeader2'><tt>cupsRasterWriteHeader2()</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#cupsRasterWritePixels'><tt>cupsRasterWritePixels()</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsRasterClose'>cupsRasterClose()</a></h3>
-<h4>Description</h4>
-<p>Close a raster stream.
-<h4>Syntax</h4>
-<p><tt>
-void<br>
-cupsRasterClose(
-    <a href='#cups_raster_t'>cups_raster_t</a> * r);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>r</tt></td><td>Stream to close</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Nothing.</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cupsRasterInterpretPPD'>cupsRasterInterpretPPD()</a></h3>
-<h4>Description</h4>
-<p>Interpret PPD commands to create a page header.
-<p>This function does not mark the options in the PPD using the &quot;num_options&quot;
-and &quot;options&quot; arguments.  Instead, mark the options prior to calling
-cupsRasterInterpretPPD() - this allows you to do per-page options
-without manipulating the options array.
-<p>The &quot;func&quot; argument specifies an optional callback function that is
+while (<a href="#cupsRasterReadHeader2">cupsRasterReadHeader2</a>(ras, &amp;header))
+{
+  /* setup this page */
+  page ++;
+  fprintf(stderr, "PAGE: %d %d\n", page, header.NumCopies);
+
+  /* allocate memory for 1 line */
+  buffer = malloc(header.cupsBytesPerLine);
+
+  /* read raster data */
+  for (y = 0; y &lt; header.cupsHeight; y ++)
+  {
+    if (<a href="#cupsRasterReadPixels">cupsRasterReadPixels</a>(ras, buffer, header.cupsBytesPerLine) == 0)
+      break;
+
+    /* write raster data to printer */
+  }
+
+  /* finish this page */
+}
+</pre>
+
+<p>When you are done reading the raster data, call the
+<a href="#cupsRasterClose"><code>cupsRasterClose</code></a> function to free
+the memory used to read the raster file:</p>
+
+<pre class="example">
+<a href="#cups_raster_t">cups_raster_t</a> *ras;
+
+<a href="#cupsRasterClose">cupsRasterClose</a>(ras);
+</pre>
+<h2 class="title"><a name="FUNCTIONS">Functions</a></h2>
+<h3 class="function"><a name="cupsRasterClose">cupsRasterClose</a></h3>
+<p class="description">Close a raster stream.</p>
+<p class="code">
+void cupsRasterClose (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_raster_t">cups_raster_t</a> *r<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>r</dt>
+<dd class="description">Stream to close</dd>
+</dl>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsRasterInterpretPPD">cupsRasterInterpretPPD</a></h3>
+<p class="description">Interpret PPD commands to create a page header.</p>
+<p class="code">
+int cupsRasterInterpretPPD (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_page_header2_t">cups_page_header2_t</a> *h,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ppd_file_t *ppd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_options,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_option_t *options,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_interpret_cb_t">cups_interpret_cb_t</a> func<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>h</dt>
+<dd class="description">Page header</dd>
+<dt>ppd</dt>
+<dd class="description">PPD file</dd>
+<dt>num_options</dt>
+<dd class="description">Number of options</dd>
+<dt>options</dt>
+<dd class="description">Options</dd>
+<dt>func</dt>
+<dd class="description">Optional page header callback</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, -1 on failure</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function does not mark the options in the PPD using the &quot;num_options&quot;
+and &quot;options&quot; arguments.  Instead, mark the options with
+<code>cupsMarkOptions</code> and <code>ppdMarkOption</code> prior to calling
+<code>cupsRasterInterpretPPD</code> - this allows you to do per-page options
+without manipulating the options array.<br>
+<br>
+The &quot;func&quot; argument specifies an optional callback function that is
 called prior to the computation of the final raster data.  The function
-can make changes to the cups_page_header2_t data as needed to use a
+can make changes to the <a href="#cups_page_header2_t"><code>cups_page_header2_t</code></a> data as needed to use a
 supported raster format and then returns 0 on success and -1 if the
 requested attributes cannot be supported.
-<p>cupsRasterInterpretPPD() supports a subset of the PostScript language.
-Currently only the [, ], &lt;&lt;, &gt;&gt;, {, }, cleartomark, copy, dup, index,
-pop, roll, setpagedevice, and stopped operators are supported.
-
-
-<h4>Syntax</h4>
-<p><tt>
-int<br>
-cupsRasterInterpretPPD(
-    <a href='#cups_page_header2_t'>cups_page_header2_t</a> * h,
-    ppd_file_t * ppd,
-    int num_options,
-    cups_option_t * options,
-    <a href='#cups_interpret_cb_t'>cups_interpret_cb_t</a> func);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>h</tt></td><td>Page header</td></tr>
-<tr><td><tt>ppd</tt></td><td>PPD file</td></tr>
-<tr><td><tt>num_options</tt></td><td>Number of options</td></tr>
-<tr><td><tt>options</tt></td><td>Options</td></tr>
-<tr><td><tt>func</tt></td><td>Optional page header callback</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>0 on success, -1 on failure</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsRasterOpen'>cupsRasterOpen()</a></h3>
-<h4>Description</h4>
-<p>Open a raster stream.
-<h4>Syntax</h4>
-<p><tt>
-<a href='#cups_raster_t'>cups_raster_t</a> *<br>
-cupsRasterOpen(
-    int fd,
-    cups_mode_t mode);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>fd</tt></td><td>File descriptor</td></tr>
-<tr><td><tt>mode</tt></td><td>Mode</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>New stream</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsRasterReadHeader'>cupsRasterReadHeader()</a></h3>
-<h4>Description</h4>
-<p>Read a raster page header and store it in a
-V1 page header structure.
-<h4>Syntax</h4>
-<p><tt>
-unsigned<br>
-cupsRasterReadHeader(
-    <a href='#cups_raster_t'>cups_raster_t</a> * r,
-    <a href='#cups_page_header_t'>cups_page_header_t</a> * h);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>r</tt></td><td>Raster stream</td></tr>
-<tr><td><tt>h</tt></td><td>Pointer to header data</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>1 on success, 0 on fail</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cupsRasterReadHeader2'>cupsRasterReadHeader2()</a></h3>
-<h4>Description</h4>
-<p>Read a raster page header and store it in a
-V2 page header structure.
-
-
-<h4>Syntax</h4>
-<p><tt>
-unsigned<br>
-cupsRasterReadHeader2(
-    <a href='#cups_raster_t'>cups_raster_t</a> * r,
-    <a href='#cups_page_header2_t'>cups_page_header2_t</a> * h);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>r</tt></td><td>Raster stream</td></tr>
-<tr><td><tt>h</tt></td><td>Pointer to header data</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>1 on success, 0 on fail</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsRasterReadPixels'>cupsRasterReadPixels()</a></h3>
-<h4>Description</h4>
-<p>Read raster pixels.
-<h4>Syntax</h4>
-<p><tt>
-unsigned<br>
-cupsRasterReadPixels(
-    <a href='#cups_raster_t'>cups_raster_t</a> * r,
-    unsigned char * p,
-    unsigned len);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>r</tt></td><td>Raster stream</td></tr>
-<tr><td><tt>p</tt></td><td>Pointer to pixel buffer</td></tr>
-<tr><td><tt>len</tt></td><td>Number of bytes to read</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of bytes read</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsRasterWriteHeader'>cupsRasterWriteHeader()</a></h3>
-<h4>Description</h4>
-<p>Write a raster page header from a V1 page
-header structure.
-<h4>Syntax</h4>
-<p><tt>
-unsigned<br>
-cupsRasterWriteHeader(
-    <a href='#cups_raster_t'>cups_raster_t</a> * r,
-    <a href='#cups_page_header_t'>cups_page_header_t</a> * h);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>r</tt></td><td>Raster stream</td></tr>
-<tr><td><tt>h</tt></td><td>Raster page header</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>1 on success, 0 on failure</p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cupsRasterWriteHeader2'>cupsRasterWriteHeader2()</a></h3>
-<h4>Description</h4>
-<p>Write a raster page header from a V2 page
-header structure.
-
-
-<h4>Syntax</h4>
-<p><tt>
-unsigned<br>
-cupsRasterWriteHeader2(
-    <a href='#cups_raster_t'>cups_raster_t</a> * r,
-    <a href='#cups_page_header2_t'>cups_page_header2_t</a> * h);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>r</tt></td><td>Raster stream</td></tr>
-<tr><td><tt>h</tt></td><td>Raster page header</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>1 on success, 0 on failure</p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cupsRasterWritePixels'>cupsRasterWritePixels()</a></h3>
-<h4>Description</h4>
-<p>Write raster pixels.
-<h4>Syntax</h4>
-<p><tt>
-unsigned<br>
-cupsRasterWritePixels(
-    <a href='#cups_raster_t'>cups_raster_t</a> * r,
-    unsigned char * p,
-    unsigned len);
-</tt></p>
-<h4>Arguments</h4>
-<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0' summary='Arguments'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>r</tt></td><td>Raster stream</td></tr>
-<tr><td><tt>p</tt></td><td>Bytes to write</td></tr>
-<tr><td><tt>len</tt></td><td>Number of bytes to write</td></tr>
-</tbody></table></div>
-<h4>Returns</h4>
-<p>Number of bytes written</p>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='STRUCTURES'>Structures</a></h2>
-<ul>
-       <li><a href='#cups_page_header2_s'><tt>cups_page_header2_s</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#cups_page_header_s'><tt>cups_page_header_s</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cups_page_header2_s'>cups_page_header2_s</a></h3>
-<h4>Description</h4>
-<p>Version 2 Page Header 
-<h4>Definition</h4>
-<p><tt>
-struct cups_page_header2_s<br>
-{<br>
-&nbsp;&nbsp;unsigned AdvanceDistance;<br>
-&nbsp;&nbsp;cups_adv_t AdvanceMedia;<br>
-&nbsp;&nbsp;cups_bool_t Collate;<br>
-&nbsp;&nbsp;cups_cut_t CutMedia;<br>
-&nbsp;&nbsp;cups_bool_t Duplex;<br>
-&nbsp;&nbsp;unsigned HWResolution[2];<br>
-&nbsp;&nbsp;unsigned ImagingBoundingBox[4];<br>
-&nbsp;&nbsp;cups_bool_t InsertSheet;<br>
-&nbsp;&nbsp;cups_jog_t Jog;<br>
-&nbsp;&nbsp;cups_edge_t LeadingEdge;<br>
-&nbsp;&nbsp;cups_bool_t ManualFeed;<br>
-&nbsp;&nbsp;unsigned Margins[2];<br>
-&nbsp;&nbsp;char MediaClass[64];<br>
-&nbsp;&nbsp;char MediaColor[64];<br>
-&nbsp;&nbsp;unsigned MediaPosition;<br>
-&nbsp;&nbsp;char MediaType[64];<br>
-&nbsp;&nbsp;unsigned MediaWeight;<br>
-&nbsp;&nbsp;cups_bool_t MirrorPrint;<br>
-&nbsp;&nbsp;cups_bool_t NegativePrint;<br>
-&nbsp;&nbsp;unsigned NumCopies;<br>
-&nbsp;&nbsp;cups_orient_t Orientation;<br>
-&nbsp;&nbsp;cups_bool_t OutputFaceUp;<br>
-&nbsp;&nbsp;char OutputType[64];<br>
-&nbsp;&nbsp;unsigned PageSize[2];<br>
-&nbsp;&nbsp;cups_bool_t Separations;<br>
-&nbsp;&nbsp;cups_bool_t TraySwitch;<br>
-&nbsp;&nbsp;cups_bool_t Tumble;<br>
-&nbsp;&nbsp;unsigned cupsBitsPerColor;<br>
-&nbsp;&nbsp;unsigned cupsBitsPerPixel;<br>
-&nbsp;&nbsp;float cupsBorderlessScalingFactor;<br>
-&nbsp;&nbsp;unsigned cupsBytesPerLine;<br>
-&nbsp;&nbsp;cups_order_t cupsColorOrder;<br>
-&nbsp;&nbsp;cups_cspace_t cupsColorSpace;<br>
-&nbsp;&nbsp;unsigned cupsCompression;<br>
-&nbsp;&nbsp;unsigned cupsHeight;<br>
-&nbsp;&nbsp;float cupsImagingBBox[4];<br>
-&nbsp;&nbsp;unsigned cupsInteger[16];<br>
-&nbsp;&nbsp;char cupsMarkerType[64];<br>
-&nbsp;&nbsp;unsigned cupsMediaType;<br>
-&nbsp;&nbsp;unsigned cupsNumColors;<br>
-&nbsp;&nbsp;char cupsPageSizeName[64];<br>
-&nbsp;&nbsp;float cupsPageSize[2];<br>
-&nbsp;&nbsp;float cupsReal[16];<br>
-&nbsp;&nbsp;char cupsRenderingIntent[64];<br>
-&nbsp;&nbsp;unsigned cupsRowCount;<br>
-&nbsp;&nbsp;unsigned cupsRowFeed;<br>
-&nbsp;&nbsp;unsigned cupsRowStep;<br>
-&nbsp;&nbsp;char cupsString[16][64];<br>
-&nbsp;&nbsp;unsigned cupsWidth;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>AdvanceDistance</tt> </td><td>AdvanceDistance value in points
-</td></tr>
-<tr><td><tt>AdvanceMedia</tt> </td><td>AdvanceMedia value (see above)
-</td></tr>
-<tr><td><tt>Collate</tt> </td><td>Collated copies value
-</td></tr>
-<tr><td><tt>CutMedia</tt> </td><td>CutMedia value (see above)
-</td></tr>
-<tr><td><tt>Duplex</tt> </td><td>Duplexed (double-sided) value
-</td></tr>
-<tr><td><tt>HWResolution[2]</tt> </td><td>Resolution in dots-per-inch
-</td></tr>
-<tr><td><tt>ImagingBoundingBox[4]</tt> </td><td>Pixel region that is painted (points)
-</td></tr>
-<tr><td><tt>InsertSheet</tt> </td><td>InsertSheet value
-</td></tr>
-<tr><td><tt>Jog</tt> </td><td>Jog value (see above)
-</td></tr>
-<tr><td><tt>LeadingEdge</tt> </td><td>LeadingEdge value (see above)
-</td></tr>
-<tr><td><tt>ManualFeed</tt> </td><td>ManualFeed value
-</td></tr>
-<tr><td><tt>Margins[2]</tt> </td><td>Lower-lefthand margins in points
-</td></tr>
-<tr><td><tt>MediaClass[64]</tt> </td><td>MediaClass string
-</td></tr>
-<tr><td><tt>MediaColor[64]</tt> </td><td>MediaColor string
-</td></tr>
-<tr><td><tt>MediaPosition</tt> </td><td>MediaPosition value
-</td></tr>
-<tr><td><tt>MediaType[64]</tt> </td><td>MediaType string
-</td></tr>
-<tr><td><tt>MediaWeight</tt> </td><td>MediaWeight value in grams/m^2
-</td></tr>
-<tr><td><tt>MirrorPrint</tt> </td><td>MirrorPrint value
-</td></tr>
-<tr><td><tt>NegativePrint</tt> </td><td>NegativePrint value
-</td></tr>
-<tr><td><tt>NumCopies</tt> </td><td>Number of copies to produce
-</td></tr>
-<tr><td><tt>Orientation</tt> </td><td>Orientation value (see above)
-</td></tr>
-<tr><td><tt>OutputFaceUp</tt> </td><td>OutputFaceUp value
-</td></tr>
-<tr><td><tt>OutputType[64]</tt> </td><td>OutputType string
-</td></tr>
-<tr><td><tt>PageSize[2]</tt> </td><td>Width and length of page in points
-</td></tr>
-<tr><td><tt>Separations</tt> </td><td>Separations value
-</td></tr>
-<tr><td><tt>TraySwitch</tt> </td><td>TraySwitch value
-</td></tr>
-<tr><td><tt>Tumble</tt> </td><td>Tumble value
-</td></tr>
-<tr><td><tt>cupsBitsPerColor</tt> </td><td>Number of bits for each color
-</td></tr>
-<tr><td><tt>cupsBitsPerPixel</tt> </td><td>Number of bits for each pixel
-</td></tr>
-<tr><td><tt>cupsBorderlessScalingFactor</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Scaling that was applied to page data 
-</td></tr>
-<tr><td><tt>cupsBytesPerLine</tt> </td><td>Number of bytes per line
-</td></tr>
-<tr><td><tt>cupsColorOrder</tt> </td><td>Order of colors
-</td></tr>
-<tr><td><tt>cupsColorSpace</tt> </td><td>True colorspace
-</td></tr>
-<tr><td><tt>cupsCompression</tt> </td><td>Device compression to use
-</td></tr>
-<tr><td><tt>cupsHeight</tt> </td><td>Height of page image in pixels
-</td></tr>
-<tr><td><tt>cupsImagingBBox[4]</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Floating point ImagingBoundingBox *
-(scaling factor not applied) 
-</td></tr>
-<tr><td><tt>cupsInteger[16]</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>User-defined integer values 
-</td></tr>
-<tr><td><tt>cupsMarkerType[64]</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Ink/toner type 
-</td></tr>
-<tr><td><tt>cupsMediaType</tt> </td><td>Media type code
-</td></tr>
-<tr><td><tt>cupsNumColors</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Number of colors 
-</td></tr>
-<tr><td><tt>cupsPageSizeName[64]</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>PageSize name 
-</td></tr>
-<tr><td><tt>cupsPageSize[2]</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Floating point PageSize (scaling *
-factor not applied) 
-</td></tr>
-<tr><td><tt>cupsReal[16]</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>User-defined floating-point values 
-</td></tr>
-<tr><td><tt>cupsRenderingIntent[64]</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>Color rendering intent 
-</td></tr>
-<tr><td><tt>cupsRowCount</tt> </td><td>Rows per band
-</td></tr>
-<tr><td><tt>cupsRowFeed</tt> </td><td>Feed between bands
-</td></tr>
-<tr><td><tt>cupsRowStep</tt> </td><td>Spacing between lines
-</td></tr>
-<tr><td><tt>cupsString[16][64]</tt> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></td><td>User-defined string values 
-</td></tr>
-<tr><td><tt>cupsWidth</tt> </td><td>Width of page image in pixels
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_page_header_s'>cups_page_header_s</a></h3>
-<h4>Description</h4>
-<p>Version 1 Page Header
-<h4>Definition</h4>
-<p><tt>
-struct cups_page_header_s<br>
-{<br>
-&nbsp;&nbsp;unsigned AdvanceDistance;<br>
-&nbsp;&nbsp;cups_adv_t AdvanceMedia;<br>
-&nbsp;&nbsp;cups_bool_t Collate;<br>
-&nbsp;&nbsp;cups_cut_t CutMedia;<br>
-&nbsp;&nbsp;cups_bool_t Duplex;<br>
-&nbsp;&nbsp;unsigned HWResolution[2];<br>
-&nbsp;&nbsp;unsigned ImagingBoundingBox[4];<br>
-&nbsp;&nbsp;cups_bool_t InsertSheet;<br>
-&nbsp;&nbsp;cups_jog_t Jog;<br>
-&nbsp;&nbsp;cups_edge_t LeadingEdge;<br>
-&nbsp;&nbsp;cups_bool_t ManualFeed;<br>
-&nbsp;&nbsp;unsigned Margins[2];<br>
-&nbsp;&nbsp;char MediaClass[64];<br>
-&nbsp;&nbsp;char MediaColor[64];<br>
-&nbsp;&nbsp;unsigned MediaPosition;<br>
-&nbsp;&nbsp;char MediaType[64];<br>
-&nbsp;&nbsp;unsigned MediaWeight;<br>
-&nbsp;&nbsp;cups_bool_t MirrorPrint;<br>
-&nbsp;&nbsp;cups_bool_t NegativePrint;<br>
-&nbsp;&nbsp;unsigned NumCopies;<br>
-&nbsp;&nbsp;cups_orient_t Orientation;<br>
-&nbsp;&nbsp;cups_bool_t OutputFaceUp;<br>
-&nbsp;&nbsp;char OutputType[64];<br>
-&nbsp;&nbsp;unsigned PageSize[2];<br>
-&nbsp;&nbsp;cups_bool_t Separations;<br>
-&nbsp;&nbsp;cups_bool_t TraySwitch;<br>
-&nbsp;&nbsp;cups_bool_t Tumble;<br>
-&nbsp;&nbsp;unsigned cupsBitsPerColor;<br>
-&nbsp;&nbsp;unsigned cupsBitsPerPixel;<br>
-&nbsp;&nbsp;unsigned cupsBytesPerLine;<br>
-&nbsp;&nbsp;cups_order_t cupsColorOrder;<br>
-&nbsp;&nbsp;cups_cspace_t cupsColorSpace;<br>
-&nbsp;&nbsp;unsigned cupsCompression;<br>
-&nbsp;&nbsp;unsigned cupsHeight;<br>
-&nbsp;&nbsp;unsigned cupsMediaType;<br>
-&nbsp;&nbsp;unsigned cupsRowCount;<br>
-&nbsp;&nbsp;unsigned cupsRowFeed;<br>
-&nbsp;&nbsp;unsigned cupsRowStep;<br>
-&nbsp;&nbsp;unsigned cupsWidth;<br>
-};</tt></p>
-<h4>Members</h4>
-<div class='table'><table align='center' border='1' width='80%' summary='Members'>
-<thead><tr><th>Name</th><th>Description</th></tr></thead>
-<tbody>
-<tr><td><tt>AdvanceDistance</tt> </td><td>AdvanceDistance value in points
-</td></tr>
-<tr><td><tt>AdvanceMedia</tt> </td><td>AdvanceMedia value (see above)
-</td></tr>
-<tr><td><tt>Collate</tt> </td><td>Collated copies value
-</td></tr>
-<tr><td><tt>CutMedia</tt> </td><td>CutMedia value (see above)
-</td></tr>
-<tr><td><tt>Duplex</tt> </td><td>Duplexed (double-sided) value
-</td></tr>
-<tr><td><tt>HWResolution[2]</tt> </td><td>Resolution in dots-per-inch
-</td></tr>
-<tr><td><tt>ImagingBoundingBox[4]</tt> </td><td>Pixel region that is painted (points)
-</td></tr>
-<tr><td><tt>InsertSheet</tt> </td><td>InsertSheet value
-</td></tr>
-<tr><td><tt>Jog</tt> </td><td>Jog value (see above)
-</td></tr>
-<tr><td><tt>LeadingEdge</tt> </td><td>LeadingEdge value (see above)
-</td></tr>
-<tr><td><tt>ManualFeed</tt> </td><td>ManualFeed value
-</td></tr>
-<tr><td><tt>Margins[2]</tt> </td><td>Lower-lefthand margins in points
-</td></tr>
-<tr><td><tt>MediaClass[64]</tt> </td><td>MediaClass string
-</td></tr>
-<tr><td><tt>MediaColor[64]</tt> </td><td>MediaColor string
-</td></tr>
-<tr><td><tt>MediaPosition</tt> </td><td>MediaPosition value
-</td></tr>
-<tr><td><tt>MediaType[64]</tt> </td><td>MediaType string
-</td></tr>
-<tr><td><tt>MediaWeight</tt> </td><td>MediaWeight value in grams/m^2
-</td></tr>
-<tr><td><tt>MirrorPrint</tt> </td><td>MirrorPrint value
-</td></tr>
-<tr><td><tt>NegativePrint</tt> </td><td>NegativePrint value
-</td></tr>
-<tr><td><tt>NumCopies</tt> </td><td>Number of copies to produce
-</td></tr>
-<tr><td><tt>Orientation</tt> </td><td>Orientation value (see above)
-</td></tr>
-<tr><td><tt>OutputFaceUp</tt> </td><td>OutputFaceUp value
-</td></tr>
-<tr><td><tt>OutputType[64]</tt> </td><td>OutputType string
-</td></tr>
-<tr><td><tt>PageSize[2]</tt> </td><td>Width and length of page in points
-</td></tr>
-<tr><td><tt>Separations</tt> </td><td>Separations value
-</td></tr>
-<tr><td><tt>TraySwitch</tt> </td><td>TraySwitch value
-</td></tr>
-<tr><td><tt>Tumble</tt> </td><td>Tumble value
-</td></tr>
-<tr><td><tt>cupsBitsPerColor</tt> </td><td>Number of bits for each color
-</td></tr>
-<tr><td><tt>cupsBitsPerPixel</tt> </td><td>Number of bits for each pixel
-</td></tr>
-<tr><td><tt>cupsBytesPerLine</tt> </td><td>Number of bytes per line
-</td></tr>
-<tr><td><tt>cupsColorOrder</tt> </td><td>Order of colors
-</td></tr>
-<tr><td><tt>cupsColorSpace</tt> </td><td>True colorspace
-</td></tr>
-<tr><td><tt>cupsCompression</tt> </td><td>Device compression to use
-</td></tr>
-<tr><td><tt>cupsHeight</tt> </td><td>Height of page image in pixels
-</td></tr>
-<tr><td><tt>cupsMediaType</tt> </td><td>Media type code
-</td></tr>
-<tr><td><tt>cupsRowCount</tt> </td><td>Rows per band
-</td></tr>
-<tr><td><tt>cupsRowFeed</tt> </td><td>Feed between bands
-</td></tr>
-<tr><td><tt>cupsRowStep</tt> </td><td>Spacing between lines
-</td></tr>
-<tr><td><tt>cupsWidth</tt> </td><td>Width of page image in pixels
-</td></tr>
-</tbody></table></div>
-<!-- NEW PAGE -->
-<h2 class='title'><a name='TYPES'>Types</a></h2>
-<ul>
-       <li><a href='#cups_interpret_cb_t'><tt>cups_interpret_cb_t</tt></a> </li>
-       <li><a href='#cups_page_header2_t'><tt>cups_page_header2_t</tt></a> <span class='info'>&nbsp;CUPS 1.2&nbsp;</span></li>
-       <li><a href='#cups_page_header_t'><tt>cups_page_header_t</tt></a> </li>
-       <li><a href='#cups_raster_t'><tt>cups_raster_t</tt></a> </li>
-</ul>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_interpret_cb_t'>cups_interpret_cb_t</a></h3>
-<h4>Description</h4>
-<p>Prototypes...
-<h4>Definition</h4>
-<p><tt>
-typedef int (*cups_interpret_cb_t)(<a href='#cups_page_header2_t'>cups_page_header2_t</a> *header, int preferred_bits);
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><span class='info'>&nbsp;CUPS 1.2&nbsp;</span><a name='cups_page_header2_t'>cups_page_header2_t</a></h3>
-<h4>Description</h4>
-<p>Version 2 Page Header 
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#cups_page_header2_s'>cups_page_header2_s</a> cups_page_header2_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_page_header_t'>cups_page_header_t</a></h3>
-<h4>Description</h4>
-<p>Version 1 Page Header
-<h4>Definition</h4>
-<p><tt>
-typedef struct <a href='#cups_page_header_s'>cups_page_header_s</a> cups_page_header_t;
-</tt></p>
-<!-- NEW PAGE -->
-<h3 class='title'><a name='cups_raster_t'>cups_raster_t</a></h3>
-<h4>Description</h4>
-<p>Raster stream data
-<h4>Definition</h4>
-<p><tt>
+
+<code>cupsRasterInterpretPPD</code> supports a subset of the PostScript language.
+Currently only the <code>[</code>, <code>]</code>, <code><<</code>, <code>>></code>, <code>{</code>,
+<code>}</code>, <code>cleartomark</code>, <code>copy</code>, <code>dup</code>, <code>index</code>,
+<code>pop</code>, <code>roll</code>, <code>setpagedevice</code>, and <code>stopped</code> operators
+are supported.
+
+</p>
+<h3 class="function"><a name="cupsRasterOpen">cupsRasterOpen</a></h3>
+<p class="description">Open a raster stream.</p>
+<p class="code">
+<a href="#cups_raster_t">cups_raster_t</a> *cupsRasterOpen (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int fd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_mode_t">cups_mode_t</a> mode<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fd</dt>
+<dd class="description">File descriptor</dd>
+<dt>mode</dt>
+<dd class="description">Mode</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New stream</p>
+<h3 class="function"><a name="cupsRasterReadHeader">cupsRasterReadHeader</a></h3>
+<p class="description">Read a raster page header and store it in a
+V1 page header structure.</p>
+<p class="code">
+unsigned cupsRasterReadHeader (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_raster_t">cups_raster_t</a> *r,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_page_header_t">cups_page_header_t</a> *h<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>r</dt>
+<dd class="description">Raster stream</dd>
+<dt>h</dt>
+<dd class="description">Pointer to header data</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 on success, 0 on fail</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsRasterReadHeader2">cupsRasterReadHeader2</a></h3>
+<p class="description">Read a raster page header and store it in a
+V2 page header structure.</p>
+<p class="code">
+unsigned cupsRasterReadHeader2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_raster_t">cups_raster_t</a> *r,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_page_header2_t">cups_page_header2_t</a> *h<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>r</dt>
+<dd class="description">Raster stream</dd>
+<dt>h</dt>
+<dd class="description">Pointer to header data</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 on success, 0 on fail</p>
+<h3 class="function"><a name="cupsRasterReadPixels">cupsRasterReadPixels</a></h3>
+<p class="description">Read raster pixels.</p>
+<p class="code">
+unsigned cupsRasterReadPixels (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_raster_t">cups_raster_t</a> *r,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned char *p,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned len<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>r</dt>
+<dd class="description">Raster stream</dd>
+<dt>p</dt>
+<dd class="description">Pointer to pixel buffer</dd>
+<dt>len</dt>
+<dd class="description">Number of bytes to read</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of bytes read</p>
+<h3 class="function"><a name="cupsRasterWriteHeader">cupsRasterWriteHeader</a></h3>
+<p class="description">Write a raster page header from a V1 page
+header structure.</p>
+<p class="code">
+unsigned cupsRasterWriteHeader (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_raster_t">cups_raster_t</a> *r,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_page_header_t">cups_page_header_t</a> *h<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>r</dt>
+<dd class="description">Raster stream</dd>
+<dt>h</dt>
+<dd class="description">Raster page header</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 on success, 0 on failure</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsRasterWriteHeader2">cupsRasterWriteHeader2</a></h3>
+<p class="description">Write a raster page header from a V2 page
+header structure.</p>
+<p class="code">
+unsigned cupsRasterWriteHeader2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_raster_t">cups_raster_t</a> *r,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_page_header2_t">cups_page_header2_t</a> *h<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>r</dt>
+<dd class="description">Raster stream</dd>
+<dt>h</dt>
+<dd class="description">Raster page header</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 on success, 0 on failure</p>
+<h3 class="function"><a name="cupsRasterWritePixels">cupsRasterWritePixels</a></h3>
+<p class="description">Write raster pixels.</p>
+<p class="code">
+unsigned cupsRasterWritePixels (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_raster_t">cups_raster_t</a> *r,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned char *p,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned len<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>r</dt>
+<dd class="description">Raster stream</dd>
+<dt>p</dt>
+<dd class="description">Bytes to write</dd>
+<dt>len</dt>
+<dd class="description">Number of bytes to write</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of bytes written</p>
+<h2 class="title"><a name="TYPES">Data Types</a></h2>
+<h3 class="typedef"><a name="cups_interpret_cb_t">cups_interpret_cb_t</a></h3>
+<p class="description">cupsRasterInterpretPPD callback function</p>
+<p class="code">
+typedef int (*cups_interpret_cb_t)(<a href="#cups_page_header2_t">cups_page_header2_t</a> *header, int preferred_bits);
+</p>
+<h3 class="typedef"><a name="cups_mode_t">cups_mode_t</a></h3>
+<p class="description">cupsRasterOpen modes</p>
+<p class="code">
+typedef enum <a href="#cups_mode_e">cups_mode_e</a> cups_mode_t;
+</p>
+<h3 class="typedef"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cups_page_header2_t">cups_page_header2_t</a></h3>
+<p class="description">Version 2 page header </p>
+<p class="code">
+typedef struct <a href="#cups_page_header2_s">cups_page_header2_s</a> cups_page_header2_t;
+</p>
+<h3 class="typedef"><a name="cups_page_header_t">cups_page_header_t</a></h3>
+<p class="description">Version 1 page header</p>
+<p class="code">
+typedef struct <a href="#cups_page_header_s">cups_page_header_s</a> cups_page_header_t;
+</p>
+<h3 class="typedef"><a name="cups_raster_t">cups_raster_t</a></h3>
+<p class="description">Raster stream data</p>
+<p class="code">
 typedef struct _cups_raster_s cups_raster_t;
-</tt></p>
+</p>
+<h2 class="title"><a name="STRUCTURES">Structures</a></h2>
+<h3 class="struct"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cups_page_header2_s">cups_page_header2_s</a></h3>
+<p class="description">Version 2 page header </p>
+<p class="code">struct cups_page_header2_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned AdvanceDistance;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_adv_t AdvanceMedia;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t Collate;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_cut_t CutMedia;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t Duplex;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned HWResolution[2];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned ImagingBoundingBox[4];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t InsertSheet;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_jog_t Jog;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_edge_t LeadingEdge;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t ManualFeed;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned Margins[2];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char MediaClass[64];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char MediaColor[64];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned MediaPosition;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char MediaType[64];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned MediaWeight;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t MirrorPrint;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t NegativePrint;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned NumCopies;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_orient_t Orientation;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t OutputFaceUp;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char OutputType[64];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned PageSize[2];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t Separations;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t TraySwitch;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t Tumble;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsBitsPerColor;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsBitsPerPixel;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float cupsBorderlessScalingFactor;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsBytesPerLine;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_order_t cupsColorOrder;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_cspace_t cupsColorSpace;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsCompression;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsHeight;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float cupsImagingBBox[4];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsInteger[16];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char cupsMarkerType[64];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsMediaType;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsNumColors;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char cupsPageSizeName[64];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float cupsPageSize[2];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;float cupsReal[16];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char cupsRenderingIntent[64];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsRowCount;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsRowFeed;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsRowStep;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char cupsString[16][64];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsWidth;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>AdvanceDistance </dt>
+<dd class="description">AdvanceDistance value in points</dd>
+<dt>AdvanceMedia </dt>
+<dd class="description">AdvanceMedia value (see above)</dd>
+<dt>Collate </dt>
+<dd class="description">Collated copies value</dd>
+<dt>CutMedia </dt>
+<dd class="description">CutMedia value (see above)</dd>
+<dt>Duplex </dt>
+<dd class="description">Duplexed (double-sided) value</dd>
+<dt>HWResolution[2] </dt>
+<dd class="description">Resolution in dots-per-inch</dd>
+<dt>ImagingBoundingBox[4] </dt>
+<dd class="description">Pixel region that is painted (points)</dd>
+<dt>InsertSheet </dt>
+<dd class="description">InsertSheet value</dd>
+<dt>Jog </dt>
+<dd class="description">Jog value (see above)</dd>
+<dt>LeadingEdge </dt>
+<dd class="description">LeadingEdge value (see above)</dd>
+<dt>ManualFeed </dt>
+<dd class="description">ManualFeed value</dd>
+<dt>Margins[2] </dt>
+<dd class="description">Lower-lefthand margins in points</dd>
+<dt>MediaClass[64] </dt>
+<dd class="description">MediaClass string</dd>
+<dt>MediaColor[64] </dt>
+<dd class="description">MediaColor string</dd>
+<dt>MediaPosition </dt>
+<dd class="description">MediaPosition value</dd>
+<dt>MediaType[64] </dt>
+<dd class="description">MediaType string</dd>
+<dt>MediaWeight </dt>
+<dd class="description">MediaWeight value in grams/m^2</dd>
+<dt>MirrorPrint </dt>
+<dd class="description">MirrorPrint value</dd>
+<dt>NegativePrint </dt>
+<dd class="description">NegativePrint value</dd>
+<dt>NumCopies </dt>
+<dd class="description">Number of copies to produce</dd>
+<dt>Orientation </dt>
+<dd class="description">Orientation value (see above)</dd>
+<dt>OutputFaceUp </dt>
+<dd class="description">OutputFaceUp value</dd>
+<dt>OutputType[64] </dt>
+<dd class="description">OutputType string</dd>
+<dt>PageSize[2] </dt>
+<dd class="description">Width and length of page in points</dd>
+<dt>Separations </dt>
+<dd class="description">Separations value</dd>
+<dt>TraySwitch </dt>
+<dd class="description">TraySwitch value</dd>
+<dt>Tumble </dt>
+<dd class="description">Tumble value</dd>
+<dt>cupsBitsPerColor </dt>
+<dd class="description">Number of bits for each color</dd>
+<dt>cupsBitsPerPixel </dt>
+<dd class="description">Number of bits for each pixel</dd>
+<dt>cupsBorderlessScalingFactor <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Scaling that was applied to page data </dd>
+<dt>cupsBytesPerLine </dt>
+<dd class="description">Number of bytes per line</dd>
+<dt>cupsColorOrder </dt>
+<dd class="description">Order of colors</dd>
+<dt>cupsColorSpace </dt>
+<dd class="description">True colorspace</dd>
+<dt>cupsCompression </dt>
+<dd class="description">Device compression to use</dd>
+<dt>cupsHeight </dt>
+<dd class="description">Height of page image in pixels</dd>
+<dt>cupsImagingBBox[4] <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Floating point ImagingBoundingBox *
+(scaling factor not applied) </dd>
+<dt>cupsInteger[16] <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">User-defined integer values </dd>
+<dt>cupsMarkerType[64] <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Ink/toner type </dd>
+<dt>cupsMediaType </dt>
+<dd class="description">Media type code</dd>
+<dt>cupsNumColors <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Number of colors </dd>
+<dt>cupsPageSizeName[64] <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">PageSize name </dd>
+<dt>cupsPageSize[2] <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Floating point PageSize (scaling *
+factor not applied) </dd>
+<dt>cupsReal[16] <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">User-defined floating-point values </dd>
+<dt>cupsRenderingIntent[64] <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Color rendering intent </dd>
+<dt>cupsRowCount </dt>
+<dd class="description">Rows per band</dd>
+<dt>cupsRowFeed </dt>
+<dd class="description">Feed between bands</dd>
+<dt>cupsRowStep </dt>
+<dd class="description">Spacing between lines</dd>
+<dt>cupsString[16][64] <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">User-defined string values </dd>
+<dt>cupsWidth </dt>
+<dd class="description">Width of page image in pixels</dd>
+</dl>
+<h3 class="struct"><a name="cups_page_header_s">cups_page_header_s</a></h3>
+<p class="description">Version 1 page header</p>
+<p class="code">struct cups_page_header_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned AdvanceDistance;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_adv_t AdvanceMedia;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t Collate;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_cut_t CutMedia;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t Duplex;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned HWResolution[2];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned ImagingBoundingBox[4];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t InsertSheet;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_jog_t Jog;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_edge_t LeadingEdge;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t ManualFeed;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned Margins[2];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char MediaClass[64];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char MediaColor[64];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned MediaPosition;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char MediaType[64];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned MediaWeight;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t MirrorPrint;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t NegativePrint;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned NumCopies;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_orient_t Orientation;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t OutputFaceUp;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char OutputType[64];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned PageSize[2];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t Separations;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t TraySwitch;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_bool_t Tumble;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsBitsPerColor;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsBitsPerPixel;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsBytesPerLine;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_order_t cupsColorOrder;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;cups_cspace_t cupsColorSpace;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsCompression;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsHeight;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsMediaType;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsRowCount;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsRowFeed;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsRowStep;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned cupsWidth;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>AdvanceDistance </dt>
+<dd class="description">AdvanceDistance value in points</dd>
+<dt>AdvanceMedia </dt>
+<dd class="description">AdvanceMedia value (see above)</dd>
+<dt>Collate </dt>
+<dd class="description">Collated copies value</dd>
+<dt>CutMedia </dt>
+<dd class="description">CutMedia value (see above)</dd>
+<dt>Duplex </dt>
+<dd class="description">Duplexed (double-sided) value</dd>
+<dt>HWResolution[2] </dt>
+<dd class="description">Resolution in dots-per-inch</dd>
+<dt>ImagingBoundingBox[4] </dt>
+<dd class="description">Pixel region that is painted (points)</dd>
+<dt>InsertSheet </dt>
+<dd class="description">InsertSheet value</dd>
+<dt>Jog </dt>
+<dd class="description">Jog value (see above)</dd>
+<dt>LeadingEdge </dt>
+<dd class="description">LeadingEdge value (see above)</dd>
+<dt>ManualFeed </dt>
+<dd class="description">ManualFeed value</dd>
+<dt>Margins[2] </dt>
+<dd class="description">Lower-lefthand margins in points</dd>
+<dt>MediaClass[64] </dt>
+<dd class="description">MediaClass string</dd>
+<dt>MediaColor[64] </dt>
+<dd class="description">MediaColor string</dd>
+<dt>MediaPosition </dt>
+<dd class="description">MediaPosition value</dd>
+<dt>MediaType[64] </dt>
+<dd class="description">MediaType string</dd>
+<dt>MediaWeight </dt>
+<dd class="description">MediaWeight value in grams/m^2</dd>
+<dt>MirrorPrint </dt>
+<dd class="description">MirrorPrint value</dd>
+<dt>NegativePrint </dt>
+<dd class="description">NegativePrint value</dd>
+<dt>NumCopies </dt>
+<dd class="description">Number of copies to produce</dd>
+<dt>Orientation </dt>
+<dd class="description">Orientation value (see above)</dd>
+<dt>OutputFaceUp </dt>
+<dd class="description">OutputFaceUp value</dd>
+<dt>OutputType[64] </dt>
+<dd class="description">OutputType string</dd>
+<dt>PageSize[2] </dt>
+<dd class="description">Width and length of page in points</dd>
+<dt>Separations </dt>
+<dd class="description">Separations value</dd>
+<dt>TraySwitch </dt>
+<dd class="description">TraySwitch value</dd>
+<dt>Tumble </dt>
+<dd class="description">Tumble value</dd>
+<dt>cupsBitsPerColor </dt>
+<dd class="description">Number of bits for each color</dd>
+<dt>cupsBitsPerPixel </dt>
+<dd class="description">Number of bits for each pixel</dd>
+<dt>cupsBytesPerLine </dt>
+<dd class="description">Number of bytes per line</dd>
+<dt>cupsColorOrder </dt>
+<dd class="description">Order of colors</dd>
+<dt>cupsColorSpace </dt>
+<dd class="description">True colorspace</dd>
+<dt>cupsCompression </dt>
+<dd class="description">Device compression to use</dd>
+<dt>cupsHeight </dt>
+<dd class="description">Height of page image in pixels</dd>
+<dt>cupsMediaType </dt>
+<dd class="description">Media type code</dd>
+<dt>cupsRowCount </dt>
+<dd class="description">Rows per band</dd>
+<dt>cupsRowFeed </dt>
+<dd class="description">Feed between bands</dd>
+<dt>cupsRowStep </dt>
+<dd class="description">Spacing between lines</dd>
+<dt>cupsWidth </dt>
+<dd class="description">Width of page image in pixels</dd>
+</dl>
+<h2 class="title"><a name="ENUMERATIONS">Constants</a></h2>
+<h3 class="enumeration"><a name="cups_adv_e">cups_adv_e</a></h3>
+<p class="description">AdvanceMedia attribute values</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_ADVANCE_FILE </dt>
+<dd class="description">Advance the roll after this file</dd>
+<dt>CUPS_ADVANCE_JOB </dt>
+<dd class="description">Advance the roll after this job</dd>
+<dt>CUPS_ADVANCE_NONE </dt>
+<dd class="description">Never advance the roll</dd>
+<dt>CUPS_ADVANCE_PAGE </dt>
+<dd class="description">Advance the roll after this page</dd>
+<dt>CUPS_ADVANCE_SET </dt>
+<dd class="description">Advance the roll after this set</dd>
+</dl>
+<h3 class="enumeration"><a name="cups_bool_e">cups_bool_e</a></h3>
+<p class="description">Types...</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_FALSE </dt>
+<dd class="description">Logical false</dd>
+<dt>CUPS_TRUE </dt>
+<dd class="description">Logical true</dd>
+</dl>
+<h3 class="enumeration"><a name="cups_cspace_e">cups_cspace_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_CSPACE_CIELab <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">CIE Lab </dd>
+<dt>CUPS_CSPACE_CIEXYZ <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">CIE XYZ </dd>
+<dt>CUPS_CSPACE_CMY </dt>
+<dd class="description">Cyan, magenta, yellow</dd>
+<dt>CUPS_CSPACE_CMYK </dt>
+<dd class="description">Cyan, magenta, yellow, black</dd>
+<dt>CUPS_CSPACE_GMCK </dt>
+<dd class="description">Gold, magenta, yellow, black</dd>
+<dt>CUPS_CSPACE_GMCS </dt>
+<dd class="description">Gold, magenta, yellow, silver</dd>
+<dt>CUPS_CSPACE_GOLD </dt>
+<dd class="description">Gold foil</dd>
+<dt>CUPS_CSPACE_ICC1 <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">ICC-based, 1 color </dd>
+<dt>CUPS_CSPACE_ICC2 <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">ICC-based, 2 colors </dd>
+<dt>CUPS_CSPACE_ICC3 <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">ICC-based, 3 colors </dd>
+<dt>CUPS_CSPACE_ICC4 <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">ICC-based, 4 colors </dd>
+<dt>CUPS_CSPACE_ICC5 <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">ICC-based, 5 colors </dd>
+<dt>CUPS_CSPACE_ICC6 <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">ICC-based, 6 colors </dd>
+<dt>CUPS_CSPACE_ICC7 <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">ICC-based, 7 colors </dd>
+<dt>CUPS_CSPACE_ICC8 <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">ICC-based, 8 colors </dd>
+<dt>CUPS_CSPACE_ICC9 <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">ICC-based, 9 colors </dd>
+<dt>CUPS_CSPACE_ICCA <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">ICC-based, 10 colors </dd>
+<dt>CUPS_CSPACE_ICCB <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">ICC-based, 11 colors </dd>
+<dt>CUPS_CSPACE_ICCC <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">ICC-based, 12 colors </dd>
+<dt>CUPS_CSPACE_ICCD <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">ICC-based, 13 colors </dd>
+<dt>CUPS_CSPACE_ICCE <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">ICC-based, 14 colors </dd>
+<dt>CUPS_CSPACE_ICCF <span class="info">&nbsp;CUPS 1.1.19&nbsp;</span></dt>
+<dd class="description">ICC-based, 15 colors </dd>
+<dt>CUPS_CSPACE_K </dt>
+<dd class="description">Black</dd>
+<dt>CUPS_CSPACE_KCMY </dt>
+<dd class="description">Black, cyan, magenta, yellow</dd>
+<dt>CUPS_CSPACE_KCMYcm </dt>
+<dd class="description">Black, cyan, magenta, yellow, *
+light-cyan, light-magenta</dd>
+<dt>CUPS_CSPACE_RGB </dt>
+<dd class="description">Red, green, blue</dd>
+<dt>CUPS_CSPACE_RGBA </dt>
+<dd class="description">Red, green, blue, alpha</dd>
+<dt>CUPS_CSPACE_RGBW <span class="info">&nbsp;CUPS 1.2&nbsp;</span></dt>
+<dd class="description">Red, green, blue, white </dd>
+<dt>CUPS_CSPACE_SILVER </dt>
+<dd class="description">Silver foil</dd>
+<dt>CUPS_CSPACE_W </dt>
+<dd class="description">Luminance</dd>
+<dt>CUPS_CSPACE_WHITE </dt>
+<dd class="description">White ink (as black)</dd>
+<dt>CUPS_CSPACE_YMC </dt>
+<dd class="description">Yellow, magenta, cyan</dd>
+<dt>CUPS_CSPACE_YMCK </dt>
+<dd class="description">Yellow, magenta, cyan, black</dd>
+</dl>
+<h3 class="enumeration"><a name="cups_cut_e">cups_cut_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_CUT_FILE </dt>
+<dd class="description">Cut the roll after this file</dd>
+<dt>CUPS_CUT_JOB </dt>
+<dd class="description">Cut the roll after this job</dd>
+<dt>CUPS_CUT_NONE </dt>
+<dd class="description">Never cut the roll</dd>
+<dt>CUPS_CUT_PAGE </dt>
+<dd class="description">Cut the roll after this page</dd>
+<dt>CUPS_CUT_SET </dt>
+<dd class="description">Cut the roll after this set</dd>
+</dl>
+<h3 class="enumeration"><a name="cups_edge_e">cups_edge_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_EDGE_BOTTOM </dt>
+<dd class="description">Leading edge is the bottom of the page</dd>
+<dt>CUPS_EDGE_LEFT </dt>
+<dd class="description">Leading edge is the left of the page</dd>
+<dt>CUPS_EDGE_RIGHT </dt>
+<dd class="description">Leading edge is the right of the page</dd>
+<dt>CUPS_EDGE_TOP </dt>
+<dd class="description">Leading edge is the top of the page</dd>
+</dl>
+<h3 class="enumeration"><a name="cups_jog_e">cups_jog_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_JOG_FILE </dt>
+<dd class="description">Move pages after this file</dd>
+<dt>CUPS_JOG_JOB </dt>
+<dd class="description">Move pages after this job</dd>
+<dt>CUPS_JOG_NONE </dt>
+<dd class="description">Never move pages</dd>
+<dt>CUPS_JOG_SET </dt>
+<dd class="description">Move pages after this set</dd>
+</dl>
+<h3 class="enumeration"><a name="cups_mode_e">cups_mode_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_RASTER_READ </dt>
+<dd class="description">Open stream for reading</dd>
+<dt>CUPS_RASTER_WRITE </dt>
+<dd class="description">Open stream for writing</dd>
+<dt>CUPS_RASTER_WRITE_COMPRESSED <span class="info">&nbsp;CUPS 1.3&nbsp;</span></dt>
+<dd class="description">Open stream for compressed writing </dd>
+</dl>
+<h3 class="enumeration"><a name="cups_order_e">cups_order_e</a></h3>
+<p class="description">cupsColorOrder attribute values</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_ORDER_BANDED </dt>
+<dd class="description">CCC MMM YYY KKK ...</dd>
+<dt>CUPS_ORDER_CHUNKED </dt>
+<dd class="description">CMYK CMYK CMYK ...</dd>
+<dt>CUPS_ORDER_PLANAR </dt>
+<dd class="description">CCC ... MMM ... YYY ... KKK ...</dd>
+</dl>
+<h3 class="enumeration"><a name="cups_orient_e">cups_orient_e</a></h3>
+<p class="description"></p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_ORIENT_0 </dt>
+<dd class="description">Don't rotate the page</dd>
+<dt>CUPS_ORIENT_180 </dt>
+<dd class="description">Turn the page upside down</dd>
+<dt>CUPS_ORIENT_270 </dt>
+<dd class="description">Rotate the page clockwise</dd>
+<dt>CUPS_ORIENT_90 </dt>
+<dd class="description">Rotate the page counter-clockwise</dd>
+</dl>
+</div>
 </body>
 </html>
index 732c91960d69bcaf04480a029e40260d4a549adf..37ab489ef612606a19f0089abe2f05ebdc846a07 100644 (file)
@@ -49,7 +49,7 @@ the <VAR>cupsd.conf</VAR> file from the console, make sure to <A
 HREF="ref-cupsd-conf.html">restart the cupsd process</A> before
 trying to use the new policy.</P>
 
-<PRE CLASS="command">
+<PRE CLASS="example">
 <EM>Listing 1: <A NAME="LISTING01">Default Operation Policy</A></EM>
 
  1    &lt;Policy default>
@@ -106,14 +106,14 @@ trying to use the new policy.</P>
 <P>The policy definition starts with an opening <TT>Policy</TT>
 directive:</P>
 
-<PRE CLASS="command">
+<PRE CLASS="example">
  1    &lt;Policy default>
 </PRE>
 
 <P>The first <TT>Limit</TT> subsection defines the rules for IPP
 job operations:</P>
 
-<PRE CLASS="command">
+<PRE CLASS="example">
  3      &lt;Limit Send-Document Send-URI Hold-Job Release-Job
       Restart-Job Purge-Jobs Set-Job-Attributes
       Create-Job-Subscription Renew-Subscription
@@ -146,7 +146,7 @@ request. The administrative operations starting on line 9,
 however, <em>do</em> use the <TT>AuthType</TT> directive, and so
 administrative operations need to be authenticated:</P>
 
-<PRE CLASS="command">
+<PRE CLASS="example">
  9      &lt;Limit CUPS-Add-Printer CUPS-Delete-Printer CUPS-Add-Class
       CUPS-Delete-Class CUPS-Set-Default>
 10        AuthType Default
@@ -180,7 +180,7 @@ more easily edit their policy without disturbing the rest. Like
 the rest of the job operations, we want the job's owner
 ("@OWNER") or an administrator ("@SYSTEM") to do it:</P>
 
-<PRE CLASS="command">
+<PRE CLASS="example">
 16      &lt;Limit Cancel-Job CUPS-Authenticate-Job>
 17        Require user @OWNER @SYSTEM
 18        Order deny,allow
@@ -193,7 +193,7 @@ this subsection for any operation you don't list specifically in
 the policy. In this case, all other operations are allowed
 without a username or authentication:</P>
 
-<PRE CLASS="command">
+<PRE CLASS="example">
 21      &lt;Limit All>
 22        Order deny,allow
 23      &lt;/Limit>
@@ -521,7 +521,7 @@ change you'll make is to give the policy a new name. Policy names
 can use the same characters as a printer name, specifically all
 printable characters except space, slash (/), and pound (#):</P>
 
-<PRE CLASS="command">
+<PRE CLASS="example">
 &lt;Policy mypolicy>
 </PRE>
 
@@ -530,7 +530,7 @@ policy. For example, if you want to allow any user to cancel any
 other users' jobs, you can change the <TT>Cancel-Job</TT> limits
 to:</P>
 
-<PRE CLASS="command">
+<PRE CLASS="example">
 &lt;Limit Cancel-Job>
   Order deny,allow
 &lt;/Limit>
@@ -613,7 +613,7 @@ the lab technicians, who are members of a special UNIX group for
 that lab called "lab999", to do job, printer, and subscription
 management operations.</P>
 
-<PRE CLASS="command">
+<PRE CLASS="example">
 <EM>Listing 2: <A NAME="LISTING02">Operation Policy for a Lab</A></EM>
 
  1    &lt;Policy lab999>
@@ -664,7 +664,7 @@ directive in the <VAR>cupsd.conf</VAR> file. For example, add the
 following line to the <VAR>cupsd.conf</VAR> file to use the
 "lab999" policy from the previous section:</P>
 
-<PRE CLASS="command">
+<PRE CLASS="example">
 DefaultPolicy lab999
 </PRE>
 
index 704e967bab2e40631bffb762e9929f7551657aed..0d768c9fb173406a85ddd00afb560bdfd718b601 100644 (file)
@@ -11,7 +11,7 @@
 
   CUPS IPP specification for the Common UNIX Printing System (CUPS).
 
-  Copyright 2007 by Apple Inc.
+  Copyright 2007-2008 by Apple Inc.
   Copyright 1997-2007 by Easy Software Products.
 
   These coded instructions, statements, and computer programs are the
@@ -2459,6 +2459,101 @@ the system.
 <p>The job-sheets-supported attribute specifies the available banner files.
 There will always be at least one banner file available called "none".
 
+<h4><a name="marker-change-time">marker-change-time (integer)</a></h4>
+
+<p>The marker-change-time attribute specifies the printer-up-time value when
+the last change to the marker-colors, marker-levels, marker-names, or
+marker-types attributes was made.</p>
+
+<h4><a name="marker-colors">marker-colors (1setof name(MAX))</a></h4>
+
+<p>The marker-colors attribute specifies the color(s) for each supply in the
+printer. It is only available when the driver provides supply levels. The
+color is either "none" or one or more hex-encoded sRGB colors of the form
+"#RRGGBB".</p>
+
+<h4><a name="marker-levels">marker-levels (1setof integer(-1:100))</a></h4>
+
+<p>The marker-levels attribute specifies the current supply levels for the
+printer. It is only available when the driver provides supply levels. A
+value of -1 indicates the level is unknown, while values from 0 to 100
+indicate the corresponding percentage.</p>
+
+<h4><a name="marker-names">marker-names (1setof name(MAX))</a></h4>
+
+<p>The marker-names attribute specifies the name(s) for each supply in the
+printer. It is only available when the driver provides supply levels.</p>
+
+<h4><a name="marker-types">marker-types (1setof type3 keyword)</a></h4>
+
+<p>The marker-types attribute specifies the type(s) of each supply in the
+printer. It is only available when the driver provides supply levels. The
+following (RFC 3805) types are currently supported:</p>
+
+<ul>
+
+       <li><tt>toner</tt></li>
+
+       <li><tt>wasteToner</tt></li>
+
+       <li><tt>ink</tt></li>
+
+       <li><tt>inkCartridge</tt></li>
+
+       <li><tt>inkRibbon</tt></li>
+
+       <li><tt>wasteInk</tt></li>
+
+       <li><tt>opc</tt></li>
+
+       <li><tt>developer</tt></li>
+
+       <li><tt>fuserOil</tt></li>
+
+       <li><tt>solidWax</tt></li>
+
+       <li><tt>ribbonWax</tt></li>
+
+       <li><tt>wasteWax</tt></li>
+
+       <li><tt>fuser</tt></li>
+
+       <li><tt>coronaWire</tt></li>
+
+       <li><tt>fuserOilWick</tt></li>
+
+       <li><tt>cleanerUnit</tt></li>
+
+       <li><tt>fuserCleaningPad</tt></li>
+
+       <li><tt>transferUnit</tt></li>
+
+       <li><tt>tonerCartridge</tt></li>
+
+       <li><tt>fuserOiler</tt></li>
+
+       <li><tt>water</tt></li>
+
+       <li><tt>wasteWater</tt></li>
+
+       <li><tt>bindingSupply</tt></li>
+
+       <li><tt>bandingSupply</tt></li>
+
+       <li><tt>stichingWire</tt></li>
+
+       <li><tt>shrinkWrap</tt></li>
+
+       <li><tt>paperWrap</tt></li>
+
+       <li><tt>staples</tt></li>
+
+       <li><tt>inserts</tt></li>
+
+       <li><tt>covers</tt></li>
+
+</ul>
+
 <h4><a name="port-monitor">port-monitor" (name(127))</a></h4>
 
 <p>The port-monitor attribute specifies the port monitor to use when printing
index 0285f4697f13001dc081a90bae86451ef751a76e..63238e557c5bea2559f13252c95630eab72289ce 100644 (file)
@@ -12,7 +12,7 @@
 
   CUPS PPD extensions specification for the Common UNIX Printing System (CUPS).
 
-  Copyright 2007 by Apple Inc.
+  Copyright 2007-2008 by Apple Inc.
   Copyright 1997-2007 by Easy Software Products.
 
   These coded instructions, statements, and computer programs are the
@@ -1192,6 +1192,20 @@ http://www.vendor.com/help"
 *End
 </pre>
 
+<h3><span class='info'>CUPS 1.4</span><a name='cupsMarkerName'>cupsMarkerName</a></h3>
+
+<p class='summary'>*cupsMarkerName/Name Text: ""</p>
+
+<p>This optional attribute maps <code>marker-names</code> strings that are
+generated by the driver to human readable text.</p>
+
+<p>Examples:</p>
+
+<pre class='command'>
+<em>*% Map cyanToner to "Cyan Toner"</em>
+*cupsMarkerName cyanToner/Cyan Toner: ""
+</pre>
+
 <h3><span class='info'>CUPS 1.2</span><a name='cupsLanguages'>cupsLanguages</a></h3>
 
 <p class='summary'>*cupsLanguages: "locale list"</p>
@@ -1204,7 +1218,7 @@ list of locale names ("en", "en_US", "fr_CA", etc.)</p>
 
 <pre class='command'>
 <em>*% Specify Canadian, UK, and US English, and Candian and French French</em> 
-*cupsLanguages: "en_CA en_UK en_US fr_CA fr_CA"
+*cupsLanguages: "en_CA en_UK en_US fr_CA fr_FR"
 </pre>
 
 <h3><a name='cupsManualCopies'>cupsManualCopies</a></h3>
index f0691fc72d714ed95d0d60a3fa76bc990bb4cc16..5f6a4aca52793b783b4e320c5c36c11f09b93d06 100644 (file)
@@ -168,9 +168,18 @@ uninstall64bit:
 apihelp:
        echo Generating CUPS API help files...
        mxmldoc --section "Programming" --title "Raster API" \
-               --intro api-raster.shtml \
+               --css ../doc/cups-printable.css \
+               --header api-raster.header --intro api-raster.shtml \
                raster.h interpret.c raster.c >../doc/help/api-raster.html
 
+framedhelp:
+       echo Generating CUPS API help files...
+       mxmldoc --section "Programming" --title "Raster API" \
+               --framed ../cups/api-raster \
+               --css ../doc/cups-printable.css \
+               --header api-raster.header --intro api-raster.shtml \
+               raster.h interpret.c raster.c
+
 
 #
 # formtops
diff --git a/filter/api-raster.header b/filter/api-raster.header
new file mode 100644 (file)
index 0000000..8c6aaa0
--- /dev/null
@@ -0,0 +1,37 @@
+<!--
+  "$Id$"
+
+  Raster API header for the Common UNIX Printing System (CUPS).
+
+  Copyright 2008 by Apple Inc.
+
+  These coded instructions, statements, and computer programs are the
+  property of Apple Inc. and are protected by Federal copyright
+  law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+  which should have been included with this file.  If this file is
+  file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">Raster API</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+       <th>Header</th>
+       <th>cups/raster.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+       <th>Library</th>
+       <td>-lcupsimage</td>
+</tr>
+<tr>
+       <th>See Also</th>
+       <td>Programming: <a href='api-overview.html'>Introduction to CUPS Programming</a><br>
+       Programming: <a href='api-cups.html'>CUPS API</a><br>
+       Programming: <a href='api-cups.html'>PPD API</a><br>
+       References: <a href='spec-ppd.html'>CUPS PPD Specification</a></td>
+</tr>
+</tbody>
+</table></div>
index 327592655b5ff77ec4fceb4a35ab31ba185fe656..b5529d2305ec6eb79845e74a46d0fd402d90ee43 100644 (file)
@@ -3,7 +3,7 @@
 
   Raster API introduction for the Common UNIX Printing System (CUPS).
 
-  Copyright 2007 by Apple Inc.
+  Copyright 2007-2008 by Apple Inc.
   Copyright 1997-2006 by Easy Software Products, all rights reserved.
 
   These coded instructions, statements, and computer programs are the
   file is missing or damaged, see the license at "http://www.cups.org/".
 -->
 
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name="OVERVIEW">Overview</a></h2>
 
-<p>The CUPS raster API provides a standard interface for reading
-and writing CUPS raster streams which are used for printing to
-raster printers. Because the raster format is updated from time
-to time, it is important to use this API to avoid
-incompatibilities with newer versions of CUPS.</p>
+<p>The CUPS raster API provides a standard interface for reading and writing
+CUPS raster streams which are used for printing to raster printers. Because the
+raster format is updated from time to time, it is important to use this API to
+avoid incompatibilities with newer versions of CUPS.</p>
 
-<h2 class='title'>General Usage</h2>
+<p>CUPS raster files (<code>application/vnd.cups-raster</code>) consists of
+a stream of raster page descriptions produced by one of the RIP filters such as
+<var>pstoraster</var>, <var>imagetoraster</var>, or
+<var>cgpdftoraster</var>. CUPS raster files are referred to using the
+<a href='#cups_raster_t'><code>cups_raster_t</code></a> type and are
+opened using the <a href='#cupsRasterOpen'><code>cupsRasterOpen</code></a>
+function. For example, to read raster data from the standard input, open
+file descriptor 0:</p>
 
-<p>The <var>&lt;cups/raster.h&gt;</var> header file must be
-included to use the <tt>cupsRaster</tt> functions.</p>
+<pre class="example">
+#include &lt;cups/raster.h&gt;>
 
-<p>Programs using these functions must be linked to the CUPS
-imaging library: <var>libcupsimage.a</var>,
-<var>libcupsimage.so.2</var>, <var>libcupsimage.2.dylib</var>,
-<var>libcupsimage_s.a</var>, or <var>libcupsimage2.lib</var>
-depending on the platform. The following command compiles
-<var>myprogram.c</var> using GCC and the CUPS imaging
-library:</p>
+<a href="#cups_raster_t">cups_raster_t</a> *ras = <a href="#cupsRasterOpen">cupsRasterOpen</a>(0, CUPS_RASTER_READ);
+</pre>
+
+<p>Each page of data begins with a page dictionary structure called
+<a href="#cups_page_header2_t"><code>cups_page_header2_t</code></a>. This
+structure contains the colorspace, bits per color, media size, media type,
+hardware resolution, and so forth used for the page. You read the page header
+using the
+<a href="#cupsRasterReadHeader2"><code>cupsRasterReadHeader2</code></a>
+function:</p>
+
+<pre class="example">
+#include &lt;cups/raster.h&gt;>
+
+<a href="#cups_raster_t">cups_raster_t</a> *ras = <a href="#cupsRasterOpen">cupsRasterOpen</a>(0, CUPS_RASTER_READ);
+<a href="#cups_page_header2_t">cups_page_header2_t</a> header;
 
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcupsimage</kbd>
+while (<a href="#cupsRasterReadHeader2">cupsRasterReadHeader2</a>(ras, &amp;header))
+{
+  /* setup this page */
+
+  /* read raster data */
+
+  /* finish this page */
+}
 </pre>
 
-<h2 class='title'>Compatibility</h2>
+<p>After the page dictionary comes the page data which is a full-resolution,
+possibly compressed bitmap representing the page in the printer's output
+colorspace. You read uncompressed raster data using the
+<a href="#cupsRasterReadPixels"><code>cupsRasterReadPixels</code></a>
+function. A <code>for</code> loop is normally used to read the page one line
+at a time:</p>
+
+<pre class="example">
+#include &lt;cups/raster.h&gt;>
+
+<a href="#cups_raster_t">cups_raster_t</a> *ras = <a href="#cupsRasterOpen">cupsRasterOpen</a>(0, CUPS_RASTER_READ);
+<a href="#cups_page_header2_t">cups_page_header2_t</a> header;
+int page = 0;
+int y;
+char *buffer;
 
-<p>Unless otherwise specified, the raster API functions require
-CUPS 1.1 or higher.</p>
+while (<a href="#cupsRasterReadHeader2">cupsRasterReadHeader2</a>(ras, &amp;header))
+{
+  /* setup this page */
+  page ++;
+  fprintf(stderr, "PAGE: %d %d\n", page, header.NumCopies);
 
-<h2 class='title'>Licensing</h2>
+  /* allocate memory for 1 line */
+  buffer = malloc(header.cupsBytesPerLine);
 
-<p>The CUPS raster API is provided under the terms of the GNU
-Library General Public License, with exceptions for MacOS X-based
-programs. Please see the CUPS license agreement for more
-information.</p>
+  /* read raster data */
+  for (y = 0; y &lt; header.cupsHeight; y ++)
+  {
+    if (<a href="#cupsRasterReadPixels">cupsRasterReadPixels</a>(ras, buffer, header.cupsBytesPerLine) == 0)
+      break;
+
+    /* write raster data to printer */
+  }
+
+  /* finish this page */
+}
+</pre>
+
+<p>When you are done reading the raster data, call the
+<a href="#cupsRasterClose"><code>cupsRasterClose</code></a> function to free
+the memory used to read the raster file:</p>
+
+<pre class="example">
+<a href="#cups_raster_t">cups_raster_t</a> *ras;
+
+<a href="#cupsRasterClose">cupsRasterClose</a>(ras);
+</pre>
index e0db81e63f580b5ab4ab9692246b300244f3303e..a4687bd2809c51240b29fdeaec86f1fca146947a 100644 (file)
@@ -123,19 +123,22 @@ static void               DEBUG_stack(_cups_ps_stack_t *st);
  * 'cupsRasterInterpretPPD()' - Interpret PPD commands to create a page header.
  *
  * This function does not mark the options in the PPD using the "num_options"
- * and "options" arguments.  Instead, mark the options prior to calling
- * cupsRasterInterpretPPD() - this allows you to do per-page options
+ * and "options" arguments.  Instead, mark the options with
+ * @code cupsMarkOptions@ and @code ppdMarkOption@ prior to calling
+ * @code cupsRasterInterpretPPD@ - this allows you to do per-page options
  * without manipulating the options array.
  *
  * The "func" argument specifies an optional callback function that is
  * called prior to the computation of the final raster data.  The function
- * can make changes to the cups_page_header2_t data as needed to use a
+ * can make changes to the @link cups_page_header2_t@ data as needed to use a
  * supported raster format and then returns 0 on success and -1 if the
  * requested attributes cannot be supported.
  *
- * cupsRasterInterpretPPD() supports a subset of the PostScript language.
- * Currently only the [, ], <<, >>, {, }, cleartomark, copy, dup, index,
- * pop, roll, setpagedevice, and stopped operators are supported.
+ * @code cupsRasterInterpretPPD@ supports a subset of the PostScript language.
+ * Currently only the @code [@, @code ]@, @code <<@, @code >>@, @code {@,
+ * @code }@, @code cleartomark@, @code copy@, @code dup@, @code index@,
+ * @code pop@, @code roll@, @code setpagedevice@, and @code stopped@ operators
+ * are supported.
  *
  * @since CUPS 1.2@
  */
index 4092dfa0d89b882e84cb0875d8a17777d18bb50e..2155ea5166cdda39718731eb4e76fe1c54264205 100644 (file)
@@ -147,12 +147,14 @@ typedef enum cups_jog_e                   /**** Jog attribute values ****/
   CUPS_JOG_SET = 3                     /* Move pages after this set */
 } cups_jog_t;
 
-typedef enum cups_mode_e               /**** Raster modes ****/
+enum cups_mode_e                       /**** cupsRasterOpen modes ****/
 {
   CUPS_RASTER_READ = 0,                        /* Open stream for reading */
   CUPS_RASTER_WRITE = 1,               /* Open stream for writing */
   CUPS_RASTER_WRITE_COMPRESSED = 2     /* Open stream for compressed writing @since CUPS 1.3@ */
-} cups_mode_t;
+};
+
+typedef enum cups_mode_e cups_mode_t;  /**** cupsRasterOpen modes ****/
 
 typedef enum cups_order_e              /**** cupsColorOrder attribute values ****/
 {
@@ -179,7 +181,7 @@ typedef enum cups_orient_e          /**** Orientation attribute values ****/
  * (from CUPS 1.2 and higher) page header, for binary compatibility.
  */
 
-typedef struct cups_page_header_s      /**** Version 1 Page Header ****/
+typedef struct cups_page_header_s      /**** Version 1 page header ****/
 {
   /**** Standard Page Device Dictionary String Values ****/
   char         MediaClass[64];         /* MediaClass string */
@@ -228,7 +230,7 @@ typedef struct cups_page_header_s   /**** Version 1 Page Header ****/
 } cups_page_header_t;
 
 /**** New in CUPS 1.2 ****/
-typedef struct cups_page_header2_s     /**** Version 2 Page Header @since CUPS 1.2@ ****/
+typedef struct cups_page_header2_s     /**** Version 2 page header @since CUPS 1.2@ ****/
 {
   /**** Standard Page Device Dictionary String Values ****/
   char         MediaClass[64];         /* MediaClass string */
@@ -295,6 +297,13 @@ typedef struct _cups_raster_s cups_raster_t;
                                        /**** Raster stream data ****/
 
 typedef int (*cups_interpret_cb_t)(cups_page_header2_t *header, int preferred_bits);
+                                       /**** cupsRasterInterpretPPD callback function
+                                        *
+                                        * This function is called by
+                                        * @link cupsRasterInterpretPPD@ to
+                                        * validate (and update, as needed)
+                                        * the page header attributes.
+                                        ****/
 
 
 /*
index 98e1b7cf0b4c3d0b862832b944cce757825129bf..706c315418ec95c5af46ccb98cafc607b6727a63 100644 (file)
@@ -2369,7 +2369,11 @@ cupsdSendHeader(
     char           *type,              /* I - MIME type of document */
     int            auth_type)          /* I - Type of authentication */
 {
-  char auth_str[1024];                 /* Authorization string */
+  char         auth_str[1024];         /* Authorization string */
+#ifdef HAVE_GSSAPI
+  static char  *gss_buf = NULL;        /* Kerberos auth data buffer */
+  static int   gss_bufsize = 0;        /* Size of Kerberos auth data buffer */
+#endif /* HAVE_GSSAPI */
 
 
  /*
@@ -2478,23 +2482,57 @@ cupsdSendHeader(
   * non-401 replies...
   */
 
-  if (con->gss_output_token.length > 0)
+  if (con->gss_output_token.length > 0 && con->gss_output_token.length <= 65536)
   {
-    char       buf[2048];              /* Output token buffer */
     OM_uint32  minor_status;           /* Minor status code */
+    int                bufsize;                /* Size of output token buffer */
+
+
+    bufsize = con->gss_output_token.length * 4 / 3 + 2;
+
+    if (bufsize > gss_bufsize)
+    {
+      char     *buf;                   /* New buffer */
+
 
+      bufsize = (bufsize + 1023) & 1023;/* Round up */
 
-    httpEncode64_2(buf, sizeof(buf),
-                  con->gss_output_token.value,
+      if (gss_buf)
+        buf = realloc(gss_buf, bufsize);
+      else
+        buf = malloc(bufsize);
+
+      if (!buf)
+      {
+       cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Unable to allocate %d bytes for Kerberos credentials!",
+                       bufsize);
+       return (0);
+      }
+
+      gss_buf     = buf;
+      gss_bufsize = bufsize;
+    }
+
+    httpEncode64_2(gss_buf, gss_bufsize,
+                  con->gss_output_token.value,
                   con->gss_output_token.length);
     gss_release_buffer(&minor_status, &con->gss_output_token);
 
     cupsdLogMessage(CUPSD_LOG_DEBUG,
-                    "cupsdSendHeader: WWW-Authenticate: Negotiate %s", buf);
+                   "cupsdSendHeader: WWW-Authenticate: Negotiate %s", gss_buf);
 
-    if (httpPrintf(HTTP(con), "WWW-Authenticate: Negotiate %s\r\n", buf) < 0)
+    if (httpPrintf(HTTP(con), "WWW-Authenticate: Negotiate %s\r\n",
+                   gss_buf) < 0)
       return (0);
   }
+  else if (con->gss_output_token.length > 65536)
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR,
+                    "Kerberos credentials larger than 64k (%d)!",
+                   con->gss_output_token.length);
+    return (0);
+  }
 #endif /* HAVE_GSSAPI */
 
   if (con->language && strcmp(con->language->language, "C"))
index df8f7e93320339f52a899062d266637ab678bccf..39ba5919b6f76b5dbd387d32738d4bad48245962 100644 (file)
@@ -4668,6 +4668,10 @@ copy_printer_attrs(
                 printer->recoverable);
 #endif /* __APPLE__ */
 
+  if (!ra || cupsArrayFind(ra, "marker-change-time"))
+    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+                  "marker-change-time", printer->marker_time);
+
   if (printer->alert && (!ra || cupsArrayFind(ra, "printer-alert")))
     ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_STRING,
                  "printer-alert", NULL, printer->alert);
index 19f48a50cd8a2137637c458e400cd6f70a2d3531..004ee51485e7f0acf3a0bd6a059b6d8facdd9e89 100644 (file)
@@ -3673,6 +3673,34 @@ update_job(cupsd_job_t *job)             /* I - Job to check */
        event |= CUPSD_EVENT_PRINTER_STATE;
       }
 
+      if ((attr = cupsGetOption("marker-colors", num_attrs, attrs)) != NULL)
+      {
+        cupsdSetPrinterAttr(job->printer, "marker-colors", (char *)attr);
+       job->printer->marker_time = time(NULL);
+       event |= CUPSD_EVENT_PRINTER_STATE;
+      }
+
+      if ((attr = cupsGetOption("marker-levels", num_attrs, attrs)) != NULL)
+      {
+        cupsdSetPrinterAttr(job->printer, "marker-levels", (char *)attr);
+       job->printer->marker_time = time(NULL);
+       event |= CUPSD_EVENT_PRINTER_STATE;
+      }
+
+      if ((attr = cupsGetOption("marker-names", num_attrs, attrs)) != NULL)
+      {
+        cupsdSetPrinterAttr(job->printer, "marker-names", (char *)attr);
+       job->printer->marker_time = time(NULL);
+       event |= CUPSD_EVENT_PRINTER_STATE;
+      }
+
+      if ((attr = cupsGetOption("marker-types", num_attrs, attrs)) != NULL)
+      {
+        cupsdSetPrinterAttr(job->printer, "marker-types", (char *)attr);
+       job->printer->marker_time = time(NULL);
+       event |= CUPSD_EVENT_PRINTER_STATE;
+      }
+
       cupsFreeOptions(num_attrs, attrs);
     }
 #ifdef __APPLE__
index 6eab48a846d9e00553a401230c6feb49d2f1ce72..6dc8bd97127adfd51e107ff63b496903c4f70a59 100644 (file)
@@ -27,6 +27,7 @@
  *   cupsdSaveAllPrinters()      - Save all printer definitions to the
  *                                 printers.conf file.
  *   cupsdSetAuthInfoRequired()  - Set the required authentication info.
+ *   cupsdSetPrinterAttr()       - Set a printer attribute.
  *   cupsdSetPrinterAttrs()      - Set printer attributes based upon the PPD
  *                                 file.
  *   cupsdSetPrinterReasons()    - Set/update the reasons strings.
@@ -1650,6 +1651,120 @@ cupsdSetAuthInfoRequired(
 }
 
 
+/*
+ * 'cupsdSetPrinterAttr()' - Set a printer attribute.
+ */
+
+void
+cupsdSetPrinterAttr(
+    cupsd_printer_t *p,                        /* I - Printer */
+    const char      *name,             /* I - Attribute name */
+    char            *value)            /* I - Attribute value string */
+{
+  ipp_attribute_t      *attr;          /* Attribute */
+  int                  i,              /* Looping var */
+                       count;          /* Number of values */
+  char                 *ptr;           /* Pointer into value */
+  ipp_tag_t            value_tag;      /* Value tag for this attribute */
+
+
+ /*
+  * Count the number of values...
+  */
+
+  for (count = 1, ptr = value;
+       (ptr = strchr(ptr, ',')) != NULL;
+       ptr ++, count ++);
+
+ /*
+  * Then add or update the attribute as needed...
+  */
+
+  if (!strcmp(name, "marker-levels"))
+  {
+   /*
+    * Integer values...
+    */
+
+    if ((attr = ippFindAttribute(p->attrs, name, IPP_TAG_INTEGER)) != NULL &&
+        attr->num_values < count)
+    {
+      ippDeleteAttribute(p->attrs, attr);
+      attr = NULL;
+    }
+
+    if (attr)
+      attr->num_values = count;
+    else
+      attr = ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, name,
+                            count, NULL);
+
+    if (!attr)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                      "Unable to allocate memory for printer attribute "
+                     "(%d values)", count);
+      return;
+    }
+
+    for (i = 0; i < count; i ++)
+    {
+      if ((ptr = strchr(value, ',')) != NULL)
+        *ptr++ = '\0';
+
+      attr->values[i].integer = strtol(value, NULL, 10);
+
+      if (ptr)
+        value = ptr;
+    }
+  }
+  else
+  {
+   /*
+    * Name or keyword values...
+    */
+
+    if (!strcmp(name, "marker-types"))
+      value_tag = IPP_TAG_KEYWORD;
+    else
+      value_tag = IPP_TAG_NAME;
+
+    if ((attr = ippFindAttribute(p->attrs, name, value_tag)) != NULL &&
+        attr->num_values < count)
+    {
+      ippDeleteAttribute(p->attrs, attr);
+      attr = NULL;
+    }
+
+    if (attr)
+      attr->num_values = count;
+    else
+      attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, value_tag, name,
+                           count, NULL, NULL);
+
+    if (!attr)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                      "Unable to allocate memory for printer attribute "
+                     "(%d values)", count);
+      return;
+    }
+
+    for (i = 0; i < count; i ++)
+    {
+      if ((ptr = strchr(value, ',')) != NULL)
+        *ptr++ = '\0';
+
+      _cupsStrFree(attr->values[i].string.text);
+      attr->values[i].string.text = _cupsStrAlloc(value);
+
+      if (ptr)
+        value = ptr;
+    }
+  }
+}
+
+
 /*
  * 'cupsdSetPrinterAttrs()' - Set printer attributes based upon the PPD file.
  */
index 7a19b973e02ff8d84785a975b525645156913b3a..a7fecdad5f60b251917e876baaeda77cc3be31c0 100644 (file)
@@ -86,6 +86,7 @@ typedef struct cupsd_printer_s
   const char   *auth_info_required[4]; /* Required authentication fields */
   char         *alert,                 /* PSX printer-alert value */
                *alert_description;     /* PSX printer-alert-description value */
+  time_t       marker_time;            /* Last time marker attributes were updated */
 
 #ifdef __APPLE__
   char         *recoverable;           /* com.apple.print.recoverable-message */
@@ -150,6 +151,8 @@ extern void         cupsdSaveAllPrinters(void);
 extern int             cupsdSetAuthInfoRequired(cupsd_printer_t *p,
                                                 const char *values,
                                                 ipp_attribute_t *attr);
+extern void            cupsdSetPrinterAttr(cupsd_printer_t *p,
+                                           const char *name, char *value);
 extern void            cupsdSetPrinterAttrs(cupsd_printer_t *p);
 extern void            cupsdSetPrinterReasons(cupsd_printer_t *p,
                                               const char *s);
index a22548e8f87a97553606dac35c4510be68b8210f..d37b07915c973d638bd9b1c76cb652b5524e2ce9 100644 (file)
@@ -106,7 +106,8 @@ cupsdCreateProfile(int job_id)              /* I - Job ID or 0 for none */
                 "#\"^/Library\" #\"^/System\" #\"^/Users\"))\n", root);
   cupsFilePrintf(fp,
                  "(allow file-write* file-read-data file-read-metadata\n"
-                 "  (regex #\"^%s$\" #\"^%s/\" #\"^%s$\" #\"^%s/\"))\n",
+                 "  (regex #\"^%s$\" #\"^%s/\" #\"^%s$\" #\"^%s/\" "
+                "#\"^/Library/Caches/\"))\n",
                 temp, temp, cache, cache);
   if (job_id)
     cupsFilePrintf(fp,