:H2. 32-bit Omni Presentation Driver (OS/2 Warp GA v3.0)
     ===============================

The Omni driver is a 32-bit raster graphics driver that was developed
in conjunction with OS/2 Warp Graphics Engine and The Generic Printer
Library to provide a complete solution for Independent Hardware/Software
Suppliers to easily create raster OS/2 Printer Drivers.

The Omni driver code consists of two major functional groupings.
The first, is a generic, "core" set of functions that are typical
to most OS/2 Presentation Device Drivers.

   These "core " functions include Managing:

          @Printer Driver Enabling/Disabling
          @Device Context (DC) Initialization
          @Job and Printer Property User-Interface

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

   These "plug-in" functions include:

            @Device Query
            @Job Initialization
            @Page/Band Rasterization
            @Job Pagination
            @Job Termination
            @Job Abort

   These "plug-in" tables include:

            @Supported Trays
            @Supported Paper Sizes
            @Supported Media Types
            @Supported Resolutions
            @Supported Print Modes
             (i.e. 1,8,24-bit image formats)

Development time of "plug-in" modules will vary based upon printer
language demands and developer experience.  However, as a gauge of
how simple adding a device is, we have witnessed addition of printer
models that utilize popular languages to be completed in as little
as a few hours.

Of course, the development time increases proportionally with
the need for customizing and extending the driver and user-interface.
Common examples include modifying user-interface to match what
is shown by a manufacturer on other operating system platforms, and
adding support for device or downloadable fonts.

The "plug-in" module can elect to "hook out" and provide many
more functions to get the level of control desired to best
utilize the printer through its native language and capabilities.

Examples of optionally hooked functions include:

            @Subclass all spooler calls (Spl calls)
            @Subclass all Port Driver calls (Prt calls)

NOTE: Nothing precludes a developer from modifying the "core" Omni
      code if they need to, to achieve better support for their device.
      The separation of the Omni code into "core" and "plug-in" is
      to help simplify a developers initial attempts at creating an
      OS/2 raster printer driver.


:H3. 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 in developing
     32-bit printer presentation drivers.

     The Omni driver is important in that it 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 in developing any
     32-bit OS/2 Printer Presentation Driver using GenPLib.

     For further information about the Generic Printer Libaray, see >>>link GENPLIB<<<

     NOTE: All code samples for GenPLib subroutines are direct excerpt from the
     Omni driver source code.

:H3. Building the Omni Driver
     ========================

Refer to "Using Your DDK" for a roadmap of the file structure used
by the Omni Driver.

  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

:H3. Adding a device
     ===============

Adding a new device that uses one of the printer languages supported by
any of the sample "plug-in" modules is very easy.  We'll take you through
the sections in the "plug-in" modules that you will want to modify for
your specific printer.

First, change to the directory where the Omni driver source code is located
(refer to to "Using Your DDK" for file locations if necessary).
All code in the directory "omni" is considered the "core" Omni driver code.

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

These are the sample "plug-in" modules 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" and so the finished driver currently consists of only the
file "omni.drv".

:H3. Modifying "Plug-in" modules
     ===========================

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

     Some sections of a "plug-in" module are typically seen in every
     "plug-in" module written.

     These sections are:

