Introduction and API

1.0 Introduction

This document describes the interface (API) that the Application Print Services library exposes to applications. This material will be of interest to programmers who wish to make use of the library, as well as those who wish to add functionality to the library or simply gain an in-depth understanding of what this component provides. Section 1.x of this document also includes the introductory material from APSOverview.html.

1.1 Table of Contents

1.0 Introduction
1.1 Table of Contents
1.2 Overview
1.3 Status of the Project
1.4 Where This Component Fits In
2.0 Basic Concepts
2.1 APS Objects
2.1.1 Handles and Objects
2.1.2 Printer Objects
2.1.3 Job Objects
2.1.4 Queue Objects
2.1.5 Job Attributes Objects
2.1.6 Model Objects
2.1.7 Filter Objects
2.1.8 Notification Subscription Objects
2.1.9 Object-Oriented Function Naming
2.2 Result Codes
3.0 Interface Reference
3.1 Library-Wide Elements
3.1.1 Result Code Support Functionality
3.1.1.1 Aps_GetResultText()
3.1.1.2 Aps_Succeeded()
3.1.2 Operations That Can be Performed on Any Type of Handle
3.1.2.1 Aps_AddRef()
3.1.2.2 Aps_ReleaseHandle()
3.1.2.3 Aps_SubscribeToNotificationCB()
3.1.2.4 Aps_IsOperationAvailable()
3.1.3 Other General-Purpose Library Functions
3.1.3.1 Aps_ReleaseBuffer()
3.2 Printer Enumeration and Instantiation
3.2.1 Aps_OpenDefaultPrinter()
3.2.2 Aps_GetPrinters()
3.2.3 Aps_OpenPrinter()
3.2.4 Aps_OpenRemotePrinter()
3.3 Printer Installation and Removal
3.3.1 Aps_AddPrinter()
3.3.2 Aps_PrinterRemove()
3.3.3 Aps_PrinterInstallLocalCopy()
3.4 Printer Configuration
3.4.1 Printer Identification
3.4.1.1 Aps_PrinterGetName()
3.4.1.2 Aps_PrinterRename()
3.4.2 Default Printer Tagging
3.4.2.1 Aps_PrinterIsDefault()
3.4.2.2 Aps_PrinterSetAsDefault()
3.4.3 Administrative and Tuning Configuration
3.4.3.1 Aps_PrinterGetMaxJobSize()
3.4.3.2 Aps_PrinterSetMaxJobSize()
3.4.3.3 Aps_PrinterGetConfigFlags()
3.4.3.4 Aps_PrinterSetConfigFlags()
3.4.4 Printer Diagnosis
3.4.4.1 Aps_PrinterSendTestPage()
3.5 Printer Manufacturer and Model Information
3.5.1 Printer Model Database Access
3.5.1.1 Aps_GetKnownManufacturers()
3.5.1.2 Aps_GetKnownModels()
3.5.1.3 Aps_AddModel()
3.5.2 Model Object Manipulation
3.5.2.1 Aps_GetPropertyString()
3.5.2.2 Aps_SetPropertyString()
3.5.2.3 Aps_GetPropertyStrArray()
3.5.2.4 Aps_SetPropertyStrArray()
3.5.2.5 Aps_ModelCommitToDatabase()
3.5.2.6 Aps_ModelRemove()
3.5.3 Configuring the Model Information Associated With a Printer
3.5.3.1 Aps_PrinterGetModel()
3.5.3.2 Aps_PrinterSetModel()
3.5.3.3 Aps_PrinterGetModelHandle()
3.5.3.4 Aps_PrinterGetPPDFileName()
3.5.3.5 Aps_PrinterSetPPDFileName()
3.6 Printer Location Information
3.6.1 Aps_GetRemotePrinters()
3.6.2 Aps_PrinterGetConnectInfo()
3.6.3 Aps_PrinterSetConnectInfo()
3.7 Printer/Job Attributes
3.7.1 Accessing a Printer's Default Attributes
3.7.1.1 Aps_PrinterGetDefAttr()
3.7.1.2 Aps_PrinterSetDefAttr()
3.7.2 Accessing a Job's Attributes
3.7.2.1 Aps_JobGetAttributes()
3.7.3 Generic Job Attribute Querying and Manipulation
3.7.3.1 Aps_AttrGetList()
3.7.3.2 Aps_AttrGetSubGroups()
3.7.3.3 Aps_AttrGetTranslatedName()
3.7.3.4 Aps_AttrGetMainData()
3.7.3.5 Aps_AttrGetTranslatedData()
3.7.3.6 Aps_AttrGetType()
3.7.3.7 Aps_AttrGetRange()
3.7.3.8 Aps_AttrGetOptions()
3.7.3.9 Aps_AttrGetSetting()
3.7.3.10 Aps_AttrSetSetting()
3.7.3.11 Aps_AttrCheckConstraints()
3.7.4 Quick Access to Common Attributes
3.7.4.1 Aps_AttrQuickGetPostScriptLevel()
3.7.4.2 Aps_AttrQuickIsColorDevice()
3.7.4.3 Aps_AttrQuickGetResOptions()
3.7.4.4 Aps_AttrQuickGetRes()
3.7.4.5 Aps_AttrQuickSetRes()
3.7.4.6 Aps_AttrQuickGetMaxCopies()
3.7.4.7 Aps_AttrQuickGetNumCopies()
3.7.4.8 Aps_AttrQuickSetNumCopies()
3.7.4.9 Aps_AttrQuickGetCollationOptions()
3.7.4.10 Aps_AttrQuickGetCollation()
3.7.4.11 Aps_AttrQuickSetCollation()
3.7.4.12 Aps_AttrQuickGetPageSizeOptions()
3.7.4.13 Aps_AttrQuickGetCustomPageSizeInfo()
3.7.4.14 Aps_AttrQuickGetPageSize()
3.7.4.15 Aps_AttrQuickSetPredefinedPageSize()
3.7.4.16 Aps_AttrQuickSetCustomPageSize()
3.7.4.17 Aps_AttrQuickGetInputSlotOptions()
3.7.4.18 Aps_AttrQuickGetInputSlot()
3.7.4.19 Aps_AttrQuickSetInputSlot()
3.7.4.20 Aps_AttrQuickGetOutputBinOptions()
3.7.4.21 Aps_AttrQuickGetOutputBin()
3.7.4.22 Aps_AttrQuickSetOutputBin()
3.7.4.23 Aps_AttrQuickGetDuplexOptions()
3.7.4.24 Aps_AttrQuickGetDuplex()
3.7.4.25 Aps_AttrQuickSetDuplex()
3.7.4.26 Aps_AttrQuickGetFonts()
3.8 Job Production and Dispatch
3.8.1 Aps_DispatchJob()
3.8.2 Aps_PrinterStartJob()
3.8.3 Aps_JobWrite()
3.8.4 Aps_JobWriteBlock()
3.8.5 Aps_JobGetFileDescriptor()
3.8.6 Aps_JobEnd()
3.8.7 Aps_JobAbort()
3.9 Queue Monitoring and Management
3.9.0 General guidelines for working with queues
3.9.1 Queue Management : Accessing and Controlling Queues
3.9.1.1 Aps_PrinterOpenQueue()
3.9.1.2 Aps_OpenGlobalQueue()
3.9.1.3 Aps_QueueIssueCommand()
3.9.1.4 Aps_QueueIssueQuery()
3.9.1.5 Aps_QueueGetNumberOfJobs()
3.9.1.6 Aps_QueueMakeQuickPrinterQInfoArray()
3.9.2 Queue Management : Accessing and Controlling Jobs
3.9.2.1 Aps_QueueIterateJobs()
3.9.2.2 Aps_JobUpdate()
3.9.2.3 Aps_JobGetStatus()
3.9.2.4 Aps_JobIssueCommand()
3.9.2.5 Aps_JobMakeQuickJobInfo()
3.9.3 Queue Management : Composing Job and Queue Filters
3.9.3.1 Aps_Filter[ObjectClass]By[FieldName]()
3.9.3.2 Aps_FilterWithFunction()
3.9.3.3 Aps_FilterAll()
3.9.3.4 Aps_FilterMerge()
3.9.3.5 Aps_FilterClear()
3.9.3.6 Aps_AttachFilter()
3.9.3.7 Aps_DetachFilter()
3.9.3.8 Aps_FilterCheck()

1.2 Overview

The Application Print Services Library provides a common printing API for GNU/Linux and other Unix systems. We embarked on this open source project because we saw a real need for such a library on GNU/Linux when working on our own applications and Linux distribution. We believe that this library can make a significant contribution to printing on GNU/Linux.

The primary goals of the library are:

  1. To make it easier for application developers to incorporate printing functionality into their software.
  2. To hide the differences between various printing systems that could be installed on the end user's system, while taking full advantage of whatever printing system is in use. We hope this will help to harmonize current printing solutions, while facilitating future improvements.
  3. Where it make sense, to improve the printing experience for the end user by providing additional functionality beyond what is provided by the underlying printing system.

The specific areas of functionality provided by the Application Print Services API are:

Things that are currently outside the scope of this library are:

1.3 Status of the Project

The Application Print Services library is very much a work in progress. We are actively doing development work on the library, and are we also continuing to refine the API.

Because we want the library to be useful to as broad an audience as possible, we're encouraging feedback, suggestions and participation from the community at large. We invite you to look at our proposed API, post suggestions or questions to our printing project mailing list, look at the code or make your own contributions.

1.4 Where This Component Fits In

The illustration below shows where this library fits into the overall printing architecture on Linux, and how it relates to other components.

As illustrated, the library is intended to be used directly by both end-user applications and printer configuration/management tools. On the back side, it is intended to work with various underlying "transport" mechanisms. We are currently focusing our work on a transport abstraction layer for lpr/LPRng (with GhostScript). We would also like to see specific support added for other currently available printing systems. Because of the library's abstraction of the underlying transport mechanism, it also facilicates the development of new printing technologies on GNU/Linux.

overview.jpg (82112 bytes)

2.0 Basic Concepts

2.1 APS Objects

2.1.1 Handles and Objects

Most operations performed with APS operate on one or more APS-defined objects. The client application refers to these objects using handles previously provided by the APS library. When the application is finished with a handle, it must call Aps_ReleaseHandle() on that handle.

The following sections describe the major objects that compose the APS architecture:

2.1.2 Printer Objects

The most rudiementary objects in the APS architecture are Printers, which are referred to using handles of type Aps_PrinterHandle. In order to send a job to a printer, access a printer's queue or modify a printer's configuration, you must first obtain an Aps_PrinterHandle to identify the printer that you wish to operate on. A handle to any available printer can be obtained using the Aps_OpenPrinter() function. A list of available printers can be obtained using Aps_GetPrinters(). To simply obtain a handle to the printer marked as "default", without going through the list of available printers, Aps_OpenDefaultPrinter() can be used.

2.1.3 Job Objects

A document to be printed by a given printer is represented by a Job object, which is referred to using a handle of type Aps_JobHandle. A job is defined to be a set of one or more pages that are to be printed together as a single unit. For an application that wishes to print, a new job may be started for a particular printer simply using the Aps_PrinterStartJob() function, and the data to be printed can be sent using functions such as Aps_JobWrite().

For an application that wishes to monitor jobs, a set of waiting jobs can be obtained from a Queue object.

2.1.4 Queue Objects

Associated with each printer is a Queue object (referred to using an Aps_QueueHandle), which is a collection of jobs to be printed. To obtain a Queue handle, use the Aps_PrinterOpenQueue() function. It is also possible to obtain a Queue combining all jobs pending for all printers using the Aps_OpenGlobalQueue() function.

2.1.5 Job Attributes Objects

Information on a printer's capabilities and associated job-specific settings are accessed using a Job Attributes object (referred to using an Aps_JobAttrHandle). Each job has its own Job Attributes object that can be obtained using Aps_JobGetAttributes(). Each printer also has a set of default job attributes to be applied to all new jobs, which can be obtained using Aps_PrinterGetDefAttr().

2.1.6 Model Objects

A Model object (referred to using an Aps_ModelHandle) stores information on a particular make and model of printer. Multiple identical printers will each share common model information in their associated Model object.

2.1.7 Filter Objects

Filter objects (referred to using handle type Aps_FilterHandle) allows the view of another object to be filtered so that only a subset of information is visible. Filters are currently used with Queue objects to allow the application to view, for example, only those jobs belonging to a particular user.

2.1.8 Notification Subscription Objects

Applications can ask to be notified of certain types of events and changes taking place in other APS objects. When an application requests to be notified of a particular type of event, it receives an Aps_NotificationHandle. While the Notification Subscription object is automatically deleted when the object being monitored is deleted, the application can cancel notification prior to this time by releasing the Aps_NotificationHandle.

2.1.9 Object-Oriented Function Naming

To make it easy to identify functions that are conceptually methods of a particular object type (class), the names of such functions begin with a common word, as shown below. This naming scheme has been chosen to create a one-to-one mapping between these name groupings and the classes of a possible future C++ interface to the library. As such, a function that creates a new instance of object type X is not grouped with the methods that operate on an existing instance of object type X.

Function Name Meaning
Aps_Printer...() Operates on an existing Aps_PrinterHandle.
Aps_Job...() Operates on an existing Aps_JobHandle.
Aps_Attr...() Operates on an existing Aps_JobAttrHandle.
Aps_Queue...() Operates on an existing Aps_QueueHandle.
Aps_Filter...() Operates on an existing Aps_FilterHandle.
Aps_Model...() Operates on an existing Aps_ModelHandle.
Aps_...() Global functions that do not operate on an existing handle, functions that accept any type of handle, and functions that construct new objects independently of existing objects.

2.2 Result Codes

Except where otherwise noted, nearly all APS functions return a result code of type Aps_Result. These are the possible values of Aps_Result:

Aps_Result Code Severity Meaning
APS_SUCCESS None Indicates that the operation has been completed successfully.
APS_HAS_EXTENDED_SUPPORT Success with extended information Indicates that the operation succeeded, but wasn't able to obtain/provide all information because the printer has extended support for this feature.
APS_OPERATION_AVAILABLE Success with extended information Indicates that an operation. Used exclusively by Aps_IsOperationAvailable() when testing whether an operation can be performed.
APS_NO_CHANGE Success with extended information Indicates that the operation succeeded but had no net effect because the desired result had already been achieved.  (e.g. Request to change status when the current status is the same.)
APS_IGNORED Success with extended information Indicates that the operation succeeded but had no net effect because the desired operation cannot be performed due to system limitations.
APS_MORE_DATA Success with extended information Indicates that the operation only returned partial data. More data could be provided if the client application called the function again or provided a larger buffer.
APS_PARTIAL_SUCCESS Success with extended information Caution!  Indicates that the operation succeeded but may not have completed all tasks precisely.  [Defined explicitly for each function that can return this value.]
APS_FILTER_NOT_SUPPORTED Failure Indicates that the current filter modes are not supported and that the function aborted the operation because it could not produce the desired effect.
APS_NO_MORE_DATA Failure Indicates that there is no additional data to be obtained.
APS_NOT_FOUND Failure The client application referenced an entity (such as printer or file) that could not be found.
APS_NOT_IMPLEMENTED Failure Functionality is not yet implemented in the APS library.
APS_NOT_SUPPORTED Failure This operation/action is not supported by the underlying printer transport mechanism.
APS_INVALID_PARAM Failure An out-of-range or otherwise invalid parameter was passed to an APS function.
APS_OUT_OF_MEMORY Failure Insufficient memory was available to complete the operation.
APS_ACCESS_DENIED Failure User does not have permission to access this entity.
APS_INVALID_HANDLE Failure The client application provided an invalid or previously released handle when calling a function.
APS_GENERIC_FAILURE Failure The operation failed, but not further details are available.
APS_DISK_FULL Failure There was insufficient disk space to complete this operation.
APS_INVALID_PWD Failure Password was not accepted.
APS_OUT_OF_SEQUENCE Failure The operation cannot be performed at this time, or in the current state. For example, attempting to send data to a print job that has already been completed would result in this error.
APS_VIOLATES_CONSTRAINTS Failure Indicates that the requested change would violate one or more constraints on the possible combinations of allowable states, such as print job attributes.
APS_INVALID_PPD Failure Indicates that the specified file isn't a valid PPD (PostScript Printer Description) file.
APS_WRONG_TYPE Failure Indicates that a request was made to that is not valid for this type of property or attribute.
APS_ALREADY_EXISTS Failure Indicates that an attempt to create a file or object failed because a file/object already exists with the specified name.
APS_OPERATION_TIMEOUT Failure APS timed out waiting for an operation to complete; typically this will be an external program that was invoked by APS, but which did not provide output within the prescribed time.
APS_IO_ERROR Failure Indicates that an operation failed due to an i/o error. The error may or may not be directly related to files that are managed by the application.
APS_SUBPROGRAM_FAILED Failure Indicates that APS was unable to complete an operation because an external component failed to execute correctly, returned incomplete / garbage results, or halted on an error or signal.

3.0 Interface Reference

3.1 Library-Wide Elements

These functions provide services that are not specific to any one handle type or area of functionality, but rather are common to all subsystems.

3.1.1 Result Code Support Functionality

3.1.1.1 Aps_GetResultText()

Obtains a text string describing a given APS result code.

Aps_Result Aps_GetResultText(
    Aps_Result result,
    char *text,
    int size);

Input

result A result code returned by a previous call to any APS function.

Output

text Pointer to a string to receive text describing this result code.
size The size of the buffer pointed to by text.

3.1.1.2 Aps_Succeeded()

Allows the application to distinguish between Aps_Result codes that indicate an operation succeeded, and result codes that indicate a fundamental failure. For example, a function that refreshes an object's state from an external data source is considered to have succeeded if there were no changes were necessary (APS_NO_CHANGE), but to have failed if it was unable to connect to the external data source.

int Aps_Succeeded(
    Aps_Result result);

Input

result An Aps_Result code returned by a call to some other APS function.

Remarks

Returns TRUE if the specified result code represents a successful operation, or FALSE if it represents a failed operation.


3.1.2 Operations That Can be Performed on Any Type of Handle

3.1.2.1 Aps_AddRef()

Adds an additional lock reference to any type of APS object.

Aps_Result Aps_AddRef(
    Aps_Handle handle);

Input

handle A handle to any type of APS object.

Remarks

