CAPS Universe documentation  1.0.4
All you need to know to be successful
Data Structures | Functions

Retrieve available printers and their state. More...

Data Structures

struct  caps_cl_printer_list
 
struct  caps_cl_printer_info
 
struct  caps_cl_printer_state
 

Functions

int caps_cl_printer_list_get (struct caps_cl_handle *instance, struct caps_cl_printer_list **list)
 
int caps_cl_printer_info_get (struct caps_cl_handle *instance, caps_identifier printer_id, struct caps_cl_printer_info **info)
 
void caps_cl_printer_info_destroy (struct caps_cl_handle *instance, struct caps_cl_printer_info *info)
 
int caps_cl_printer_state_get (struct caps_cl_handle *instance, caps_identifier printer_id, struct caps_cl_printer_state *state)
 
int caps_cl_printer_PPD_get (struct caps_cl_handle *instance, caps_identifier printer_id, int *ppdfh)
 
int caps_cl_printer_name_to_id (struct caps_cl_handle *instance, const char *name, caps_identifier *printer_id)
 

Detailed Description

Some descriptions here use the description printer, some other the description printing provider. A printer is always the physical device, the printing provider the logical unit to manage this printer. It's a piece of software only and thus, can be run anywhere. Please bear with me if I don't use these two descriptions consequently. But most of the time it makes no difference, which one I use.

A printing provider is always identified by its identifier. This identifier is a 63 bit unique value (yes! sixty three) and names exactly one printing provider.

Attention
Printing providers can come and go as they like. You should always be prepared for the case the identifier is rejected with a returned -ENODEV error code.

You can retrieve the currently know printing providers with a call to caps_cl_printer_list_get(). It returns a list of printing provider identifiers. The content of this list you can use to retrieve the details for each entry in a second step.

In your program it looks like that:

void retrieve_list(struct caps_cl_handle *instance)
{
struct caps_cl_printer_list *pr_list;
size_t u = 0;
int rc:
rc = caps_cl_printer_list_get(instance, &pr_list);
if (rc == -ENODEV) {
fprintf(stderr, "No printers available\n");
return;
}
while (u < pr_list->cnt) {
rc = caps_cl_printer_info_get(instance, pr_list->list[u++], &info);
if (rc == -ENODEV)
continue; // just ignore it
// do something with the information
}
free(pr_list);
}
void caps_cl_printer_info_destroy(struct caps_cl_handle *instance, struct caps_cl_printer_info *info)
Definition: libcapsclient.c:384
int caps_cl_printer_info_get(struct caps_cl_handle *instance, caps_identifier printer_id, struct caps_cl_printer_info **info)
Definition: libcapsclient.c:270
int caps_cl_printer_list_get(struct caps_cl_handle *instance, struct caps_cl_printer_list **list)
Definition: libcapsclient.c:151
Definition: libcapsclient.c:45
Definition: libcapsclient.h:370
char * info
Definition: libcapsclient.h:372
Definition: libcapsclient.h:346
caps_identifier list[0]
Definition: libcapsclient.h:348
Note
Connecting to the Printing Coordinator must already be done outside the shown function above. Refer Be part of the whole thing for details.

Knowing the printer ID is the key to retrieve other information/data of the printer as well.

Using the function caps_cl_printer_state_get() let you retrieve the current state the printer is in. Refer Printer State Definitions for details about states a printer can be in.

You can also request for the PostScript Printer Description file (aka PPD) for a more detailed feature description of the printer via the function caps_cl_printer_PPD_get(). Content from this file let you control the print job later on.

Attention
Expect PPD files as not static. They are always generated on the fly by the printing provider and my change over the time it is online
Think about the printer is capable to detect its loaded paper and the user loads a different paper to its tray. In this case two consecutive calls to caps_cl_printer_PPD_get() may result into a different PPD file content.
Todo:
From name to ID, what are the IDs?

Function Documentation

◆ caps_cl_printer_list_get()

int caps_cl_printer_list_get ( struct caps_cl_handle instance,
struct caps_cl_printer_list **  list 
)

Request for a list of IDs of currently known printing providers

Parameters
[in]instanceClient instance
[in,out]listWhere to store the result
Return values
0Success and *list is valid
-ENODEVIf no printers are available (*list is invalid)
-EIOReal communication error with the Printing Coordinator (should not happen)
-EINVALBad/unexpected reply from the Printing Coordinator (should not happen)
Note
The returned list is always a snap shot: it depends on the currently known printing providers - which can come and go dynamically.
Precondition
A registered client instance
Postcondition
-EIO and -EINVAL create a readable error message (refer caps_cl_error_messages_catch())
The returned structure in *list must be freed with free() afterwards.

Developer's corner

The communication with the printing coordinator:

The full call stack:

Note
Counterpart is dbus_get_printer_list_dispatch()

◆ caps_cl_printer_info_get()

int caps_cl_printer_info_get ( struct caps_cl_handle instance,
caps_identifier  printer_id,
struct caps_cl_printer_info **  info 
)

Retrieve a printing provider's base information

