CAPS Universe documentation  1.0.4
All you need to know to be successful
Data Structures | Macros | Functions
libcapsclient.c File Reference

Library to gain access to the printing coordinator for clients. More...

Data Structures

struct  caps_cl_handle
 

Macros

#define valid_instance_assert(instance)   { if (instance->conn == NULL) caps_developers_failure_report(__func__); }
 

Functions

void caps_libclient_version_get (unsigned *major, unsigned *minor, unsigned *micro)
 
static void print_argument_failure (struct caps_cl_handle *instance, DBusMessage *message, const DBusError *error)
 
static void print_rpc_failure (struct caps_cl_handle *instance, DBusMessage *message, const DBusError *error)
 
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)
 
int caps_cl_job_commit (struct caps_cl_handle *instance, caps_identifier printer_id, int job_fd, const char *parameter, caps_identifier *job_id)
 
int caps_cl_job_state_get (struct caps_cl_handle *instance, caps_identifier job_id, struct caps_cl_job_state *state)
 
static int send_message_and_receive_int32 (struct caps_cl_handle *instance, DBusMessage *message)
 
int caps_cl_job_cancel (struct caps_cl_handle *instance, caps_identifier job_id)
 
bool caps_cl_job_check_if_done (struct caps_cl_handle *instance, const struct caps_cl_job_state *state)
 
int caps_cl_job_progression_get (struct caps_cl_handle *instance, caps_identifier job_id, struct caps_job_progression *prog)
 
static int client_introduction (struct caps_cl_handle *instance)
 
static DBusHandlerResult handle_provider_change_notifier (DBusMessage *message, void *data)
 
static DBusHandlerResult handle_job_change_notifier (DBusMessage *message, void *data)
 
static DBusHandlerResult client_signal_dispatch (DBusConnection *connection, DBusMessage *message, void *data)
 
static int dbus_signal_handling_register (struct caps_cl_handle *instance, const struct caps_cl_notifier *notifier, void *data)
 
static DBusBusType dbus_bus_type_detect (void)
 
struct caps_cl_handlecaps_cl_instance_create (void)
 
int caps_cl_error_messages_catch (struct caps_cl_handle *instance, char **ptr, size_t *size)
 
void caps_cl_error_messages_reset (struct caps_cl_handle *instance)
 
static dbus_bool_t caps_client_add_watch_function (DBusWatch *watch, void *data)
 
static void caps_client_remove_watch_function (DBusWatch *watch, void *data)
 
static void caps_client_watch_toggle_function (DBusWatch *watch, void *data)
 
static int setup_watches (struct caps_cl_handle *instance)
 
int caps_cl_instance_register (struct caps_cl_handle *instance, const struct caps_cl_notifier *notifier, void *data)
 
void caps_cl_instance_unregister (struct caps_cl_handle *instance)
 
void caps_cl_instance_destroy (struct caps_cl_handle *instance)
 
int caps_cl_notifiers_process (struct caps_cl_handle *instance)
 
int caps_cl_connection_fd_get (struct caps_cl_handle *instance)
 

Detailed Description

Author
Jürgen Borleis
Warning
Use as experimental

Macro Definition Documentation

◆ valid_instance_assert

#define valid_instance_assert (   instance)    { if (instance->conn == NULL) caps_developers_failure_report(__func__); }

Force a registered client instance

Parameters
[in]instanceClient instance

Using an unregistered client instance violated the API for most of the functions here. Be rigorous and crash the caller in this case.

Function Documentation

◆ print_argument_failure()

static void print_argument_failure ( struct caps_cl_handle instance,
DBusMessage *  message,
const DBusError *  error 
)
static

Just print a unified error message when the RPC arguments are wrong

Parameters
[in]instanceThe library instance handle
[in]messageJust to get the method to show where it happens
[in]errorThe error message to print

◆ print_rpc_failure()

static void print_rpc_failure ( struct caps_cl_handle instance,
DBusMessage *  message,
const DBusError *  error 
)
static

Just print a unified error message when the RPC fails

Parameters
[in]instanceThe library instance handle
[in]messageJust to get the method to show where it happens
[in]errorThe error message to print
Todo:
Since an invalid printer ID is a regular use case (and no error), we should suppress a corresponding error message here. A return value of -ENODEV could help the caller to make the correct decisions. Refer dbus_report_unknown_pr_id() for the error message in this case.

◆ send_message_and_receive_int32()

static int send_message_and_receive_int32 ( struct caps_cl_handle instance,
DBusMessage *  message 
)
static

Send the given message and read back an int32_t reply

Parameters
instanceThe library instance handle
messageThe message to send
Return values
positiveReturned RPC value on success (0 is positive)
-EIOReal communication error with the printing coordinator
-EINVALBad/unexpected reply from the Printing Coordinator (should not happen)
Postcondition
The message still needs to be freed (via dbus_message_unref())