Whenever APS supplies a new handle of any type to the application, that handle is assumed to have a single reference. That is, the reference count is 1. The handle will continue to be valid until it is released, either by a call to an APS function that implicitly releases the object (as described in this documentation), or by an explicit call Aps_ReleaseHandle(). In certain situations, the application may wish to lock a handle so that it will continue to be valid after a call to one of these functions. In this case, the handle may be locked by explicitly adding an extra reference to the object by a call to Aps_AddRef().

The application can also make use of Aps_AddRef() in situations where it is passing a copy of an APS handle to a separate object/entity with a separate lifetime. In such a situation, by making an explicit call to Aps_AddRef() when copying the handle, the application can call Aps_ReleaseHandle() on each copy of the handle. The underlying object will then continue to exist until the last release of that object.


3.1.2.2 Aps_ReleaseHandle()

Called to indicate to APS that a particular handle is no longer needed.

Aps_Result Aps_ReleaseHandle(
    Aps_Handle handle);

Input

handle A printer, job settings or job handle previous returned by an APS function.

Remarks

This function should be called each copy of an APS handle, when that copy of the handle is no longer needed. Failure to call Aps_ReleaseHandle() may result in memory or other resources not being released in a timely fashion, if at all.


3.1.2.3 Aps_SubscribeToNotificationCB()

Allows the application to be notified via a callback function when some event associated with the specified object takes place, such as a particular change in the object's state.

Aps_Result Aps_SubscribeToNotificationCB(
    Aps_Handle object,
    Aps_Event event,
    Aps_NotificationCallback callbackFunction,
    void *appData,
    Aps_NotificationHandle *notificationHandle);

Input

object A handle to any type of APS object supporting notifications.
event The type of event that the application wishes to be notified of.
callbackFunction A pointer to the callback function to be called whenever the specified event occurs.
appData An optional pointer to application-defined data to be passed back to the callback function whenever the event occurs.

Output

notificationHandle An optional pointer to an Aps_NotificationHandle to receive a handle to this notification subscription. This handle can be used in the future to revoke the subscription to this notification. To cancel the notification, simply release the notification object by calling Aps_ReleaseHandle on this handle. Since all notification handles are automatically released when the associated object is destroyed, the application is not required to release this handle unless it wishes to stop receiving notifications before the object is deleted.

Remarks

The prototype for the callback function must follow this format:

void NotificationCallback(Aps_Handle objectSendingNotification,
                          Aps_Event eventThatHasOccurred,
                          void *reserved,
                          void *appSpecifiedData);

Since the notification callback function is provided with a handle to the APS object in which the event has taken place, along with the type of event that has occurred, the application may implement a single callback function to handle multiple types of events for multiple objects. Alternatively, the application may choose to provide different callback functions for each type of event and/or object.


3.1.2.4 Aps_IsOperationAvailable()

Checks whether the specified operation is currently unavailable for a particular APS object.

Aps_Result Aps_IsOperationAvailable(
    Aps_Handle object,
    Aps_OperationID operation,
    Aps_Result *anticipatedResult);

Input

object A handle to any APS object to be queried on the availability of a particular operation, or NULL when querying the availability of a global operation.
operation The ID of the operation to be queried. Note that many operations will only be valid for certain types of objects.

Output

anticipatedResult The address of an Aps_Result to receive APS_OPERATION_AVAILABLE if this operation is currently available, or the anticipated reason for failure if it is known that this operation cannot be performed.

Remarks

This function is intended to allow the application to disable or remove UI features that are tied to particular APS operations when it can be determined ahead of time that the operation cannot be performed.

It is important to emphasize that if this function indicates an operation is available, there no guarantee that the operation will succeed. However, if this function indicates the operation is unavailable, you can assume that the operation will not succeed.