Parameters
[in]instanceClient instance
[in]printer_idThe printing provider's identifier to query
[out]infoWhere to store the pointer to the information
Return values
0On success (*info is valid)
-ENODEVprinter_id invalid or outdated (*info is invalid)
-EIOReal communication error with the Printing Coordinator (should not happen, *info is invalid)
-EINVALBad/unexpected reply from the Printing Coordinator (should not happen, *info is invalid)

Returns some generic information about the printer_id printing provider. This information is mostly originated by some admin when installing the printer and connecting a printing provider to it. The language is unknown. Encoding of all strings is utf8.

The returned information in info is inspired by the IPP protocol and the PPD file content. It should enable the client to select a specific printing provider later on.

As an example it could look like this:

Typ String Content
name Main Office Printer
info Don't use for mass printing
location 2nd floor
vendor Acme
model Laser Printer
Note
The information stored in info uses dynamically allocated memory and needs to be freed after use. Refer the postcondition note below.
Precondition
printer_id must be valid (e.g. a positive value, not CAPS_INVALID_IDENTIFIER for example)
A registered client instance
Postcondition
The returned caps_cl_printer_info structure must be freed by a call to caps_cl_printer_info_destroy()
-EIO and -EINVAL create a readable error message (refer caps_cl_error_messages_catch())

Developer's corner

The communication with the printing coordinator:

The full call stack:

Note
Counterpart is dbus_get_printers_info_dispatch()

◆ caps_cl_printer_info_destroy()

void caps_cl_printer_info_destroy ( struct caps_cl_handle instance,
struct caps_cl_printer_info info 
)

Free resources from caps_cl_printer_info_get()

Parameters
[in]instanceClient instance
[in]infoPrinter information to destroy
Precondition
A registered client instance

Developer's corner

The full call stack:

◆ caps_cl_printer_state_get()

int caps_cl_printer_state_get ( struct caps_cl_handle instance,
caps_identifier  printer_id,
struct caps_cl_printer_state state 
)

Get the state of a specific printer/printing provider

Parameters
[in]instanceClient instance
[in]printer_idThe printing provider's identifier
[out]stateWhere to store the printing provider's state
Return values
0On success (*state is valid)
-ENODEVprinter_id invalid (*state is invalid)
-EIOReal communication error with the Printing Coordinator (should not happen, *state is invalid)
-EINVALBad/unexpected reply from the Printing Coordinator (should not happen, *state is invalid)

From the client point of view, a printer can be in one of the following active states:

Or in one of the tear down states (e.g. no acceptance of new print jobs anymore):

Refer Printer State Definitions for details about printing provider states.

Attention
Be always prepared for the -ENODEV return value. A printing provider can disappear at every point of time.
Note
Even if the printer is already gone, you can still query its state for a specific number of times:
Precondition
printer_id must be valid (e.g. a positive value, not CAPS_INVALID_IDENTIFIER for example)
A registered client instance
Postcondition
Always evaluate the return value. The data at *state is valid only if the return value is '0'!
-EIO and -EINVAL create a readable error message (refer caps_cl_error_messages_catch())

Developer's corner

The communication with the printing coordinator:

The full call stack:

Note
Counterpart is dbus_get_printers_state_dispatch()

◆ caps_cl_printer_PPD_get()

int caps_cl_printer_PPD_get ( struct caps_cl_handle instance,
caps_identifier  printer_id,
int *  ppdfh 
)

Get the printer's PPD file as a file descriptor

Parameters
[in]instanceClient instance
[in]printer_idThe printing provider's identifier to query
[out]ppdfhWhere to store the PPD's file descriptor
Return values
0On success (*ppdfh is valid)
-ENODEVprinter_id invalid (*ppdfh is invalid)
-EIOReal communication error with the Printing Coordinator (should not happen, *ppdfh is invalid)
-EINVALBad/unexpected reply from the Printing Coordinator (should not happen, *ppdfh is invalid)

After the call the PPD file's read pointer is at the beginning of the file. This returned file descriptor isn't a shared resource - this function delivers a self removing copy instead. If you close the file descriptor the file is gone.

Note
The returned filehandle is opened read-only.
Precondition
A registered client instance
printer_id must be valid (e.g. a positive value, not CAPS_INVALID_IDENTIFIER for example)
Postcondition
-EIO and -EINVAL create a readable error message (refer caps_cl_error_messages_catch())

Developer's corner

The communication with the printing coordinator:

The full call stack:

Note
Counterpart is dbus_get_printers_PPD_dispatch()

◆ caps_cl_printer_name_to_id()

int caps_cl_printer_name_to_id ( struct caps_cl_handle instance,
const char *  name,
caps_identifier printer_id 
)

Get the unique ID of a named printing provider

Parameters
[in]instanceClient instance
[in]nameThe name of the printer (from the caps_cl_printer_info::name member)
[out]printer_idThe ID of the requested printer
Return values
0On success (*printer_id is valid)
-ENODEVNo printer with name found (*printer_id is invalid)

If you know the name of a printer, but not its identifier, you can call this function.

Note
This operation is somehow dangerous, because the caps_cl_printer_info::name should be unique, but you cannot really rely on it (think about a mistake made by the admin when defining the name of a printer). Only the printing provider ID is unique in each Printing Coordinator instance.
Precondition
A registered client instance

Developer's corner

The communication with the printing coordinator: