Facilities provided by the new PDriver module (version 0.00)

The new printer sharer module allows many printer driver modules to be resident at once in the machine. The module is required so that devices like FAX cards can have their drivers present at the same time as a printer driver - or, indeed, many real printer drivers, say for a local dot-matrix and a network PostScript printer.

The module steals the SWI chunk used by standard printer drivers. All the standard printer driver SWIs pass through the printer driver sharer module. There are also two completely new SWIs, PDriver_DeclarePrinter and PDriver_SelectPrinter. The first of these allows the new printer driver modules to declare themselves to the printer sharer, which they must do before they can be used. The second of these SWIs allows the user to choose which printer driver is to be used for subsequent PDriver SWIs.

One new service call is introduced - Service_PDriverStarting. This is issued when the printer sharer module starts up, and it lets any printer drivers resident at that time declare themselves to the printer sharer module.

To provide for these new features the old printer drivers have to be recompiled with a new printer-independent source code, and with a single slight adjustment to one of the printer-dependent source code files (to provide a null service routine). These changes have been performed on our four current drivers, and they all appear to work correctly. ISVs who have written their own drivers using our printer-independent code will be able to recompile their drivers without any difficulty at all.

The SWI handling

The new printer sharer module has completely taken over the printer driver SWI chunk. When a SWI such as PDriver_PageSize is issued the printer sharer module must pass it on to a particular declared printer driver module. To do this it has a 'current printer driver' concept.

To set the current printer driver use:

SWI PDriver_SelectPrinter (&80156) On entry:
R0 = printer number to select
On exit:
R0 = printer number previously selected, or error pointer

The printer number is as specified in RISC OS, and Hdr.PDriver:

        0 PDriverType_PS        Acorn PostScript
        1 PDriverType_DM        Acorn Dot Matrix
        2 PDriverType_LJ        Acorn LaserJet
        3 PDriverType_IX        Acorn Integrex
        4 PDriverType_FX        Computer Concepts Fax
        5 PDriverType_LZ        Computer Concepts Laser board
        6 PDriverType_LB        Computer Concepts Laser board
        7 PDriverType_UF        Acorn Printer Dumper driver
       99 PDriverType_JX        Ace Computing Epson JX/Star LC10 driver
       99 PDriverType_PJ        Ace Computing PaintJet

There will be some confusion with Tony Cheal's drivers (both using 99!), but that's his fault.

Any calls to these SWIs will be passed to the current printer driver:

        PDriver_Info
        PDriver_SetInfo
        PDriver_PageSize
        PDriver_SetPageSize
        PDriver_CheckFeatures
        PDriver_SelectJob
        PDriver_SelectIllustration
        PDriver_ScreenDump
        PDriver_SetPrinter

Any of the SWIs above may be postfixed by 'ForDriver', giving PDriver_InfoForDriver, PDriver_SelectJobForDriver and so on. These SWIs use a printer number in R7 instead of the 'current printer driver' number, thus allowing temporary selction of a printer driver just for a single SWI.

Job handling SWIs are treated differently. The printer sharer module keeps track of which printer driver owns which jobs, so that calls to PDriver_AbortJob etc can be passed on to the correct driver. There are three sorts of SWI which affect jobs - those which are handled completely by the sharer, those which are handled completely by the printer driver itself, and those which require both sides.

Those which are handled internally are PDriver_CurrentJob and PDriver_EnumerateJobs. These just require some inspection of the printer sharer's internal job management structures, and no interaction with the real drivers.

Those which are handled completely by the printer drivers are PDriver_CancelJob and PDriver_CancelJobWithError. These simply set flags inside the real driver to stop future printer actions on the specified job from working - they do not affect the job management in the printer sharer module itself.

The last set of job handling SWIs is PDriver_SelectJob, PDriver_SelectIllustration, PDriver_AbortJob, PDriver_EndJob, PDriver_Reset. The code for the select SWIs is quite complex, as it has to deselect the current job on one driver and then select the new job on a new driver. Any errors occurring in the selection process will lead to NO job being selected on exit - this is an incompatible change, but should really affect nobody. Ending and Aborting are easily handled, they just clear the internal data for the specified job and then pass thorugh to the real driver. PDriver_Reset has to reset ALL the printer drivers, which is again easily performed.

Two classes of SWI remain. Those like PDriver_DrawPage and PDriver_GetRectangle, which must be passed on to the driver which owns the currently selected job, and PDriver_DeclarePrinter. The first class is easily handled.

SWI PDriver_DeclarePrinter
On entry:
R0 => branch code for handling the SWIs, given R11 and R12. R1 = R12 for the calls to the branch code R2 = printer number
On exit:
All preserved

This declares a printer driver module to the printer sharer. R2 is the printer number for the printer driver module. R0 points to the SWI handler code in the printer driver. This is called with R11 being the SWI number (a kind of reason code) as specified by the operating system to a standard SWI handler. R1 contains the workspace pointer (R12) for calls to the printer driver SWI handler. This mechanism means that there is little real change required in the real printer driver modules.

Use of the printer sharer

New printer drivers (and that includes our own, which must still be upgraded) will have to RmEnsure the printer sharer module and their own printer driver module. Internal calls to set line spacing, resolution, colour modes, page size etc. should all use PDriver_...ForDriver to perform their work transparentlyto other printer drivers. New printer drivers will also have to have some means of selecting a driver as the 'current printer driver'. The icon on the iconbar should be highlighted, perhaps? Some mechanism will have to be found for this.

All the changes should be completely transparent to applications. The user should even be able to do two multitasking graphics dumps to two different printer types without any change to current applications.