Common reasons that operations may be unavailable are due to the user not having permission to perform the operation (such as deleting another user's job by users without administrative privileges), or due to a particular underlying printer transport not supporting the operation.

Some operations may be available at one point in time, but not available at another point in time.

It is also important to distinguish between the Aps_Result code returned by this function, which indicates whether the Aps_IsOperationAvailable function has succeeded, and the Aps_Result passed back in the anticipatedResult parameter, which indicates whether or not the specified operation is available.


3.1.3 Other General-Purpose Library Functions

3.1.3.1 Aps_ReleaseBuffer()

Deallocates space used by a temporary buffer returned to the application by APS

Aps_Result Aps_ReleaseBuffer(
    void *buffer);

Input

buffer A pointer to the APS-owned buffer to be released.

Remarks

Various APS functions will provide the application with a temporary buffer in order to pass data back to the application. This buffer may be a string, array or other data structure. As these buffers are managed internally by APS, the application must notify APS when it is finished with a buffer, so that APS can reclaim the space for future use. An application should not simply call free() on one of these buffers.

Functions that return a buffer that must be disposed of using Aps_ReleaseBuffer() explicitly document those parameters that must be released.

When used with an array or struct returned by an APS function, Aps_ReleaseBuffer() correctly deallocates not only the array/structure itself, but also any strings or other sub-structures associated with the main buffer.


3.2 Printer Enumeration and Instantiation

To access any settings or information specific to a particular printer, you must first obtain a handle to a printer object. A handle to the system default printer can be obtained using the Aps_OpenDefaultPrinter() function. To obtain the handle to any other printer, use Aps_OpenPrinter(), which must be supplied with the name of the printer to be opened. The names of all available printers can be obtained using the Aps_GetPrinters() API.

3.2.1 Aps_OpenDefaultPrinter()

Obtains a handle to the current default printer, if any.

Aps_Result Aps_OpenDefaultPrinter(
    Aps_PrinterHandle *printer);

Output

printer A pointer to an Aps_PrinterHandle that will receive the handle to the newly opened printer on success.

Remarks

When you are finished with the handle obtained by this function, call Aps_ReleaseHandle() on that handle.

Typical Use

Aps_PrinterHandle printer;
if (Aps_OpenDefaultPrinter(&printer) == APS_SUCCESS) {
    /* Perform operations on the printer handle. */

    /* Dispose of the handle when no longer needed. */
    Aps_ReleaseHandle(printer);
}

3.2.2 Aps_GetPrinters()

Obtains a list of names of printers than can be opened using Aps_OpenPrinter().

Aps_Result Aps_GetPrinters(
   char ***names,
   int *count);

Output

names The address of a pointer to receive an array of string pointers consisting of the names of all available printer. If this function succeeds, it is the caller's responsibility to dispose of this array when finished with it by calling Aps_ReleaseBuffer().
count A pointer to an int to receive the count of the number of elements filled in the array names.

Typical Use

char **printerNames;
int numNames;
int i;

if (Aps_GetPrinters(&printerNames, &numNames) == APS_SUCCESS) {
    for (i = 0; i < numNames; ++i)
        printf("name = %s\n", printerNames[i]);

    Aps_ReleaseBuffer(printerNames);
}

3.2.3 Aps_OpenPrinter()

Obtains a handle to the named printer.

Aps_Result Aps_OpenPrinter(
   const char *name,
   Aps_PrinterHandle *printer);

Input

name A string containing the name of the printer to be opened. For this function to succeed, this must be the name of an existing printer. This parameter must not be NULL.

Output

printer A pointer to an Aps_PrinterHandle that will receive the handle to the newly opened printer on success.

Remarks

When you are finished with the handle obtained by this function, call Aps_ReleaseHandle() on that handle. Use Aps_GetPrinters() to obtain the names of printers that can be opened.

Typical Use

Aps_PrinterHandle printer;
if (Aps_OpenPrinter(printerName, &printer) == APS_SUCCESS) {
    /* Perform operations on the printer handle. */

    /* Dispose of the handle when no longer needed. */
    Aps_ReleaseHandle(printer);
}

3.2.4 Aps_OpenRemotePrinter()

Obtains a handle to a remote printer that is not installed on this machine's/user's list of regularly used printers. A typical use for this function would be to allow one-time printing to a network printer without requiring the printer to be "installed" locally.

Aps_Result Aps_OpenRemotePrinter(
    Aps_ConnectionType connectionType,
    const char *location,
    Aps_PrinterHandle *printer);

Input

connectionType An Aps_ConnectionType, which together with the location parameter uniquely specify the remote printer to connect to. Refer to the Aps_PrinterGetConnectInfo() function for information on the use of these two parameters.
location A location string that uniquely identifies a remote printer for a given connectionType.

Output

printer The address of an Aps_PrinterHandle

Remarks

Note that this functionality may be unsupported by some transports. Use Aps_IsOperationAvailable() to test whether this operation is supported in a particular environment.

Even in situations where the user has the option of doing a one-time print to a remote printer using Aps_OpenRemotePrinter(), it is often desirable to locally install a reference to regularly used printers. This allows the printer to be conveniently located in the future, and allows local customization of the printing preferences that are to be applied when printing to that printer in the future. For environments supporting Aps_OpenRemotePrinter(), the list of locally installed printers should be thought of as the list of commonly used printers. Local installation of a printer opened with Aps_OpenRemotePrinter() can be achieved using Aps_PrinterInstallLocalCopy().


3.3 Printer Installation and Removal

These functions provide the ability to modify the set of available printers. After a printer has been added, its configuration can be modified using the settings in the following section.

3.3.1 Aps_AddPrinter()

Installs a new printer that may be printed to in the future.

Aps_Result Aps_AddPrinter(
    const char *name,
    Aps_PrinterHandle *printer);

Input

name The name to give the new printer. This string must differ from the name of any printer that already exists.

Output

printer The address of an Aps_PrinterHandle to receive a handle to the newly created printer. This may be NULL of the caller does not require the printer handle.

Remarks

For some transports, the set of available printers is maintained on a system wide basis, and so installing and removing printers is often a privileged operation. Other transports may support per-user printers, in which case normal users can add and remove their own printers, though still only the superuser will be able to add or remote system-wide printers.

On success, if the caller has requested a handle to the new printer (that is, the provided printer parameter is non-NULL), it is the caller's responsibility to release this handle when it is no longer required by calling Aps_ReleaseHandle().

Typical Use

Aps_PrinterHandle printer;
if (Aps_PrinterAdd(newPrinterName, &printer) == APS_SUCCESS) {
    /* Set model, port, other basic configuration parameters */
    /* using printer handle. */

    /* Release the printer handle when you're finished with it. */
    Aps_ReleaseHandle(printer);
}

3.3.2 Aps_PrinterRemove()

Uninstalls a printer.

Aps_Result Aps_PrinterRemove(
    Aps_PrinterHandle printer);

Input

printer An Aps_PrinterHandle identifying the printer to be removed.

Remarks

If this function is successful (indicated by a return value of APS_SUCCESS), the handle passed in the printer parameter will automatically be released.


3.3.3 Aps_PrinterInstallLocalCopy()

Adds a new printer to the current machine/user's list of regularly used printers, given a printer handle opened by Aps_OpenRemotePrinter(). In environments where Aps_OpenRemotePrinter() is supported, installing a printer locally allows the user to conveniently locate this printer in the future, and to modify the default job attributes to be applied to future jobs.

Aps_Result Aps_PrinterInstallLocalCopy(
    Aps_PrinterHandle remotePrinter,
    Aps_PrinterHandle *newLocalCopy);

Input

remotePrinter A handle to the remote printer opened using Aps_OpenRemotePrinter(). This handle will not be released by this function.

Output

newLocalCopy The address of an Aps_PrinterHandle to receive a handle to the new locally installed copy of this printer, or NULL if not required. If not NULL, it is the caller's responsibility to dispose of this handle when no longer needed by calling Aps_ReleaseHandle().

Remarks

On success, a new printer handle to the locally installed printer is returned. At this point, most applications will want to dispose of the original remote printer handle using Aps_ReleaseHandle(), and then proceed to work with the new local handle.

A remote printer can also be installed using Aps_AddPrinter(), and then Aps_PrinterSetConnectInfo(). However, for some transports, using Aps_OpenRemotePrinter() followed by Aps_PrinterAddLocalCopy() allows other settings and default attributes that have been configured for the remote printer to be applied to the locally installed pointer to that printer.


3.4 Printer Configuration

These functions provide access to basic configuration information about a given printer, along with the ability to modify that configuration where user privileges and the underlying print system allow.

3.4.1 Printer Identification

3.4.1.1 Aps_PrinterGetName()

Obtains the name of an open printer.

Aps_Result Aps_PrinterGetName(
    Aps_PrinterHandle printerHandle,
    char **name);

Input

printerHandle A handle to a currently open printer.

Output

name The address of a character pointer to receive the location of a new string with the name of this printer. If this function succeeds, it is the caller's responsibility to pass this string to Aps_ReleaseBuffer() when finished with it.

3.4.1.2 Aps_PrinterRename()

Changes the name of a printer.

Aps_Result Aps_PrinterRename(
    Aps_PrinterHandle printer,
    const char *newName);

Input

printer A handle to the printer to be renamed.
newName A string containing the new name to assign to this printer.

3.4.2 Default Printer Tagging

3.4.2.1 Aps_PrinterIsDefault()

Determines whether or not a particular printer is the default printer.

Aps_Result Aps_PrinterIsDefault(
    Aps_PrinterHandle printer,
    int *isDefault);

Input

printer A handle to the printer in question.

Output

isDefault Set to TRUE if this is the default printer, FALSE if it isn't.

3.4.2.2 Aps_PrinterSetAsDefault()

Changes which printer will be the default printer for this user/system.

Aps_Result Aps_PrinterSetAsDefault(
    Aps_PrinterHandle printer);

Input

printer A handle to the printer that should become the default.

Remarks

The application should assume that the default printer may be maintained on a user-by-user basis with some systems, and may be a machine wide setting requiring privileged access to alter on other systems.


3.4.3 Administrative and Tuning Configuration

3.4.3.1 Aps_PrinterGetMaxJobSize()

Obtains the maximum size of job that is permitted by this printer.

Aps_Result Aps_PrinterGetMaxJobSize(
    Aps_PrinterHandle printer,
    int *maxSize);

Input

printer A handle to the printer in question.

Output

maxSize The maximum size of job, in bytes, that this printer will accept, or APS_NO_MAX_SIZE if the printer is configured to accept jobs of any size.

3.4.3.2 Aps_PrinterSetMaxJobSize()

Sets the maximum size of job that a printer will accept, or configures a printer to accept jobs of any size.

Aps_Result Aps_PrinterSetMaxJobSize(
    Aps_PrinterHandle printer,
    int maxSize);

Input

printer A handle to the printer to change the configuration of.
maxSize The maximum size of job, in bytes, that this printer should accept, or APS_NO_MAX_SIZE if this printer

Remarks

Note that this may be a privileged operation for some printers or underlying print systems.


3.4.3.3 Aps_PrinterGetConfigFlags()

Obtains the set of standard configuration flags that are set for a particular printer.

Aps_Result Aps_PrinterGetConfigFlags(
    Aps_PrinterHandle printer,
    long int *configFlags);

Input

printer A handle to the printer in question

Output

configFlags An int to receive the set of printer configuration flags that are currently set.

Remarks

Zero or more of these printer configuration flags may be set (turned) on at any one time. Various flags are combined together using the bitwise-or operator.

The available flags are:

Printer Configuration Flag Meaning
APS_CONFIG_EOF_AT_END Causes an EOF character to be sent to the printer at the end of a job.
APS_CONFIG_ADD_CR Causes a carriage return to be sent to the printer for every line feed character encountered in the input stream.
APS_CONFIG_TEXT_AS_TEXT Causes text files to be sent to the printer as plain ASCII text, rather than rasterizing or representing the text in the device's native language.
APS_CONFIG_HEADER_PAGE Causes a header page to be sent before each job to allow individual user's jobs to be more easily identified.

3.4.3.4 Aps_PrinterSetConfigFlags()

Modifies the set of standard configuration flags that are set for a particular printer.

Aps_Result Aps_PrinterSetConfigFlags(
    Aps_PrinterHandle printer,
    long int flagsToSet,
    long int flagsToReset);

Input

printer A handle to the printer in question.
flagsToSet Zero or more flags to turn on (set), joined together by the bitwise-or operator. A value of 0 causes no flags to be turned on.
flagsToReset Zero or more flags to turn off (reset), joined together by the bitwise-or operator. A value of 0 causes no flags to be turned off.

Remarks

Note that this may be a privileged operation for some printers or underlying print systems.

See the Aps_PrinterGetConfigFlags() function for information on the set of available printer configuration flags.


3.4.4 Printer Diagnosis

3.4.4.1 Aps_PrinterSendTestPage()

Prints a standard test page to allow the user to confirm that a printer is functioning correctly, and to assist in the diagnosis of common problems.

Aps_Result Aps_PrinterSendTestPage(
    Aps_PrinterHandle printer,
    Aps_JobHandle *job);

Input

printer A handle to a printer to print the test page on.

Output

job A pointer to a job handle to receive a handle to allow monitoring of the progress of printing the test page. May be NULL if not required. If non-NULL, on success it is the caller's responsibility to release this handle when finished with it by passing it to Aps_ReleaseHandle().

3.5 Printer Manufacturer and Model Information

These functions provide access to the database of known printer manufacturers and models, and permits configuration of the model associated with a particular printer.

3.5.1 Printer Model Database Access

3.5.1.1 Aps_GetKnownManufacturers()

Obtains a list of printer manufacturer names for which one or more printer models are known.

Aps_Result Aps_GetKnownManufacturers(
    char ***manufacturerNames,
    int *numManufacturers);

Output

manufacturerNames The address of a pointer to receive the address of an array of string pointers, each containing the name of a known manufacturer. If this function succeeds, it is the caller's responsibility to deallocate this memory when finished with it by passing this pointer to Aps_ReleaseBuffer().
numManufacturers On success, the int at this address will receive the count of the number of printer manufacturers in the array provided to manufacturerNames.

Remarks

This function is intended to be used in conjunction with Aps_GetKnownModels() to obtain the printer model names for each manufacturer.

Typical Use

See Aps_GetKnownModels().


3.5.1.2 Aps_GetKnownModels()

Obtains a list of printer models known for a particular manufacturer.

Aps_Result Aps_GetKnownModels(
    const char *manufacturerName,
    char ***modelNames,
    int *numModels);

Input

manufacturerName A string containing the name of the manufacturer for which model names are to be retrieved.

Output

modelNames The address of a pointer to receive the address of an array of string pointers, each containing the name of a known model. If this function succeeds, it is the caller's responsibility to deallocate this memory when finished with it by passing this pointer to Aps_ReleaseBuffer().
numModels On success, the int at this address will receive the count of the number of printer models in the array provided to modelNames.

Remarks

To obtain a list of manufacturer names than can be passed to this function, use Aps_GetKnownManufacturers().

Typical Use

char **manNames;
int numMans;
int man;
char **modelNames;
int numModels;
int mod;

if (Aps_GetKnownManufacturers(&manNames, &numMans) == APS_SUCCESS) {
    for (man = 0; man < numMans; ++man) {
        if (Aps_GetKnownModels(manNames[man], &modelNames, &numModels)
            == APS_SUCCESS) {
            for (mod = 0; mod < numModels; ++mod) {
                printf("manufacturer = %s, model = %s\n",
                    manNames[man],
                    modelNames[mod]);
            }

            Aps_ReleaseBuffer(modelNames);
        }
    }

    Aps_ReleaseBuffer(manNames);
}

3.5.1.3 Aps_AddModel()

Creates an empty entry in the printer database for a new printer model.

Aps_Result Aps_AddModel(
    const char *manufacturer,
    const char *model,
    Aps_ModelHandle *modelHandle);

Input

manufacturer A string with the name of the printer manufacturer for the new model.
model A string with the name of the specific printer model.

Output

modelHandle The address of an Aps_ModelHandle to receive a handle to the new printer model, or NULL if not required.

Remarks

This function modifies the model database; note that most systems will be configured so that normal users do not have privileges to modify the model database.

On success, it is the caller's responsibility to dispose of the model handle when no longer needed by calling Aps_ReleaseHandle().


3.5.2 Model Object Manipulation

The contents of a Model object are accessed using a set of generic functions that read and modify arbitrary properties. Since these functions are currently only used with model objects, they are grouped into this section. However, since they are designed so that they can be extended to other object types in the future, they are intentionally not named Aps_Model...().

Modifying any property of a model object does not immediately update the model database. In order to save changes to a model object, use the Aps_ModelCommitToDatabase().

The set of currently defined Model properties are:

Property Name Meaning
"Manufacturer" A string containing the name of the manufacturer of this printer model.
"Model" A string containing the manufacturer's name for this specific model, without the manufacturer name.
"PPD" The name of the PPD file the describes this model, if applicable.
3.5.2.1 Aps_GetPropertyString()

Obtains the current value of a property represented as a character string.

Aps_Result Aps_GetPropertyString(
    Aps_Handle object,
    const char *propertyName,
    char **value);

Input

object A handle to the object to obtain the property from.
propertyName A string that uniquely identifies the property to retrieve.

Output

value The address of a string pointer to receive a string containing this property's current value. On success, it is the caller's responsibility to dispose of this string when no longer needed by passing it to Aps_ReleaseBuffer().

3.5.2.2 Aps_SetPropertyString()

Modifies the current value of a property represented as a character string.

Aps_Result Aps_SetPropertyString(
    Aps_Handle object,
    const char *propertyName,
    char *value);

Input

object A handle to the object to obtain the property from.
propertyName A string that uniquely identifies the property to retrieve.
value A string containing the new value to assign to this property.

3.5.2.3 Aps_GetPropertyStrArray()

Obtains the current value of a property represented as an array of zero or more character strings.

Aps_Result Aps_GetPropertyStrArray(
    Aps_Handle object,
    const char *propertyName,
    char ***value,
    int *numElements);

Input

object A handle to the object to obtain the property from.
propertyName A string that uniquely identifies the property to retrieve.

Output

value The address of a char ** to receive an array of string pointers containing the value of this property. On success, it is the caller's responsibility to dispose of this array when no longer needed by passing it to Aps_ReleaseBuffer().
numElements The address of an int to receive the size of the array pointed to by value.

3.5.2.4 Aps_SetPropertyStrArray()

Modifies the current value of a property represented as an array of zero or more character strings.

Aps_Result Aps_SetPropertyStrArray(
    Aps_Handle object,
    const char *propertyName,
    const char **value,
    int numElements);

Input

object A handle to the object to obtain the property from.
propertyName A string that uniquely identifies the property to retrieve.
value The address of an array of string pointers that compose the new value for this property. This may not be NULL unless numElements is 0.
numElements The number of elements in the array pointed to by value.

3.5.2.5 Aps_ModelCommitToDatabase()

Commits any changes to a model object into the model database.

Aps_Result Aps_ModelCommitToDatabase(
    Aps_ModelHandle model);

Input

model A handle to a printer model object, whose changes should be saved into the printer model database.

Remarks

Note that this function requires that the user has write permission on the model database. Most systems will be configured so that normal users do not have permission to do this.


3.5.2.6 Aps_ModelRemove()

Removes the specified printer model from the model database.

Aps_Result Aps_ModelRemove(Aps_ModelHandle model);

Input

model A handle to the model to be removed.

Remarks

If this function succeeds, the model handle will be released before the function returns. You should not normally call Aps_Release() after calling this function. If for any reason you wish to retain a handle to the model after calling this function, lock it by calling Aps_AddRef(), and then release it when no longer needed by calling Aps_Release().

This function modifies the model database; note that most systems will be configured so that normal users do not have privileges to modify the model database.


3.5.3 Configuring the Model Information Associated With a Printer

3.5.3.1 Aps_PrinterGetModel()

Determines the manufacturer and model names associated with a given printer.

Aps_Result Aps_PrinterGetModel(
    Aps_PrinterHandle printer,
    char **manufacturer,
    char **model);

Input

printer A handle to a currently open printer

Output

manufacturer The address of a string pointer to receive a buffer with the name of this printer's manufacturer.
model The address of a string pointer to receive the name of the specific model.

Remarks

If this function succeeds, it is the caller's responsibility to release the buffers pointed to by manufacturer and model using the Aps_ReleaseBuffer() function.

For some underlying print systems, this information may be unavailable.


3.5.3.2 Aps_PrinterSetModel()

Sets which driver should be used for this printer by providing a manufacturer and model name.

Aps_Result Aps_PrinterSetModel(
    Aps_PrinterHandle printer,
    const char *manufacturer,
    const char *model);

Input

printer A handle to the printer to change the associated driver for.
manufacturer A string containing the name of this model's manufacturer.
model A string containing the name of the manufacturer's specific model.

Remarks

The names of available printer manufacturers and models may be obtained using the Aps_GetKnownManufacturers() and Aps_GetKnownModels() functions.

Note that this may be a privileged operation for some printers or underlying print systems.


3.5.3.3 Aps_PrinterGetModelHandle()

Obtains a handle to a particular printer's model object. This allows access to more extensive information about this printer's model, rather than just its manufacturer and model name.

Aps_Result Aps_PrinterGetModelHandle(
    Aps_PrinterHandle printer,
    Aps_ModelHandle *model);

Input

printer A handle to a currently open printer.

Output

model The address of an Aps_ModelHandle to receive a handle to this printer's model object.

Remarks

On success, it is the caller's responsibility to dispose of the model handle when no longer needed by calling Aps_ReleaseHandle().


3.5.3.4 Aps_PrinterGetPPDFileName()

Obtains the name of the PPD file currently associated with this printer.

Aps_Result Aps_PrinterGetPPDFileName(
    Aps_PrinterHandle printer,
    char **filename);

Input

printer An Aps_PrinterHandle identifying the printer to query.

Output

filename The address of a pointer to receive the address of a new string containing the name of the PPD file. If this function succeeds, it is the caller's responsibility to pass this string to Aps_ReleaseBuffer() when it is no longer needed.

Remarks

Applications that require direct access to the PPD file should use this function to determine the associated PPD file, if any. Note that some printers may not have an associated PPD file, or APS may be unable to determine the name of the PPD file.


3.5.3.5 Aps_PrinterSetPPDFileName()

Changes the PPD file that is associated with a particular printer.

Aps_Result Aps_PrinterSetPPDFileName(
    Aps_PrinterHandle printer,
    const char *filename);

Input

printer An Aps_PrinterHandle identifying the printer for which the current PPD file should be changed.
filename A string containing the full path and filename of the PPD file to be associated with this printer.

3.6 Printer Location Information

These functions provide access to the location of a printer, be it a local port/device, or a location on the network.

3.6.1 Aps_GetRemotePrinters()

Obtains a list of available remote printers.

Aps_Result Aps_GetRemotePrinters(
    Aps_ConnectionType connectionType,
    const char *subLocation,
    Aps_RemotePrinter ***remotePrinters);

Input

connectionType The type of printer connection to search for local printers on.
subLocation An optional string identifying the server or group of printers within the specified connection type.

Output

remotePrinters The address of a pointer to receive the address of a new array of Aps_RemotePrinter structures. On success, it is the caller's responsibility to dispose of this array when no longer needed by passing it to Aps_ReleaseBuffer().

Remarks

The Aps_ConnectionType enumeration can take on one of the following values:

Aps_ConnectionType Value Meaning
APS_CONNECT_LOCAL Indicates that the printer is connected to a device on the local system. In this case, location is the name of the device that the printer is connected to.
APS_CONNECT_NETWORK_LPD Indicates that the printer is on a remote lpd (UNIX) server. In this case, location is the host and printer name of the remote printer.
APS_CONNECT_NETWORK_SMB Indicates that the printer is accessed of and SMB (Windows) network. In this case, location is the server and printer name, in the format "\\server\printer".
APS_CONNECT_ALL Locates printers on all connections. Used only with Aps_GetRemotePrinters().

The Aps_RemotePrinter structure is defined as follows:

typedef struct Aps_RemotePrinter_ {
    char *name;     /* A user-friendly name for this printer; may be NULL. */
    Aps_ConnectionType connectionType; /* See above. */
    char *location; /* A string uniquely identifying this printer within the connection type. */
} Aps_RemotePrinter;

Some transports may allow users to print to a remote printer directly, without having to install it locally, using Aps_OpenRemotePrinter(). Other transports may require a reference to the printer to be installed locally before it can be printed to. Aps_IsOperationAvailable() allows you to determine which functionality is available under the current operating environment.


3.6.2 Aps_PrinterGetConnectInfo()

Obtains information on how a connection is established with a particular printer. This includes the connection method, such as the printer being connected to a local device, or being accessed over the network. It also includes a string identifying the specific device or network path of the printer.

Aps_Result Aps_PrinterGetConnectInfo(
    Aps_PrinterHandle printer,
    Aps_ConnectionType *connectionType,
    char **location);

Input

printer A handle to the printer in question.

Output

connectionType The address of an Aps_ConnectionType to receive information on which type of connection is being used. Refer to the Aps_GetRemotePrinters() function for information on the possible values for Aps_ConnectionType.
location The address of a char * to receive a string with the device/network name that this printer is attached to. If this function succeeds, it is the caller's responsibility to dispose of this string by passing it to Aps_ReleaseBuffer().

3.6.3 Aps_PrinterSetConnectInfo()

Changes the method and/or location used to connect to a particular printer. The method can be via a local device, or via a network. In the case of a local printer, the location is the name of the device that the printer is connected to. In the case of a network printer, the location is the network path to the printer.

Aps_Result Aps_PrinterSetConnectInfo(
    Aps_PrinterHandle printer,
    Aps_ConnectionType connectionType,
    const char *location);

Input

printer A handle to the printer in question.

Output

connectionType An Aps_ConnectionType identifying the mechanism (local / remote) used to communicate with this printer.
location A string containing the device name or network path for this printer.

Remarks

Refer to the Aps_PrinterGetRemotePrinters() function for information on the possible values of Aps_ConnectionType


3.7 Printer/Job Attributes

These functions provide the ability to examine and modify a job attributes object. These objects provide information on a printer's capabilities such as available resolutions, page sizes and the paper handling features, and the ability to modify corresponding job-specific settings such as the specific resolution, page size, and the paper handling options to be used. Job attributes objects are used both for examining and changing the settings to be used for a particular job, and for examining and changing the default settings to be applied to new all jobs printed from a particular printer.

While the application may wish to query for specific attributes that it knows about, the job attributes mechanism is designed to be extensible in such a way that the application doesn't need to know about all possible attributes in order to make use of them. Specifically, it is designed to provide enough information to enable applications to provide a user interface for controlling printer-specific features, without having to know ahead of time about all possible printer features. Information includes the localized (translated) text to display for each setting, the type of control/widget to use, and facilities to enforce constraints to the possible combinations of settings that are permitted together.

The implementation of job attributes is also designed to be flexible enough to support a number of underlying mechanisms that may be providing access to the attributes. Perhaps the most common source for job attributes is a PPD (PostScript Printer Description) file, and APS provides full access to all the information that is available in a PPD file. For information on the full set of attributes available from a PPD file, please refer to Adobe's PPD Specification. In the case of non-PostScript printers supported through the basic lpr & GhostScript configuration, job attributes are also provided for various options implemented by lpr and GhostScript. The mechanism is also designed to be flexible enough to support possible future mechanisms, such as the Printer Working Group's UPDF effort.

Note that in order to take advantage of the job attributes services provided by APS, an application generating PostScript output should make use of the Aps_JobWriteBlock() function. For example, in the case of printing directly to a PostScript printer via lpr, Aps_JobWriteBlock() generates the device-specific PostScript code for controlling the printer's features that are described in the PPD file. This also means that the use of Aps_DispatchJob() is not recommended for applications that want to have full control over a printer's features using the job attributes functionality.

Alternatively, an application may elect not to use the job attributes features of APS. In this case, job settings for true PostScript printers may still be controlled from the application by manually generating the appropriate PostScript code. In other cases, the job will be printed with a default set of settings.

Each type of attribute that can be present in a job attributes object is identified by a unique string ID. The IDs of the attributes that are available from a particular job attributes object can be obtained by calling Aps_AttrGetList(). For consistency with the PPD format, all attributes which are provided by PPD files are named beginning with an asterisk (e.g. "*LanguageLevel").

Some attributes only provide read-only information, such as the level of PostScript that the printer supports. Others also have a corresponding setting that can be modified, such as the page size to use. The following information can be retrieved for a given attribute in a job attributes object:

Attributes are arranged into a hierarchy of categories, called groups. At the root level, all attributes are grouped into either the read-only data group (APS_ATTR_READ_ONLY_DATA), or the user-settings group(APS_ATTR_ROOT_SETTINGS). Settings may be further broken into subgroups, where the root group and all subgroups can consist of both attributes and further subgroups. The arrangement of attributes under the root user-settings group will vary from printer to printer, and will generally be categorized in whatever way makes sense for that particular printer.

In addition to the functions that provide generic access to all attributes, special-purpose helper functions are provided for accessing some common attributes, such as page size and resolution.

In the case of attributes provided by PPD files, the attribute ID corresponds directly to the name of a main key, without the initial *. The main data corresponds to the value of the main key. Likewise, the translated name and translated data that can be queried from the job attributes object correspond directly to the translated name and translated value of the main key in the PPD file. PPD files only support Boolean, "pick one" and "pick many" UI keys, and so you will never see an attribute from a PPD file of one of the numeric types. In the case of "pick one" and "pick many" keys, the corresponding option keys map directly to the list of options presented by the job attributes API. All non-UI keys are placed in the APS_ATTR_READ_ONLY_DATA group, while the group and sub-group structure of UI keys is preserved in the grouping presented by the job attributes API.

3.7.1 Accessing a Printer's Default Attributes

3.7.1.1 Aps_PrinterGetDefAttr()

Obtains a complete copy of the default job attributes to be applied to future jobs printed on the given printer.

Aps_Result Aps_PrinterGetDefAttr(
    Aps_PrinterHandle printer,
    Aps_JobAttrHandle *jobAttributes);

Input

printer A handle to the printer to obtain the default job attributes for.

Output

jobAttributes The address of an Aps_JobAttrHandle that will receive a handle to the job attributes copy on success. It is the caller's responsibility to dispose of this handle when finished with it by calling Aps_ReleaseHandle().

Remarks

As the returned job attributes handle is a copy of the printer's master job attributes, any change to this job attributes will have no effect on future jobs until such time as those changes are committed by passing this job attributes copy to Aps_PrinterSetDefAttr().

Typical Use

Aps_JobAttrHandle jobAttributes;
if (Aps_PrinterGetDefAttr(printer, &jobAttributes) == APS_SUCCESS) {
    /* Examine and/or modify the job attributes object. */

    /* Optionally commit changes using Aps_PrinterSetDefAttr(). */

    Aps_ReleaseHandle(jobAttributes);
}

3.7.1.2 Aps_PrinterSetDefAttr()

Sets the default job attributes to be applied to future jobs printed on a particular printer.

Aps_Result Aps_PrinterSetDefAttr(
    Aps_PrinterHandle printer,
    Aps_JobAttrHandle jobAttributes);

Input

printer The printer to change the default job attributes for.
jobAttributes The default job attributes to apply to future jobs sent to this printer.

Remarks

Calling this function will only affect jobs that are initiated after this call; any already active jobs will remain unaffected. Be aware that changing the default job attributes may only affect jobs printed using APS for some underlying print systems and/or types of jobs.

The job attributes object passed to this function must have originated from the same printer that it is being applied to. That is it must have been obtained by calling Aps_PrinterGetDefAttr() on this printer, or by calling Aps_JobGetAttributes() on a job associated with this printer.

This function copies the contents of the passed job attributes object to the printer's master job attributes without modifying the passed job attributes object. This means that the passed job attributes may be retained for further use or modification. It also means that the passed job attributes must still be explicitly released by calling Aps_ReleaseHandle().


3.7.2 Accessing a Job's Attributes

3.7.2.1 Aps_JobGetAttributes()

Obtains the job attributes objects for the specified job.

Aps_Result Aps_JobGetAttributes(
    Aps_JobHandle job,
    Aps_JobAttrHandle *attributes);

Input

job A handle to the job whose job attributes should be returned.

Output

attributes The address of a job attributes handle to receive a handle to this job's attributes object.

Remarks

Any changes made to the job attributes instance that is returned by this function will take effect immediately. That is, there is no need to commit the changes, nor is there an Aps_SetJobSettings() function. Although this job attributes object is not a copy, when finished with this handle, the application should still release its lock on the object using Aps_ReleaseHandle().

Unless otherwise stated, applications should only change the job attributes before the first data is sent to the job. That is, most attributes may only be changed when Aps_JobGetStatus() returns APS_JOB_SETUP.


3.7.3 Generic Job Attribute Querying and Manipulation

These functions provide generic access to all attributes available in a given job attributes object. For more information on job attributes, please refer to the introductory material at the beginning of section 3.7.

3.7.3.1 Aps_AttrGetList()

Obtains a list of individual attributes available in a particular job attributes object. This can be a list of all attributes, or only the subset of attributes specified by the group parameter.

Aps_Result Aps_AttrGetList(
    Aps_JobAttrHandle jobAttributes,
    const char *group,
    int *numAttributes,
    char ***attributeIDs);

Input

jobAttributes A handle to a job attributes object.
group A string containing the name of the attributes group to be retrieved, or APS_GROUP_??? to retrieve a predefined subset of attributes. Possible preset values are:
  • APS_GROUP_ROOT to obtain attributes at the root level. Note that the root level normally only consists of the two subgroups APS_GROUP_ROOT_SETTINGS and APS_GROUP_READ_ONLY_DATA, and but no attributes of is own.
  • APS_GROUP_ROOT_SETTINGS to obtain those settings at the root level of the user-settings sub-hierarchy.
  • APS_GROUP_ALL_SETTNG to obtain all user-settings in a flat arrangement, irrespective of which group or subgroup they belong to.
  • APS_GROUP_READ_ONLY_DATA to obtain the group of attributes that have no corresponding user-settings.

Output

numAttributes A pointer to an integer to receive the number of attributes that were found.
attributeIDs A char *** that receives a buffer containing an array of pointers to strings composing the attribute IDs. When finished with this buffer, you must call Aps_ReleaseBuffer().

Typical Use

int numAttributes;
char **attributeIDs;
int i;
if (Aps_AttrGetList(jobAttributes, APS_GROUP_ALL_SETTINGS,
                    &numAttributes, &attributeIDs) == APS_SUCCESS) {
    for (i = 0; i < numAttributes; ++i) {
        printf("Attribute = %s\n", attributeIDs[i]);
    }
    Aps_ReleaseBuffer(attributeIDs);
}

3.7.3.2 Aps_AttrGetSubGroups()

Obtains a list of attribute sub-groups belonging to another attribute group.

Aps_Result Aps_AttrGetSubGroups(Aps_JobAttrHandle jobAttributes,
                                const char *group,
                                int *numSubGroups,
                                char ***subGroupNames);

Input

jobAttributes A handle to a job attributes object.
group A string containing the name of the attributes group to be searched for subgroups, APS_GROUP_ROOT to obtain groups at the root level, or APS_GROUP_ROOT_SETTINGS to obtain root level groups or user-controllable settings.

Output

numSubGroups A pointer to an integer to receive the number of groups that were found.
subGroupNames A char *** that receives a buffer containing an array of pointers to strings composing the list of group names. When finished with this buffer, you must call Aps_ReleaseBuffer().

Typical Use

The following example illustrates how to recursively retrieve all user-setting attributes in all groups in the hierarchy:

void GetAllSettings(Aps_JobAttributesHandle attr)
{
    GetSettingsInGroup(attr, APS_GROUP_ROOT_SETTINGS);
}

void GetSettingsInGroup(Aps_JobAttributesHandle attr, char *groupName)
{
    char **names;
    int total;
    int i;

    /* First, recursively get all subgroups. */
    if (Aps_AttrGetSubGroups(attr, groupName, &total, &names)
        != APS_SUCESS) return;
    for (i = 0; i < total; ++i) {
        printf("Subgroup %s:\n", names[i]);
        GetSettingsInGroup(attr, names[i]);
    }
    Aps_ReleaseBuffer(names);

    /* Now, get the IDs of attributes in this group. */
    if (Aps_AttrGetList(attr, groupName, &total, &names)
        != APS_SUCESS) return;
    for (i = 0; i < total; ++i) {
        printf("    Attribute ID: %s\n", names[i]);
    }
    Aps_ReleaseBuffer(names);
}

3.7.3.3 Aps_AttrGetTranslatedName()

Obtains the local translated name for the specified attribute. This is the text that should be displayed to the user when presenting a list of settings that can be altered.

Aps_Result Aps_AttrGetTranslatedName(
    Aps_JobAttrHandle jobAttributes,
    const char *attributeID,
    char **translatedName);

Input

jobAttributes A handle to a job attributes object.
attributeID A string identifying the attribute being queried.

Output

translatedName A pointer to a string pointer that receives a new buffer with the translated name for this attribute. When you are finished with this buffer, call Aps_ReleaseBuffer().

3.7.3.4 Aps_AttrGetMainData()

Obtains the main (read-only) data provided by this attribute. The meaning and contents of the main data string is dependant on the particular attribute being queried.

Aps_Result Aps_AttrGetMainData(
    Aps_JobAttrHandle jobAttributes,
    const char *attributeID,
    char **mainData);

Input

jobAttributes A handle to the job attributes object.
attributeID A string uniquely identifying the attribute to retrieve.

Output

mainData A pointer to a char* to receive a new buffer containing the main data stored in this attribute. If this function succeeds, it is the caller's responsibility to dispose of this string when finished with it by calling Aps_ReleaseBuffer().

3.7.3.5 Aps_AttrGetTranslatedData()

Obtains the translated data string for a particular attribute.

Aps_Result Aps_AttrGetTranslatedData(
    Aps_JobAttrHandle jobAttributes,
    const char *attributeID,
    char **translatedData);

Input

jobAttributes A handle to the job attributes object.
attributeID A string uniquely identifying the attribute to retrieve.

Output

translatedData A string pointer to receive a new buffer with the translated data. When finished with this buffer, you must call Aps_ReleaseBuffer().

3.7.3.6 Aps_AttrGetType()

Obtains the type of a particular attribute. Attributes may be read-only informational attributes, or may store one of a variety of types of user-modifiable settings.

Aps_Result Aps_AttrGetType(
    Aps_JobAttrHandle jobAttributes,
    const char *attributeID,
    Aps_AttrType *attributeType);

Input

jobAttributes A handle to the job attributes object.
attributeID A string uniquely identifying the attribute to retrieve.

Output

attributeType A pointer to an Aps_AttrType to receive the
* type of the attribute.

Remarks

These are the possible attribute types that Aps_AttrType can be set to:

Aps_AttrType Value Meaning
APS_ATTR_READ_ONLY_DATA Indicates an attribute which has no corresponding
APS_ATTR_SETTING_INT A user-controllable setting that can be any integer value in the range returned by Aps_AttrGetRange().
APS_ATTR_SETTING_FLOAT A user-controllable setting that can be any floating point value in the range returned by Aps_AttrGetRange().
APS_ATTR_SETTING_BOOL A user-controllable setting that can be either TRUE or FALSE. Aps_AttrGetOptions() may be able to provide information on the meaning of TRUE and FALSE.
APS_ATTR_SETTING_PICK_ONE A user-controllable setting that can take on the value of any one option returned by Aps_AttrGetOptions().
APS_ATTR_SETTING_PICK_MANY A user-controllable setting that can be any subset of the set of options returned by Aps_AttrGetOptions().

3.7.3.7 Aps_AttrGetRange()

Obtains the range of possible values for attributes with integer or floating point user settings.

Aps_Result Aps_AttrGetRange(
    Aps_JobAttrHandle jobAttributes,
    const char *attributeID,
    double *minSetting,
    double *maxSetting);

Input

jobAttributes A handle to the job attributes object.
attributeID A string uniquely identifying the attribute to retrieve.

Output

minSetting A double to receive the minimum value.
maxSetting A double to receive the maximum value.

Remarks

For integer settings, minSetting and maxSetting will always be integer values, meaning that they can safely be casted to ints.


3.7.3.8 Aps_AttrGetOptions()

Obtains a list of options (e.g. possible values for the user-setting) of the specified attribute.

Aps_Result Aps_AttrGetOptions(
    Aps_JobAttrHandle jobAttributes,
    const char *attributeID,
    int *numOptions,
    Aps_AttrOption **options);

Input

jobAttributes A handle to the job attributes object.
attributeID A string uniquely identifying the attribute to retrieve.

Output

numOptions A pointer to an integer to receive the number of available options.
options An Aps_AttrOption pointer to receive a pointer to a new array. When finished with this array, you must pass it to Aps_ReleaseBuffer().

Remarks

The Aps_AttrOption structure stores the following fields:

optionID A pointer to a string ID that uniquely identifies this option.
translatedName A pointer to a string containing the text to display to the user for this option.
value Information used by APS or the underlying print system to activate this option if selected. In the case of attributes provided by a PPD file, this will be the PostScript code that is used to turn on this option.

Typical Use

Aps_AttrOption options;
int numOptions;
int i

if (Aps_AttrGetOptions(jobAttributes, attributeID, &numOptions, &options)
    == APS_SUCCESS) {
    for (i = 0; i < numOptions; ++i) {
        printf("Text for option ID %s = %s\n",
            options[i].optionID, options[i].translatedName);
    }

    Aps_ReleaseBuffer(options);
}

3.7.3.9 Aps_AttrGetSetting()

Obtains the current value of the user-setting for a particular attribute.

Aps_Result Aps_AttrGetSetting(
    Aps_JobAttrHandle jobAttributes,
    const char *attributeID,
    char **setting);

Input

jobAttributes A handle to the job attributes object.
attributeID A string uniquely identifying the attribute to retrieve.

Output

setting A pointer to a char * to receive a new buffer containing the current user-setting for this attribute. When finished with this buffer, deallocate it by calling Aps_ReleaseBuffer().

For "pick-one" and "pick-many" settings, this string will correspond to the option ID obtained from Aps_AttrGetOptions(). For integer and floating point settings, this will be a string representation of the numerical value. For Boolean settings, this will be the string "0" for FALSE, and "1" for TRUE.


3.7.3.10 Aps_AttrSetSetting()

Changes the user-setting for a particular attribute.

Aps_Result Aps_AttrSetSetting(
    Aps_JobAttrHandle jobAttributes,
    const char *attributeID,
    const char *setting);

Input

jobAttributes A handle to the job attributes object.
attributeID A string uniquely identifying the attribute to modify.
setting The new value for the user-setting. For "pick-one" and "pick-many" settings, this should correspond to the option ID obtained from Aps_AttrGetOptions(). For integer and floating point settings, this should be a string representation of the numerical value. For Boolean settings, this should be the string "0" for FALSE, and "1" for TRUE.

3.7.3.11 Aps_AttrCheckConstraints()

Tests whether a proposed change to a particular attribute's user-setting would violate any of the user-setting constraints.

Aps_Result Aps_AttrCheckConstraints(
    Aps_JobAttrHandle jobAttributes,
    const char *attributeID,
    const char *setting,
    char **conflictingAttribute,
    char **conflictingSetting);

Input

jobAttributes A handle to a job attributes object.
attributeID A string uniquely identifying the attribute whose user setting is being proposed for modification.
setting A string containing the new user setting being proposed for this attribute.

Output

conflictingAttribute If a conflict is found, this will be given a string buffer containing the ID of the first attribute found to conflict with the proposed change. Use Aps_ReleaseBuffer() to deallocate this buffer when finished with it.
conflictingSetting If a conflict is found, this will contain conflicting user-setting. Use Aps_ReleaseBuffer() to deallocate this buffer.

Remarks

This function returns APS_SUCCESS if no constraints would be violated by this change, APS_VIOLATES_CONSTRAINTS if there is is a conflict, or another Aps_Result code when there is an error.

Refer to the documentation on Aps_AttrGetSetting() for information on the formation of the setting and conflictingSetting strings.

Typical Use

char *conflictingAttribute;
char *conflictingSetting;
Aps_Result result;

result = Aps_AttrCheckConstraints(jobAttributes, modifiedAttributeID,
                                  newValue, &conflictingAttribute,
                                  &conflictingSetting);
if (result == APS_SUCCESS) {
    /* It is safe to proceed in changing this attribute using */
    /* Aps_AttrSetSetting(). */
} else if (result == APS_VIOLATES_CONSTRAINTS) {
    /* Notify user that this choice is not compatible with the */
    /* setting identified by conflictingAttribue. */

    /* Release returned buffers. */
    Aps_ReleaseBuffer(conflictingAttribute);
    Aps_ReleaseBuffer(conflictingSetting);
}

3.7.4 Quick Access to Common Attributes

These functions provide quick access to the most commonly used attributes. Note that for many printers, this will only be a small subset of all attributes available through the generic attribute functions described in section 3.7.3.

Note that in some cases some cases the information retrieved by these functions will be unavailable from the job attributes object, in which case the function will return APS_NOT_SUPPORTED.

3.7.4.1 Aps_AttrQuickGetPostScriptLevel()

Obtains the level of the PostScript language that is supported, if PostScript is supported.

Aps_Result Aps_AttrQuickGetLanguageLevel(
    Aps_JobAttrHandle jobAttributes,
    Aps_PostScriptSupport *languageLevel);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

languageLevel The address of an Aps_PostScriptSupport enumeration to be set to the language level supported by this device, if known.

Remarks

This function packages information from the "SupportedLanguage" and "*LanguageLevel" attributes.

For true PostScript devices, this information will be taken from the PPD file for the device (if found). For non-PostScript devices for which the output will be rasterized on the host, this will be the level of PostScript supported by the software RIP (e.g. by GhostScript).

The languageLevel output parameter may be set to one of the following values:

Aps_PostScriptSupport Value Meaning
APS_PS_NOT_SUPPORTED PostScript is not supported
APS_PS_LEVEL1 PostScript level 1 support only
APS_PS_LEVEL2 PostScript level 2 and level 1 support
APS_PS_LEVEL3 PostScript 3, level 2 and level 1 support

3.7.4.2 Aps_AttrQuickIsColorDevice()

Determines whether or not this device is capable of printing in color.

Aps_Result Aps_AttrQuickIsColorDevice(
    Aps_JobAttrHandle jobAttributes,
    int *colorDevice);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

colorDevice The address of an int to be set to TRUE if this is a color-capable device, FALSE if the device can only print grayscale.

Remarks

This function packages information from the "*ColorDevice" attribute.


3.7.4.3 Aps_AttrQuickGetResOptions()

Obtains a list of available resolutions.

Aps_Result Aps_AttrQuickGetResOptions(
    Aps_JobAttrHandle jobAttributes,
    Aps_Resolution ***resolutions,
    int *numResolutions);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

resolutions The address of a pointer to receive and array of Aps_Resolution pointers, consisting of one element for each available resolution. If this function succeeds, the caller is responsible for disposing of this array when no longer needed by calling Aps_ReleaseBuffer().
numResolutions An int to receive the number of resolutions that have been listed in the resolutions array.

Remarks

This function packages information from the "*Resolution" attribute.

Each element in the array of resolutions is an Aps_Resolution structure, which is defined as follows:

typedef struct Aps_Resolution_ {
    double horizontalRes; /* Horizontal resolution in dots per inch */
    double verticalRes;   /* Vertical resolution, also in DPI */
} Aps_Resolution;

Note that for some printers, the horizontal and vertical resolutions will always be the same as one another, whereas for other printers they may differ.


3.7.4.4 Aps_AttrQuickGetRes()

Obtains the currently selected resolution that will be used for rasterization.

Aps_Result Aps_AttrQuickGetRes(
    Aps_JobAttrHandle jobAttributes,
    Aps_Resolution *resolution);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

resolution The address of an Aps_Resolution structure to receive the current resolution setting.

Remarks

This function obtains the current setting associated with the "*Resolution" attribute.


3.7.4.5 Aps_AttrQuickSetRes()

Sets the resolution that will be used for rasterization.

Aps_Result Aps_AttrQuickSetRes(
    Aps_JobAttrHandle jobAttributes,
    const Aps_Resolution *resolution);

Input

jobAttributes A handle to an existing Job Attributes object.
resolution An Aps_Resolution

Remarks

This function changes the setting associated with the "*Resolution" attribute.

The resolution set must be one of the supported resolutions, as list of which can be obtained using the Aps_AttrQuickGetResOptions() function.


3.7.4.6 Aps_AttrQuickGetMaxCopies()

Obtains the maximum number of copies of a job that can be printed.

Aps_Result Aps_AttrQuickGetNumCopies(
    Aps_JobAttrHandle jobAttributes,
    int *maxCopies);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

maxCopies The address of an int to receive the maximum number of copies.

Remarks

This function packages information from the "NumCopies" attribute.


3.7.4.7 Aps_AttrQuickGetNumCopies()

Obtains the number of copies of the entire job that will be printed.

Aps_Result Aps_AttrQuickGetNumCopies(
    Aps_JobAttrHandle jobAttributes,
    int *numCopies);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

numCopies The address of an int to receive the number of copies of the job to be printed.

Remarks

This function obtains the current setting associated with the "NumCopies" attribute.


3.7.4.8 Aps_AttrQuickSetNumCopies()

Changes the number of copies of the entire job that will be printed.

Aps_Result Aps_AttrQuickSetNumCopies(
    Aps_JobAttrHandle jobAttributes,
    int numCopies);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

numCopies The number of copies to be printed.

Remarks

This function changes the setting of the "NumCopies" attribute.


3.7.4.9 Aps_AttrQuickGetCollationOptions()

Obtains a list of standard collation options that are available.

Aps_Result Aps_AttrQuickGetCollationOptions(
    Aps_JobAttrHandle jobAttributes,
    char ***collationOptions,
    int *numOptions);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

collationOptions The address of a char ** to receive an array string pionters with the possible collation options. If this function succeeds, it is the caller's responsibility to dispose of this array when no longer needed by passing it to Aps_ReleaseBuffer().
numOptions An integer to receive the number of options in the collationOptions array.

Remarks

This function packages information from the "*Collate" attribute.

The table below lists the currently defined collation options. Note: Some printers may provide non-standard collation options in addition to those listed below.

Collation Setting Meaning
"True" Multiple copies will be collated, so that all pages of one copy are printed prior to all pages of the next copy.
"False" Multiple copies will be printed in un-collated order, so that all copies of one page are printed prior to all copies of the next page.

3.7.4.10 Aps_AttrQuickGetCollation()

Obtains the current setting for copy collation.

Aps_Result Aps_AttrQuickGetCollation(
    Aps_JobAttrHandle jobAttributes,
    char **collationSetting);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

collationSetting The address of a char * to receive the current collation setting. On success it is the caller's responsibility to dispose of this string when no longer needed by calling Aps_ReleaseBuffer(). Refer to the Aps_AttrQuickGetCollationOptions() function for information on the standard collation settings.

Remarks

This function obtains the current setting associated with the "*Collate" attribute.


3.7.4.11 Aps_AttrQuickSetCollation()

Changes the current setting for copy collation.

Aps_Result Aps_AttrQuickGetCollation(
    Aps_JobAttrHandle jobAttributes,
    const char *collationSetting);

Input

jobAttributes A handle to an existing Job Attributes object.
collationSetting An Aps_CopyCollation enumeration identifying the current collation setting. This must be one of the values that are currently available, as identified by the Aps_AttrQuickGetCollationOptions(). See the documentation of that function for information on the possible values for this setting.

Remarks

This function modifies the current settings associated with the "*Collate" attribute.


3.7.4.12 Aps_AttrQuickGetPageSizeOptions()

Obtains a list of available pre-defined pages sizes.

Aps_Result Aps_AttrQuickGetAvailPageSizeOptions(
    Aps_JobAttrHandle jobAttributes,
    Aps_PageSize ***pageSizes,
    int *numPageSizes);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

pageSizes The address of an Aps_PageSize ** to receive an array of pointers to Aps_PageSize structures, each of which will contain information on one of the page sizes that are available. If this function succeeds, it is the caller's responsibility to dispose of this array when no longer needed by calling Aps_ReleaseBuffer().
numPageSizes An int to receive the number of available page sizes that have been listed in the pageSizes array.

Remarks

This function packages information from the "*PaperDimension" and "*ImageableArea" attributes.

The Aps_PageSize structure is defined as follows:

typedef struct Aps_PageSize_ {
    char *id;                /* A string uniquely identifying this page size. */
    char *translatedName;    /* The page size name to display to the user. */
    double mediaWidth;       /* The width of the paper/media in points */
    double mediaHeight;      /* The height in points */
    double imageableAreaLLx; /* X-coordinate of lower left corner of imageable area. */
    double imageableAreaLLy; /* Y-coordinate of lower left corner of imageable area. */
    double imageableAreaURx; /* X-coordinate of upper right corner of imageable area. */
    double imageableAreaURy; /* Y-coordinate of upper right corner of imageable area. */

    /* Information used only when specifying a custom page size. */
    double widthOffset;          /* The position of the page on the media for roll-fed devices */
    double heightOffset;
    Aps_Rotation orientation;    /* One of: APS_ROTATE_[0,90,180,270] */
    int useHWMargins;            /* Normally TRUE, FALSE to force roll-fed */
    Aps_LeadingEdge leadingEdge; /* One of: APS_LEADING_[SHORT,LONG,PREFERLONG,FORCED,UNKOWN] */
} Aps_PageSize;

All measurements in this structure are given in points, where one point is equal to 1/72nd of an inch. The coordinates for the imageable area are given relative to the lower left corner of the page (media).


3.7.4.13 Aps_AttrQuickGetCustomPageSizeInfo()

Obtains an Aps_CustomPageSizeInfo structure with information on the range of custom page sizes that are available, if custom page sizes are supported by this printer.

Aps_Result Aps_AttrQuickGetCustomPageSizeInfo(
    Aps_JobAttrHandle jobAttributes,
    Aps_CustomPageSizeInfo **customPageSizeInfo);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

customPageSizeInfo The address

Remarks

This function packages information from the following attributes: "*CustomPageSize", "*MaxMediaWidth", "*MaxMediaHeight", "*CenterRegistered", "*HWMargins", "*UseHWMargins"

If custom page sizes cannot be used, this function will return APS_NOT_SUPPORTED.

The Aps_CustomPageSizeInfo structure is defined as follows:

typedef struct Aps_CustomPageSizeInfo_ {
    double maxMediaWidth;   /* Maximum width of the page */
    double maxMediaHeight;  /* Maximum height of the page */
    int centerRegistered;   /* TRUE if page must be centered on media */
    double leftHWMargin;    /* Size of non-imageable area at left edge of media */
    double bottomHWMargin;  /* Size of non-imageable area at bottom of media */
    double rightHWMargin;   /* Size of non-imageable area at right edge of media */
    double topHWMargin;     /* Size of non-imageable area at top of media */
    int optionalHWMargins;  /* TRUE if there is a mode where HW margins can be turned off */
    double minWidthOffset;  /* The minimum offset of the page across the media */
    double maxWidthOffset;  /* The maximum offset of the page across the media */
    double minHeightOffset; /* The minimum offset of the page down the media */
    double maxHeightOffset; /* The maximum offset of the page down the media */
    Aps_LeadingEdge leadingEdgeOptions; /* One or more of the APS_LEADING_* flags */
};

In this structure, all dimensions are given in points, where one point is equal to 1/72nd of an inch. The "width" of the page is defined to be its size perpendicular to the direction in which the media is fed into the device; the "height" is parallel to the media feed direction.

The optionalHWMargins flag indicates a device that can be switched into a mode where the entire page can be imaged, as a device that can switch between cut-sheet and roll-fed modes.

The leadingEdgeOptions member will list the possible values that can be used for the leadingEdge member in the Aps_PageSize structure, all ORed together.


3.7.4.14 Aps_AttrQuickGetPageSize()

Obtains the page size that is currently selected.

Aps_Result Aps_AttrQuickGetPageSize(
    Aps_JobAttrHandle jobAttributes,
    Aps_PageSize **pageSize);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

pageSize An Aps_PageSize pointer to receive the address of a new instance of this structure with information on the currently selected page size. If this function succeeds, it is the caller's responsibility to dispose of this structure when no longer needed by calling Aps_ReleaseBuffer(). See the Aps_AttrQuickGetPageSizeOptions() function for information on the contents of an Aps_PageSize structure.

Remarks

This function obtains the current setting associated with the "*PageSize" attribute.


3.7.4.15 Aps_AttrQuickSetPredefinedPageSize()

Sets the current page size to one of the pre-defined page sizes obtained by Aps_AttrQuickGetPageSizeOptions().

Aps_Result Aps_AttrQuickSetPredefinedPageSize(
    Aps_JobAttrHandle jobAttributes,
    const char *pageSizeID);

Input

jobAttributes A handle to an existing Job Attributes object.
pageSizeID A string containing the ID of the page size to be selected. This should

Remarks

This function changes the current setting associated with the "*PageSize" attribute.


3.7.4.16 Aps_AttrQuickSetCustomPageSize()

Selects a custom page size, rather than using one of the page sizes in the list of predefined page sizes.

Aps_Result Aps_AttrQuickSetCustomPageSize(
    Aps_JobAttrHandle jobAttributes,
    const Aps_PageSize *customPageSize);

Input

jobAttributes A handle to an existing Job Attributes object.
Aps_PageSize The address of an Aps_PageSize structure containing the parameters that describe the page size to be used. See the Aps_QuickGetPageSizeOption() function for information on the contents of this structure.

Remarks

Not all devices support custom page sizes. Use the Aps_AttrQuickGetCustomPageSizeInfo() function to determine whether or not a device supports custom page sizes, and to obtain information on the constraints placed on the range of possible custom page sizes. This function uses the following information from the provided Aps_PageSize structure:

Aps_PageSize member Default value *
mediaWidth n/a
mediaHeight n/a
widthOffset 0
heightOffset 0
orientation APS_ROTATE_0
useHWMargins TRUE
leadingEdge APS_LEADING_DEFAULT

* If you wish to specify a custom page size using only the width and height of the media, you may set the default values for the other members. If you wish to control all of these parameters, refer to Adobe's PPD specification for the proper use of the remaining options.


3.7.4.17 Aps_AttrQuickGetInputSlotOptions()

Obtains a list of available standard input slots that are available.

Aps_Result Aps_AttrQuickGetInputSlotOptions(
    Aps_JobAttrHandle jobAttributes,
    char ***inputSlots,
    int *numInputSlots);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

inputSlots The address of a char ** to receive an array of string pointers with the available input slots. If this function succeeds, it is the caller's responsibility to dispose of the array when no longer needed by calling Aps_ReleaseBuffer().
numInputSlots An int to receive the number of available input slots that were placed in the array.

Remarks

This function packages the information from the "*InputSlot" and "*ManualFeed" attributes.

The table below shows the set of standard input slots defined for use by this function. Note that printers may support input slots additional input slots other than the standard slots listed below.

Aps_InputSlot Value Meaning
"Lower" A tray that has no specific attributes other than being positioned lower than other similar trays.
"Middle" Like "Lower", but the tray between other trays.
"Upper" Like "Lower", but the tray above other trays.
"Rear" A slot on the rear side of the device.
"Envelope" A tray specifically designed for feeding envelopes.
"Cassette" The standard tray used when it doesn't make sense to distinguish between lower, middle and upper trays.
"LargeCapacity" A tray designed to hold a large number of sheets of media.
"AnySmallFormat" A tray designed to hold small sized sheets of media.
"AnyLargeFormat" A tray designed to hold large sized sheets of media.
"Manual" A manual feed slot that may only accept one page at a time.

3.7.4.18 Aps_AttrQuickGetInputSlot()

Obtains the currently selected input slot.

Aps_Result Aps_AttrQuickGetInputSlot(
    Aps_JobAttrHandle jobAttributes,
    char **inputSlot);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

inputSlot The address of a char * to receive a string with the current input slot selection. On success, it is the caller's responsibility to dispose of this string when no longer needed by calling Aps_ReleaseBuffer(). Refer to the Aps_AttrQuickGetInputSlotOptions() for a list of standard input slot ID strings.

Remarks

This function obtains the current setting associated with the "*InputSlot" attribute.


3.7.4.19 Aps_AttrQuickSetInputSlot()

Changes the currently selected input slot.

Aps_Result Aps_AttrQuickSetInputSlot(
    Aps_JobAttrHandle jobAttributes,
    const char *inputSlot);

Input

jobAttributes A handle to an existing Job Attributes object.
inputSlot An input slot ID string identifying the input slot to use. Refer to the Aps_AttrQuickGetInputSlotOptions() for a list of standard input slot values.

Remarks

This function modifies the current setting associate with the "*InputSlot" attribute.


3.7.4.20 Aps_AttrQuickGetOutputBinOptions()

Obtains a list of available standard output bins that are available.

Aps_Result Aps_AttrQuickGetOutputBinOptions(
    Aps_JobAttrHandle jobAttributes,
    char ***outputBins,
    int *numOutputBins);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

outputBins The address of a char ** to receive an array of string pointers with the available output bins. If this function succeeds, it is the caller's responsibility to dispose of the array when no longer needed by calling Aps_ReleaseBuffer().
numOutputBins An int to receive the number of available output bins that were placed in the array.

Remarks

This function packages the information from the "*OutputBin" attribute.

The table below shows the set of standard output bins defined for use by this function. Note that printers may support additional output bins other than the standard bins listed below.

Aps_OutputBin Value Meaning
"Upper" The standard output bin located in the higher position. This is often used for printers only supporting one primary output bin.
"Lower" The standard output bin located in the lower position.
"Rear" An output bin located at the rear of the printer. On many printers, this output tray provides a relatively straight paper path suitable for printing on thicker stock that should not or cannot be bent to the extent required to print to other output bins.

3.7.4.21 Aps_AttrQuickGetOutputBin()

Obtains the currently selected output bin.

Aps_Result Aps_AttrQuickGetOutputBin(
    Aps_JobAttrHandle jobAttributes,
    char **outputBin);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

outputBin The address of a char * to receive a string with the current output bin setting. On success, it is the caller's responsibility to dispose of this string when no longer needed by calling Aps_ReleaseBuffer(). Refer to the Aps_AttrQuickGetOutputBinOptions() function for a list of standard input slot ID strings.

Remarks

This function obtains the current setting associated with the "*OutputBin" attribute.


3.7.4.22 Aps_AttrQuickSetOutputBin()

Changes the currently selected output bin.

Aps_Result Aps_AttrQuickSetOutputBin(
    Aps_JobAttrHandle jobAttributes,
    const char *outputBin);

Input

jobAttributes A handle to an existing Job Attributes object.
outputBin A string with the ID of the output bit to use. This must be one of the output bins identified by the Aps_AttrQuickGetOutputBinOptions() function. Refer to this function for information on the standard output bin IDs.

Remarks

This function modifies the current setting associate with the "*OutputBin" attribute.


3.7.4.23 Aps_AttrQuickGetDuplexOptions()

Obtains a list of available settings for duplex (double-sided) printing.

Aps_Result Aps_AttrQuickGetDuplexOptions(
    Aps_JobAttrHandle jobAttributes,
    char ***duplexSettings,
    int *numDuplexSettings);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

duplexSettings The address of a char ** to receive an array of string pointers with the available duplex settings. If this function succeeds, it is the caller's responsibility to dispose of the array when no longer needed by calling Aps_ReleaseBuffer().
numDuplexSettings The number of elements in the array provided via duplexSettings.

Remarks

This function packages the information from the "*Duplex" attribute.

The table below shows the standard values for the duplex setting:

Aps_Duplex Value Meaning
"None" Prints on one side of the page, in the normal orientation.
"SimplexTumble" Prints on one side of the page, rotating each page 180 degrees.
"DuplexNoTumble" Prints on both sides of the page, in the normal orientation. Typically used when the pages will be bound along the long edge of the page.
"DuplexTumble" Prints on both sides of the page, rotating the second side of each page 180 degrees. Typically used when the pages will be bound along the short edge of the page.

3.7.4.24 Aps_AttrQuickGetDuplex()

Obtains the current setting for duplex printing.

Aps_Result Aps_AttrQuickGetDuplex(
    Aps_JobAttrHandle jobAttributes,
    char **duplexSetting);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

duplexSetting The address of a char * to receive a string with the current value of the duplex setting. On success, it is the caller's responsibility to dispose of this string when no longer needed by calling Aps_ReleaseBuffer(). Refer to the Aps_AttrQuickGetDuplexOptions() function for a list of standard input slot ID strings.

Remarks

This function obtains the setting associated with the "*Duplex" attribute.


3.7.4.25 Aps_AttrQuickSetDuplex()

Changes the current setting for duplex printing.

Aps_Result Aps_AttrQuickSetDuplex(
    Aps_JobAttrHandle jobAttributes,
    const char *duplexSetting);

Input

jobAttributes A handle to an existing Job Attributes object.
duplexSetting A string with the ID of the duplex setting to use. This must be one of the available duplex settings identified by the Aps_AttrQuickGetDuplexOptions() function. Refer to this function for information on the standard duplex setting IDs.

Remarks

This function changes the setting associated with the "*Duplex" attribute.


3.7.4.26 Aps_AttrQuickGetFonts()

Obtains a list of fonts that are available (resident) on the device.

Aps_Result Aps_AttrQuickGetFonts(
    Aps_JobAttrHandle jobAttributes,
    Aps_FontInfo ***fonts,
    int *numFonts);

Input

jobAttributes A handle to an existing Job Attributes object.

Output

fonts The address of a pointer to receive an array of pointers to Aps_FontInfo structures, with one element for each resident font. If this function succeeds, it is the caller's responsibility to dispose of this array when no longer needed by calling Aps_ReleaseBuffer().
numFonts An integer to receive the number of fonts in the array that the fonts parameter passes back.

Remarks

This function packages the information from the "*Font" attribute.

The Aps_FontInfo structure is defined as follows:

typedef struct Aps_FontInfo_ {
    char *name;    /* The name of the font */
    int isDefault; /* TRUE if this is the devices default font, FALSE otherwise. */
    Aps_FontType;  /* One of: APS_FONT_[STANDARD,SPECIAL] */
} Aps_FontInfo;

3.8 Job Production and Dispatch

To send a new job to be printed, you can use one of two methods:

  1. If you have an existing file to be printed, you can send the entire job in one step using the Aps_DispatchJob() function.
  2. If you are generating PostScript or another format on the fly, it is preferable to send the job using Aps_PrinterStartJob(), followed by one or more write()/Aps_JobWrite() calls, followed by Aps_JobEnd(). When using this mechanism, you can choose to cancel the job at any point before calling Aps_JobEnd() using Aps_JobAbort(). Using this method, you can take advantage of Aps_JobWriteBlock() to have APS look after generating the printer-specific commands for controlling job attributes.

3.8.1 Aps_DispatchJob()

Dispatches a job in a single atomic operation, reading the data to be printed from a file.

Aps_Result Aps_DispatchJob(
    Aps_PrinterHandle printer,
    char *filename,
    char *format,
    Aps_JobAttrHandle jobAttributes,
    Aps_JobHandle *job);

Input

printer An optional handle to the printer to print this job on. If NULL, the job will be printed on the default printer.
filename The name of the file or other file system entity to print from.
format A string describing the format (e.g. PostScript, raw text, etc.) of the data being submitted. This can be any MIME data type, or one of the following predefined formats:
  • APS_FORMAT_POSTSCRIPT - PostScript language.
jobAttributes An optional handle to the job attributes to apply to this job. If this parameter is NULL, the default attributes settings for this printer will be used.

Output

job An optional pointer to receive an Aps_JobHandle to allow future monitoring of this job, or NULL if not required. If the caller does receive a handle to the job, it is the caller's responsibility to dispose of this handle when no longer needed by calling Aps_ReleaseHandle().

Remarks

The simplest way of sending a job via APS is by making the following single function call:

Aps_DispatchJob(NULL, filename, NULL, NULL, NULL);

This will print the file specified by filename to the default printer, using its default job attributes, attempting to autodetect the type of data if needed, and without providing a handle for future monitoring of this job.


3.8.2 Aps_PrinterStartJob()

Begins a new job on the device, providing the caller with an Aps_JobHandle that can be used to manipulate job settings, or to write data to be printed.

Aps_Result Aps_PrinterStartJob(
    Aps_PrinterHandle printer,
    char *format,
    Aps_JobHandle *job);

Input

printer Handle to the printer to print this job, or NULL to use the default printer.
format A string describing the format (e.g. PostScript, raw text, etc.) of the data being submitted. See the Aps_DispatchJob() function for more information on possible format values.

Output

job A pointer to an Aps_JobHandle to receive the new job handle.

3.8.3 Aps_JobWrite()

Writes data to be printed as part of this job.

Aps_Result Aps_JobWrite(
    Aps_JobHandle job,
    void *data,
    int size);

Input

job A handle to an active job, as returned by Aps_PrinterStartJob().
data A pointer to the buffer containing data to be printed.
size The number of bytes to be printed from the buffer pointed to by data. If this is 0, no data is written.

Remarks

This function can be used as an alternative to calling write() on the file descriptor provided by Aps_PrinterStartJob().

The data passed to this function must be in the format for this job, as specified in the call to Aps_PrinterStartJob(). For instance, for a PostScript format job, this must be valid PostScript language commands.


3.8.4 Aps_JobWriteBlock()

Writes a printer-specific block of data, including printer-specific commands to trigger the settings that have been selected via the job attributes mechanism.

Aps_Result Aps_JobWriteBlock(
    Aps_JobHandle job,
    Aps_BlockType blockType);

Input

job A handle to the job to write the standard block of printer-specific commands to.
blockType An Aps_BlockType representing the type of block to be written.

Remarks

The following types of blocks can be specified using Aps_BlockType:

Aps_BlockType Value Meaning
APS_BLOCK_FILE_HEADER Outputs the printer-specific header which should be the very first data sent to the printer. This may include commands to switch the printer into the appropriate language according to the format specified in the call to Aps_PrinterStartJob(), and it may also include commands to set some settings set in the job attributes.
APS_BLOCK_PS_PATCH If a patch file is available to fix bugs in the device's firmware (ROM code), this will output the PostScript code that downloads the patch to the device.

This block should be output after the PostScript header information has been sent, but prior to the prolog section of the PostScript file. That is, for DSC-compliant files, this should be output prior to the %%BeginProlog comment.

APS_BLOCK_PS_DEV_SETUP Outputs any device-specific PostScript code needed to realize the settings that have been set in the job attributes, based on information provided by the printer's PPD file. This function generates PostScript code corresponding to all UI keys in the PPD file, along with the code to setup a custom page size if needed. Any order dependencies provided in the PPD file will be honored.

This block should be output in the document setup portion of the PostScript file. The PostScript DSC rules require this information to be output within your %%BeginSetup section.

APS_BLOCK_FILE_FOOTER Outputs the printer-specific footer, which should be the very last data sent to the printer.

Note that in some cases, no specific information will be required for one or more block types. In these cases, Aps_JobWriteBlock() succeeds, silently outputting no data.

Typical Use

The typical application that generates PostScript code, and that uses APS's job attributes mechanism to support printer-specific features, will generate the job using the following sequence:

Aps_JobHandle job;
Aps_PrinterStartJob(printer, APS_FORMAT_POSTSCRIPT, &job);

Aps_JobWriteBlock(job, APS_FILE_HEADER);

/* One or more Aps_JobWrite() calls to write PostScript header & prolog. */

Aps_JobWriteBlock(job, APS_PS_DEV_SETUP);

/* One or more Aps_JobWrite() calls to write page contents. */

Aps_JobWriteBlock(job, APS_FILE_FOOTER);

Aps_JobEnd(job);

3.8.5 Aps_JobGetFileDescriptor()

Obtains a file descriptor to allow the application to write directly to this job without using the Aps_Write() function.

Aps_Result Aps_JobGetFileDescriptor(
    Aps_JobHandle job,
    int *fileDescriptor);

Input

job An Aps_JobHandle identifying a job that is being produced.

Output

fileDescriptor The address of an int to receive the file descriptor for writing to this job.

Remarks

This function is primarily designed to make it easier to integrate APS into existing applications where the code already writes the data to a file.

Note that this function may not be supported for all transports. If it is supported, using this function may require APS to create a pipe to receive data from the file descriptor, creating extra overhead. As such, it is recommended that new applications use Aps_Write() instead.


3.8.6 Aps_JobEnd()

Called by the application to indicates that all data for this job has now been sent by the application, and that the job should now be scheduled for printing.

Aps_Result Aps_JobEnd(
    Aps_JobHandle job);

Input

job An Aps_JobHandle identifying the job to be dispatched.

Remarks

Ending a job indicates that there is no more data to be printed as part of this job, and schedules the job for printing if this hasn't already been done.

Calling this function implicitly releases the job handle. If you wish to monitor the status of this job after calling this function, call Aps_AddRef() on the handle first, and then call Aps_ReleaseHandle() when you are finished monitoring the job.


3.8.7 Aps_JobAbort()

Called by the application to terminate a job.

Aps_Result Aps_JobAbort(
    Aps_JobHandle job);

Input

job An Aps_JobHandle identifying the job to be aborted.

Remarks

Applications shouldn't assume that no data has been sent to the printer before this function is called. That is, it is possible that some of the job may be printed even if this function is called.

Note that calling this function implicitly releases the job handle.


3.9 Queue Monitoring and Management

These functions provide access to the system's print queues.  This section is subdivided into three main headings: Accessing and Controlling Queues, Accessing and Controlling Jobs, Composing Job and Queue Filters.

3.9.0 General guidelines for working with queues

  1. Aps_Queue objects are abstract representations of some underlying transport mechanism.   Since the library does not at this time handle print queues themselves -- it forwards all queue operations to a qualified transport -- so APS is unable to guarantee the function of many queue-related operations.  For instance, transports may not support certain job-related functions such as pausing or resuming jobs.  Alternately, they may not process attributes and queries identically; some may ignore priority codes and others may never return APS_JOB_QUEUEING.
  2. As Aps_Queue objects must communicate with external components to provide services for an application, the success of any given operation ultimately rests on the capabilities and robustness of those components.  Moreover, even if you have a handle to a printer's queue, do not assume that the printer is accessible or even necessarily installed.  It is possible for a user to remove or reconfigure a printer such that it becomes inaccessible, so check all return codes.
  3. When processing error codes in a user interface, try to display the most precise information available.  Also, some error codes actually represent recoverable errors, like APS_FILTER_NOT_SUPPORTED or APS_NO_MORE_DATA, or warnings, such as APS_PARTIAL_SUCCESS, APS_NO_CHANGE or APS_IGNORED.  Use Aps_Succeeded() or the Table of APS Result Codes to determine if the code represents a warning that can be safely ignored.
  4. Many queue functions provide handles to other objects such as jobs or printers.  As all handles in APS, the handles returned by these functions have a designated lifetime, as described in the remarks section for certain functions.   If you intend to retain access to the object beyond its handle's documented normal lifetime, add a reference to it with Aps_AddRef(), then free it later with Aps_ReleaseHandle().  Failure to perform these tasks may cause unpredictable results and crashing.
  5. It is not possible for a 'normal' user to control how other users print and in many cases, 'normal' users may view but not modify jobs belonging to others.  For this reason, operations may fail with APS_ACCESS_DENIED due to access restrictions.  To resolve this, setuid() to root before trying any operations that may affect the global state of the system.  However, this may still fail if the transport requires authentication to an external device, as on a network.
  6. Filters may be associated with Aps_Queue objects to provide precise control over resources that are to be accessed.  In the event that the underlying transport does not support filtering, or APS cannot emulate it, such functions will return APS_FILTER_NOT_SUPPORTED.  If you wish operations to automatically fallback upon a non-filtered version if the filter fails, attach the filter with the APS_FILTER_FALLBACK option.  If on fall-back the operation succeeds, APS_PARTIAL_SUCCESS is returned, otherwise a suitable error message is generated.  If a function is said to honor a filter, it implies that it will always check the filter that was selected at the time of the function call to determine which jobs are to be acted upon.  i.e. Setting AUTODENYNEWJOBS with a filter ensures that only jobs that match the filter will be affected.
  7. Some functions return the most up-to-date information available and it is possible for this information to change (unpredictably) from one moment to the next. This may lead to conflicting information to be displayed to the user if, for instance, Aps_QueueGetNumberOfJobs() was used to show the number of jobs and Aps_QueueIterateJobs() was used to display a list.  The correct procedure would be to produce the list using Aps_QueueIterateJobs() and maintain an internal count of entries displayed in the process, then display this internal count.
  8. Other ...QueryXXX() functions are specifically designed to return locally cached data to maintain user interface consistency.  For these, Aps_JobUpdate() must be used to get the most recent information.  Alternately, a notification function may be set up.
  9. Aps_QueueHandle's are unique for each opener of a queue since they store context-sensitive information.  Special context settings, such as filtering, will be lost when the queue is closed.

3.9.1 Queue Management : Accessing and Controlling Queues

This section covers the functions used to get access to a queue and perform generic manipulation of its contents or status.

Before doing anything, an application must obtain a handle to a queue.  These handles should not be shared between independent (sub)tasks as they contain context-sensitive information pertinent only to its user.  APS does not perform arbitration for access to the queue object so it is the responsibility of the application to synchronize access if a single object is shared across threads (unwise).

Once a handle has been obtained, the application is free to submit control and query requests to the queue, but must check error codes at all times.  The application may also obtain as many locks on a queue as it needs with Aps_AddRef().  However, when finished, it must call Aps_ReleaseHandle() exactly once for each Aps_AddRef() it performed, and once more to free the object (for Aps_PrinterOpenQueue/Aps_OpenGlobalQueue).

This section only covers those operations that are performed without information about the contents of the queue, and not individual jobs (see following section).

Example: Purging print queue

/*== Purge printer queue and deny new jobs, by name.
 * Returns Aps_Result to indicate success / failure.
 */
Aps_Result PurgePrinterQueueAndDenyByName(char *name) {
    Aps_PrinterHandle printerHandle;
    Aps_QueueHandle   queueHandle;
    Aps_Result        result;

    result = Aps_PrinterOpenQueue(name, &printerHandle);
    if (Aps_Succeeded(result)) {
        result = Aps_OpenPrinterQueue(printerHandle, &queueHandle);
        if (Aps_Succeeded(result)) {
            result = Aps_QueueIssueCommand(queueHandle, APS_OP_QPURGE);

        Aps_ReleaseHandle(queueHandle);
        } else { /* queue did not open -- handle error */ }

    Aps_ReleaseHandle(printerHandle);
    } else { /* printer did not open -- handle error */ }

    return result;
}

Typical Use: Finding out which printers in the system have active jobs for a user, and how many.

/*== Display the names of printers in the system with active jobs
 *   for a designated user and how many.
 * Returns Aps_Result to indicate success / failure.
 */
Aps_Result ShowPrintersWithJobsForUserByName(char *name) {
    Aps_QueueHandle globalQueueHandle;
    Aps_Result      result;

    result = Aps_OpenGlobalQueue(&globalQueueHandle);
    if (Aps_Succeeded(result)) {
        Aps_QuickPrinterQInfo **printerQInfo;
        Aps_FilterHandle        filterHandle;
        int                     numElements;
        result = Aps_FilterJobByOwnerName(&filterHandle,
            APS_FILTER_REQUIRE | APS_FILTER_NOCASE, name);
        if (Aps_Succeeded(result)) {
            result = Aps_AttachFilter(globalQueueHandle, filterHandle, APS_FILTER_FALLBACK);
            /* may return APS_FILTER_NOT_SUPPORTED */
        }
        if (! Aps_Succeeded(result)) {
            /* filter was not created successfully -- warn user */
            name = "<everyone I can see>";
        }
        result = Aps_QueueMakeQuickPrinterQInfoArray(globalQueueHandle, &printerQInfo, &numElements);
        Aps_DetachFilter(globalQueueHandle, NULL, NULL);
        if (result == APS_FILTER_NOT_SUPPORTED) {
            /* attached filter is not supported -- warn user */
            name = "<everyone I can see>";
            result = APS_PARTIAL_SUCCESS;
        }
        if (Aps_Succeeded(result)) {
            int i;
            for (i = 0; i < numElements; i++) {
                printf("%s has %d jobs for %s in each of the following categories\n",
                    printerQInfo[i]->printerName,
                    printerQInfo[i]->numJobsMatch,
                    name);
                printf("  - PRODUCTION : %d\n"
                       "  - PENDING    : %d\n"
                       "  - WORKING    : %d\n"
                       "  - ON HOLD    : %d\n"
                       "  - ENDED      : %d\n\n",
                    printerQInfo[i]->numJobsProduction,
                    printerQInfo[i]->numJobsPending,
                    printerQInfo[i]->numJobsWorking,
                    printerQInfo[i]->numJobsOnHold,
                    printerQInfo[i]->numJobsEnded);
            }
            Aps_ReleaseBuffer(printerQInfo);
        } else { /* array was not created successfully -- handle error */ }

    Aps_ReleaseHandle(globalQueueHandle);
    } else { /* queue did not open -- handle error */ }

    return result;
} 

3.9.1.1 Aps_PrinterOpenQueue()

Obtains a handle to the specified printer's queue.

Aps_Result Aps_PrinterOpenQueue(
    Aps_PrinterHandle printerHandle,
    Aps_QueueHandle  *queueHandle);

Input

printerHandle Aps_PrinterHandle identifying the printer for which a queue handle should be returned.

Output

queueHandle Pointer to an Aps_QueueHandle that will receive the new handle.
On failure, will be filled with NULL.

Remarks

The returned handle must be freed by Aps_ReleaseHandle().

On failure *queueHandle set to NULL and detailed result returned.


3.9.1.2 Aps_OpenGlobalQueue()

Obtains a handle to a queue representing all printers in the system.

The returned object may ONLY be used with certain functions at the moment which will explicitly state that they can.

For now, use Aps_QueueIterateSubQueues and perform the operation on individual queues instead.

The Aps_Queue object obtained may represent multiple system print queues on different transports.  If a printer is added to the system, this queue object will automatically consider it when performing operations.  Similarly, if a printer is removed, this queue object will not return any failure codes caused by its disappearance.   For this reason it is unwise to perform complicated filter operations using this special object.

Aps_Result Aps_OpenGlobalQueue(
    Aps_QueueHandle *queueHandle);

Output

queueHandle Pointer to an Aps_QueueHandle that will receive the new handle.
On failure, will be filled with NULL.

Remarks

The returned handle must be freed by Aps_ReleaseHandle().

On failure, *queueHandle set to NULL and detailed result returned.

Some users may not have access to all printer queues, so the provided handle only represents those that are accessible.


3.9.1.3 Aps_QueueIssueCommand()

Performs a single specific operation on a queue.  The possible operations are listed below.
This function supports queues obtained via Aps_OpenGlobalQueue(). (It will repeat the operation for all visible printers.)

Aps_Result Aps_QueueIssueCommand(
    Aps_QueueHandle queueHandle,
    Aps_OperationID operationCode,
    void *reserved);

Input

queueHandle Handle of the print queue to operate on.
operationCode One of the defined APS_OP_Qxxxxx commands described below.
reserved Optional parameters. Not used at the moment; can safely be set to NULL.

Remarks

Many operations may not be supported by some transports and will return APS_NOT_SUPPORTED. It is not harmful to attempt an unsupported operation. To verify if an operation is supported by a given print queue, use Aps_IsOperationAvailable(queueHandle, operationCode, &result).  This allows you to disable (e.g. gray out or hide) options or buttons in a user interface accordingly.

Available Commands

Aps_OperationID Code Meaning
APS_OP_QPURGE Purge the (accessible) contents of the queue.
User must have access rights to remove each queue entry.
This command respects the current filter settings, if supported.

Returns APS_PARTIAL_SUCCESS if not all entries visible with the current filter were removed.

Returns APS_ACCESS_DENIED if the user is not permitted to perform this type of operation at all (even on his own entries).

APS_OP_QSUSPEND Suspend (pause) all printing until the next APS_OP_QRESUME.
User must have access rights to manipulate printer / queue status.
This command ignores the current filter settings.

Returns APS_PARTIAL_SUCCESS if the queue will forbid additional entries from being printed but was unable to pause the current job as well.

Returns APS_NO_CHANGE if the queue was already suspended.

APS_OP_QRESUME Resume all printing.  Reverses the effect of APS_OP_QSUSPEND.
User must have access rights to manipulate printer / queue status.
This command ignores the current filter settings.

Returns APS_NO_CHANGE if the queue was not suspended.

APS_OP_QPAUSEALLJOBS Mark all jobs in the queue as paused.  Does not affect new jobs.
User must have access rights to modify the status of each queue entry.
This command respects the current filter settings, if supported.

Returns APS_PARTIAL_SUCCESS if not all entries visible with the current filter were paused.

Returns APS_ACCESS_DENIED if the user is not permitted to perform this type of operation at all (even on his/her own entries).

APS_OP_QRESUMEALLJOBS Resume all jobs in the queue presently marked as paused.  Does not affect new jobs.
User must have access rights to modify the status of each queue entry.
This command respects the current filter settings, if supported.

Returns APS_PARTIAL_SUCCESS if not all entries visible with the current filter were resumed.

Returns APS_ACCESS_DENIED if the user is not permitted to perform this type of operation at all (even on his/her own entries).

APS_OP_QAUTOPAUSENEWJOBS Automatically pauses all new jobs being added to the queue.  Does not affect existing jobs.
User must have access rights to manipulate printer / queue status.
Applications may still resume new jobs explicitly, overriding this setting.
This command respects the current filter settings, if supported.

Returns APS_PARTIAL_SUCCESS if not all new entries visible with the current filter will be paused properly.

Returns APS_ACCESS_DENIED if the user is not permitted to perform this type of operation at all (even on his/her own entries).

Returns APS_NO_CHANGE if the the setting was already enabled for this queue.

APS_OP_QNOAUTOPAUSENEWJOBS Reverses the effect of APS_OP_QAUTOPAUSENEWJOBS.
Same restrictions and results as above.
APS_OP_QAUTODISCARDNEWJOBS Automatically discards all new jobs being added to the queue.  Does not affect existing jobs.
User must have access rights to manipulate printer / queue status.
Applications will not be that their documents are being sucked into a black hole until they finish writing to the spool at which point the status becomes APS_JOB_DISCARDED.
This command respects the current filter settings, if supported.

Returns APS_PARTIAL_SUCCESS if not all new entries visible with the current filter will be discarded properly.

Returns APS_ACCESS_DENIED if the user is not permitted to perform this type of operation at all (even on his/her own entries).

Returns APS_NO_CHANGE if the the setting was already enabled for this queue.

APS_OP_QNOAUTODISCARDNEWJOBS Reverses the effect of APS_OP_QAUTODISCARDNEWJOBS.
Same restrictions and results as above.
APS_OP_QAUTODENYNEWJOBS Automatically denies all new jobs from being added to the queue.  Does not affect existing jobs.
User must have access rights to manipulate printer / queue status.
Applications will not be that their documents are being sucked into a black hole until they finish writing to the spool at which point the status becomes APS_JOB_DISCARDED.
This command respects the current filter settings, if supported.

Returns APS_PARTIAL_SUCCESS if not all new entries visible with the current filter will be denied properly.

Returns APS_ACCESS_DENIED if the user is not permitted to perform this type of operation at all (even on his/her own entries).

Returns APS_NO_CHANGE if the the setting was already enabled for this queue.

APS_OP_QNOAUTODENYNEWJOBS Reverses the effect of APS_OP_QAUTODENYNEWJOBS.
Same restrictions and results as above.

3.9.1.4 Aps_QueueIssueQuery()

Performs a single specific verification request from a queue.  The possible requests are listed below.
This function does not support queues obtained via Aps_OpenGlobalQueue().

Aps_Result Aps_QueueIssueQuery(
    Aps_QueueHandle queueHandle,
    Aps_OperationID queryCode,
    void *output);

Input

queueHandle Handle of the print queue to operate on.
queryCode One of the defined APS_IS_Qxxxxx commands described below.

Output

output A query-specific type to receive the output of this query. All existing queries require this to be the address of an int, which is set to either TRUE or FALSE.

Remarks

Many queries may not be supported by some transports and will return APS_NOT_SUPPORTED. It is not harmful to attempt an unsupported query.

To verify if an operation is supported by a given print queue, use Aps_IsOperationAvailable(queueHandle, operationCode, &result). This allows you to disable (e.g. gray out or hide) options or buttons in a user interface accordingly.

Available Queries

Aps_OperationID Code Meaning
APS_IS_QREADY Queries if the queue is ready to receive new jobs matching the current filter and print them.  This will normally return TRUE unless the queue has been suspended, denies / discards new jobs, or the printer is for some reason unavailable.
This command respects the current filter settings, if supported.
APS_IS_QSUSPENDED Queries if the queue is suspended. (see APS_OP_QSUSPEND / APS_OP_QRESUME)
This command ignores the current filter settings.
APS_IS_QAUTOPAUSENEWJOBS Queries if the queue pauses new jobs matching the current filter automatically.  (see APS_OP_Q[NO]AUTOPAUSENEWJOBS)
This command respects the current filter settings, if supported.
APS_IS_QAUTODENYNEWJOBS Queries if the queue denies new jobs matching the current filter automatically.  (see APS_OP_Q[NO]AUTODENYNEWJOBS)
This command respects the current filter settings, if supported.
APS_IS_QAUTODISCARDNEWJOBS Queries if the queue (silently) discards new jobs matching the current filter automatically.  (see APS_OP_Q[NO]AUTODISCARDNEWJOBS)
This command respects the current filter settings, if supported.

3.9.1.5 Aps_QueueGetNumberOfJobs()

Gets the number of jobs matching the filter in the queue.
This function supports queues obtained via Aps_OpenGlobalQueue(). (It will return the total of all jobs matching the filter that are visible to this user.)

Aps_Result Aps_QueueGetNumberOfJobs(
    Aps_QueueHandle queueHandle,
    int            *numberOfJobs);

Input

queueHandle Handle to the print queue containing jobs to be listed.

Output

numberOfJobs Receives the total number of jobs matching the specified filter.

Remarks

This is a convenience function and does not guarantee the accuracy of results. It provides a quick snapshot of the most recent status information available and should not be used when building a complex user interface that requires more data than is returned here.


3.9.1.6 Aps_QueueMakeQuickPrinterQInfoArray()

Returns an array of pointers to Aps_QuickPrinterQInfo structures containing a snapshot survey of multiple printer status.

This function supports queues obtained via Aps_OpenGlobalQueue(). (It will return an array of all printers that are visible to this user.)

Aps_Result Aps_QueueMakeQuickPrinterQInfoArray(
    Aps_QueueHandle          queueHandle,
    Aps_QuickPrinterQInfo ***printerQueueInfo,
    int                     *numElements);

Input

queueHandle Handle to the print queue containing jobs to be listed.

Output

printerQueueInfo Pointer to an array of pointers to Aps_QuickPrinterQInfo structures. On failure, will be filled with NULL. On success, it is the caller's responsibility to dispose of this buffer when finished with it by calling Aps_ReleaseBuffer().
numElements Number of elements in the resulting array. Careful, may be 0.

Remarks

If you intend on accessing fields not marked 'v0' (version 0), you must first check the 'version' member of this structure to ensure that they are present.

This is a convenience function and does not guarantee the accuracy of results. It provides a quick snapshot of the most recent status information available and should not be used when building a complex user interface that requires more data than is returned here.

The following structure is returned by this function:

typedef struct Aps_QuickPrinterQInfo_ {
    int                version;         /* Version 0 for now */
    Aps_PrinterHandle  printerHandle;   /* v0 - handle of printer */
    Aps_PrinterStatus  printerStatus;   /* v0 - RESERVED */
    char              *printerName;     /* v0 - name of printer */
    /* (Total)    # Jobs visible (ignores filter) */
    int numJobsTotal;    /* v0 */
    /* (Match)    # Jobs matching filter */
    int numJobsMatch;    /* v0 */
    /* (Producing)# Jobs matching filter AND APS_JOB_PHASE_PRODUCTION */
    int numJobsProduction;
    /* (Pending)  # Jobs matching filter AND APS_JOB_PHASE_PENDING */
    int numJobsPending;  /* v0 */
    /* (Working)  # Jobs matching filter AND APS_JOB_PHASE_WORKING */
    int numJobsWorking;  /* v0 */
    /* (On Hold)  # Jobs matching filter AND APS_JOB_PHASE_ON_HOLD */
    int numJobsOnHold;  /* v0 */
    /* (Ended)    # Jobs matching filter AND APS_JOB_PHASE_ENDED */
    int numJobsEnded;   /* v0 */
} Aps_QuickPrinterQInfo;

3.9.2 Queue Management : Accessing and Controlling Jobs

This section covers the functions used to get access to job in a queue and perform generic manipulation of their contents or status.

In order to access jobs, an application must first have obtained a handle to a queue (see previous section).  Then, using one of the job access functions, the application may obtain handles to jobs.  To simplify this task, filters may be applied to a queue so that only jobs of specific interest are reported to- / affected by the library functions.  Unlike queues, job handles are unique for each job but are local to the scope of the application.  Since jobs do not contain any context-sensitive information, they may be passed freely between (sub)tasks or threads sharing the same memory space.  Also, unlike with queues, APS performs arbitration for access to job objects to ensure that they are thread-safe without any additional interaction on the part of the application.

Once a handle has been obtained, the application is free to submit control and query requests to the Job, but must check error codes at all times.  The application may also obtain as many locks on a job as it needs with Aps_AddRef().  However, when finished, it must call Aps_ReleaseHandle() exactly once for each Aps_AddRef() it performed, then call Aps_ReleaseHandle() or Aps_QueueIterateJobs() to free the object depending on how it was obtained -- the proper procedure is documented for each function that returns a job handle.

This section covers all operations that may be performed on jobs that either have entered the queue or are still in the process of being created (see previous sections).  Some operations may not be performed on jobs unless they are in certain states that will be clearly indicated for each such operation.

Typical Use: Pick jobs from the list, store them, do something, then release them.

/*== Do something with an array of jobs
 * Returns Aps_Result to indicate success / failure.
 */
Aps_Result DoSomethingWithJobs(Aps_QueueHandle queueHandle);
    Aps_JobHandle     jobHandle;
    Aps_JobHandle     jobHandleTable[<...xxx...>];
    Aps_Result        result;
    int               numJobsPicked;
    int               i;

    numJobsPicked = 0;
    jobHandle = NULL;
    /* loop until we get an error or there are no more jobs */
    while (Aps_Succeeded( result = Aps_QueueIterateJobs(queueHandle, &jobHandle) )) {
        /* is there data available? */
        if (! jobHandle) break;
        /* Aps_QueueIterateJobs() has obtained a lock on the job on behalf of the app */
        /* choose */
        if (<...we select the job...>) {
             /* add a reference to it, then store in buffer */
             Aps_AddRef( jobHandle );
             jobHandleTable[ numJobsPicked++ ] = jobHandle;
        }
        /* Aps_QueueIterateJobs() will now free its lock on the job */
    }
    /* check for error -- premature exit */
    if (! Aps_Succeeded( result )) {
        /* free our lock on all handles */
        while (numJobsPicked) Aps_ReleaseHandle( jobHandleTable[numJobsPicked--] );
        return result;
    }

    /* do something */
    for (i = 0; i < numJobsPicked; i++) {
        jobHandle = jobHandleTable[i];
        /* ...do something... */
        <...do something here...>
        /* free our lock on the handle */
        Aps_ReleaseHandle( jobHandle );
    }
    return APS_SUCCESS;
}

3.9.2.1 Aps_QueueIterateJobs()

Returns a handle to the next job matching the filter in a print queue.  Use to scan the list of all entries in the queue.
This function supports queues obtained via Aps_OpenGlobalQueue().  (It will iterate through all jobs matching the filter on all printers.)

Returned handles have a designated lifetime. The application must explicitly call Aps_AddRef() and Aps_ReleaseHandle() to extend this period.

Aps_Result Aps_QueueIterateJobs(
    Aps_QueueHandle queueHandle,
    Aps_JobHandle  *jobHandle);

Input

queueHandle Handle to the print queue containing jobs to be listed.  Must be specified for all iterations.
jobHandle Pointer to the last Aps_JobHandle that was returned by this call.  Initialize the handle to NULL the first time.

Output

jobHandle Pointer to an Aps_JobHandle that will receive the handle.

Remarks

The job handle must be initialized to NULL the first time.  Don't pass NULL as second argument, however.

If no entries are available, returns APS_SUCCESS and *jobHandle is set to NULL.

If entries are available, returns APS_SUCCESS and *jobHandle is non-NULL handle of job object.

The returned handle must be passed to Aps_QueueIterateJobs() or Aps_ReleaseHandle() when finished.  Use the latter to abort the scanning operation.

The most recent information available is always used. You do not need to call Aps_JobUpdate().


