DDDR/2 - Distributed Console Access Facility (DCAF)

This chapter explains, in addition to the fundamentals of the Distributed Console Access Facility (DCAF), DCAF environment and its various components. It is important to understand this information if you are installing DCAF.

The IBM Distributed Console Access Facility (DCAF) product provides a remote console function that allows one programmable workstation, called a controlling workstation, to control the keyboard and mouse input and monitor the display output of another programmable workstation, called a target workstation.

Operating States
The DCAF product has two main operating states: monitoring and active.

Monitoring State
When the DCAF session is in the monitoring state, the controlling-workstation user (hereafter referred to as the controller) sees a screen image of the target workstation's display. The target workstation user (hereafter referred to as the target user) has complete control of the target workstation operations.

Active State
When the DCAF session is in the active state, the controller operates and controls the target workstation. The keystrokes typed by the controller are relayed to the target workstation and acted upon as if they were typed by the target user. The keystroke input and the resulting screen image are seen on both the controlling and target workstations.

During the active state, keystroke input from the target workstation is not accepted. However, if the hot key combination is enabled for the target workstation, the target user can invoke this key combination to regain control of the target workstation. The target user also can choose to change the session state (for example, from active to monitoring).

The controller can establish concurrent sessions with multiple target workstations and can access each session by switching to a different window. Multiple controlling workstations can be defined within the network, however, only one of them at a time can establish a session with any single target workstation.

The controlling and target workstations are connected by a communication link.



The Sample DCAF Direct Connection figure above shows a direct connection between the controlling workstation and the OS/2 target workstation. Direct modem connections can be established between OS/2 workstations or between OS/2 controlling workstations and Windows Version 3.1 target workstations.



The Sample DCAF Connection figure above shows a connection via a DCAF Gateway workstation that acts as an interface between the controlling workstation and the target workstations on a Local Area Network (LAN). Connections through the DCAF Gateway can be established from a DCAF controlling workstation to any kind of DCAF target (OS/2, DOS or Windows).

Benefits of using DCAF
Within a customer's network, DCAF's ability to monitor or control a remote workstation from a central site makes it a powerful tool for network management, network administration, network security, problem determination and diagnosis, and application assistance in the form of Help Desk functions.

This remote capability can save time and money, as well as increase the productivity of the administration and support personnel. Technical expertise can be centralized at the controlling site, reducing the need for highly skilled personnel at remote locations. Reduced operational requirements will decrease costs and allow for faster growth of distributed applications within the distributed intelligent workstation environment.

System management of a secure-session environment is streamlined and made easier with the location of the DCAF Security Administrator component at the controlling site. The DCAF secure-session security helps protect the customer's software assets because DCAF's logged connections create a security audit trail.

Typical Uses of DCAF
Here is a typical scenario of the DCAF Help Desk function:
 * View and control another PC
 * Control unattended PCs remotely
 * Support customers and provide help remotely
 * Diagnose and solve problems on another PC by modem or over a LAN
 * Transfer text and data between PCs
 * Run DOS, Windows and OS/2 on an unattended PC by modem or over a LAN
 * Remote Help Desk assistance for applications, online education, and maintenance of application programs.
 * Remote problem determination for trace and dump analysis, including file transfer of data.
 * Remote control of unattended workstations (for example, LAN servers).
 * Remote management of Personal System/2 (PS/2) workstations and accessibility to data and programs stored on a PS/2 (for example, in the home or in the office)
 * Remote access to system consoles when they are implemented on PS/2s.
 * A target user is having difficulty understanding the company's new accounting program.
 * The target user contacts the Help Desk person who, in turn, opens a session with that particular target workstation.
 * With the target workstation accounting program on the screen, the controller (Help Desk person) switches to active state and types the correct keystrokes to run the accounting program.
 * The target user observes this process and learns how to use the new accounting program.
 * After demonstrating how to use the accounting program, the controller switches to the monitoring state and returns control to the target user.

Understanding the DCAF Environment
DCAF offers two main levels of security, which limit users' ability to take over your target workstations. These levels, basic DCAF (or nonsecure) and secure DCAF, offer protection for your workstations to varying degrees. For typical nonsecure environments that deal with nonconfidential information, basic DCAF provides adequate protection. Secure DCAF is more complex and caters to environments, such as banks and insurance companies, that work with confidential material and require greater protection.

In order to be part of the DCAF environment, the workstations must have DCAF components installed.

The DCAF Components
Before you begin the installation, you should be familiar with the DCAF components. The role of each workstation in your network determines the component(s) you install on that workstation. All components, except targets, run on OS/2 workstations only.

You can install one or more components on the same workstation, but it is recommended that you install only the necessary components on each workstation. For example, on one workstation you might install a controller, on another, the gateway and LAN directory, and on a third, a target component.

