# Collaborators wanted: share-to-printer plugin

I was recently reminded that there still is no printer support in SFOS, so i took a look at the printer support situation. Yes, there is CUPS, and there is QtPrintSupport bindings for that. However, they are quite big and complicated. Sure, if one was to implement bindings for the whole API the configuration possibilities would be pretty great, but simple things like "just throwing a PDF at the printer" seems to involve rendering it client-side (ugh!).

This lead me to looking in to what network printing support actually means. The Printer Working Group would at least want you to think that it is IPP (Internet Printing Protocol), which supposedly ships with 98% of modern (network-enabled) printers. Also, any Linux box or Mac should be able to act as an IPP server. It seems that IPP-enabled printers tend to accept PDFs as a transport format. Sure, this approach limits printing to supported formats, at least initially, but PDF alone would take care of a sizeable chunk of printing needs.

So i made a quick IPP client in my favourite protocol handling language, Erlang, and before too long i had printed a PDF. IPP is pretty simple, and relying of huge monolith libraries seems as unnecessary as i thought. Following this, I started on a client in QT-flavoured C++, i.e. for SailfishOS. It sort of works, but boy was it painful. It must have taken an order of magnitude more time for a similar level of functionality. No GUI bindings or anything yet either... Since i print things about twice a year, the chances i'll bother finishing this are approaching zero.

Does anyone feel like pitching in? Do you just want to complain that this is the wrong approach?

Find me on IRC, #sailfishos at freenode.

More on sharing plugins here: https://together.jolla.com/question/164166/how-to-create-sharing-plugin-for-sailfish/

PS, while disillusioned by C++ i started a mDNS (discovery protocol used by IPP) client in Erlang too, and unless there is a really spot-on implementation available i'd say we are better off making our own client here too.

edit retag close delete

Sort by » oldest newest most voted

This post is a wiki. Anyone with karma >75 is welcome to improve it.

devel-su pkcon install cups-ipptool
LC_ALL=POSIX ipptool -t -v http://<ip to printer here>:631/ipp/print get-printer-attributes.test | grep document-format-supported


(your printer could have another url, but /ipp/print is the most common)

Find the entry document-format-supported, and post results below.

We are looking for application/pdf or (more hassle, but still driver-free) image/pwg-raster

Results:

• CUPS on Linux ( @attah ): application/pdf,image/jpeg,image/pwg-raster [pass]
• OKI MB461: application/octet-stream,application/vnd.hp-PCL,image/urf [fail]
• Canon MX920: application/octet-stream,image/jpeg,image/urf [fail]
• Kyocera FS2100DN: application/octet-stream,application/pdf,image/tiff,image/jpeg,image/urf,application/postscript,application/vnd.hp-PCL,application/vnd.hp-PCLXL,application/vnd.xpsdocument,image/pwg-raster [pass]
• Xerox C8030: application/octet-stream,application/vnd.hp-PCL,text/plain,image/urf,image/pwg-raster,application/postscript,application/pdf,application/PCLm,image/jpeg,image/tiff [pass]
• HP M401dne: image/urf,application/pdf,application/postscript,application/vnd.hp-PCL,application/vnd.hpPCLXL,application/PCLm,application/octet-stream [pass]
more

1

The printer in my office (Canon-iR-ADV-C5030i) doesn't support IPP, at least it's not listening to port 631. However it listens to port 9100, the raw TCP port for printing. If I send a PDF to the printer via netcat it gets printed.

( 2019-08-06 23:14:37 +0300 )edit

@jollajo: that's a very unexpected, but convenient behaviour! It would be interesting to know if/how printers that work like that can be discovered.

( 2019-08-06 23:28:54 +0300 )edit

HP M401dne: image/urf,application/pdf,application/postscript,application/vnd.hp-PCL,application/vnd.hp-PCLXL,application/PCLm,application/octet-stream

( 2019-08-09 16:17:47 +0300 )edit

Do you just want to complain that this is the wrong approach?

I would vote for "this is the wrong approach" (though I understand you find interesting to re-invent the wheel).

I would vote for still using CUPS:

• Sailfish OS is a full blown GNU/Linux, just like the Ubuntu/Fedora/Tumbleweed running on your laptop.
• CUPS is the de-facto standard printing system on most Unix (Linux, Mac OS X, BSD, etc.)
• CUPS is the most likely software to get upgraded/updated as newer stuff appear.

## Demo

### Install cups

zypper install cups


or

pkcon install cups


and ignore & override complains about missing chkconfig (as Sailfish is systemd-based and doesn't use this anymore).

### Configure non-root usage

As user Root doesn't have any password on Sailfish OS, it's unusable.

#### Groups-based

I've misssed it in the first version, but as pointed out in older threads, you can also add user nemo to the lp group:

usermod -a -G lp nemo


#### Access rights-based

Basically, for any right that you want to grant ( <Limit CUPS-Add-Modify-Printer...) you need to change Require user @SYSTEM into Require user @SYSTEM nemo.

For example:

sed -ri '/<Limit CUPS-Add-Modify-Printer/,+4s/Require user @SYSTEM/\0 nemo/' /etc/cups/cupsd.conf


That's the only step that is unusual.

### Start cups

systemctl start cups


Browse to http://localhost:631/admin click on the Add printer button and configure your printer (almost) as if you would be doing on your laptop (with the exception that you need to log as nemo, not root).

The beauty is that CUPS will support IPP, but also LPD or straigh raw TCP/IP printing (port 9100).

Keep in mind that out-of-the-box Sailfish OS doesn't have any mDNS installed (no avahi here). So for the moment being you can't (yet) use .local network addresses. Use either IP addresses (hint: IPv6 Link Local fe80:: addresses derived from the MAC address are stable so prefer that if the printers support IPv6) or the domain provided by your home modem-router (e.g.: .fritz.box )

Simply use one of the Generic drivers (e.g.: Generic PostScript, Generic PCL). Throw your printer out of the window if it doesn't support any of PDF, PS nor PCL. (URF and other similar proprietary protocols should burn in hell). No self-respecting networked printer should skip that.

#### Pro tips:

If you find the screen of your smartphone too small, you can also use an SSH tunnel to have it on your laptop (remember to stop your local CUPS before, otherwise your port will be busy, or simply use a different port on the right hand side of the mapping with -L) :

systemctl stop cups
ssh -L 631:127.0.0.1:631 nemo@192.168.2.15


And then you can open the settings on your browser.

(Same can also be done with the advanced settings of PuTTY on Windows)

(Or you can go down the whole rabbit hole and configure network administration on your smartphone's CUPS. But this will require a hostname, a SSL certificate, etc.)

### Print

From the command line:

lp -d{your printer}--{your PDF}

where your printer is the pintername, as listed in the left-most column of /etc/printcap or as listed by lpstat -a. e.g.:

lp -d samsung -- Downloads/mail_attachments/21/4945-2/volvo.pdf


That's it. It works. You can "just send a PDF to the printer" from the command line.

You'll notice that, except for switching from root to nemo as an administrative user, everything else is nearly similar to any other UNIX system.

What would be needed from here to have a quick "send to printer":

• Automate the administrative user (see either sed script or usermod above)
• make a nice "send-to" handle for PDF (application/pdf) and Postscript (application/postscript) mime-types that simply calls the lp command. the various share plugins on openrepos would be a starting point.
• add a nice drop-down list of pinters based on lpstat -a
• compile a Sailfish version of CUPS Cloud Print to have possibility of printing to Google Cloud.
• recompile a newer version of avahi for Sailfish OS (because my package is horrendously out of date and doesn't work anymore) so that .local addresses work again.
• at this point CUPS would get some automatic discovery of networked printers.

Further developments:

• a full blown integration of QtPrint
• a full blown printer native administration in QML as some distribution do (e.g.: Suse's YaST printer module) :-P
more

While I really like this solution from the perspective of the operating system, I still fear that this will fail with the majority of users, simply because of the lack of data format support with most cheap printers. People just don't check these things before buying, and with "people", I don't mean us TJC nerds.

( 2019-08-07 09:55:04 +0300 )edit

Regarding data formats, the thing is that we're looking at networked/wifi printers.

• AirPrint is the only slightly problematic, because the only hard requirement is the URF format, which is patented. (On the other hand, Jolla is euro-centric, and it's going to be rather easy to have an .rpm package with the filter hosted in a country that doesn't recognize pure software patents, like France. See VLC). It is possible to have printer that only supports URF and a bunch of proprietary bullshit.
• Google Cloud Printing: support for PDF is mandatory
• Random networked printers and MFC: most support at least one out of PDF, PS and/or PCL - all either standards or defacto standard. The ones that don't are expensive door stopper that are going to break anyway once support for Windows 7 runs out and the user realize that they can't get them to work on Windows 10 due to missing proprietary binary drivers from a company that doesn't exist anymore.
( 2019-08-07 11:41:51 +0300 )edit

Wow, very comprehensive. Thanks. Although i still sort of doubt how much useful functionality CUPS adds. Or should I say, how much of the functionality added would actually be used... Like, how many printers can it actually deal with without rendering plugins/drivers, that doesn't already have have PDF or PWG? As you say, add URF and PCL to the mix and there can't be a whole lot left. I mean it really does mainly exist to keep these drivers associated with the printers and provide render plugins, from what i understand. Ideally neither would actually be needed, or only one or two rendering plugins would be used. After all, Apple, the "owner" of CUPS use AirPrint and nothing more for their mobile devices.... Hmm, the OKI i mentioned does support some Google Cloud Printing, but still not PDF over IPP. That's a bit odd. I thought they (Android) only do local plugins drivers, and that the cloud indeed dictates some common interface. AFAIK CUPS only has URF to PDF and not the other way around... but i guess it could be doable to make something for the inverse. BTW, where did you find that it was patented? Edit: oh, it's the whole thing... that's silly. Still not sure how much of the format is covered.

( 2019-08-07 21:30:07 +0300 )edit

Although i still sort of doubt how much useful functionality CUPS adds.

Multiple connection protocols: not only the IPP you've implemented, but also LPD (very popular on networked Laserprinter and MFCs, in my experience), raw 9100.

Has also connectors for Google Cloud Printing (Note: that doesn't have a package in Sailfish OS yet).

Has capabilities to autodetect network printers (Note: this depends on Avahi which currently isn't on Sailfish OS neither)

Missing package wouldn't be a huge problem to add through openrepos.net, though.

Also it's a general printing service which is able to handle all the ancillary tasks: configuring permanent printers (your home printer, your Google Printers, etc. basically anything that you won't auto-detect on the fly). And managing Jobs and print queues.

But the main reason: it's the generic solution used by virtually all other unices. If it needs maintenance (bugfixes, security fixes, etc.) chances are high that it's going to get it. (e.g.: it has devs on Apple's payroll).

I mean it really does mainly exist to keep these drivers associated with the printers and provide render plugins, from what i understand.

No, it's not only a driver collection, it's also a printing service.

Also regarding drivers: they are stored in separate package, and Sailfish doesn't even have them (no cups-filters, neither foomatic nor gutemprint). Which makes sense: portable devices are most likely to print to a networked printer.

Like, how many printers can it actually deal with without rendering plugins/drivers, that doesn't already have have PDF or PWG?

No printer that isn't garbage should.

AFAIK CUPS only has URF to PDF and not the other way around... but i guess it could be doable to make something for the inverse.

It's patented, only doable in jurisdictions that don't allow pure software patents like VLC does in France.

( 2019-08-08 11:40:27 +0300 )edit

I noticed that CUPS Cloud Print is actually a noarch package (it's python).

The RPM package that they provide should be usable on Sailfish.

To be tested next time...

( 2019-08-08 12:21:30 +0300 )edit

It's not that easy, especially with popular customer grade printers. IPP is just a kind of transport standard. You still need to have custom rendering software, and there are a bunch of "standards" for this. Each printer (class) brings its own rendering filter, generating appropriate (usually bitmapped) data for the printer, and you would need to package that, too. Some (most) printer vendors don't have open-sourced these filters, and if you're lucky, you can find some (i386) binaries.

While I find this very interesting, I doubt it can be achieved with reasonable effort.

more

2

I know this used to be the case, but i got the distinct impression PDF as a rendering format is becoming widely supported, along with image/pwg-raster. Sounds like we need to find/make a survey.

( 2019-08-06 19:00:21 +0300 )edit

I'd love to be proved wrong!

( 2019-08-06 20:52:14 +0300 )edit

I went to check on a networkable printer i have access to. It is a very simple monochrome OKI, but it makes a point of having PDF support. However, it would appear you are still correct. It does not support PDF over IPP, it appears to be limited to USB drives plugged in to the front. To its defence it was a much older model then i thought (ca 2011). It lists the following formats:

application/octet-stream,application/vnd.hp-PCL,image/urf


So i assume native, ancient compat format, and Apple AirPrint. OKI actually does support (seemingly cross-platform) plugins for CUPS, but for these intents and purposes that's besides the point. AirPrint-urf is unfortunately not an open format (shocker!), but it leads me to this page https://wiki.debian.org/DriverlessPrinting#PDLs_for_Driverless_Printing

So I still have hope for PDF and PWG-raster being common enough to be useful. (I'll update the question with a survey)

( 2019-08-06 22:13:38 +0300 )edit

PCL is also a somewhat de facto standard, not as popular as PS nor PDF, but still standard (and supported by standard pxl driver in cups, no need of proprietary x86 binary)

Basically any networked printer worth its salt supports at least one out of PDF, PS and/or PCL. Those who don't are basically expensive door stopper.

PDF and PS are a bit more memory hungry than PCL, so some printer might only support that one out of the box and require a memory DIMM installed + firmware update before supporting (the turing complete) PS (e.g.: some old Samsung).

(By printer I mean Laser Printer. Ink jets are single use devices that shouldn't be used beyond the ink that came pre-packaged with them. Otherwise you'd need a few organs to sell on the black market to afford the price of the replacement ink, which cost probably 3x the price of the printer. Per cartridge. It's probably made out of unicorn blood or something.)

UFR is a proprietary language supported by Canon, I suspect your OKI uses a main board by Canon. (There aren't that many manufacturers of laser components - basically it's Xerox, Canon and HP. Everybody else uses parts from them).

( 2019-08-06 23:32:35 +0300 )edit

Thanks for the info. However, it is urf, not ufr. Pretty sure it is AirPrint unirast.

( 2019-08-06 23:57:24 +0300 )edit