## Presentation Device Driver Reference for OS/2

[prev][next][parent][TOC]

### GreSetScreenBits - Remarks

It is permissible to implement this function by returning 0 to indicate that the bits were not saved and, therefore, must be saved by the calling routine.

GreSetScreenBits calls EnterDriver and performs some initial error tests, checking the FunN field and the DC type, as follows:

If the COM_PATH or the COM_AREA flags are set in FunN, the function logs PMERR_INV_IN_PATH or PMERR_INV_IN_AREA, respectively, and returns 0 (zero).

If the DC is not a direct DC, the PMERR_INV_DC_TYPE error is logged and the call returns 0 (zero).

If a bit map is not selected in the DC, the PMERR_BITMAP_NOT_SELECTED error is logged and the call returns 0 (zero).

Next, the data length is checked to see if it is at least the size of the header and that the passed data length matches the data length given in the packet header. If the data lengths do not match, the PMERR_INV_LENGTH_OR_ COUNT error is logged and the call returns 0 (zero).

GreSetScreenBits also checks that the coupling local format and received data format are valid. This is done by creating a word containing the internal (screen) format and the external (data received) format. The AGSBValidDataFormats table is scanned for a match. This table is an array of valid source and destination format pairs, as defined in the VALID_DATA_ FORMATS data structure. See VALID_DATA_FORMATS in Data Types for details on this data structure.

If a match is found, the format is valid. Otherwise, the format is invalid, the PMERR_INCOMPAT_COLOR_FORMAT error is logged and the call returns 0. If conversion is required for the pair, the pointer to the compression function for the required format combination is retrieved from the aGSBValidDataFormats structure, and the corresponding routine is called to create the conversion table. The creation calls for the conversion table of valid format pairs; all of them are defined in DCAFCNVT.C:

CreateConvertTable_4ext_4int creates a 256-entry table of bytes to convert 4bpp external (default VGA) format to 4bpp internal (fudged).

Pels are converted a pair at a time, which is why the conversion table is 256 entries, rather than the expected 16. To do this, after the memory allocation, the NearestRestrictedColourIndex (in CONVINT.C) is called, in order to map the entries in the VGA default table (see the appendix regarding default color palettes in the IBM OS/2 Display Device Driver Reference) to the nearest entry in the Reduced16DeviceDefaultPalette table (the 16-entry XGA default palette defined in EDDDATA.C).

The remaining values in the internal table are obtained by combining pairs of conversion values, in the following way:

              for (i = 0; i < 256; i++)

              {

                   pConvertTable[i] = (abLocalConvertTable[i >> 4] << 4) |

                                      (abLocalConvertTable[i & 0x0F]) ; }

CreateConvertTable_4ext_8int creates a 16-entry table of bytes to convert 4bpp to 8bpp.

After the memory allocation, the NearestRestrictedColourIndex (in CONVINT.C ) is called, in order to map the entries in the standard VGA table (see the appendix regarding default color palettes in the IBM OS/2 Display Device Driver Reference) to the nearest entry in the FullSizeDeviceDefaultPalette (the 256-entry XGA default palette defined in EDDDATA.C).

CreateConvertTable_4ext_16int creates a 16-entry table of words to convert 4bpp to 16bpp.

After the memory allocation, the RGB16FromPRGB2 (macro in CONVFUNS.H) is used to transform the VGA standard palette to 16 bpp values. Note that the VGA standard palette is in RGB2 format (see the appendix regarding default color palettes in the IBM OS/2 Display Device Driver Reference for details of these formats).

The entries are returned in Intel format, as follows:

                   Bit7..Bit 0   Bit15..Bit8

                     BYTE 0        BYTE 1

and then must be converted to Motorola format, as follows:

                   Bit15...Bit8   Bit7..Bit0

                      BYTE 0        BYTE 1

CreateConvertTable_8ext_16int creates a 256-entry table of words to convert 8bpp external to 16bpp internal.

After the memory allocation, the RGB16FromPRGB2 (macro in CONVFUNS.H) is used in order to transform the XGA device standard palette FullSizeDeviceDefaultPalette to 16 bpp values. The entries are returned in Intel format and must then be converted to Motorola format.

Next, WaitForRealHWFunction in HWACCESS.ASM is called to ensure that the hardware is ready before using the PHUNK buffers.

At this point, the main loop starts:

    : for next byte in the input buffer < last buffer in the input buffer

    : : check that the next rectangle in the buffer is valid; otherwise, log PMERR_INV_RECT and return 0.

    : : calculate some data on the current rectangle (number of row, bytes per row, etc)

    : : if source data is with 8-bit data fields

    : : // expand the rectangle and return the pointer to the next rectangle in the input buffer

    : : : call ExpandRect8

    : : otherwise // source data is with 16-bit data fields

    : : // expand the rectangle and return the pointer to the next rectangle in the input buffer

    : : : call ExpandRect16

    : : endif

    : : subtract the just decompressed rectangle from the passed region using

        GreCombineRectRegion (CRGN_DIFF)

    : endfor

    return 1

At the end, ExitDriver is called and a return code of 1 is issued.

The ExpandRect8 and ExpandRect16 calls (in EXPAND.ASM) perform the decompression of the data and, if the internal display driver format is different from the data format, the conversion of the data takes place. The following routines (in DCAFCNV.ASM and EXPAND.ASM) are used:

              convert_row_4pl_4pk           (scr 4bpp planar, dst  4bpp packed)

                                                        changes only the planes to linear

              convert_row_4pl_4pkint        (src 4bpp planar, dst  4bpp packed)

                                                        calling: convert_row_4pl_4pk;

                                                                   convert_row_4pk_16pk

              convert_row_4pl_8pk           (scr 4bpp planar, dst  8bpp packed)

                                                        calling: convert_row_4pl_4pk;

                                                                   convert_row_4pkt_8pk

              convert_row_4pl_16pk          (scr 4bpp planar, dst 16bpp packed)

                                                         calling: convert_row_4pl_4pk;

                                                                   convert_row_4pkext_4pkint

              convert_row_4pkext_4pkint     (scr 4bpp packed, dst  4bpp packed)

                                                         using ConvertTable_4ext_4int

              convert_row_4pk_8pk           (scr 4bpp packed, dst  8bpp packed)

                                                         using ConvertTable_4ext_8int

              convert_row_4pk_16pk          (scr 4bpp packed, dst 16bpp packed)

                                                         using ConvertTable_4ext_16int

              convert_row_8pk_16pk          (scr 8bpp packed, dst 16bpp packed)

                                                         using ConvertTable_8ext_16int

Conversion between different data formats (for example, 4bpp and 8bpp) is done independently from the data expansion. That is, if the source and destination formats differ, the source data is first expanded (in a intermediate buffer), and then converted to the destination format. If the source and destination formats match, the data is decompressed directly from the source buffer to the destination internal bitmap. As in GreGetScreenBits, the data conversion routines use tables wherever possible to improve performance (see Converting Data in Code Modifications Required in Base Driver for DCAF for more information).