3.9.2.2 Aps_JobUpdate()

Updates a job object to reflect its current status (if possible).
This function supports jobs in all possible states.

Aps_Result Aps_JobUpdate(
    Aps_JobHandle jobHandle);

Input

jobHandle Handle of the job entry to be updated.

Remarks

Returns APS_NO_CHANGE if there was no detectable change in job status.

Returns APS_IGNORED if the library was unable to update the status of the job.


3.9.2.3 Aps_JobGetStatus()

Obtains status information for a job, indicating whether it is currently being spooled, waiting to be printing, being printed, completed, on hold for any reason, or cancelled for any reason.

Warning: This function uses the last stored state of the job.  To get the most recent information, call Aps_JobUpdate() first.

Aps_Result Aps_JobGetStatus(
    Aps_JobHandle job,
    Aps_JobStatus *status);

Input

job The Aps_JobHandle of the job to be queried.

Output

status A pointer to an Aps_JobStatus to receive an identifier describing the phase this the job is currently in.

Remarks

This information may not be available to some users or on some configurations; will return APS_NOT_SUPPORTED.

During its lifetime a job typically passes through a number of major phases. Within each of these phases, there are a number of finer-grained states that a job may be in. The table below lists the major phases, together with the fine-grained states encompassed by each phase.

These phases and fine-grained states are not necessarily mutually-exclusive. For example, phases may overlap, with the beginning of the document being sent to the printer (APS_JOB_PHASE_WORKING) while the application is still sending data for subsequent pages (APS_JOB_PHASE_PRODUCTION). For this reason, Aps_JobStatus is represented as a set of bit fields, and individual states or flags should be tested for using the bitwise and operator (&), as illustrated in the example below.

