Jump to content

GreSetScreenBits

From EDM2

GreSetScreenBits takes compressed data, generated by a previous call to GreGetScreenBits, from a buffer and decompresses it into the currently selected memory bit map. The call is only valid for a memory DC that has a bit map selected that is the same size as the screen of the machine on which the GreGetScreenBits call was performed. There is no clipping; if a rectangle exceeds the bit-map dimensions, the function will terminate immediately with an error logged. The bit map may be left in a partially drawn state as prior rectangles may have been copied into it.

This is a drawing primitive; therefore, correlation, boundary accumulation and drawing could take place. Function bits are ignored, however, and only drawing will be done.

The function may be passed a region handle, in which case the area defined by the set bits will be added to the region.

The DCAF-enabled driver may be passed 4bpp planar, 4bpp packed, 8bpp packed and 16bpp packed data.

Simulation support
This function is mandatory for display drivers that want to be DCAF-enabled.

Syntax

GreSetScreenBits(hdc, pBuffer, cBytes, hrgn, pdcArg, FunN)

Parameters

hdc (HDC) - input
Any valid, direct (screen) device context handle.
The valid handle must have selected into it a bit map the same size as the screen from which the source data was read.
pBuffer (PBYTE) - input
Pointer to source (compressed) data.
Pointer to the memory buffer where the source data is located.
cBytes (ULONG) - input
Length of the memory buffer pointed to by pBuffer.
This must be the same value as that returned by the corresponding GreGetScreenBits call.
hrgn (HRGN) - input
A valid region handle.
The area that is updated in the memory bit map by this call is added to the region identified by this handle.
pdcArg (PDC) - input
Pointer to instance data.
FunN (ULONG) - input
High-order word=Flags; Low-order word=NGreSetScreenBits.

Return Code

rc (LONG) - returns
This function returns one of the following:
  • 1 The supplied data is successfully decompressed in the memory bit map.
  • 0 An error occurred.
Possible Errors Detected: When an error is detected, the handling routine must call WinSetErrorInfo to post the condition. Error codes for conditions that the handling routine is expected to check include:
  • PMERR_BITMAP_NOT_SELECTED
  • PMERR_INCOMPAT_COLOR_FORMAT
  • PMERR_INV_DC_TYPE
  • PMERR_INV_IMAGE_DIMENSION
  • PMERR_INV_IN_AREA
  • PMERR_INV_IN_PATH
  • PMERR_INV_LENGTH_OR_COUNT
  • PMERR_INV_RECT
Refer to the "Error Explanations" section in the Presentation Manager Programming Reference for further explanation.

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).

Declaration

#define INCL_GRE_SCREEN
#include <os2.h>
#include <pmddi.h>

HDC      hdc;      /*  Any valid, direct (screen) device context handle. */
PBYTE    pBuffer;  /*  Pointer to source (compressed) data. */
ULONG    cBytes;   /*  Length of the memory buffer pointed to by pBuffer. */
HRGN     hrgn;     /*  A valid region handle. */
PDC      pdcArg;   /*  Pointer to instance data. */
ULONG    FunN;     /*  High-order word=Flags; Low-order word=NGreSetScreenBits. */
LONG     rc;

rc = GreSetScreenBits(hdc, pBuffer, cBytes, hrgn, pdcArg, FunN);