summaryrefslogtreecommitdiff
path: root/cups/api-cups.shtml
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2008-01-31 17:01:57 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2008-01-31 17:01:57 +0000
commit5a738aeaea5c4dd9384a8601cc5c99be683b69ca (patch)
tree519e13a0beb3234458a686c2f7cb25b36fef4f72 /cups/api-cups.shtml
parentd9bca400bee5f6168a7e07f85279251f040d734c (diff)
downloadcups-5a738aeaea5c4dd9384a8601cc5c99be683b69ca.tar.gz
Merge changes from CUPS 1.4svn-r7282.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@614 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'cups/api-cups.shtml')
-rw-r--r--cups/api-cups.shtml428
1 files changed, 404 insertions, 24 deletions
diff --git a/cups/api-cups.shtml b/cups/api-cups.shtml
index 483feb30b..29982e58d 100644
--- a/cups/api-cups.shtml
+++ b/cups/api-cups.shtml
@@ -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
@@ -13,35 +13,415 @@
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>