Aps_JobStatus Major Phases Aps_JobStatus Fine-Grained Flags Meaning
APS_JOB_PHASE_PRODUCTION APS_JOB_SETUP Indicates that the job has been opened by a call to Aps_JobStart(), but that no data has been sent to the printer yet.  At this point, job attributes can still be altered.
[Depending on the transport, jobs may not appear in a queue while in this state.]
APS_JOB_SPOOLING Indicates that the application is now sending data to be printed as part of this job.  This phase begins when the first call to write()/Aps_JobWrite() is made.
[Depending on the transport, jobs may not appear in a queue while in this state.]
APS_JOB_PHASE_PENDING APS_JOB_QUEUEING Indicates that the application has finished printing (ie. Aps_JobEnd() has been called).  The job is currently being queued.
[Depending on the transport, jobs may not appear in a queue while in this state.]
APS_JOB_PENDING Indicates that the job is waiting in a queue to be printed.
APS_JOB_PHASE_WORKING APS_JOB_SENDING Indicates that the job is being sent to the transport for printing.  Depending on the transport, this may not indicate that it is actually being printed since it may be buffered remotely or discarded.
APS_JOB_PRINTING Indicates that the job is being printed right now or is imminent, barring hardware problems
[Depending on the transport, it may be impossible to determine when this state occurs.]
APS_JOB_PHASE_ON_HOLD APS_JOB_PAUSED Indicates that the job is waiting in a queue but that it has been paused and will not commence printing until explicitly resumed.
APS_JOB_SUSPENDED Indicates that the job is waiting in a queue which has been suspended and will not commence printing until the queue has been explicitly resumed.
APS_JOB_PHASE_ENDED APS_JOB_COMPLETED Indicates that the job has been successfully printed or sent to the remote device.
[Jobs in this state may not appear in queries to a queue, but if their QueryEntry handle persists, it will indicate this state.]
APS_JOB_STORED Indicates that the job has been stored but that no attempt to print it will be made.  It will remain in this state until explicitly purged.
APS_JOB_FAILED Indicates that for some reason the job has failed and has been discarded.  This occurs when a request to the underlying transport fails with an error.
[Jobs in this state may not appear in queries to a queue, but if their QueryEntry handle persists, it will indicate this state.]
APS_JOB_ABORTED Indicates that the job was never completely written to the queue and that it was explicitly aborted by the application using Aps_JobAbort().
[Jobs in this state may not appear in queries to a queue, but if their QueryEntry handle persists, it will indicate this state.]
APS_JOB_CANCELLED Indicates that the job has been explicitly cancelled while in the queue and that no further attempts will be made to continue printing the job.
[Jobs in this state may not appear in queries to a queue, but if their QueryEntry handle persists, it will indicate this state.]
APS_JOB_DISCARDED Indicates that the job has been discarded automatically by the print queue manager and that it is not possible to recover its contents.
[Jobs in this state may not appear in queries to a queue, but if their QueueEntry handle persists, it will indicate this state.]