◆ client_introduction()

static int client_introduction ( struct caps_cl_handle instance)
static

Introduce ourself at the printing coordinator

Parameters
instanceThe library instance handle
Return values
positiveReturned RPC value on success (0 is positive)
-EIOReal communication error with the printing coordinator
-EINVALBad/unexpected reply from the Printing Coordinator (should not happen)
-ENOSYSUnsupported client version

Currently an unsupported client version means, the expected and implemented DBUS interfaces do not match.

Counterpart is dbus_client_introduction_dispatch()

◆ handle_provider_change_notifier()

static DBusHandlerResult handle_provider_change_notifier ( DBusMessage *  message,
void *  data 
)
static

Handle the "Printing Provider Change" DBUS signal, convert it to a library callback/notifier

Parameters
[in]messageThe signal message itself, must be of method SEND_PROVIDER_CHANGE_NOTIFIER_METHOD
[in]dataOur local library handle
Returns
DBUS message handling state

This signal is sent by the printing coordinator if a printing provider becomes visible or is gone. It always carries the current run-time state information with it.

This handler must act in accordance to dbus_client_send_provider_change_notifier()

◆ handle_job_change_notifier()

static DBusHandlerResult handle_job_change_notifier ( DBusMessage *  message,
void *  data 
)
static

Handle the "Job Change" DBUS signal, convert it to a library callback/notifier

Parameters
[in]messageThe signal message itself, must be of SEND_JOB_CHANGE_NOTIFIER_METHOD
[in]dataOur local library handle
Returns
DBUS message handling state

This signal is sent by the printing coordinator if a job's state changes.

This handler must act in accordance to dbus_client_send_job_change_notifier()

◆ client_signal_dispatch()

static DBusHandlerResult client_signal_dispatch ( DBusConnection connection,
DBusMessage *  message,
void *  data 
)
static

Dispatch a received DBUS signal as a notifier to a client routine

Parameters
[in]connectionDBUS connection
[in]messageReceived signal as a regular message
[in]dataOut instance information as anonymous data
Return values
DBUS_HANDLER_RESULT_HANDLEDMessage has had its effect - no need to run more handlers
DBUS_HANDLER_RESULT_NOT_YET_HANDLEDMessage has not had any effect - see if other handlers want it
Precondition
In order to receive a special signal, we must be registered for it. Refer dbus_bus_add_match() calls in caps_cl_instance_register().
Todo:
Who needs to free the message ?

related to dbus_message_new_method_call()?

◆ dbus_signal_handling_register()

static int dbus_signal_handling_register ( struct caps_cl_handle instance,
const struct caps_cl_notifier notifier,
void *  data 
)
static

If we are interested in receiving coordinator signals (about printer and/or job status changed)

Parameters
[in]instanceThe library instance handle
[in]notifierNotifier to call (if any)
[in]dataAnonymous data to be send to the notifier
Return values
0On success
-EIOFailed to register the object path (dbus specific)
-ENOMSGNo signals of the requested types available

◆ dbus_bus_type_detect()

static DBusBusType dbus_bus_type_detect ( void  )
static

Select the DBUS bus variant we should connect to

Returns
DBUS bus variant (DBUS_BUS_SESSION or DBUS_BUS_SYSTEM)

Default bus variant is 'DBUS_BUS_SYSTEM'. This can be changed in the DEBUG build to 'DBUS_BUS_SESSION' if the environment variable 'CAPS_DBUS_BUS' is present (its value doesn't matter). If the 'DBUS_BUS_SESSION' bus variant is in use, all CAPS components must use the same setting in the 'DBUS_SESSION_BUS_ADDRESS' environment variable, else no connection is possible.

Todo:
Move this documentation to a global section.

◆ caps_client_add_watch_function()

static dbus_bool_t caps_client_add_watch_function ( DBusWatch *  watch,
void *  data 
)
static

◆ caps_client_remove_watch_function()

static void caps_client_remove_watch_function ( DBusWatch *  watch,
void *  data 
)
static

◆ caps_client_watch_toggle_function()

static void caps_client_watch_toggle_function ( DBusWatch *  watch,
void *  data 
)
static

◆ setup_watches()

static int setup_watches ( struct caps_cl_handle instance)
static

Set a 'watch' to the DBUS connection in order to be able to wait for activity

Parameters
[in]instanceClient instance
Return values
0'Watch' added
-EINVALFailed to add a watch to the connection

If this function fails, there is no way to wait for activity on this connection.

Todo:

How does it really work?

https://stackoverflow.com/questions/9378593/dbuswatch-and-dbustimeout-examples