>>>>>Feature ID Section
     ------------------

     This section contains all the unique IDs that will be used to
     reference unique printer models and specific features of
     individual printer models.

     Please note that different printer models can reference the
     same ID if they have the same capability.  This is often true
     when a "printer family" exists and all printers in the family
     support the same paper sizes, trays etc.

     Printer Model IDs
     -----------------
         Assign a new unique internal model ID for every new printer added

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

     Print Qualitiy IDs
     ------------------
         Assign a new unique internal Print Quality ID for each quality
         setting available on your printer models.

         A unique print quality typically corresponds to each setting your
         printer allows to control the # print head passes per scanline
         (e.g. draft, letter quality, fine) and for each resolution supported).

         Example:  #define RES_ID_DRAFT             0
                   #define RES_ID_NORMAL            1
                   #define RES_ID_PRESENTATION      2

     Print Mode IDs
     --------------
         Assign a new unique internal Print Mode ID for each
         bitmap format you want to support on your printer using
         your rendering software or the ones provided in GenPLib.

         Note: Available formats that work on OS/2 Warp include:
          8 bit/pel logical on a  1 bit/pel physical bitmap (256 grayscale)
          8 bit/pel logical on a  8 bit/pel physical bitmap (256 color)
         24 bit/pel logical on a 24 bit/pel physical bitmap (16.7 million color)

         Example:  #define PRINT_MODE_ID_MONOCHROME      0
                   #define PRINT_MODE_ID_COLOR_8_BPP     1
                   #define PRINT_MODE_ID_COLOR_24_BPP    2

     Device Font IDs
     ---------------
         The implementation of device fonts is not yet complete, but you
         may see the currently planned implementation 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.

         Example:  #define TRAY_ID_SHEET_FEEDER     0
                   #define TRAY_ID_ENVELOPE         1
                   #define TRAY_ID_AUTO             2
                   #define TRAY_ID_MANUAL           3

     Form Size IDs
     -------------
          Assign a unique ID for each unique paper size supported by your printer
          models.

          NOTE: You can have multiple form definitions for the same paper size.
          For example, three Form size IDs can exist for one paper size like
          "Letter" each with different margins.

          This is because different printer models within a printer family
          may have different margins for the same paper size.

          There may even be different margins used on one form size
          "Letter" within the same printer model depending on which
          tray or printhead is being used.

          Example:   #define FORM_ID_LETTER           0
                     #define FORM_ID_LEGAL            1
                     #define FORM_ID_A4               2
                     #define FORM_ID_C10_ENVELOPE     3
                     #define FORM_ID_LETTER_2         4

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

          Example:  #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 new unique internal Form Connection ID for each different
        combination of "Tray", "Form", and "Media Type" a user can select

        NOTE: Not every permutation need be displayed since the user can
        define uncommon combinations from the Omni's Printer Property panels.

        Example: #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

      !!Warning about Feature IDs: !!
      -------------------------------

      1)     These IDs should NEVER be changed once added and shipped with
             a printer or cross-network printing could fail (i.e. a newer
             and older driver need to communicate data across network).

      2)     Each group of IDs should have the default option for the
             group assigned the ID == 0 (zero).  This helps the core
             driver fail invalid IDs and pick 0 (zero) as a default
             fallback in an emergency.

>>>>>Device Handle Section
     ---------------------
     The device handle is simply 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 a useful place to put state data and variables that are
     re-used by the plug-in module during rendereing a print job

     NOTE: A standard practice is that the first field in
           the structure contain the "count of bytes" of the
           entire structure and the second field contain a
           4 character unique signature to uniquely identify
           the structure from other similar structures in memory.

     Example:  #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 simply contains all prototypes and functions used
     by the "plug-in" module either for private use or to be placed
     in the function hook table.

>>>>>Tables Section
     --------------

     This is the section where you fill out tables that represent
     the features available on your printer models.  There exists a
     table for each of the "Feature ID" types listed above and there
     will be a unique entry in a table for each "Feature ID" declared.

      Note: the structures that define a feature, such as a paper size or
      tray are all defined in the "core" Omni driver in the file "device.h"

     These tables are:

     PRINT QUALITY TABLE (RESINFO structure)
     -------------------
     Fill in table for all Print qualities supported by all printer
     models supported in this module.

     This table is comprised from RESINFO structures in device.h

     Example:

     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 device.h

     Example:

     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 device.h

    Example:

    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 device.h

    NOTE : We do not fill in xPels or yPels in this structure
           but determine this value dynamically based on
           current resolution
           also HCAPS_SELECTABLE and CURRENT are determined from
           printer and job props dynamically as well

    Example:

    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 */

    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 device.h

     Example:

     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
     ---------------
     This table indicates whether the "core" omni driver should allow
     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 FALSE
     is set the Printer Property panel will not allow users to enter
     new features of that type.

     Example:

     // a standard way of filling this in is as 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.  Remember these are unique
    combinations of Tray, Paper Size, and Media type.

    This table is comprised from FORMCONNECTION structures in device.h

    Example:

    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.  Fill the table in with those commands you wish to
     use in the most logical entry for them.

     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 defualt function the "plug-in"
     module wishes to subclass to generate a print job.

     The Omni driver does not require any function to be subclassed;
     however, the omni "core" driver's default action is to do
     nothing for these calls.

     NOTE: The "core" Omni driver will allow you to dynamically
           modify this table in the "Device Query" function for
           printers that require special handling.

     Example:

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

>>>>>Supported Features Section
     --------------------------
     This section will define arrays of Feature IDs that will reference the
     Feature Tables defined above.  Each array will be designed around a
     particular printer model and only contain those feature IDs for
     the features that particular model actually supports.

     Think of the feature tables as "supersets" of available features
     and these arrays as "subsets" of those supersets.  Each subset (array)
     defines features for a particaular printer model.

     The types of arrays directly correlate to the feature tables types:

            PRINT QUALITIES
            PRINT MODES
            DEVICE FONTS
            PAPER TRAYS
            FORM SIZES
            MEDIA TYPES
            FORM CONNECTIONS

    NOTE: first value in array is default value for device in case
          a mismatch or error occurs.

>>>>Devices Section
    ---------------

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

    Example:

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

    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
        //------------------------------------------------
        {
           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,          // Half Tone Snap as default
           127,                       // Default 127 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 contains the
    structure which describe your overall driver.  This will
    include all the feature tables you defined and the array
    of supported devices (DEVICEINFO structures) you defined.

    Example:

    The DRIVERINFO structure is defined in the file "device.h"
    and be filled in like this:

     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 */




:H3. Preparing Driver for Shipping
     =============================

     There are a few things that must be done to rename the driver
     and prepare it for shipping.   These steps help make sure that
     your driver will be unique and not be in conflict with other
     drivers developed from this same source code.

     Renaming the driver
     -------------------
     1) Change the Omni driver makefile so that the
        MACRO for the driver's name is the name you want instead
        of the name "omni".

        Example:

        replace:   DRIVER = OMNI
        to:        DRIVER = <fill your name in here>

        NOTE: keep driver name to 8 characters or less to work
        on systems that utilize the FAT file structure.

     2) Rename the files: omni.rc, omni.dlg, omni.ipf
        to be the same name as you filled in the makefile
        in step 1).  Leave the renamed files in the same directory
        which the original files were found.

        Example:

        rename: omni.rc
        to:     <myname>.rc

        NOTE: repeat this for omni.dlg and omni.ipf.

     Including only your "plug-in" modules
     --------------------------------------

     The Omni driver can include many "plug-in" modules for all the
     printers and languages it wishes to support.  To limit those
     "plug-in" modules to just the ones you need for supporting your
     printers simply modify the #include lines in the omni "core" file
     "driver.c"

     Example:

     Look for the following lines at the top of "driver.c":

      #else  // this is a DDKBLD
        #include "devices\samp_pcl.c"
        #include "devices\samp_eps.c"
        #include "devices\tiff.c"          // TIFFDEVICE
      #endif

     Change the #include lines between the #else and #endif bracket
     to only include those "plug-in" files you have written and wish 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.  Failure to change this semaphore
     name can lead to the drivers using the same semaphore name at the same
     time to 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 look for the
     following lines in "driver.c" 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 of the global sem (DDK)
      #endif

      };

      replace the line between the #else and the #endif line to be a
      semaphore name that will be unique to your driver.  The easiest
      way to do this is to change the portion of the name that reads
      "SAMP" to be 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 to avoid conflicts
     with the Omni driver.

     Example:

     1) In the file "driver.h" look for the lines that look like this

        #ifndef DDKBLD
        #define APPNAME_DEBUGINFO         "OmniDriver"
        #else
        #define APPNAME_DEBUGINFO         "SampDriver"
        #endif

        replace the name "SampDriver" with the name you wish information
        to be stored under in the OS/2 system INI file for your driver.

     2) In the same file "driver.h" look for the lines that look like this:

         #else // this is a DDKBLD
         PDRIVERINFO Drivers[]  = {
            pSAMPPCLDriver     ,
            pSAMPEPSONDriver   ,
            pTIFFDriver        ,
         };
         #endif

         replace the DRIVERINFO pointers (i.e. pSAMPPCLDriver, pSAMPEPSDriver)
         to only include 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, 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.

         NOTE: There is a benefit to attempting to utilize as much of the
         original Omni driver translatable files (i.e. omni.rc, omni.dlg,
         and omni.ipf).  This is because IBM has these files translated to
         some 13 or more country-specific languages and these files can
         be made available to you through the OS/2 Developer Support.