Typical Use

Aps_JobStatus status;
if (Aps_JobGetStatus(job, &status) == APS_SUCCESS) {
    if (status & APS_JOB_SPOOLING)
        printf("Job is being spooled.\n");
    if (status & APS_JOB_PHASE_ON_HOLD) {
        printf("Job is on hold.\n");
    }
    /* Etc. */
}

3.9.2.4 Aps_JobIssueCommand()

Performs a single specific operation on a job.  The possible operations are listed below.

Warning: This function uses the last stored state of the job.  To get the most recent information, call Aps_JobUpdate() first.

Some OperationID's of this function only support Jobs in specific states.

Aps_Result Aps_JobIssueCommand(
    Aps_JobHandle   jobHandle,
    Aps_OperationID operationCode,
    void *reserved);

Input

jobHandle Handle of the print job to operate on.
operationCode One of the defined APS_OP_Jxxxxx commands described below.
reserved Optional parameters. Not used at the moment; can safely be set to NULL.

Remarks

Many operations may not be supported by some transports and will return APS_NOT_SUPPORTED. It is not harmful to attempt an unsupported operation.

Operations performed on jobs in invalid states will return APS_IGNORED.

To verify if an operation is supported by a given print queue, use Aps_IsOperationAvailable(queueHandle, operationCode, &result). This allows you to disable (e.g. gray out or hide) options or buttons in a user interface accordingly.

Available Commands

Aps_OperationID Code Meaning
APS_OP_JPAUSE Pauses the job until the next APS_OP_JRESUME.   Halts printing if necessary (and possible).
User must have access rights to manipulate job status.
This command only supports jobs which are 'ACTIVE' or 'CREATING'.

Returns APS_PARTIAL_SUCCESS if the job is marked as paused, but the library was unable to halt printing in progress.

Returns APS_NO_CHANGE if the job was already paused.

APS_OP_JRESUME Allow a previously paused job to print.   Reverses the effect of APS_OP_JPAUSE.
User must have access rights to manipulate printer / queue status.
This command only supports jobs which are 'ACTIVE' or 'CREATING'.

Returns APS_PARTIAL_SUCCESS if the job is marked as resumed, but the library was unable to resume an interrupted printing process.

Returns APS_NO_CHANGE if the job was not previously paused.

APS_OP_JSTORENOW Immediately store the job on the queue for later access (permanently paused).  Does not halt printing if it is in progress; instead, sets APS_OP_JSTOREWHENCOMPLETE.
This command only supports jobs which are 'ACTIVE'.

Returns APS_PARTIAL_SUCCESS if the job will not be stored until it has been fully printed.

Returns APS_NO_CHANGE if the job was already stored for later.

APS_OP_JSTOREWHENCOMPLETE When processing is complete, i.e. when the status is 'STOPPED', store the job on the queue for later access (permanently paused).  Does not halt printing if it is in progress.
This command only supports jobs which are 'ACTIVE'.

Returns APS_NO_CHANGE if the job was already stored for later.

APS_OP_JDELETE Remove this job from the queue.  Halts printing if necessary (and possible).
User must have access rights to remove the job.
This command only supports jobs which are NOT 'CREATING'.

Returns APS_PARTIAL_SUCCESS if the job will not print but will still appear in print queue listings.

Returns APS_NO_CHANGE if the job had already been removed from the queue.

APS_OP_JCANCEL Prevent this job from printing.  Halts printing if necessary (and possible).  Job may be removed from queue (as with delete) in some implementations, sometimes after a time delay or during the next boot.
User must have access rights to cancel the job.
This command only supports jobs which are NOT 'CREATING'.

Returns APS_NO_CHANGE if the job was NOT 'ACTIVE' or 'CREATING'.


3.9.2.5 Aps_JobMakeQuickJobInfo()

Produces a pointer to a Aps_QuickJobInfo structure containing a snapshot survey of a single job's current status.

Warning: This function uses the last stored state of the job.  To get the most recent information, call Aps_JobUpdate() first.

Aps_Result Aps_JobMakeQuickJobInfo(
    Aps_JobHandle      jobHandle,
    Aps_QuickJobInfo **jobInfo);

Input

jobHandle Handle of the job to examine.

Output

jobInfo Pointer to a Aps_QuickJobInfo structure containing a snapshot of the last stored status.
On failure, will be filled with NULL.

Remarks

If you intend on accessing fields not marked 'v0' (version 0), you must first check the 'version' member of this structure to ensure that they are present.

This is a convenience function and does not guarantee the accuracy of results. It provides a quick snapshot of the most recent status information available and should not be used when building a complex user interface that requires more data than is returned here.

The following structure is returned by this function:

typedef struct Aps_QuickJobInfo_ {
    int               version;         /* Version 0 for now */

    /* job information */
    Aps_JobHandle jobHandle;    /* v0 - handle of job */
    Aps_JobStatus jobStatus;    /* v0 - status of job at last update */
    char      *jobHost;         /* v0 - hostname Job was created on or "" */
    char      *jobName;         /* v0 - name of job or ""
                                 *      may be same as filename */
    char      *jobFilename;     /* v0 - original filename of job or "" */
    int        jobID;           /* v0 - job ID (assigned by transport) */
    size_t     jobSize;         /* v0 - size of job in bytes */
    time_t     jobCreationTime; /* v0 - date and time of job creation */
    char      *jobFormat;       /* v0 - job format string or "" */
    int        jobOrder;        /* v0 - rank of job in the printer queue
                                 *      indicating the order in which the
                                 *      jobs will be printed
                                 *      <0 - unknown or complete
                                 *       0 - being serviced now or complete
                                 *      >0 - next job to be printed is #1, etc...
                                 *      [numbers not necessarily sequential] */
    int        jobPriority;     /* v0 - RESERVED */

    /* printer information */
    Aps_PrinterHandle printerHandle; /* v0 - handle of printer or NULL */
    Aps_PrinterStatus printerStatus; /* v0 - RESERVED */
    char             *printerName;   /* v0 - name of printer or "" */

    /* document information, fields are "" if unknown */
    char *docTitle;    /* v0 - title of document */
    char *docRevision; /* v0 - name / number of document revision */
    char *docComments; /* v0 - document comments (free form), may contain LF's
                        *      but not CR's */
    char *docAuthor;   /* v0 - name of author */
    char *docType;     /* v0 - document type (file extension) */
    char *docCreator;  /* v0 - name of app and version string as "name (version)"
                        *      (with parenthesis), eg. "Corel Draw (9.01)" */

    /* owner information, fields are 0 or "" if unknown / remote */
    char      *ownerName; /* v0 - name of job owner */
    short int  ownerID;   /* v0 - id of owner */

    /* local routing information */
    char *localHost;   /* v0 - qualified hostname of local machine or ""*/
    char *localFile;   /* v0 - original path of file that was added to
                        *      the local print queue.  Differs from
                        *      jobFilename which tells us the original name
                        *      of the file printed, rather than the one
                        *      we are actually printing from local disk
                        *      space. "" if none of unknown */

    /* spool routing information */
    char *spoolHost;  /* v0 - qualified hostname of spool machine
                       *      when job is sent, or "" if unknown */
    char *spoolFile;  /* v0 - path of spool file on host or "" if
                       *      synthesized / pipe / unknown */

    /* job attributes */
    Aps_JobAttrHandle jobAttr; /* v0 - handle of job attributes or NULL */
} Aps_QuickJobInfo;

3.9.3 Queue Management : Composing Job and Queue Filters

This section covers the functions used to provide fine-grained access to print queue-related resources using simple criteria-matching filters.  This is very useful when only certain entries are of interest.

As most simple applications are only interested in specific sub-groupings of job entities, the filtering operations involved can become quite a nuisance for the programmer. For this reason, APS provides a simple easily-extended base on which to construct filters for a variety of tasks. Though presently only jobs are directly supported by the filter, future versions of this library will likely extend this functionality to include all searchable public objects.

Before attempting to construct a filter, it is imperative that the programmer construct (mentally, on paper, or in code) a Boolean representation of each comparison that is to take place. As the current version of the library does not support partial matching schemes, each comparison must be explicitly identified and will be checked for exactness; but there are exceptions.  Then, it is necessary to translate this expression into a series of operations that will be evaluated serially.  Multiple filters may also be joined to handle special semantics like parenthesis.  Though it may look confusing at first, this approach minimizes the effective overhead.

String comparisons may also be qualified with APS_FILTER_NOCASE or APS_FILTER_WILDCARDS to permit case-insensitive comparisons and/or wildcards.  Presently '*' is defined to match any substring or nothing.

In some cases, it may be necessary to perform an Aps_FilterAll(..., ...EXCLUDE / INCLUDE).  For an exclusion filter (match all but...) it may be necessary to add an INCLUDE ALL step at the end.  Similarly, for an inclusion filter (match only these...) it may be necessary to add an EXCLUDE ALL step at the end.  The rule is as follows: A filter matches, if and only if it passes all preceding checks, and it ends in, a REQUIRE or INCLUDE that matches, or an EXCLUDE that does not match.

The application may obtain as many locks on a filter as it needs with Aps_AddRef().  However, when finished, it must call Aps_ReleaseHandle() exactly once for each Aps_AddRef() it performed, and once more to free the object (for Aps_FilterXXX).

This section only covers the creation and management of Aps_Filter objects.   Consult the previous sections to see how they can interact with jobs and queues.

Example: Creating typical filters

Suppose the programmer comes up with a Boolean expression like this: IF (((job.ownername == "John Doe") OR (job.ownername == "Mary J*")) AND (job.status == APS_JOB_ACTIVE)) OR ((job.printername == "MyPrinter") AND (job.status == APS_JOB_XWORKING)), it would create it serially like this:

Aps_FilterHandle buildSpecialFilter() {
    Aps_FilterHandle filterOut = NULL;  /* output filter */
    Aps_FilterHandle filterTemp = NULL; /* to construct second clause */

    /* Reorder the operation like this:
     *
     * filterTemp:
     *   (REQUIRE) job.printername == "MyPrinter"
     *   (REQUIRE) job.status      == APS_JOB_XWORKING
     * [Status comparisons may be grouped with OR by virtue of their
     *  being bitfields, see earlier sections]
     *
     * filterOut:
     *   (INCLUDE) filterTemp (merged)
     *   (REQUIRE) job.status    == APS_JOB_ACTIVE
     *   (INCLUDE) job.ownername == "John Doe"
     *   (INCLUDE) job.ownername ~= "Mary J*" (wild and nocase)
     *
     * Ideally, should check return codes
     */
    /* Build second clause */
    Aps_FilterJobByPrinterName(&filterTemp,
        APS_FILTER_REQUIRE, "MyPrinter");
    Aps_FilterJobByStatus(&filterTemp,
        APS_FILTER_REQUIRE, APS_JOB_ACTIVE);

    /* Once a filter has been created, it can be used as a single
     * indivisible entity. Aps_FilterMerge() obtains a lock on the
     * merged filter which will be freed when the resulting filter
     * is freed.  Note that if the merged filter (filterTemp)
     * changed, the resulting filter would also change.
     *
     * Even though filterOut is not defined, this operations is
     * NOT the same as a straight 'copy'.
     */
    Aps_FilterMerge(&filterOut,
        APS_FILTER_INCLUDE, filterTemp);
    Aps_ReleaseHandle(filterTemp); /* still locked by merge */

    /* Add the remaining rules from the first clause */
    Aps_FilterJobByStatus(&filterOut,
        APS_FILTER_REQUIRE, APS_JOB_XWORKING);
    Aps_FilterJobByOwnerName(&filterOut,
        APS_FILTER_INCLUDE, "John Doe");
    Aps_FilterJobByOwnerName(&filterOut,
        APS_FILTER_INCLUDE | APS_FILTER_WILDCARDS | APS_FILTER_NOCASE,
        "MaRy j*");

3.9.3.1 Aps_Filter[ObjectClass]By[FieldName]()

Compose a filter rule for [ObjectClass] that compares field [FieldName].

Aps_Result Aps_Filter[ObjectClass]By[FieldName](
    Aps_FilterHandle *filterHandle,
    Aps_FilterMode    filterMode,
    [FieldType]       matchField);

Input

filterHandle Pointer to an Aps_FilterHandle.  Initialize to NULL the first time.
filterMode Any one of APS_FILTER_XXX modes and any combination of the options (or'd).
matchField Some source data of type [FieldType].   Comparisons will attempt to determine if the provided field matches that of objects being checked.
The data will be automatically copied into a private control structure which will remain constant even if the original changes.

Output

filterHandle If NULL, will receive the handle of a new Aps_Filter, locked and ready for use, else, new filter definition will be appended to tail of existing filter but locking is unchanged.

Remarks

The returned handle must be freed by Aps_ReleaseHandle().

On failure, *filterHandle will be unchanged and a detailed result returned.  It is legal to continue building a filter even if a step fails mid-way.

Binary arithmetic may be used to group status codes together to ease checking multiple states.

Aps_FilterMode Code Meaning
APS_FILTER_INCLUDE Mode: If the target comparison succeeds, skips all following comparisons and returns success; otherwise, continues.
If placed at the end of a filter and the comparison fails, returns failure.
[Short-circuiting logical OR operation]
APS_FILTER_REQUIRE Mode: If the target comparison fails, skips all following comparisons and returns failure; otherwise, continues.
If placed at the end of a filter and the comparison succeeds, returns success.
[Logical AND operation]
APS_FILTER_EXCLUDE Mode: If the target comparison succeeds, skips all following comparisons and returns failure; otherwise, continues.
If placed at the end of a filter and the comparison fails, returns success.
[Logical AND NOT (or BUT) operation]
(option) APS_FILTER_NOCASE Option: Affects comparisons such that objects (strings) only differing in letter case match.
[To activate, bitwise OR with mode]
(option) APS_FILTER_WILDCARDS Option: Affects string comparisons such that:
'*' - matches any substring (possibly nothing)
'?' - matches any single character
[To activate, bitwise OR with mode]
(option) APS_FILTER_GREATERTHAN Option: Affects comparisons such that only numeric/string values which are greater than the matchvalue are matched. To obtain a greater than or equals mode, use APS_FILTER_LESSTHAN with APS_FILTER_EXCLUDE.
[To activate, bitwise OR with mode]
(option) APS_FILTER_LESSTHAN Option: Affects comparisons such that only numeric/string values which are less than the matchvalue are matched. To obtain a less than or equals mode, use APS_FILTER_GREATERTHAN with APS_FILTER_EXCLUDE.
[To activate, bitwise OR with mode]
(option) APS_FILTER_ALLBITS Option: Affects comparisons such that only bitfields which match all bits will be selected. The default is for bitfields to match if any bits are common between them.
[To activate, bitwise OR with mode]

Implementations

Aps_Result Aps_FilterJobByStatus(Aps_FilterHandle *, Aps_FilterMode,
    Aps_JobStatus);
Aps_Result Aps_FilterJobByHost(Aps_FilterHandle *, Aps_FilterMode,
    const char *);
Aps_Result Aps_FilterJobByName(Aps_FilterHandle *, Aps_FilterMode,
    const char *);
Aps_Result Aps_FilterJobByFilename(Aps_FilterHandle *, Aps_FilterMode,
    const char *);
Aps_Result Aps_FilterJobByID(Aps_FilterHandle *, Aps_FilterMode,
    int);
Aps_Result Aps_FilterJobByCreationTime(Aps_FilterHandle *, Aps_FilterMode,
    time_t);
Aps_Result Aps_FilterJobByFormat(Aps_FilterHandle *, Aps_FilterMode,
    const char *);
Aps_Result Aps_FilterJobByOrder(Aps_FilterHandle *, Aps_FilterMode,
    int);
Aps_Result Aps_FilterJobByPriority(Aps_FilterHandle *, Aps_FilterMode,
    int);
Aps_Result Aps_FilterJobByPrinterStatus(Aps_FilterHandle *, Aps_FilterMode,
    Aps_PrinterStatus);
Aps_Result Aps_FilterJobByPrinterName(Aps_FilterHandle *, Aps_FilterMode,
    const char *);
Aps_Result Aps_FilterJobByOwnerName(Aps_FilterHandle *, Aps_FilterMode,
    const char *);
Aps_Result Aps_FilterJobByOwnerID(Aps_FilterHandle *, Aps_FilterMode,
    int);
Aps_Result Aps_FilterJobByLocalHost(Aps_FilterHandle *, Aps_FilterMode,
    const char *);
Aps_Result Aps_FilterJobByLocalFile(Aps_FilterHandle *, Aps_FilterMode,
    const char *);
Aps_Result Aps_FilterJobBySpoolHost(Aps_FilterHandle *, Aps_FilterMode,
    const char *);
Aps_Result Aps_FilterJobBySpoolFile(Aps_FilterHandle *, Aps_FilterMode,
    const char *);

3.9.3.2 Aps_FilterWithFunction()

Compose a filter rule from the provided user callback function.

Warning: Filters created in part or whole in this manner will not work with all automated operations (eg. filtered auto-deny new jobs).

Aps_Result Aps_FilterWithFunction(
    Aps_FilterHandle *filterHandle,
    Aps_FilterMode    filterMode,
    Aps_FilterFunc    matchFunction,
    void             *userArg);

Input

filterHandle Pointer to an Aps_FilterHandle.  Initialize to NULL the first time.
filterMode Any one of APS_FILTER_XXX modes and any combination of the options (or'd).
matchFunction Pointer to a function used as a step in the filter comparison.  Must return TRUE or FALSE based on the fields of the object it has been passed.  This function must return a consistent result (equal result for equal input).
userArg An argument that will be passed to the function during comparisons.  May be NULL.

Output

filterHandle If NULL, will receive the handle of a new Aps_Filter, locked and ready for use, else, new filter rule will be appended to tail of existing filter but locking is unchanged.

Remarks

The returned handle must be freed by Aps_ReleaseHandle().

On failure, *filterHandle will be unchanged and a detailed result returned.  It is legal to continue building a filter even if a step fails mid-way.

typedef int (*Aps_FilterFunc)(Aps_Handle object, void *arg);

3.9.3.3 Aps_FilterAll()

Compose a filter rule that always matches.

Aps_Result Aps_FilterAll(
    Aps_FilterHandle *filterHandle,
    Aps_FilterMode    filterMode);

Input

filterHandle Pointer to an Aps_FilterHandle.  Initialize to NULL the first time.
filterMode Any one of APS_FILTER_XXX modes and any combination of the options (or'd).

Output

filterHandle If NULL, will receive the handle of a new Aps_Filter, locked and ready for use, else, new filter rule will be appended to tail of existing filter but locking is unchanged.

Remarks

The returned handle must be freed by Aps_ReleaseHandle().

On failure, *filterHandle will be unchanged and a detailed result returned.  It is legal to continue building a filter even if a step fails mid-way.


3.9.3.4 Aps_FilterMerge()

Compose a new step formed by merging in a second filter as an independent clause.   The second filter will be evaluated as a single step, as always.

Warning: If the merged filter changes, the new filter's operation will change likewise.

Aps_Result Aps_FilterMerge(
    Aps_FilterHandle *filterHandle,
    Aps_FilterMode    filterMode,
    Aps_FilterHandle  srcHandle);

Input

filterHandle Pointer to an Aps_FilterHandle.  Initialize to NULL the first time.
filterMode Any one of APS_FILTER_XXX modes and any combination of the options (or'd).
srcHandle Handle of the filter to be merged in.  May be NULL, in which case this operation is ignored.

Output

filterHandle If NULL, will receive the handle of a new Aps_Filter, locked and ready for use, else, new filter rule will be appended to tail of existing filter but locking is unchanged.

Remarks

The returned handle must be freed by Aps_ReleaseHandle().

On failure, *filterHandle will be unchanged and a detailed result returned.  It is legal to continue building a filter even if a step fails mid-way.

Obtains a lock on srcHandle which will be freed only when the new filter is freed.   It is legal for an application to call Aps_ReleaseHandle() on srcHandle, and forget about the source filter, as it will be automatically disposed when the new filter is freed.

This operation is very useful for building compound filters with multiple clauses, or extending existing filters without modifying them.


3.9.3.5 Aps_FilterClear()

Clears a filter, but does not dispose of the handle.

Note: A 'blank' filter always matches.

Aps_Result Aps_FilterClear(
    Aps_FilterHandle *filterHandle);

Input

filterHandle Pointer to an Aps_FilterHandle.  Initialize to NULL the first time.

Output

filterHandle If NULL, will receive the handle of a new (blank) Aps_Filter, locked and ready for use, else, the existing filter will be wiped but locking unchanged.

Remarks

The returned handle must be freed by Aps_ReleaseHandle().

On failure, *filterHandle will be unchanged and a detailed result returned.  It is legal to continue building a filter even if a step fails mid-way.

This operation is useful if the application wishes to modify the operation of a filter in real time.


3.9.3.6 Aps_AttachFilter()

Obtains a lock on a filter and attaches it to an object for all future filtered operations.

Aps_Result Aps_AttachFilter(
    Aps_Handle        objHandle,
    Aps_FilterHandle  filterHandle,
    Aps_FilterOptions filterOptions);

Input

objHandle Handle of the object to attach the new filter to.
filterHandle Handle of the new filter to attach, or NULL to remove like Aps_DetachFilter().
filterOptions Set of options (or'd together) used when attached.

Remarks

If a filter is currently attached, it is removed and unlocked as if Aps_DetachFilter() had been called, and is finally returned to the application.

It is not necessary to explicitly detach a filter from an object if that object is disposed of via Aps_ReleaseHandle().

Filters affect many operations on queues and jobs performed in a local queue context.

Aps_FilterOptions Code Meaning
APS_FILTER_INVERT Attaches the inverse of a filter to the object.  Good for masking out matches.
APS_FILTER_FALLBACK If this filter is not supported for a given operation, automatically falls back on non-filtered access and tries again.

3.9.3.7 Aps_DetachFilter()

Detaches a filter from an object thereby resuming 'normal' operation.

Aps_Result Aps_DetachFilter(
    Aps_Handle         objHandle,
    Aps_FilterHandle  *oldFilterHandle,
    Aps_FilterOptions *oldFilterOptions);

Input

objHandle Handle of the object to detach the filter from.

Output

oldFilterHandle Will receive the handle of the previously attached filter, or NULL if there was none or if it no longer exists (see below).   [May be NULL to ignore.]
oldFilterOptions Will receive the set of options of the previously attached filter.  [May be NULL to ignore.]

Remarks

It is possible (and legal) for an application to create a filter, attach it, then release its reference, in which case the filter is automatically freed when it is detached.  NULL will be returned as oldFilterHandle.

It is safe to call this function even if no filter is presently attached.

It is not necessary to explicitly detach a filter from an object if that object is disposed of via Aps_ReleaseHandle().

Filters affect many operations on queues and jobs performed in a local queue context.


3.9.3.8 Aps_FilterCheck()

Checks to see if a specific object matches a filter.

Aps_Result Aps_FilterCheck(
    Aps_FilterHandle   filterHandle,
    Aps_FilterOptions  filterOptions,
    Aps_Handle         objHandle,
    int               *matchesFilter);

Input

objHandle Handle of the object to verify.
filterHandle Handle of the filter to be used for checking.
filterOptions Set of options (or'd together) as with Aps_AttachFilter().  APS_FILTER_FALLBACK is ignored here.

Output

matchesFilter Set to TRUE if this object matches the filter, FALSE if not.

Remarks

If filterHandle is NULL, this function always succeeds and sets matchesFilter to TRUE, unless the APS_FILTER_INVERT mode is selected, then FALSE.

For jobs:  This function uses the last stored state of the job.  To get the most recent information, call Aps_JobUpdate() first.