The Controller
The controller enables you to control the keyboard and mouse input and monitor the display output of a target workstation. It enables you to transfer files between the controller and target.

The Target
The target runs on three kinds of operating systems:
 * The OS/2 target enables an OS/2 workstation to be monitored and controlled by the controller.
 * The Windows target enables a Windows workstation to be monitored and controlled by the controller. The controller connects to the workstation whether it is operating in DOS full-screen mode or in a Windows graphic environment.
 * The DOS target enables a DOS workstation to be monitored and controlled by the controller. To install the DOS target, either create an installation package or use the CID method. Use the packager on an OS/2 workstation to create a DOS target installation package and then install the target on the DOS workstation.

In each case, the controller connects to the target directly if it is a basic DCAF target, or through a gateway if the workstation is secure.

The Gateway
The gateway links a controller with secure targets or with targets connected through an SNA backbone. The gateway always requires that you install a LAN directory on a workstation-any workstation-on the same LAN.

The gateway connects to all targets using the NetBIOS communication protocol. Therefore, install the gateway only in those parts of your network that use NetBIOS.

The gateway supports more than one session at a time so you probably need one gateway per logical LAN. To connect to secure targets, the gateway must be secure as well.

The LAN Directory
The LAN directory provides a list of the targets on a LAN that are available to the controller. When the controller connects directly with the targets via IPX/SPX, NetBIOS, or TCP/IP, the LAN directory is optional. When the controller connects with the targets through a gateway, the LAN directory is required.

Install one LAN directory per logical LAN. If you install more than one LAN directory on a logical LAN, give each a unique name.

The LAN directory also keeps a list that associates the workstation's physical address on the LAN with a nickname that makes the target name easy to remember. This list also enables the controller to find targets quickly. You can install the LAN directory on the target, gateway (if present), or on any workstation on the same LAN as the target.

The Security Administrator
The security administrator is necessary for secure DCAF only. It provides centralized maintenance of the databases for controllers, target access tables, secure target workstations, and security authenticators. Install one security administrator, typically on a controller, for your entire network if you are using secure DCAF. Safeguard this workstation from unauthorized access.

The security administrator keeps an encrypted database of authorized users, as well as an audit log file, EQNADMN.LOG. To be able to transfer security database files to the security authenticator, you must install either the security authenticator or a controller on the same workstation as the security administrator.

The Security Authenticator
The security authenticator is necessary for secure DCAF only. It authenticates sessions with secure targets. The security authenticator also gives access to secure targets based on security profiles for authorized controllers that it receives from the security administrator.

Install the security authenticator on an OS/2 target on the same LAN. Install it either on the security administrator workstation or on the secure OS/2 target workstation, so that it can receive security information from the security administrator.

If you install the security administrator on the LAN, you can install the security authenticator on the same workstation. Install at least one security authenticator for each logical LAN in your network.

The Packager
The packager is an installation aid only. It creates installation packages of DCAF components that you can install on other workstations. In addition, the packager enables you to prepare a component with the same personalization features to be installed in large numbers all over your network. Always install DOS targets using the packager.

The DCAF Network
The DCAF network includes the workstations that have DCAF installed and the communications that link them.

The Example of a Distributed Console Access Facility Environment figure on the right, is one example of a basic DCAF environment.

The DCAF workstations communicate with the following communication protocols:
 * Advanced Peer-to-Peer Networking (APPN)
 * Advanced Program-to-Program Communication or APPC); more specifically, Logical Unit Type 6.2
 * Asynchronous (also called Asynchronous Communications Device Interface or ACDI)
 * IPX/SPX (except for DOS targets)
 * NetBIOS
 * TCP/IP (except for DOS targets)

Controller A communicates directly with target E and with gateway B using switched asynchronous communication.

Controller A also communicates, via LU 6.2 over a Systems Network Architecture (SNA) network or backbone, through gateway B to the targets on the LAN. The SNA backbone represents the part of the network that connects (via switched lines, leased lines, or satellite communications) host computers, communication controllers, and other computer hardware. Any connections over an SNA backbone must go through a gateway.

Controller A communicates directly with target F via LU 6.2. For LU 6.2 communications, the physical unit type for the controller, target workstation, and DCAF gateway workstation must be configured as a type 2.1 (PU2.1).

Controller A communicates via TCP/IP through a router with LAN directory I and with target H.

Controller A communicates via IPX/SPX through a router with LAN directory K and with target J.

Controller A communicates via NetBIOS directly with LAN directory M and with targets L, N, and O on the LAN.

OS/2 target workstations on the LAN require that OS/2 Communications Manager, LAN Adapter and Protocol Support (LAPS) from NTS/2, or the LAN Server 2.0 be installed to provide the NetBIOS device drivers. In order to run DCAF with other applications that require NetBIOS services, you may need to increase the NetBIOS resources via the OS/2 Communications Manager or LAN Services.

