From Fedora Project Wiki

"New printer" dialog in the admin tool

This page describes the actions that need to be taken when the user/admin clicks on "New printer" in system-config-printer.

A dialog will be displayed, and it will ask for a number of things:

The name of the queue to create

A short description

(this is the 'printer-info')

A short location description

(this is the 'printer-location')

The device to use

(this is the 'printer-uri')

The available backends and any devices they already know about will be obtained using cups.Connection.getDevices(). Some backends will just have a scheme name (such as 'lpd') and a description; others will provide complete URIs for available printers, complete with IEEE 1284 Device IDs in the 'device-id' attribute:

>>> import cups
>>> cups.setServer("hoopoe")
>>> c=cups.Connection()
>>> c.getDevices()
{'smb':
{'device-class': 'network',
'device-make-and-model': 'Unknown',
'device-info': 'Windows Printer via SAMBA',
'device-id': ''},
'http':
{'device-class': 'network',
'device-make-and-model': 'Unknown',
'device-info': 'Internet Printing Protocol (http)',
'device-id': ''},
[...] 
'usb://HP/DeskJet%20990C?serial=US05N1J00XLG':
{'device-class': 'direct', 'device-make-and-model':
'HP DeskJet 990C',
'device-info': 'HP DeskJet 990C USB #1',
'device-id': 'MFG:HEWLETT-PACKARD;MDL:DESKJET 990C;CMD:MLC,PCL,PML;CLS:PRINTER;DES:Hewlett-Packard DeskJet 990C;SN:US05N1J00XLG;S:00808880800010032C1000000C2000000;P:0800,FL,B0;J:                    ;'},
[...] 
}

For some backends that do not provide complete URIs, such as the 'smb' backend, the "New printer..." dialog will help the user to find a printer. For the 'smb' backend for example, a browser widget similar to the one used in Fedora Core 4's system-config-printer will allow the user to navigate to a particular Windows printer, and a URI will be constructed for that. For the 'lpd' backend we could have textentry widgets for 'printer' and 'queue', so that the resulting URI is lpd://printer/queue. A checkbutton could extend that to lpd://printer/queue?reserve=yes (for RFC 1179 compliance).

The user must be able to edit the URI as well.

There are some special cases for which backend to use. A given printer may appear as a complete URI from several different backends at once. For example, an HP printer could be found by the HPLIP 'hp' backend, the CUPS 'usb' backend, and from the 'hal' backend (which delegates to the 'usb' backend I think).

If the HPLIP 'hp' backend can detect the printer, that backend should be used for it in preference to 'usb' or 'hal'. This is so that multi-function devices can have their other functions used as well. HPLIP provides scanning and faxing functionality in addition to printing.

The printer model

Once a device URI has been created, we need to know what PPD to use to drive the printer. For this we need the IEEE 1284 Device ID, if we can get hold of it. For 'usb', 'hp', and 'hal' backends, this should be provided in the 'device-id' attribute we got from cups.Connection.getDevices() [note: only 'usb' works right now] . For 'socket' (JetDirect) printers, we can use SNMP to get an IEEE 1284 Device ID in some cases.

Now we need to locate a foomatic entry for the printer model, if there is one. So:

  • if we have an IEEE 1284 Device ID, use it to look up a foomatic printer model by ID.
  • otherwise, if we have the manufacturer and model names, try using them to look up a foomatic printer model by name.

If we have a foomatic database entry for the printer model at this stage, we can find out which drivers are supported:

  • For certain types of printer, there might be manufacturer-supplied PPDs shipped with foomatic (and the foomatic entry will have a pointer to these). These PPD files are obviously the best ones to use.
  • If there is a 'driver' entry in foomatic, that is the recommended driver to use.
  • The available drivers will be listed in the 'drivers' tag.

Given a foomatic printer model and driver combination, a PPD file can be obtained using 'foomatic-ppdfile -p printer -d driver', and where no manufacturer-supplied PPD is available foomatic will generate one.

If we didn't find a foomatic entry, but we have an IEEE 1284 Device ID, we can examine the 'CMD' or 'COMMANDSET' field to see what page description languages the device understands, i.e. POSTSCRIPT, PXL, etc. Foomatic can provide PPDs for Generic PostScript or PXL printers, but if the user has the manufacturer's PPD then that should be used in preference, so we need to ask them if they have that.

Otherwise, we're stuck, and we have to ask the user to tell us what printer model they have.

  • They can select from the list of printers in the foomatic database
  • They can select from the list of CUPS PPDs; i.e. what you get from cups.Connection.getPPDs()
  • Or, as a last resort, we can ask them to just give us a PPD.

The printer driver, if there is more than one possibility

If the user selected from the list of foomatic printers, and there is no recommended driver but several available drivers, we can either just pick one arbitrarily, or offer the user the choice. (Alternatively, of course, I can change foomatic so that there is always a recommended driver, even if it is arbitrary.)