PDDR/2 - 32-bit Omni Presentation Driver

From EDM2
Jump to: navigation, search

Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation

Printer Device Driver Reference

32-bit Omni Presentation Driver

Omni is a 32-bit raster-graphics driver developed in conjunction with the OS/2 Warp graphics engine and The Generic Printer Library. The Omni model was designed to provide Independent Hardware/Software Suppliers with a device-driver model that allows them to easily create raster OS/2 Printer Drivers.

Omni driver code consists of two major functional groups. The first group is a generic, core set of functions that are typical to most OS/2 presentation device drivers. These core functions manage the following:

  • Printer driver enabling and disabling
  • Device context (DC) initialization
  • Job and printer property user-interface

The second set of functions are "plug-in" routines that support specific raster languages and printers. Each module requires that a developer need only supply a few functions and fill out a few tables to describe the language and characteristics for the specified printer models. The plug-in functions include the following:

  • Device query
  • Job initialization
  • Page/band rasterization
  • Job pagination
  • Job termination
  • Job abort

The plug-in tables describe the following:

  • Supported trays
  • Supported paper sizes
  • Supported media types
  • Supported resolutions
  • Supported print modes (i.e. 1,8,24-bit image formats)

Omni code has been organized into core and plug-in functional groups to simplify a developer's initial attempt to create an OS/2 raster printer driver. However, developers can modify the core Omni code to achieve better support for their devices.

The time required to develop plug-in modules will vary based on the printer language and the developer's experience. On printer models that utilize popular languages, a device can be added in as little as a few hours. Development time will increase in proportion to the level of customizing and extending required for the driver and for the user-interface. Common examples include modifying the user-interface to match another manufacturer's user-interface and adding support for device or downloadable fonts.

The plug-in module can be designed to "hook out" and provide the functions required for the level of control that best utilizes the printer through its native language and capabilities. Examples of optionally hooked functions include the following:

  • Subclass all spooler calls (Spl calls)
  • Subclass all port driver calls (Prt calls)

Generic Printer Library (GenPLib)

The Generic Printer Library is a set of subroutines developed in conjunction with the Omni driver for OS/2 Warp. These routines are useful when developing 32-bit printer presentation drivers.

The Omni driver is the only driver on the DDK that utilizes all of the Generic Printer Library functions in its source code. That makes the Omni code a valuable example for anyone using GenPLib to develop a 32-bit OS/2 Printer Presentation Driver.

All code samples for GenPLib subroutines are a direct excerpt from the Omni driver source code. For further information about the Generic Printer Library, see Generic Printer Library.

Building the Omni Driver

Refer to the "Using Your DDK", available on the DDK CD, for a roadmap of the file structure used by the Omni Driver. The "Using Your DDK" roadmap also shows how to build the source code. The location for the core and plug-in code will look similar to the following:

src\osdd\omni - Core Omni driver files and makefile
src\osdd\omni\devices - Plug-in Omni driver files
src\osdd\omni\icons - Omni driver icon and graphics

Adding a Device

The following information takes you through the sections in the plug-in modules you will need to modify for your specific printer.

It is relatively easy to add a device that uses one of the printer languages supported by any of the sample plug-in modules. Begin by changing to the directory in which the Omni driver source code is located (refer to the "Using Your DDK", available on the DDK CD, for file locations). All code in the "omni" directory is considered core Omni driver code.

The "devices" subdirectory, located below the "omni" directory, contains the plug-in modules that provide code for specific printer models and their languages.

The following sample plug-in modules are provided with the DDK:

samp_pcl.c - sample PCL language module
samp_eps.c - sample ESC/P(2) language module
tiff.c - sample TIFF language module (with G3/G4 compression)