DOS target workstations on the LAN require that a LAN support program be installed, such as the IBM LAN Support product. DCAF supports DOS target workstations on the LAN only.

Levels of DCAF Security
DCAF provides the following levels of security:
 * Basic (Nonsecure)
 * -No password
 * -Password-only


 * Secure
 * -Secure session

Basic (Nonsecure) Level
A no password session exists between a controlling workstation and a gateway or target workstation for which a password is not defined and, therefore, is not necessary.

A password-only session exists between a controlling workstation and a gateway or target workstation for which a password is defined. The controller must type the password before the session can be established.

In both the no password and password-only cases, the target component was installed as basic, or nonsecure. Basic DCAF provides adequate protection for nonsecure environments that deal with nonconfidential information.



Secure Level
Secure DCAF offers a higher and more advanced level of security for environments such as banks and insurance companies that work with confidential material. You can make a target workstation almost impregnable to intruders by designating it as a secure target. The controller must access the secure target through a secure gateway.

A secure session exists between a controlling workstation and a gateway or target workstation that has been installed as a secure gateway or target. These secure workstations do not have passwords. Instead, the controller, authorized to access a secure gateway or target, has a personal pass phrase (a compound password) and an access-level profile for a specific secure workstation.

DCAF security works with the following communication connections only: The Example of a DCAF Environment with Session Security figure shows some workstations in a secure DCAF environment. The gateway can use only NetBIOS to communicate with the secure targets. Secure targets must be on a LAN ( see targets C and D in the figure on the right.)
 * A controller can connect to a secure gateway via APPC/APPN or asynchronous.
 * The secure Gateway can connect to a secure target via NetBIOS only.

Controller A communicates via secure gateway B with the secure targets on the LAN. When the controller wants to take over secure target C, security authenticator D verifies that the controller is authorized to access that workstation.

DOS or Windows target E on the LAN is not secure and does not require authentication. It has password-only security. Controller A can also establish a session with secure target workstation F. Typically, the secure DCAF gateway, LAN directory, and security authenticator reside on target workstation F. In this case, controller A connects to gateway F via APPC, and gateway F connects internally to target F via NetBIOS.

The security administrator is typically installed on a controller workstation. It provides security file maintenance, a message log file, and control access information used by the DCAF security authenticators, all in a central location. Security files are transferred from the security administrator via a secure session to all of the remote security authenticators. Security administrator workstation G transfers new or updated security files to security authenticators D and F.

When the controller wants to change a pass phrase, the security authenticator verifies the authorization before a session is allowed, and keeps a log file of the authentication activity. The verification compares the controller's input with the ciphered data stored on the security authenticator. The advantage of this mechanism is that there is no way to intercept or discover the pass phrase during transmission, because only the ciphered data is sent.

For auditing purposes, the gateway logs all session connections and the communication errors that it filters.

Entry Points from DCAF to OS/2 Presentation Manager
This portion of the chapter describes the additional entry points that implement the new capabilities of the XGA Display Driver in order to efficiently track the screen region that is updated by Presentation Manager drawing functions and to handle the related data.

Modifications to the XGA Display Driver fall into two distinct areas:
 * Efficient accumulation maintenance and querying of clipped screen bounds of all screen drawing operations. This is provided by the following new functions:
 * -GreOpenScreen Change Area
 * -GreGetScreenChangeArea
 * -GreCloseScreenChangeArea


 * Compression of data from a specified area of the screen into a memory buffer and, usually after transmission over network, decompression of that data into an internal memory bit map. This is accomplished by the following new functions:
 * -GreGetScreenBits
 * -GreSetScreenBits

Data conversion must be performed between the different modes (bpp) and the different data formats (planar or packed), in order to allow the data interchange between XGA and VGA, between XGAs working in different internal formats and, in general, between all the display drivers providing these entry points.

GreOpenScreenChangeArea
Description:

GreOpenScreenChangeArea allocates a data area internal to the display driver, in which the driver will accumulate screen changes. GreOpenScreenChangeArea returns a 32-bit handle that is required to identify the area in GreGetScreenChangeArea and GreCloseScreenChangeArea calls.

Parameters:
 * HDC hdc
 * PDC pdcArg
 * ULONG FunN

Refer to the chapter regarding mandatory and simulated graphics engine functions in the OS/2 Presentation Device Driver Reference for details on this function.

GreGetScreenChangeArea
Description:

GreGetScreenChangeArea takes an SCA handle and, for the identified SCA, adds its rectangles to the region pointed to by the phrgnfield. The SCA is reset to NULL as a result of this call.

Parameters:
 * HDC hdc
 * HSCA hsca
 * PHRGN phrgn
 * PDC pdcArg
 * ULONG FunN

Refer to the chapter regarding mandatory and simulated graphics engine functions in the OS/2 Presentation Device Driver Referencefor details on this function.

GreCloseScreenChangeArea
Description:

GreCloseScreenChangeArea frees the data area internal to the display driver, identified by the SCA handle, that was accumulating screen changes.

Parameters:
 * HDC hdc
 * HSCA hsca
 * PDC pdcArg
 * ULONG FunN

Refer to the chapter regarding mandatory and simulated graphics engine functions in the OS/2 Presentation Device Driver Reference for details on this function.

GreGetScreenBits
Description:

GreGetScreenBits queries a region of screen pixel data and saves it in the memory provided by the caller. The data is compressed, and can be converted into a format suitable for another supported display device. The process will stop when either of the following situations occurs:
 * The supplied memory area is full
 * The requested region has been returned

Parameters:
 * HDC hdc
 * HRGN hrgnApp
 * PBYTE pDest
 * PULONG pulLength
 * ULONG flCmd
 * PDC pdcArg
 * ULONG FunN

Refer to the chapter regarding mandatory and simulated graphics engine functions in the OS/2 Presentation Device Driver Reference for details on this function.

GreSetScreenBits
Description:

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.

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 XGA driver may be passed 4bpp planar, 4bpp packed, 8bpp packed and 16bpp packed data.

Parameters:
 * HDC hdc
 * PBYTE pBuffer
 * ULONG cBytes
 * HRGN hrgn
 * PDC pdcArg
 * ULONG FunN

Refer to the chapter regarding mandatory and simulated graphics engine functions in the OS/2 Presentation Device Driver Reference for details on this function.

Code Modifications Required in Base Driver for DCAF
The majority of the new code is contained within new modules that are simply linked with the base driver. The areas of the base driver code that must be modified include the following:
 * The Dispatch Table, which contains the new Entry Points
 * All drawing functions, which contain extra tests to determine whether they should accumulate clipped screen bounds and, if necessary, code to calculate the clipped bounding rectangle
 * Seamless Windows cursor exclusion code, which is modified to call the new bounds accumulation routine.

Dispatch Table
In the EDDEFLDB.C, where the dispatch table is filled in with the display driver entry points, the five new entry points are included in the Driver Dispatch Table with the following function numbers:
 * GreOpenScreenChangeArea 0x4012
 * GreGetScreenChangeArea 0x4013
 * GreCloseScreenChangeArea 0x4014
 * GreGetScreenBits 0x401D
 * GreSetScreenBits 0x401E

Accumulating and Querying Screen Bounds
Traditional Presentation Manager bounds are unclipped, and use a single rectangle to define their limits. In order to better define the bounding area, the DCAF-enabled display driver now has the ability to maintain one or more clipped, multirectangle regions (Screen Change Areas or SCAs) that are updated to indicate areas on the screen that have been drawn to.

This ability is provided by the following changes to the base driver:
 * Three new entry points or functions to create, query and delete Screen Change Areas, as follows:
 * -GreOpenScreenChangeArea
 * -GreGetScreenChangeArea
 * -GreCloseScreenChangeArea
 * Two bounds accumulation internal routines, which add a single rectangle to all of the currently active SCAs.
 * An extra flag test in the path of every display driver drawing function ( for COM_SCR_BOUND in the high-order word in the last parameter of the GreXX calls, FunN).
 * If this flag is set and the drawing operation is going to the screen, the drawing function passes a clipped bounding rectangle of the drawing primitive to the bounds accumulation functions described above. The code required to do this is driver-specific.
 * Interception of Windows cursor exclusion calls and passing the supplied exclusion rectangle to the new bounds accumulation function.

Compressing and Decompressing Data
The bounding routines described above and under Performing the Bounding Accumulation efficiently track the regions on the screen that are updated by Presentation Manager drawing functions. The DCAF-enabled display driver also provides the ability to compress, decompress and, if necessary, convert the format of screen data.

This ability is provided by the following two new entry points or functions: The task is performed by the internal routine CompressRect in COMPRESS.ASM. The compressed data that is passed between display drivers uses a private format (that is, no external application or program has the right to examine, alter or make any assumptions about the content of the data). This allows the compression method to be improved in later versions of the driver. Definitions of the data structures are as follows: The rectangle data is split into individual rows. Each row is split into run-length encoded blocks (cells), each of which comprises a length field followed by one or more data fields. The sizes of both the length and data fields vary according to the format of the data being transmitted (as specified by the data_format field in the packet header), as follows:
 * GetScreenBits
 * SetScreenBits
 * 1) PACKET HEADER
 * dd total_data_packet_length (including header)
 * dw data_format
 * 1) RECTANGLE HEADER
 * dw xLeft
 * dw yBottom
 * dw xRight
 * dw yTop
 * 1) RECTANGLE DATA
 * 4bpp field size is one byte (8 bits)
 * 8bpp, 16bpp field size is two bytes (16 bits)

The following encoding rules are used:
 * If the length field contains a positive value (most significant bit not set), then the following single data field is repeated (length) times. If the data field size is 8 bits, this value will be limited to a maximum of 127.
 * If the length field contains a negative value (most significant bit set), then (length - most significant bit) fields of nonrepeating data follow. If the data field size is 8 bits, this value will be limited to a maximum of 127.
 * If the length field is zero and the following field is nonzero, the nonzero field is a count of the number of times that the single previous row is repeated. If the data field size is 8 bits, this value will be limited to a maximum of 127. This will only appear as the first cell in a row, and only after there has been at least one row of data.
 * If the length field is zero and the following field is zero, the next (third) field is a count of the number of times that the previous pair of rows are repeated. If the data field size is 8 bits, this value will be limited to a maximum of 127. This will only appear as the first cell in a row, and only after there have been at least two rows of data.

The following example shows the hexadecimal values of an 8bpp compressed bitmap: 0003 0004 00FA 0405 0706 0802 0104 0903 0001  ...........  0000 0003  0000 0000 0004  ... lf  df    lf   df   df   df   df   df   df                lf    df    lf   df   df   cell1                cell2                                 celln      celln+1

This bitmap would expand as follows (two-digit values represent a color index for a single pixel): 00 04 00 04 00 04 04 05 07 06 08 02 01 04 09 03 00 01 ............ row1

do three more identical rows (celln):

00 04 00 04 00 04 04 05 07 06 08 02 01 04 09 03 00 01 ............ row2 00 04 00 04 00 04 04 05 07 06 08 02 01 04 09 03 00 01 ............ row3 00 04 00 04 00 04 04 05 07 06 08 02 01 04 09 03 00 01 ............ row4

do four pairs of identical couples (celln+1):

00 04 00 04 00 04 04 05 07 06 08 02 01 04 09 03 00 01 ............ row5 00 04 00 04 00 04 04 05 07 06 08 02 01 04 09 03 00 01 ............ row6

00 04 00 04 00 04 04 05 07 06 08 02 01 04 09 03 00 01 ............ row7 00 04 00 04 00 04 04 05 07 06 08 02 01 04 09 03 00 01 ............ row8

00 04 00 04 00 04 04 05 07 06 08 02 01 04 09 03 00 01 ............ row9 00 04 00 04 00 04 04 05 07 06 08 02 01 04 09 03 00 01 ............ row10

00 04 00 04 00 04 04 05 07 06 08 02 01 04 09 03 00 01 ............ row11 00 04 00 04 00 04 04 05 07 06 08 02 01 04 09 03 00 01 ............ row12 The following example shows the hexadecimal values of a 4bpp compressed bitmap: 03 04 FA 04 05 07 06 08 02 ...........  00 03  00 00 04  ... lf df lf df df df df df df              lf df  lf df df cell1        cell2                       celln  celln+1 This bitmap would expand as follows (one-digit value represents a color index for a single pixel): 0 4 0 4 0 4 0 4 0 5 0 7 0 6 0 8 0 2 ............ row1

do three more identical rows (celln):

0 4 0 4 0 4 0 4 0 5 0 7 0 6 0 8 0 2 ............ row2 0 4 0 4 0 4 0 4 0 5 0 7 0 6 0 8 0 2 ............ row3 0 4 0 4 0 4 0 4 0 5 0 7 0 6 0 8 0 2 ............ row4

do four pairs of identical couples (celln+1):

0 4 0 4 0 4 0 4 0 5 0 7 0 6 0 8 0 2 ............ row5 0 4 0 4 0 4 0 4 0 5 0 7 0 6 0 8 0 2 ............ row6

0 4 0 4 0 4 0 4 0 5 0 7 0 6 0 8 0 2 ............ row7 0 4 0 4 0 4 0 4 0 5 0 7 0 6 0 8 0 2 ............ row8

0 4 0 4 0 4 0 4 0 5 0 7 0 6 0 8 0 2 ............ row9 0 4 0 4 0 4 0 4 0 5 0 7 0 6 0 8 0 2 ............ row10

0 4 0 4 0 4 0 4 0 5 0 7 0 6 0 8 0 2 ............ row11 0 4 0 4 0 4 0 4 0 5 0 7 0 6 0 8 0 2 ............ row12 Standard Golomb Run Length Encoding compression is inefficient at compressing 2x2 dither patterns, which are commonly used by Presentation Manager Display Drivers. The modified compression algorithm handles these patterns efficiently for the following reasons:
 * For 4bpp and 8bpp, the data field size is such that, when a row is compressed, pairs of adjacent pels are put in each data field. Note that there is no dithering at 16bpp.
 * When searching for duplicate scanlines, the algorithm also searches for duplicate scanline pairs that will match and compress patterns that repeat on alternate scanlines.

The actual pixel data is stored in Motorola format; that is, the most significant bits of a byte contain the leftmost pels. An example is shown below for a pair of pixels (PEL1,PEL2): for the 4bpp format: - PEL1 goes in bits 7..4 - PEL2 goes in bits 3..0

for the 8bpp format: - PEL1 goes in bits 15..8 - PEL2 goes in bits 7..0 All 4bpp data is defined as indices into the standard VGA palette. All 8bpp data is defined as indices into the standard XGA palette. All 16bpp data is defined as XGA-format 16-bit color values. (See the appendix regarding default color palettes in the IBM OS/2 Display Device Driver Reference for details of these formats).

All changed drivers must convert their own internal format into one of these standard formats before transmission. Refer to the section on later in this chapter.

Maintaining and Tracking Screen Change Areas (SCAs)
A key part of the modifications concerns the maintenance and tracking of SCAs.

SCA Definition
These areas track, as efficiently as possible, regions of the screen that are altered by display driver drawing routines. This tracking is done by using multiple rectangles to define the area, rather than the usual single bounding rectangle provided by traditional Presentation Manager bounding functions.

SCAs are maintained within the driver in an SCA data structure, defined in the new DCAF.H file. For details, refer to the SCA data structure in the Appendixes of the OS/2 Presentation Device Driver Reference. Instances of this structure are dynamically created and destroyed upon calls to GreOpenScreenChangeArea and GreCloseScreenChangeArea, respectively. For details, refer to these functions in the chapter of the OS/2 Presentation Device Driver Referencethat discusses mandatory and simulated graphics engine functions.

A global variable, pStartSCA, points to the latest SCA instance created. If pStartSCA is null, there are no active SCAs. All SCA instances are linked together in a list using the pscaNext field of the SCA data structure. A null value in this field indicates the end of the list (the earliest created SCA). For example: Memory loc. ---      pStartSCA = 250; | pscaNext = 200 | |                |            |      4th SCA    | 0x250     ---

---           | pscaNext = 150  | |                |            |      3th SCA    | 0x200     ---

---           | pscaNext = 100  | |                |            |      2nd SCA    | 0x150     ---

---           | pscaNext = 0    | |                |            |      1st SCA    | 0x100     --- Each SCA instance can store multiple rectangles, up to MAX_SCA_RECTS (14), which define the area on the screen that has changed since the SCA was created or last queried. These rectangles are stored in the array arcl[]. The number of rectangles stored within the array is kept in the cRects field, which will never exceed MAX_SCA_RECTS. If cRects is zero, the SCA is a null area - the initial state.

The remaining field in the SCA data structure, aulRectSize[], is an array containing the sizes of the rectangles in arcl[]. This is not strictly necessary, because the sizes can be calculated on the fly using the dimensions in arcl[]. However, when accumulating a rectangle into a SCA, the size of each of the rectangles is frequently needed. Caching the rectangle sizes in this array saves having to recalculate the sizes every time, resulting in better performance.

The SCA data structure defines space for (MAX_SCA_RECTS+1) rectangles, but only MAX_SCA_RECTS are ever used to define the SCA. The extra rectangle is used to simplify the routine that accumulates rectangles into the SCA.

Creating a new SCA
Creating a new SCA, accomplished by GreOpenScreenChangeArea (SCRAREA.C), requires the following steps:
 * Allocate memory for the new SCA instance
 * Set the cRectsfield to be zero
 * Set the pStartScaglobal variable to point to the new SCA address
 * Link the instance to the linked list of SCAs

The newly created SCA will be identified by a 32-bit handle, which is the address of the SCA location in the display driver.

Accumulating a Rectangle into an SCA
All display driver functions that draw to the screen are modified to accumulate clipped bounding rectangles into all active SCAs when necessary. The drawing functions determine whether they should do this by examining the FunN (Function Number/COM_ flags) parameter. If the COM_SCR_BOUND flag is set, and the function is drawing to the screen, then bounding rectangles are accumulated into the active SCAs; otherwise, no accumulation takes place. The setting of COM_SCR_BOUND is controlled by the GreOpenScreenChangeArea and GreCloseScreenChangeArea functions. For details, refer to these functions in the chapter of the OS/2 Presentation Device Driver Reference that discusses mandatory and simulated graphics engine functions.

In every drawing call, the following test is performed: if (DCAFBoundsRequired(FunN)) {     accumulate the bound } where the DCAFBoundsRequired macro is defined in DCAFEXTF.H as follows: ( (FunN & COM_SCR_BOUND) &&      \    /* COM_SCR_BOUND is set   */      (FunN & COM_DRAW) &&            \    /*  COM_DRAW is set    */      (pdc->DCIDCType == OD_DIRECT) )      /*  the destination is the screen */ When change-area tracking is not needed, COM_SCR_BOUND will never be set. The difference in operation and performance of the DCAF-enabled base driver will be negligible-one additional check of the COM_SCR_BOUND flag per drawing function.
 * 1) define DCAFBoundsRequired(FunN)     \

Performing the Bounding Accumulation
Two routines (in SCBOUNDS.C) perform the bounding accumulation:
 * VOID AccumulateScreenBounds( PRECTL prclArgBound);
 * VOID AccumulateScreenBoundsThroughClips( pDevRect pBoundCoords, ULONG ulCoordType );

AccumulateScreenBounds
This routine is called by GreSetPel and GrePolyShortLine, the drawing functions that are able to pass preclipped bounding rectangles. Its task is to take the passed rectangle and accumulate it into all the current SCAs. The passed rectangle is in exclusive SCREEN coordinates.

AccumulateScreenBoundsThroughClips
This routine takes the supplied (unclipped) bounding rectangle, intersects it with each of the clip rectangles in the DC and accumulates each of the clipped bounds into the active SCAs. The supplied bounding rectangle can be in one of the following types of coordinates:
 * 16-bit AI coordinates (COORD_AI) Origin is top-left of screen
 * 16-bit Device coordinates (COORD_DEVICE_WORD) Origin is current DC origin
 * 32-bit Screen Coordinates Origin is bottom-left of screen

The ulCoordtype field specifies which of these coordinates is being supplied.

AccumulateScreenBoundsThroughClips can be called from the same point in drawing functions as the ordinary (unclipped) bounds are accumulated. This minimizes the complexity and number of changes required in the main drawing code. Before accumulating the bounding rectangle, according to the following accumulation algorithm, the coordinate conversion (if required) to exclusive SCREEN coordinates and the clipping of the passed rectangle must be performed. The clipping can be done against the DC cache clip rectangles, or it may require a call back to the Graphics Engine to get the clip set. When a rectangle is added into an SCA, it is done in such a way as to minimize the increase in area of the SCA.

The following accumulation algorithm accomplishes this: for (pscaCurrent = each SCA in the linked list)
 * // First check whether the new rect is already contained within this SCA
 * for (rclCurrent = each rectangle in current SCA)
 * : if rclNew lies completely within rclCurrent
 * : : no more work - skip straight to next SCA
 * : endif
 * endfor
 * endfor


 * // We have to add the rectangle to the SCA.
 * // First see if there is free space for the rectangle within the SCA.
 * if pscaCurrent->cRects < MAX_SCA_RECTS
 * : copy rect into SCA
 * : calculate size and store in SCA
 * : increment pscaCurrent->cRects
 * else
 * : // All of the SCA rects are used.
 * : // Copy the new rect into the SCA at position (MAX_SCA_RECTS+1) and the
 * : // problem then becomes:
 * : // We have MAX_SCA_RECTS+1 rectangles, which we have to reduce
 * : // to MAX_SCA_RECTS by merging two of the rectangles into a single rectangle.
 * : // The pair of rects that we merge are the two that will cause the smallest
 * : // increase in area.
 * : initialize ulSmallestAreaIncrease to be maximum possible value
 * : for (iRect1 = each rectangle in the SCA)
 * : : for (iRect2 = iRect1+1 to MAX_SCA_RECTS+1)
 * : : // This inner loop is the performance bottleneck.
 * : : // Make it as fast as possible, if you can!!
 * : : : if area increase of (iRect1,iRect2) merged < ulSmallestAreaIncrease
 * : : : : set ulSmallestAreaIncrease to be area increase of (iRect1,iRect2) merged
 * : : : : set best pair of rects to be (iRect1,iRect2)
 * : : : endif
 * : : endfor
 * : endfor
 * : merge best pair of rects found into the slot originally occupied by Rect1
 * : if rclNew was not one of those merged
 * : : copy rclNew into vacant slot made by merging pair
 * : endif
 * endif
 * endif

endfor When change-area tracking is active, this routine is called by every function that draws to the screen. Therefore, the routine must be as efficient as possible (particularly in the inner loop) to minimize the hit on performance.

Deleting an SCA
This task is performed by GreCloseScreenChangeArea (SCRAREA.C), as follows: In a typical example, if we close the second SCA: Memory loc. ---  pStartSCA = 250; | pscaNext = 200 | |                |          |      4th SCA    | 0x250   ---
 * Unlink the SCA instance from the linked list of SCAs
 * Free the memory for the SCA instance

---         | pscaNext = 150  | |                |          |      3th SCA    | 0x200   ---

---         | pscaNext = 100  | |                |          |      2nd SCA    | 0x150   ---

---         | pscaNext = 0    | |                |          |      1st SCA    | 0x100   --- we will get: Memory loc. --- pStartSCA = 250; | pscaNext = 200 | |                |          |      4th SCA    | 0x250   ---

