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:
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:
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]) ; }
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).
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
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).