diff options
author | msweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be> | 2008-01-31 17:01:57 +0000 |
---|---|---|
committer | msweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be> | 2008-01-31 17:01:57 +0000 |
commit | 5a738aeaea5c4dd9384a8601cc5c99be683b69ca (patch) | |
tree | 519e13a0beb3234458a686c2f7cb25b36fef4f72 /cups/api-cups.shtml | |
parent | d9bca400bee5f6168a7e07f85279251f040d734c (diff) | |
download | cups-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.shtml | 428 |
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><cups/cups.h></var> header file must be included to -use the CUPS functions.</p> +<pre class='example'> +#include <cups/cups.h> -<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>(&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 <cups/cups.h> + +<a href='#cups_dest_t'>cups_dest_t</a> *dests; +int num_dests = <a href='#cupsGetDests'>cupsGetDests</a>(&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 <cups/cups.h> + +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, &options); + +/* This adds a second option value */ +num_options = <a href='#cupsAddOption'>cupsAddOption</a>("second", "value", num_options, &options); + +/* This replaces the first option we added */ +num_options = <a href='#cupsAddOption'>cupsAddOption</a>("first", "new value", num_options, &options); +</pre> + +<p>Use a <code>for</code> loop to copy the options from a destination:</p> + +<pre class='example'> +#include <cups/cups.h> + +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, &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 <cups/cups.h> + +<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 <cups/cups.h> + +<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 <cups/cups.h> + +<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 <= 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 <cups/cups.h> + +<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 < IPP_JOB_STOPPED) +{ + /* Get my jobs (1) with any state (-1) */ + num_jobs = <a href='#cupsGetJobs'>cupsGetJobs</a>(&jobs, dest->name, 1, -1); + + /* Loop to find my job */ + job_state = IPP_JOB_COMPLETED; + + for (i = 0; i < 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 < 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 <cups/cups.h> + +<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 <cups/cups.h> + +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 <cups/cups.h> + +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> |