Closed tillkamppeter closed 3 years ago
@tillkamppeter The papplPrinterSetDriverData
API explicitly resets the attributes. The caller is expected to pass in an ipp_t
pointer for any custom/vendor attributes:
Note: This function regenerates all of the driver-specific capability attributes like "media-col-database", "sides-supported", and so forth. Use the
papplPrinterSetDriverDefaults
orpapplPrinterSetReadyMedia
functions to efficiently change the "xxx-default" or "xxx-ready" values, respectively.
I got the "Installable Options" support for the PostScript Printer Application completely working now. The update of the driver data looks a little awkward though as I have to backup and restore the vendor option IPP attributes:
static bool // O - `true` on success, `false` on failure
ps_status(
pappl_printer_t *printer) // I - Printer
{
int i;
pappl_system_t *system; // System (for logging)
pappl_pr_driver_data_t driver_data;
ps_driver_extension_t *extension;
ipp_t *driver_attrs,
*vendor_attrs;
ipp_attribute_t *attr;
char buf[1024];
// Get system for logging...
system = papplPrinterGetSystem(printer);
papplLog(system, PAPPL_LOGLEVEL_DEBUG,
"Status callback called for printer %s.",
papplPrinterGetName(printer));
// Load the driver data
papplPrinterGetDriverData(printer, &driver_data);
driver_attrs = papplPrinterGetDriverAttributes(printer);
extension = (ps_driver_extension_t *)driver_data.extension;
if (!extension->updated)
{
if ((attr = ippFindAttribute(driver_attrs, "installable-options-default",
IPP_TAG_ZERO)) != NULL &&
ippAttributeString(attr, buf, sizeof(buf)) > 0)
papplLog(system, PAPPL_LOGLEVEL_DEBUG,
"Applying installable accessories settings: %s", buf);
else
papplLog(system, PAPPL_LOGLEVEL_DEBUG,
"Installable Options settings not found");
// Update the driver data to correspond with the printer hardware
// accessory configuration ("Installable Options" in the PPD)
ps_driver_setup(system, NULL, NULL, NULL, &driver_data, &driver_attrs,
NULL);
// Copy the vendor option IPP attributes
vendor_attrs = ippNew();
for (i = 0; i < driver_data.num_vendor; i ++)
{
snprintf(buf, sizeof(buf), "%s-default", driver_data.vendor[i]);
attr = ippFindAttribute(driver_attrs, buf, IPP_TAG_ZERO);
if (attr)
ippCopyAttribute(vendor_attrs, attr, 0);
snprintf(buf, sizeof(buf), "%s-supported", driver_data.vendor[i]);
attr = ippFindAttribute(driver_attrs, buf, IPP_TAG_ZERO);
if (attr)
ippCopyAttribute(vendor_attrs, attr, 0);
}
// Save the updated driver data back to the printer
papplPrinterSetDriverData(printer, &driver_data, NULL);
// Save the vendor options IPP attributes back into the driver attributes
driver_attrs = papplPrinterGetDriverAttributes(printer);
ippCopyAttributes(driver_attrs, vendor_attrs, 0, NULL, NULL);
ippDelete(vendor_attrs);
// Save new default settings
papplSystemSaveState(system, STATE_FILE);
}
return (true);
}
Vendor options and their choices are held in the
printer->driver_attrs
IPP structure, not in theprinter->driver_data
structure, there only the names of the added IPP attributes are held.If I call
papplPrinterSetDriverData()
to save changes in theprinter->driver_data
theprinter->driver_attrs
IPP structure is completely deleted and re-made only based on information from theprinter->driver_data
structure, which DOES NOT contain the types and choices of the vendor options. So the vendor options are lost after callingpapplPrinterSetDriverData()
.Here is the code of the function:
The first line saves the new
printer->driver_data
structure, the second deletesprinter->driver_attrs
and the last generates new attributes solely from theprinter->driver_data
.