---         | pscaNext = 100  | |                |          |      3th SCA    | 0x200   ---

---         | pscaNext = 0    | |                |          |      1st SCA    | 0x100   --- If the last remaining SCA is being freed, pStartSCA is set to NULL. If the latest SCA created is being freed, pStartSCA is set to the address of the SCA created immediately prior to it (the previous SCA).

Converting Data
The changed display drivers use different internal data formats: When data is transmitted between display drivers, it is done at the lower bpp of the two drivers (or at the lowest bpp; for example, a pair of 16bpp DCAF-enabled drivers could communicate at 4bpp to reduce the amount of data transmitted). Therefore, the following conversion routines are required by the display driver: XGA (4bpp, 8bpp, 16bpp packed)
 * VGA 4bpp planar
 * XGA 4bpp packed, 8bpp packed, 16bpp packed

internal format    required format

16bpp packed ->  8bpp packed (compression) 16bpp packed ->  4bpp packed (compression) 16bpp packed ->  4bpp planar (compression) 8bpp packed ->  8bpp packed (compression) 8bpp packed ->  4bpp packed (compression) 8bpp packed ->  4bpp planar (compression) 4bpp packed ->  4bpp planar (compression)

external data format    internal format

(decompression) 8bpp packed -> 16bpp packed (decompression) 8bpp packed ->  8bpp packed (decompression) 4bpp packed -> 16bpp packed (decompression) 4bpp packed ->  8bpp packed (decompression) 4bpp planar -> 16bpp packed (decompression) 4bpp planar ->  8bpp packed (decompression) 4bpp planar ->  4bpp packed The conversions from packed to planar and vice versa are assisted by the use of a lookup table to split packed bytes into bits that can be conveniently reassembled into planar format (and vice versa).

All conversions to planar format are done by first converting the bits per pel to 4 (still in packed format) and then performing an optimized 4bpp packed-to-planar conversion. In conversions from 4bpp planar a similar, but reverse, process is performed- converting from 4bpp planar to 4bpp packed and then to the required packed destination format.

Conversions from 4bpp and 8bpp use a lookup table to efficiently translate the colors. Conversions from 16bpp cannot use a direct lookup table because the size is prohibitive. Therefore, colors have to be searched for on a nearest color basis in the destination color table. This is much slower than a simple table lookup. To improve performance, a cache of the most recently calculated colors is kept, which saves having to repeatedly recalculate commonly used colors.

Seamless Windows Support
In OS/2 2.1, Seamless Windows is supported by allowing the Windows display driver to draw directly on the Presentation Manager (PM) screen. This means that Seamless Windows updates do not go through the PM drawing functions and, therefore, will not update the active screen change area (SCA) in the usual way. As a result, Seamless Windows requires special treatment.

Prior to drawing on the PM screen, the Seamless Windows driver calls the PM driver through an exported entry point, SeamlessExcludeCursor. This call excludes the PM cursor from the area in which the Seamless Driver is about to draw. The modified DCAF-enabled display driver intercepts this call and passes the rectangle coordinates to AccumulateScreenBounds.

Under DCAF, during PM display driver initialization, Seamless Windows must be granted addressability to all data and code that it will access during the call to SeamlessExcludeCursor. In order to add the supplied rectangle to all active SCAs, which can reside anywhere in the display driver heap, there is a single, static SSA (Seamless Screen Area), called scaSeamless, used for this purpose. All Seamless bounding rectangles will be accumulated in scaSeamless; then, this SCA is merged with the other active SCAs when a query is issued via GreGetScreenChangeArea.

As a result, at initialization (in InitializeSeamless), the Seamless Windows driver is given access to AccumulateScreenBounds, to scaSeamless and to the DDT display driver control block, in order to retrieve the screen dimension at seamless time. The addresses of this data are stored in the SeamlessAddresses control block, owned by the Windows driver.

Before writing to the PM screen, the Seamless Windows driver will call SeamlessExcludeCursor. The exclusion rectangle will be passed in the following registers in so-called AI coordinates (i.e., 16-bit inclusive; 0, 0 is top left of screen):
 * Left cx
 * Top dx
 * Right si
 * Bottom di

The display driver will determine whether the new bounds accumulation is needed by checking the value of the pStartSCA pointer and, in SeamlessExcludeCursor32, will call AccumulateSeamlessBounds to initiate the bounds accumulation. AccumulateSeamlessBounds converts the passed rectangle to EXCLUSIVE SCREEN coordinates, clips the rectangle to the screen dimensions and calls AccumulateScreenBounds. This causes the rectangle supplied to SeamlessExcludeCursor to be added to only scaSeamless. When an SCA is queried using GreGetScreenChangeArea, the Seamless SCA is merged with the active SCAs and then reset to NULL.