PDA

View Full Version : Cocoa: listening for print




Denarius
Feb 6, 2008, 08:46 AM
Hi all,

I suspect I may be biting off more than I can chew, being very much a beginner in application development on OSX (server side scripting's my usual bag), but here goes.

I'm looking to write a control panel that needs to listen for any command from the print dialogue in any program to print. Ideally, the overall effect needed is to put the print command on hold for about 10 seconds while the control panel does some business and then let the print command spool the print job off to the other printer.

That's my first choice, but if that's not possible is it possible for the control panel to trigger it's main function when an application calls the print dialogue? I was wondering if the Apple Event Object Model could help with this, but I'm not really sure where to look at this stage.

Any advice (up to but not including do something more simple - I really want to write this app if it's possible regardless of the vertical learning curve :) ) will be very gratefully received.



robbieduncan
Feb 6, 2008, 08:53 AM
I don't think it's possible to do what you want they way you are thinking about doing it. The best way would probably be to have a "dummy" printer driver that is printed to. That would communicate with your "control panel". The dummy printer driver would simply have to present the same interface as the target printer and pass the data to/from the application without modification, but buffered to allow you to do your delay.

This is a non-trivial thing to do and the slightest mistake will mess up the printing totally. Perhaps if you gave us some details as to what this "control panel" will do we could suggest better alternatives to this approach.

Denarius
Feb 6, 2008, 09:10 AM
I don't think it's possible to do what you want they way you are thinking about doing it. The best way would probably be to have a "dummy" printer driver that is printed to. That would communicate with your "control panel". The dummy printer driver would simply have to present the same interface as the target printer and pass the data to/from the application without modification, but buffered to allow you to do your delay.

This is a non-trivial thing to do and the slightest mistake will mess up the printing totally. Perhaps if you gave us some details as to what this "control panel" will do we could suggest better alternatives to this approach.

Hi Robby, thanks for the quick reply. I like the sound of that approach.
Essentially, the idea stemmed from our home network where we have a G5 that has all our printers connected to it. Because of this the G5 has to be kept awake all of the time. So it got me thinking that it would be nice if the client computer could automatically send a wake on Lan command to the computer hosting the printer before the print job is actually sent.

Denarius
Feb 6, 2008, 09:27 AM
So now I've been mulling it over, I'd need the app to find the list of available remote printers on the network and have a class to generate the dummy driver to buffer the print job for a short time before sending it on?

robbieduncan
Feb 6, 2008, 10:50 AM
I would not try and generate print drivers: this basically will not work fast enough. I was suggesting you write one single print driver, install it and set it as the default printer. Note that printer drivers are not written in Cocoa and this may be an exceptionally complex task.

I'd suggest reading the CUPS documentation very carefully and working out if there is a way to run a script pre-print (or perhaps have a CUPS filter that passes the data straight on to another filter)

mduser63
Feb 6, 2008, 12:21 PM
Wirelessly posted (Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/4A93 Safari/419.3)

You could always get a network printer or a router with support for a printer (like an Airport base station). Seems like a faster, easier and much less frustrating solution to a problem that has already been solved before. I have a Samsung printer that I bought at the Apple store and it is on my network via a built in Ethernet port. Setup took all of 30 seconds (plug two cables in, turn it on) and I can easily print to it from any of my Macs.

Denarius
Feb 6, 2008, 12:33 PM
Thanks for your thoughts Rob. Just found the CUPs documentation. Looks like this may take some time...:)

Denarius
Feb 6, 2008, 05:37 PM
Okay, I've now established that's CUPS goes through a process
Scheduler->Filters->Backend->Printer. What isn't clear is whether in a scenario of a server with a printer and and a client that wants to print to the printer, is the print-job processed through the filters client side or server side?

robbieduncan
Feb 6, 2008, 05:41 PM
My guess (and it's a guess) is client side...

Denarius
Feb 7, 2008, 07:32 AM
I certainly hope so at any rate: Otherwise I'll have to contemplate the appalling prospect of the user having to click a button (gasp of horror) before printing.

Thanks again Robbie. Early days, but at least I now know where to start.

Denarius
Feb 8, 2008, 04:29 AM
Just in case anyone's interested there exists a piece of open-source software called Tea4CUPS written by Jerome Alet, which is a generic backend wrapper for CUPS that can be used to add extra filters, call scripts before the print job is sent or call scripts after the print job is sent.

You can download it at http://linux.softpedia.com/progDownload/Tea4CUPS-Download-6448.html

Found this out on the cups.org forums, with the kind help of Michael Sweet and Jerome.

Thanks once again for pointing me at CUPS for the solution.

robbieduncan
Feb 8, 2008, 05:02 AM
Wow, that sounds like a cool piece of software, good find :)

Denarius
Feb 8, 2008, 05:58 PM
I just found out the version above is buggy. Jerome gave me a subversion link to the latest which works a treat.
In terminal type
svn co svn://svn.librelogiciel.com/tea4cups/tags/3.12/ tea4cups
(look up subversion on the web if you don't know about it, I found a package installer for osx with a quick Google. I only mention it because I'd never come across subversion before)

In terminal do
cd tea4cups
sudo tea4cups /usr/libexec/cups/backend/
sudo chown root /usr/libexec/cups/backend/tea4cups
sudo chgrp wheel /usr/libexec/cups/backend/tea4cups
sudo chmod 0700 /usr/libexec/cups/backend/tea4cups
sudo cp tea4cups.conf /private/etc/cups/

Need to restart cups now (I just restarted the computer)
Open browser.
Go to localhost:631 and note the URL of the printer you want to use.
Modify printer and continue through to Devices and select tea4cups network printer, then continue.
Add the old URL exactly as it was after 'tea4cups:'
Just finish up by adding the right drivers for your printer.
Add your prehook/posthook scripts in /private/etc/cups/tea4cups.conf
i.e. (in my case)
'prehook_wake : wakeonlan [MAC address]' (I installed a perl script called wakeonlan in /usr/sbin/ with an added 'sleep(5);' at the end of the subroutine to give the server a chance to wake up before the print job is actually sent. I've seen quite a few python scripts about as well, which are probably a better idea given that python's already there without xcode. Anyway this is the script I used: http://gsd.di.uminho.pt/jpo/software/wakeonlan/

I now have wake on lan printing. Wahey! :D Now to work out where to go from here....