TealPrint Driver Developer's Notes

Introduction

In order to offer flexible support for a maximum number of printers, TealPrint supports interchangeable printer drivers. This package is meant as a resource for programmers and Printer manufacturers to write their own sofware printer drivers compatible with TealPrint. It assumes both a good working knowledge with C and Palm OS programming.

Overview

TealPrint printer drivers are actually independent programs. TealPrint identifies them by their icon name, which must start with "TP-" (case sensitive) to be identified as a printer driver.

As independent programs, TealPrint printer drivers can still be launched from the Palm applications launcher. Normally, they only need put up some useful "About" information and perhaps offer options to do some debugging or print a test page.

TealPrint's print engine handles the majority of print-oriented tasks, including rendering, rotating, effects, and text wrapping. Drivers only need know how to send a prerendered bitmap raster row or text line (if applicable), and maintain current information about the current print mode and paper settings, and are responsible communicating with the printer hardware.

Calling Mechanism

TealPrint calls printer drivers directly to query information or perform print functions. It does this by launching the application with specific custom launch codes and passing it a pointer to a corresponding data structure. Note that programs launched with custom launch codes cannot access global data. Supported launch codes and functions include the following values defined in the include file tealprnt.h:

Driver Launch Codes

DRIVER_CMD_ShowInfo
Bring up a dialog box or modal form displaying information about the current driver including name and version.
DRIVER_CMD_GetDriverInfo
Get basic information about the printer driver including paper sizes and supported text and graphic print modes.
DRIVER_CMD_GetGModeInfo
Get information about a specified graphics mode including resolution.
DRIVER_CMD_GetTModeInfo
Get information about a specified text mode including print density.
DRIVER_CMD_GetPaperInfo
Get information about a specified paper size including dimensions and margins.
DRIVER_CMD_SetPaperInfo
Set margins and sizes for a specified paper size
DRIVER_CMD_SetSettings
Bring up a modal form to set driver-specific setting like communication speed.
DRIVER_CMD_EjectPaper
Issue a form feed command, ejecting the current sheet of paper from the printer
DRIVER_CMD_PrintBitmap
Print a raster bitmap.
DRIVER_CMD_PrintText
Print a sequence of raw text.
DRIVER_CMD_HardReset
Perform a hard reset of the printer, bringing it to a known state. Typically called only upon specific user direction, as the response to this call is allowed to take a little time.
DRIVER_CMD_SoftReset
Perform a soft reset of the printer, bringing it to a known state. May be called by software before issuing a print job or after aborting a print operation. This call must quickly return.

Printing Text

When printing raw text to the printer, the printer driver wraps the raw ascii text and sends the following structure to the printer driver:
   typedef struct {

      // where to return success to the print engine.
      // 0 = success
      // nonzero = error or abort

      long   retval;

      int cols;           // total number of columns to print
      int lines;          // total number of text lines to print
      int blank_lines;    // number of blank lines before printed lines
      int blank_cols;     // number of blank columns before printed columns

		// function pointer used by driver to fetch text for printing

      void (*getline_func)( 
         char **text,     // returned text pointer to text data
         int    line,     // text line to get, starting at blank_lines
         int   *offset,   // returned starting column where text goes
         int   *count, 	  // returned count of text characters
         void  *data );   // pass copy of app_data, below

      void *app_data;     // data to pass through to getline_func()

      long print_flags;   // special print flags
      int  mode_number;   // text mode to use
      int  paper_number;  // paper number to use

   } DriverPrintTextType;
A typical driver goes into a loop for each line of text after sending the blank lines to the printer. For each line, it calls getline_func() to fetch the text for that line and translates it, if necessary, and sends it to the printer. For most printers, this routine can be nearly identical to that in the default drivers.

Printing Graphics

Graphics printing, unlike text printing, is almost always highly printer-specific. TealPrint calls the driver, passing it the following structure:
   typedef struct {

      // where to return success to the print engine.
      // 0 = success
      // nonzero = error or abort

      long   retval;

      int width;         // width in pixels of bitmap to render
      int height;        // height in pixels of the bitmap to render
      int blank_lines;   // number of blank rows to offset image from top
      int blank_cols;    // number of blank columns to offset image from left

      // Call this function to get a row of pixel data

      void (*getraster_func)(

         unsigned char **targ,    // returned pointer to bitmap data
         int line,                // index to pixel row, starting at blank_lines
         int offset,              // offset of pixel columen to get
         int count,               // count of pixels to get
         void *data, 				 // pass copy of app_data
         unsigned char bgcolor ); // value for white, typically 0 or 255

      void *app_data;             // value to pass to getraster_func()
      long print_flags;           // print flags
      int  mode_number;           // graphic mode to print
      int  paper_number;          // paper number to use
   } DriverPrintBitmapType;
A typical driver goes into a loop for each row of graphics after sending the blank rows to the printer. For each line, it calls getraster_func() to fetch the bits for that line and translates it, if necessary, then sending it to the printer. The basic graphics routines send black and white graphical data one bit per pixel, with the MSB (most significant byte) to LSB (least signicant byte). For printers that expect the data in other formats, the bits may need to be processed and/or reordered.

Example Source Code

The easiest way to actually write a driver is to use the enclosed sample source code as a starting point. EPSON.C is sample C-language source code for a combination text and graphics driver that supports serial and infared communication. It was written to compile with GNU-C, using PilRc as a resource compiler. When altering this driver for another printer, at the very least, you'll need to:
  1. Change the Creator ID to a new custom value, registering it with Palm.
  2. Change the driver program name. It must still start with "TP-".
  3. Customize the driver info flags, reflecting capabilities of the printer
  4. Customize text mode return values to reflect supported character pitches
  5. Customize graphic mode return values to reflect supported resolutions
  6. Tweak custom text print routine, if necessary
  7. Write custom raster graphic print routine.

Conclusion

That's it. Questions? Please contact support@tealpoint.com. Check the developer's section of our Software page for other hints, tools, and information. Thanks,

TealPoint Software Staff