All plug-in modules are currently included by the core omni driver file, driver.c. (#include driver.c), and the finished driver currently consists only of the file "omni.drv".

Modifying Plug-in Modules

The plug-in module is a 'C' source code module that will include any needed header files as well as any definitions, macros, or IDs specifically required to compile.

Proceed to the following sections for a description of the plug-in modules that are typically included in every plug-in module.

#Feature ID Section
#Device Handle Section
#Function Section
#Tables Section
#Supported Features Section
#Devices Section
#Driver Section

Feature ID Section

This section contains all the unique IDs that can reference unique printer models and specific features of individual printer models.

If two different printer models have the same capability, they can reference the same ID, such as printers within a printer "family" that support the same paper sizes, trays, and so on.

Once a feature ID has been added and shipped with a printer, do not change it. This could cause cross-network printing to fail. For example, two different versions of the same printer drivers must use the same feature ID on both networked systems to successfully communicate.

Each group of IDs should have the default option for that group assigned the ID == 0 (zero). This helps the core driver to fail invalid IDs and to pick 0 (zero) as a default fallback in an emergency. Proceed to the following sections for a description of the feature IDs:

#Printer Model IDs
#Print Qualitiy IDs
#Print Mode IDs
#Device Font IDs
#Paper Tray IDs
#Form Size IDs
#Media Type IDs
#Form Connection IDs

Printer Model IDs

Assign a unique internal model ID for each new printer you add.

The following example shows how to define IDs for three printer models:

#define PRN_ID_MODEL_500        2000
#define PRN_ID_MODEL_500_SX     2001
#define PRN_ID_MODEL_510        2002

Print Qualitiy IDs

Assign a unique internal print quality ID for each quality setting available on your printer models. A unique print quality typically corresponds to each of your printer settings. This allows you to control the resolution and the number of print head passes for each scanline, such as draft, letter quality, fine.

The following example shows how to define IDs for three quality settings:

#define RES_ID_DRAFT          0   // 150 dpi
#define RES_ID_NORMAL         1   // 300 dpi
#define RES_ID_PRESENTATION   2   // 600 dpi

Print Mode IDs

Assign a unique internal print mode ID for each bitmap format you want to support. You can use your rendering software or the functions provided in GenPLib to render each bitmap format.

The following example shows how to define IDs for three bitmap formats:

#define PRINT_MODE_ID_MONOCHROME      0   // 1 bit/pel format
#define PRINT_MODE_ID_COLOR_8_BPP     1   // 8 bit/pel format
#define PRINT_MODE_ID_COLOR_24_BPP    2   // 24 bit/pel format

Note: Available formats that work on OS/2 Warp include the following:

8 bit/pel logical on an 1 bit/pel physical bitmap (256 grayscale)
8 bit/pel logical on an 8 bit/pel physical bitmap (256 color)
24 bit/pel logical on a 24 bit/pel physical bitmap (16.7 million color)

Device Font IDs

You can see the planned, but not yet implemented, device fonts in the "samp_eps.c" plug-in module. This module has a sample Epson 24-pin printer that supports several DBCS Japanese fonts and codepages.

Paper Tray IDs

Assign a new unique internal tray ID for each physical tray your printer models support.

The following example shows how to define four tray IDs:

#define TRAY_ID_SHEET_FEEDER     0
#define TRAY_ID_ENVELOPE         1
#define TRAY_ID_AUTO             2  // automatic sheet feeder
#define TRAY_ID_MANUAL           3  // manual sheet feeder

Form Size IDs

Assign a unique ID for each unique paper size supported by your printer models.

Different printer models within a printer family can have different margins for the same paper size. To accommodate this variation, you can create multiple form definitions for the same paper size. For example, three form size IDs can exist for the size "letter". Each would represent "letter" with a different margin.

In addition, different margins can be used on one form size "letter" within the same printer model, depending on which tray or printhead is used.

The following example shows how to define five form size IDs:

#define FORM_ID_LETTER           0  // Letter-sized form
#define FORM_ID_LEGAL            1
#define FORM_ID_A4               2
#define FORM_ID_C10_ENVELOPE     3
#define FORM_ID_LETTER_2         4  // Letter size with margins different from FORM_ID_LETTER

Media Type IDs

Assign a new unique internal media type ID for each different media type your printer models support.

The following example shows how to define four media type IDs:

#define MEDIA_ID_PLAIN       0   // Normal copier paper
#define MEDIA_ID_TRANS       1   // Transparency paper
#define MEDIA_ID_GLOSSY      2   // Chrome Coated paper
#define MEDIA_ID_SPECIAL     3   // Coated Paper

Form Connection IDs

Assign a unique internal form connection ID for each different combination of tray, form, and media type a user can select. The following are examples:

The following example shows how to define four form connection IDs:

#define CONN_ID_1      0   // auto, letter, plain
#define CONN_ID_2      1   // auto. letter. manual
#define CONN_ID_3      2   // manual, C10, plain
#define CONN_ID_4      3   // manual, A4, transparency

Note: Because the user can define uncommon combinations from the Omni Printer Property panels, every permutation need not be displayed.

Device Handle Section

The device handle is a data structure that is unique to a specific plug-in module. A pointer to this data area can be given to the core Omni driver, and this sample pointer will be passed as an input parameter to all functions the plug-in module will subclass. This is an efficient place to put state data and variables that are re-used by the plug-in module while rendering a print job.

It is standard practice to put the count of bytes for the entire structure in the first field of the structure, and a 4 character signature that uniquely identifies the structure in the second field of the structure, as follows:

 #define SAMPLE_SIG   0x5350434C      // 'SAMP'

 typedef struct _SampleHandle {
    ULONG         cb;        // Count of bytes
    ULONG         ulSig;     // Signature
    // Place more variables here as desired
 } SAMPHANDLE, *PSAMPHANDLE;

Function Section

This section contains all prototypes and functions used by the plug-in module either for private use or to be placed in the function hook table.

The following example shows the function the core Omni driver code calls at the beginning of each print job:

// Function called at beginning of each print job subclassed
// from the Omni core driver code.

BOOL  _System SampleBeginJob( PVOID pv, PVOID pvHandle )
{
   PDDC           pddc       = (PDDC)pv;
   PDEVICEINFO    pDevice    = pddc->pdb->pDevice;
   PSAMPPCLHANDLE pHandle  = (PSAMPPCLHANDLE)pvHandle;

   // If this printer has defined an Initialization command in the
   // plug-in command table.
   if (pDevice->pCmds->ulCmdInit)
   {
      // Send Initialize printer escape codes to output thread
      GplThreadWriteBlock (pddc->pdb->hThread,
                           pDevice->pCmds->pszCmdInit,
                           pDevice->pCmds->ulCmdInit);
   } /* end if */

   // NOTE: Send other escape codes to initialize printer here

   // Set printer's physical head position in our core Omni DDC
   pddc->ptlPrintHead.x = 0;

   // Initialize absolute pel position in core Omni based on orientation
   if (ORIENTATION_PORTRAIT == pddc->pdb->pJobProperties->ulOrientation)
      pddc->ptlPrintHead.y = pddc->pdb->pFormInfo->hcInfo.yPels-1;
   else
      pddc->ptlPrintHead.y = pddc->pdb->pFormInfo->hcInfo.xPels-1;

   // Reset flags for beginning of a new (next) page

   // Reset rendering flag used by GENPLIB dithering code
   // inside DITHERREQUEST structure we store in our Device Handle
   pHandle->Req.SrcOptions.fStartOfPage = TRUE;

   // Initialize a state flag in our Device Handle to indicate
   // Graphics state on printer has not yet been initialized
   pHandle->fHaveSetupPrinter = FALSE;

   return TRUE;

} /* end SampleBeginJob */

Note: Tailor the required escape codes and variables to your specific printer models.

Tables Section

In this section, you fill out tables that represent the features available on your printer models. The structures that define a feature, such as a paper size or tray, are all defined in the core Omni driver file, device.h. A table exists for each of the feature ID types, and there will be a unique entry in a table for each feature ID declared. Proceed to the following sections for a description of the tables.

#Print Quality Table
#Print Mode Tables
#Tray Definition Tables
#Form Definition Tables
#Media Definition Tables
#Feature Support Table
#Form Connection Tables
#Command Support Table
#Subclassed Function Table

Print Quality Table

Fill in table for all print qualities supported by all printer models supported in this module. This table is comprised from RESINFO structures in the device.h file.

The following is an example of a print quality table with a "draft" print- mode entry:

     RESINFO SAMPLE_pRes[] =
     {
      {  RES_ID_DRAFT,                  // ulResID;
         RES_STRING_DRAFT,              // ulNameID (ID from file omni.rc)
         "",                            // szResName[32];
                                        // (if not in omni.rc)
         150,                           // ulXRes;
         150,                           // ulYRes;
         5,                             // usCmdLength;
         _ESC_"*r1Q",                   // szCmdSelectRes[32];
         0,                             // ulCapabilities
         0,                             // ulReserved
         0,                             // usPrintMethod;
         0,                             // usNumPhysicalPins;
         0,                             // bAdjacentDotPrinting;
         1,                             // usDotsPerColumn;
         0,                             // usBytesPerColumn;
         0,                             // usLenLineSpacing;
         _NUL_,                         // szCmdLineSpacing[8];
         0,                             // ulUnitsLineSpacing;
         0,                             // usLenVerticalDensity;
         _NUL_,                         // szCmdVerticalDensity[8];
         0,                             // ulUnitsVerticalDensity;

       } /* end draft table entry */

     } /* end table */

Print Mode Tables

Fill in table for all print modes supported by all printer models supported in this module. This table is comprised from PRINTMODE structures in the device.h file.

The following is an example of a print mode table with an 8 bit/pel print-mode entry:

     PRINTMODE SAMPLE_pPrintModes[] =
     {
       {
         PMODE_ID_COLOR_8_BPP,           // ulPrintModeID;
         COLOR_TECH_CMY,                 // ulColorTechnology;
         PRINT_MODE_STRING_COLOR_ONLY,   // ulNameID; (from omni.rc)
         "",                             // szPrintMode[32];
                                         // (if not in omni.rc)
         8,                              // Physical bit count
         8,                              // Logical  bit count
         1,                              // # color planes (always 1 for OS/2)
         0,                              // reserved
       } /* end 8 bit/pel print mode */
     }; /* end Print Modes */

Tray Definition Tables

Fill in table for all paper trays supported by all printer models supported in this module. This table is comprised from TRAYINFO structures in the device.h file.

The following is an example of a tray definition table with an "automatic" tray entry:

    TRAYINFO SAMPLE_pTrays[] =
    {
      {
         TRAY_ID_AUTO,         // ulTrayID;
         TRAY_SHEET_FEEDER,    // ulTrayCapability
         DJP_TRY_AUTO,         // ulDJPid; Dynamic Job Property
         TRAY_STRING_AUTO,     // ulNameID;
         "",                   // pszTrayName;
         TRAY_TYPE_AUTO,       // ulTrayType;
         5,                    // ulCmdSelectTray;
         _ESC_ "&l1H",         // szCmdSelectTray;
         0,                    // reserved1
         (PULONG)NULL          // reserved2
      } /* end tray auto */
    } /* end tray table */

Form Definition Tables

Fill in table for all paper sizes supported by all printer models supported in this module. This table is comprised from FORMINFO2 structures in the device.h file.

The following is an example of a form definition table with a "letter" form-size entry:

    FORMINFO2 SAMPPCL_pForms[] =
    {
      {
        FORM_ID_LETTER,             // ulFormID;
        FORM_LETTER,                // ulFormCap;
        DJP_PSI_LETTER,             // ulDJPid;
        FORM_CLASS_SHEET_PAPER,     // ulFormClass;
        FORM_STRING_LETTER,         // ulNameID;
        5,                          // usLenCmdSelectForm;
        { _ESC_ "&l2A" },           // szCmdSelectForm[LEN_CMD];
        {                           // hcInfo
          "",                       // szFormname[32] optional
          US_LETTER_WIDTH,          // cx; (100ths of mm)
          US_LETTER_HEIGHT,         // cy; (100ths of mm)
          630,                      // xLeftClip; (100ths of mm)
          1490,                     // yBottomClip; (100ths of mm)
          US_LETTER_WIDTH-630,      // xRightClip; (100ths of mm)
          US_LETTER_HEIGHT,         // yTopClip; (100ths of mm)
          0,                        // xPels; (pels)
          0,                        // yPels; (pels)
          0                         // flAttributes;
        },
        FALSE                       // bHasBeenSetup;
      } /* end papaer size letter */
    } /* end paper size table */

Note: xPels or yPels are not filled in, in this structure. These values are determined dynamically based on current resolution. HCAPS_SELECTABLE and CURRENT are also determined dynamically from printer and job props.

Media Definition Tables

Fill in table for all Media Types supported by all printer models supported in this module. This table is comprised from MEDIAINFO structures in the device.h file.

The following is an example of a media definition table with a "plain" media-type entry:

     MEDIAINFO SAMPLE_pMedias[] =
     {
       {
         MEDIA_ID_PLAIN,               // ulMediaID;
         MEDIA_TYPE_PLAIN,             // ulMediaCap;
         DJP_MED_PLAIN,                // ulDJPid;
         MEDIA_STRING_PLAIN,           // ulNameID;
         "",                           // szMediaName[LEN_MEDIANAME];
         5,                            // ulCmdSelectMedia
         _ESC_ "&l0M",                 // szMediaTypeCmd;
         FALSE,                        // ulColorAdjustRequired
         HEAVY_ABSORPTION,             // ulAbsorptionAdjust
       }, /* end Plain media */
     } /*end media table */

Feature Support Table

This table indicates whether the core Omni driver should allow the user to add their own trays, paper sizes, fonts and form connections.

If a field is set to TRUE, the Printer Property panels will allow users to define new features of that particular type. If a field is set to FALSE, the Printer Property panel will not allow users to enter new features of that type. A standard way of filling this table in follows:

     FEATUREINFO SAMPLE_Features =
     {
       FALSE,               // bSupUserDefTrays; (no user trays)
       TRUE,                // bSupUserDefForms; (allow user forms/margins)
       FALSE,               // bSupUserDefFonts; (no user fonts)
       TRUE                 // bSupUserDefConnects; (allow user connections)
     }; /* end SAMPPCL_Features */

Form Connection Tables

Fill in table for all Form Connections supported by all printer models supported in this module. These are unique combinations of Tray, Paper Size, and Media type. This table is comprised from FORMCONNECTION structures in the device.h file.

The following is an example of a form connection table with two connection entries. The first connection is comprised of an automatic tray, an A4 form size, and a plain media type. The second connection is comprised of an manual tray, an A4 form size, and a transparency media type.

    FORMCONNECTION SAMPLE_pConnects[] =
    {
      { CONN_ID_1,  TRAY_ID_AUTO,    FORM_ID_A4,  MEDIA_ID_PLAIN   },
      { CONN_ID_2,  TRAY_ID_MANUAL,  FORM_ID_A4,  MEDIA_ID_TRANS   },
    } /* end Form Connection Table */

Command Support Table

This table contains an extensive list of commands typically used by printers. Find the most logical entry for the commands you want to use, and fill them in appropriately.

Note: The Omni core driver does not utilize this table and does not expect any command to be filled in.

Subclassed Function Table

This table should contain the default function the plug-in module will attempt to subclass to generate a print job. Although the Omni driver does not require any function to be subclassed, the Omni core driver default action is to do nothing for these calls.

The core Omni driver will allow you to dynamically modify this table in the "device query" function for printers that require special handling.

The following is an example of a subclassed function table with six functions subclassed. The functions that appear in this table would typically be coded in #Function Section.

     FNSUBCLASS SAMPLE_Subclassed_Functions =
     {
        SampleBeginJob,         // pfnInitJob; -subclassed
        SampleChooseRasterize,  // pfnRasterizeBand; -subclassed
        SampleNewFrame,         // pfnNextPage; -subclassed
        SampleEndJob,           // pfnTermJob; -subclassed
        SampleAbortJob,         // pfnAbortJob; -subclassed
        SampleDeviceQuery,      // pfnDeviceQuery; -subclassed
        NULL,                   // pfnQueryFonts;
        NULL,                   // pfnDeviceOpen;
        NULL,                   // pfnDeviceClose;
        NULL,                   // pfnDeviceWrite;
        NULL,                   // pfnSpoolerOpen;
        NULL,                   // pfnSpoolerStartJob;
        NULL,                   // pfnSpoolerEndJob;
        NULL,                   // pfnSpoolerClose;
     }; /* end Subclassed_Functions */

Supported Features Section

This section defines arrays of feature IDs that reference the feature tables (refer to #Tables Section). Each array is designed around a particular printer model and contains only those feature IDs for the features supported by that particular model.

The feature tables can be thought of as supersets of available features and the arrays as subsets of those supersets. Each array subset defines features for a particular printer model. The types of arrays directly correlate to the following feature tables types:

  • Print Qualities
  • Print Modes
  • Device Fonts
  • Paper Trays
  • Form Sizes
  • Media Types
  • Form Connections

The first value in an array is the default value for device, in case a mismatch or an error occurs.

Devices Section

All the feature arrays that you have defined to describe a particular model will be combined with other information to describe an Omni driver plug-in device. The plug-in device will in turn be combined to define the array of devices that your plug-in module will support.

The structure that needs to be filled in to describe a device is the DEVICEINFO structure defined in the device.h file.

The following is an example of a device array with a single "Sample Printer Model 500" device entry:

 DEVICEINFO SAMPLE_pDevices[] =
 {
   {
     PRN_ID_SAMPLE_500,
     "Sample Printer Model 500",   // pszDeviceName;
     "Sample Printer Model 500",   // pszDeviceDesc;
     "IBM",                        // pszDeviceVendor;
     1,                            // usDeviceMajorVersion;
     0,                            // usDeviceMinorVersion;
     CAPS_TECH_RASTER_PRINTER,     // ulOS2DeviceTechnology;
     OMNI_CAP_MONO,                // ulOmniDeviceTechnology;
     DEV_FUNC_RASTER,              // ulDeviceFunctions;
     RASTER_TOP_TO_BOTTOM,         // Raster info
     DEV_MIRROR,                   // ulDeviceBits;
     SAMPPCL_RLLDELTAROW,          // compression supported
     &SampleMemory,                // pMemory;
     &SAMPLE_Commands,             // pCommands;
     &SAMPLE_Sub_Functions,        // pSubclassedFunctions;
     &SAMPLE_Features,             // pFeatures;
     //----------------------------
     // Feature arrays
     //----------------------------
     SAMPLE_SUPPORTED_RESOLUTIONS, // usNumRes;
     SAMPLE_pulResolutions,        // pulRES;
     0,                            // usNumFonts;
     NULL,                         // pFONTS;
     SAMPLE_SUPPORTED_TRAYS,       // usNumTrays;
     SAMPLE_pulTrays,              // pTRAYS;
     SAMPLE_DEFINED_FORMS,         // ulNumForms;
     SAMPLE_pForms,                // pFORMS;
     SAMPLE_SUPPORTED_MEDIAS,      // ulNumMedias;
     SAMPLE_pulMedias,             // pulMedias;
     NULL,                         // pInkInfo;
     SAMPLE_SUPPORTED_CONNECTIONS, // usNumConnects;
     SAMPLE_pulConnects,           // pConnects;
     SAMPLE_SUPPORTED_PRINT_MODES,
     SAMPLE_pulPrintModes,
     //----------------------------
     // HSV color model modifers
     //----------------------------
     0,                            // ulNumModifiers;
     (PTRIPLETMODIFIERS)NULL,      // pTripletModifiers;
     &SAMPLE_UserData,
     //------------------------------------------------
     // Default Job Property settings for this printer
     // used in User interface (refer to the device.h file
     // for values).
     //------------------------------------------------
     {
        0,                         // cb        ***IGNORED***
        {0},                       // achDriver ***IGNORED***
        0,                         // ulSig     ***IGNORED***
        ORIENTATION_PORTRAIT,      // ulOrientation
        1,                         // cCopies
        CONN_ID_1,                 // ulDefConnID
        CONN_ID_5,                 // ulDefNonMetricConnID;
        0,                         // ulDefFontID
        RES_ID_DRAFT,              // ulDefResID
        PRINT_MODE_ID_COLOR_8BPP   // ulDefPrintModeID
        SAMPPCL_RLLDELTAROW,       // compression supported
        COLOR_BLACK,               // usForeground = COLOR_BACK
        COLOR_WHITE,               // usBackground = COLOR_WHITE
        IMAGE_OPTION_NOMIRROR,     // OR options together
        HT_MAGIC_SQUARES,          // Magic Square halftone as default algorithm
        127,                       // Default for HT_LEVEL HaftTone Algorithm
        0,                         // lHue;    // % deviation along circle
        0,                         // lSaturation;// % deviation along radius
        0,                         // lValue;   // % deviation darkness value
        0,                         // lDarkness;// % deviation darkness value
        FF_CTL_NONE,               // bFFControlType
        0,                         // ulJobPhaseControl
        0L,                        // Gamma Adjustment Red
        0L,                        // Gamma Adjustment Green
        0L,                        // Gamma Adjustment Blue
        0L,                        // Bias of Red Gamma
        0L,                        // Bias of Green Gamma
        0L,                        // Bias of Blue Gamma
        0L,                        // Duplex Options
        0,                         // Black Gamma Adjustment
        0,                         // Bias of Black Gamma
        0,                         // Black Reduction %
     }
   } /* end Sample Printer model 500 */
   , // repeat DEVICEINFO structure to define other printer models

 }; /* end SAMPLE_pDevices block */

Driver Section

The final section of the plug-in module will contain the structure that describes your overall driver. This will include all the feature tables you defined and the array of supported devices (DEVICEINFO structures) you defined.

The DRIVERINFO structure is defined in the file device.h. The following is an example of a driver structure:

 DRIVERINFO pSAMPLEDriver[] =
 {
   {
     "Sample Printer Driver",         // pszDriverName;
     "IBM",                           // pszDriverVendor;
     0x0210,                          // usDriverVersion;
     SAMPLE_DEFINED_RESOLUTIONS,      // usNumRes;
     SAMPLE_pRes,                     // pRES; (Print Mode Table)
     0,                               // usNumFonts;
     NULL,                            // pFONTS; (Font Table)
     SAMPLE_DEFINED_TRAYS,            // usNumTrays;
     SAMPLE_pTrays,                   // pTRAYS; (Tray Table)
     SAMPLE_DEFINED_FORMS,            // usNumForms;
     SAMPLE_pForms,                   // pFORMS; (Form Table)
     SAMPLE_DEFINED_MEDIAS,           // ulNumMedias;
     SAMPLE_pMedias,                  // pMEDIAS; (Media Type Table)
     SAMPLE_DEFINED_CONNECTIONS,      // usNumConnects;
     SAMPLE_pConnects,                // pCONNECTS; (Form Connection Table)
     SAMPLE_DEFINED_PRINT_MODES,      // usNumPrintModes;
     SAMPLE_pPrintModes,              // pPrintModes; (Print Mode Table)
     SAMPLE_SUPPORTED_DEVICES,        // usNumDevices;
     SAMPLE_pDevices,                 // pDEVICES;  (Device Array)
     SAMPLE_pGammas,                  // pGammaTables;
   } /* end logical block */

 }; /* end Driver block */

Preparing Driver for Shipping

You must rename the driver and prepare it for shipping. This helps to ensure that your driver will be unique and not be in conflict with other drivers developed from this same source code. Proceed to the following sections for guidelines.

#Renaming the Driver
#Including Only Your Plug-In Modules
#Changing Global Semaphore Name
#Modify Application Name Used in INI files
#Changing User Interface

Renaming the Driver

To rename the driver, do the following:

  1. In the Omni driver makefile, the MACRO for the driver name is "omni". Change the driver name to the name you want to use. For example, replace DRIVER = OMNI with DRIVER = <your_name>.
    For systems that use FAT file structure, you must use the 8.3 file naming convention.
  2. Rename the files: omni.rc, omni.dlg, omni.ipf to the same name you used in step 1. Leave the renamed files in the same directory in which the original files were found. For example, rename: omni.rc to <your_name>.rc.
  3. Repeat this for omni.dlg and omni.ipf.

Including Only Your Plug-In Modules

The Omni driver can include plug-in modules for all the printers and languages you want it to support. To limit those plug-in modules to just the ones you need for supporting your printers, modify the #include lines in the Omni core file driver.c. as follows:

1.Look for the following lines at the top of the driver.c. file.
  #else  // this is a DDKBLD
    #include "devices\samp_pcl.c"
    #include "devices\samp_eps.c"
    #include "devices\tiff.c"          // TIFFDEVICE
  #endif
2.Change the #include lines between the #else and #endif bracket to include only those plug-in files you have written and want to ship in your driver.

Changing Global Semaphore Name

The Omni driver utilizes a named global semaphore that should remain unique within the operating system. If you do not change this semaphore name, the drivers can attempt to use the same semaphore name at the same time which will lock (deadlock) the operating system. The printer driver is a "trusted" extension of the base operating system and should behave with multi- tasking in mind.

To change the Omni driver's global semaphore name, do the following:

1.Look for the following lines in the driver.c file that define Omni's global data:
      GLOBALS  globals =
      {
        0L,
        (HMODULE) 0,                    // supplied on first load in INITTERM.C
        ....,
      #ifndef DDKBLD
        "\\SEM32\\OMNI\\GLOBAL\\SEM",   // pointer to string containing the name
                                        // of the global sem (OMNI)
      #else
        "\\SEM32\\SAMP\\GLOBAL\\SEM",   // pointer to string containing the name
      #endif                            // of the global sem (DDK)

      };
2.Replace the line between the #else and the #endif line with a semaphore name that will be unique to your driver. The easiest do this is to replace the portion of the name that reads "SAMP" with the name of your new driver.

Modify Application Name Used in INI files

The Omni driver stores user defined features and printer properties in a named location in the OS/2 system INI file. You must change the name of this location, as follows, to avoid conflicts with the Omni driver.

1.In the file driver.h, look for the following lines:
       #ifndef DDKBLD
       #define APPNAME_DEBUGINFO         "OmniDriver"
       #else
       #define APPNAME_DEBUGINFO         "SampDriver"
       #endif
2.Replace the name "SampDriver" with the name you want information to be stored under in the OS/2 system INI file for your driver.
3.In the file driver.h, look for the following lines:
         #else // this is a DDKBLD
         PDRIVERINFO Drivers[]  = {
            pSAMPPCLDriver     ,
            pSAMPEPSONDriver   ,
            pTIFFDriver        ,
         };
         #endif
4.Replace the DRIVERINFO pointers, such as pSAMPPCLDriver and pSAMPEPSDriver, to include only the pointer to the DRIVERINFO structure you declared in your plug-in module.

Changing User Interface

The Omni driver has a generic user-interface, stringtable, and help panels that can be modified to better represent your driver.

Many hardware companies choose to (and can) modify the user interface to appear the same as that user interface may appear on other operating system platforms. Also, many companies wish to add their corporate logos to many of the printer panels for brand recognition. The names of particular printer model features and options may not appear in the Omni driver stringtable and can be customized with new strings. Often copyrighted names are added when modifying the driver.

It is beneficial to use the original Omni driver files, omni.rc, omni.dlg, and omni.ipf, because IBM has translated these files into 13 or more country-specific languages, and these files are available to you through the Driver Development Support Center (DDSC) and the DUDE bulletin board system.