/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/**********************************************************************/
/*                                                                    */
/*   Description     = DCAF related definitions                       */
/*                                                                    */
/*   Function        =                                                */
/*                                                                    */
/*   Reference       = Device Driver Interface Specification          */
/*                                                                    */
/*                                                                    */
/**********************************************************************/

#define MAXULONG 0xFFFFFFFF

/**********************************************************************/
/* Driver internal definitions.                                       */
/**********************************************************************/
#ifdef NRECT
/**********************************************************************/
/* NRECT was set on the command line, so use the passed value.        */
/**********************************************************************/
/* XLATOFF */
#define MAX_SCA_RECTS NRECT
/* XLATON */
/* ASM
% MAX_SCA_RECTS equ NRECT
*/
#else ; NRECT
/**********************************************************************/
/* NRECT was not set on the command line, so use default values.      */
/**********************************************************************/
#define MAX_SCA_RECTS 14
#endif ; NRECT


/**********************************************************************/
/* It would be logical to combine each rectangle's coords and size    */
/* together in a single structure, and to have an array of these      */
/* structures.                                                        */
/* However, when passing the rectangles back to the Engine region     */
/* handling code it is more efficient if they are all stored together.*/
/* We therefore maintain two separate arrays for the rectangles and   */
/* their sizes.                                                       */
/**********************************************************************/
typedef struct _SCA { /* sca */
    struct _SCA FAR *   pscaNext;               /* Linked list pointer    */
    ULONG               cRects;                 /* No. rects in area      */
    RECTL               arcl[MAX_SCA_RECTS+1];
    ULONG               aulRectSize[MAX_SCA_RECTS+1];
} SCA;

typedef SCA FAR * PSCA;

/**********************************************************************/
/* Function prototypes.                                               */
/**********************************************************************/
DDIENTRY GetScreenBits( HDC     hdc,
                        HRGN    hrgn,
                        PBYTE   pbuffer,
                        PULONG  pulLength,
                        ULONG   flCmd,
                        PDC     pdcArg,
                        ULONG   FunN );

DDIENTRY SetScreenBits( HDC     hdc,
                        PBYTE   pbuffer,
                        ULONG   cbytes,
                        HRGN    hrgn,
                        PDC     pdcArg,
                        ULONG   FunN );

DDIENTRY OpenScreenChangeArea( HDC       hdc,
                               PDC       pdcArg,
                               ULONG     FunN );

DDIENTRY GetScreenChangeArea( HDC        hdc,
                              HSCA       hsca,
                              PHRGN      phrgn,
                              PDC        pdcArg,
                              ULONG      FunN );

DDIENTRY CloseScreenChangeArea( HDC      hdc,
                                HSCA     hsca,
                                PDC      pdcArg,
                                ULONG    FunN );

#ifdef DCAFTEST
#define DEVESC_DCAF_OSCA 0xDCAF
#define DEVESC_DCAF_GSCA 0xDCAE
#define DEVESC_DCAF_CSCA 0xDCAD
#define DEVESC_DCAF_ON   0xDCAC
#define DEVESC_DCAF_OFF  0xDCAB
#define DEVESC_DCAF_GSB  0xDCAA
#define DEVESC_DCAF_SSB  0xDCA9
#endif /* DCAFTEST */

/**********************************************************************/
/* Compression data structures.                                       */
/**********************************************************************/

/**********************************************************************/
/* Define the format of the compressed data                           */
/**********************************************************************/
typedef struct _PACKETHDR { /* phd */
    ULONG   ulLength;       /* Length of data (including header)   */
    USHORT  usFormat;       /* Format of data. This specifies      */
                            /* bpp and planar/packed format.       */
                            /* Use the following constants:        */
                            /*  GSB_OPT_4BPP                       */
                            /*  GSB_OPT_8BPP                       */
                            /*  GSB_OPT_16BPP                      */
                            /*  GSB_OPT_LINEAR                     */
                            /*  GSB_OPT_PLANAR                     */
} PACKETHDR;

typedef PACKETHDR FAR * PPACKETHDR;


/**********************************************************************/
/* Constants used within data runs                                    */
/**********************************************************************/
#define CD_MAX_8BIT_RUN_LENGTH          0x7F
#define CD_NON_REPEATING_DATA_FLAG_8    0x80
#define CD_NON_REPEATING_DATA_FLAG_16   0x8000

/**********************************************************************/
/* Define the maximum resolutions for the various adapters, plus the  */
/* maximum scanline lengths (in bytes).                               */
/**********************************************************************/
#define MAX_X_RESOLUTION       1024

/* 16bpp maximum -> 2 bytes per pel */
#define MAX_SCANLINE_BYTES     (MAX_X_RESOLUTION*2)

/**********************************************************************/
/* The following definitions are placed here so that there is a       */
/* single include file for a all DCAF related things.                 */
/**********************************************************************/
/**********************************************************************/
/* Calculate the worst case row length.                               */
/*                                                                    */
/* Repeating data never expands the data size. The worst case is when */
/* there are only two repeating fields which results in the data      */
/* remaining the same size (one length field and one data field).     */
/*                                                                    */
/* Non-repeating data always expands the "run" by one data field i.e. */
/* the length field in addition to all of the data fields.            */
/*                                                                    */
/* Our compression algorithm ensures that after a non-repeating data  */
/* cell there is a repeating data cell representing at least 3        */
/* data cells, which compresses the data by at least one field and    */
/* therefore at least cancels out the non-repeating data's header.    */
/*                                                                    */
/* The worst case is therefore when there is a non-repeating data     */
/* cell at the end of a row which has no "cancelling" repeating data  */
/* cell, and there has been no compression in the remainder of the    */
/* row.  The simplest case of this is when the whole row is           */
/* non-repeating data.  This will increase the size of the data by    */
/* one data field (the header).                                       */
/*                                                                    */
/* The worst case data increase therefore appears to be one data      */
/* field, and this is the case when using 16-bit data fields.         */
/*                                                                    */
/* When using 8-bit data fields (at 4bpp), run-lengths are limited to */
/* a maximum of 127.  A full-width row may be up to 1024 pels wide,   */
/* requiring multiple data cells.  The worst case data increase is    */
/* therefore one data field for each maximum length run in a maximum  */
/* length row.                                                        */
/*                                                                    */
/* This currently works out to (for XGA - the worst case):            */
/*      roundup(1024/127) = 9 bytes                                   */
/*                                                                    */
/* As this is only a very small overhead, we will always use this     */
/* value as our worst case row expansion.  i.e.  even if using 16-bit */
/* data fields, when the worst case row expansion is 2 bytes, we will */
/* not waste time trying to work out whether we should use the lower  */
/* value.                                                             */
/*                                                                    */
/* Except...On a planar system each plane could increase by this      */
/* amount and so VGA will have a 4 times higher values than the       */
/* others.                                                            */
/**********************************************************************/

#define WORST_CASE_PLANE_EXPAND \
((MAX_X_RESOLUTION+CD_MAX_8BIT_RUN_LENGTH-1)/CD_MAX_8BIT_RUN_LENGTH)

#if _VGA
#define WORST_CASE_ROW_EXPANSION (4 * WORST_CASE_PLANE_EXPAND)
#else
#define WORST_CASE_ROW_EXPANSION WORST_CASE_PLANE_EXPAND
#endif

#define WORST_CASE_ROW_LENGTH (MAX_SCANLINE_BYTES+WORST_CASE_ROW_EXPANSION)

/**********************************************************************/
/* Define the minimum buffer size that we can be passed.              */
/* This is the sum of:                                                */
/*   - sizeof(data header)                                            */
/*   - sizeof(rectangle header)                                       */
/*   - sizeof(worst case row length)                                  */
/**********************************************************************/
#define MIN_BUFFER_SIZE \
(sizeof(PACKETHDR) + sizeof(RECTS) + WORST_CASE_ROW_LENGTH)

/**********************************************************************/
/* Define all of the possible GSB_OPT flags.                          */
/**********************************************************************/
#ifdef S3
    #define GSB_OPT_FLAGS \
     (GSB_OPT_4BPP | GSB_OPT_8BPP | GSB_OPT_16BPP | GSB_OPT_24BPP | \
      GSB_OPT_LINEAR | GSB_OPT_PLANAR | \
      GSB_OPT_HRGN)
#else
    #define GSB_OPT_FLAGS \
     (GSB_OPT_4BPP | GSB_OPT_8BPP | GSB_OPT_16BPP | \
      GSB_OPT_LINEAR | GSB_OPT_PLANAR | \
      GSB_OPT_HRGN)
#endif

/**********************************************************************/
/* Define all of the possible GSB_ format flags.                      */
/**********************************************************************/
#ifdef S3
    #define GSB_FORMAT_FLAGS \
     (GSB_OPT_4BPP | GSB_OPT_8BPP | GSB_OPT_16BPP | GSB_OPT_24BPP | \
      GSB_OPT_LINEAR | GSB_OPT_PLANAR)
#else
    #define GSB_FORMAT_FLAGS \
     (GSB_OPT_4BPP | GSB_OPT_8BPP | GSB_OPT_16BPP | \
      GSB_OPT_LINEAR | GSB_OPT_PLANAR)
#endif

/**********************************************************************/
/* Define all of the possible GSB_ bpp flags.                         */
/**********************************************************************/
#ifdef S3
    #define GSB_BPP_FLAGS \
     (GSB_OPT_4BPP | GSB_OPT_8BPP | GSB_OPT_16BPP | GSB_OPT_24BPP)
#else
    #define GSB_BPP_FLAGS \
     (GSB_OPT_4BPP | GSB_OPT_8BPP | GSB_OPT_16BPP)
#endif

/**********************************************************************/
/* Define some constants for the supported bpp values.                */
/**********************************************************************/
    #define GSB_4BPP_PLANAR  (GSB_OPT_4BPP | GSB_OPT_PLANAR)
    #define GSB_4BPP_LINEAR  (GSB_OPT_4BPP | GSB_OPT_LINEAR)
    #define GSB_8BPP_LINEAR  (GSB_OPT_8BPP | GSB_OPT_LINEAR)
    #define GSB_16BPP_LINEAR (GSB_OPT_16BPP | GSB_OPT_LINEAR)
#ifdef S3
    #define GSB_24BPP_LINEAR (GSB_OPT_24BPP | GSB_OPT_LINEAR)
#endif

/**********************************************************************/
/* Define return codes for compression function CompressScreenBits.   */
/**********************************************************************/
#define RC_COMPRESS_ERROR             0
#define RC_COMPRESS_OK_COMPLETED      1
#define RC_COMPRESS_OK_UNCOMPLETED    2
#define RC_COMPRESS_OK_NULL_REGION    3

/**********************************************************************/
/* Define a structure that we use in tables that define valid         */
/* src and dest formats, whether conversion is required etc.          */
/**********************************************************************/
typedef struct _VALID_DATA_FORMATS
{
    ULONG   ulSrcDstFormat;             // Combined src + dst codes
    PFN     pfnRowConversionRoutine;    // NULL->No conversion required
    PBYTE  *ppConvertTable;             // NULL->No conversion table required
    PFN     pfnCreateConvertTable;
} VALID_DATA_FORMATS;
