Input/Output Device Driver Reference/Touch Inter-Device-Driver Communication Interfaces

This chapter describes the inter-device-driver communication (IDC) interfaces for the IBM Touch Display device driver provided by the OS/2 operating system - both device-independent to device-dependent and device-dependent to device-independent.

Device-Independent to Device-Dependent IDC Interfaces
The IDC interfaces provided by the device-independent-device driver are:
 * Process Packet
 * Disable Support

Process Packet
This interface is called by the device-dependent-driver when it completes receiving and formatting Touch device data into the shared data buffer address, so that the data can be processed by the device-independent driver.

Input: AX = Function Request Code = 0001H SI = Shared data buffer offset DS = Device-independent driver's DS value ES = Device-dependent driver's DS value (caller) BX,CX,DX, and DI register contents are undefined Output: AX = Error return code (if Carry Set;     undefined if Carry Clear) DS = Device-independent driver's DS value ES = Device-dependent driver's DS value (caller) BX,CX,DX,SI and DI register contents are undefined

Disable Support
This interface is used by the device-dependent-device driver to inform the device-independent driver that it has received a Deinstall request and wants to release its system resources. The device-independent driver cannot uninstall itself at this point, but it can disable the API interfaces.

Input: AX = Function Request Code = 0002H DS = Device-independent driver's DS value ES = Device-dependent driver's DS value (caller) BX,CX,DX,SI and DI register contents are undefined Output: AX = Error Return Code (if Carry Set;    undefined if Carry Clear) DS = Device-independent-driver's DS value ES = Device-dependent-driver's DS value (caller) BX,CX,DX,SI and DI register contents are undefined

Device-Dependent to Device-Independent IDC Interface
The IDC interface provided by the Touch component of the device-dependent-device driver is identical to that provided by a PS/2 Mouse device-dependent-driver, with two exceptions: Enable and Disable device functions do not enable or disable the device at the IRQ level, which would cause the Touch device to be enabled or disabled simultaneously. The Enable and Disable device functions simply stop and start reporting of data to the device-independent driver.

The IDC interface provided by the Touch component of the device-dependent device driver consists of the following functions:
 * Query Configuration
 * Enable Read
 * Disable Write
 * Enable Device
 * Disable Device
 * Set Mouse Emulation State

Query Configuration
Input: AX = Function Request Code = 0001H DI = Configuration data buffer offset DS = Device-dependent driver's DS value ES = Device-independent driver's DS value (caller) BX,CX,DX, and SI register contents are undefined ES:DI points to a data structure that is filled in by the device-dependent driver to convey configuration information back to the device-independent driver, according to the following format: config_data struc

length   dw ? ; length (inclusive) of structure in bytes irq_num  db ? ; interrupt request level for device mou_stat dw ? ; mouse device status flags ; bit 0 =1 Physical PS/2 mouse attached ; bit 1 =1 Device independent driver attached ; bit 2 =1 Protected mode emulation enabled ; bit 3 =1 Real mode emulation enabled tou_stat dw ? ; touch device status flags ; bit 0 =1 Touch device calibrated

config_data ends Output: AX = Error return code (if Carry Set, undefined if Carry Clear) DI = Configuration data buffer offset ES = Device-independent driver's DS value (caller) BX,CX,DX,SI and DS register contents are undefined

Enable Read
This function is issued by the device-independent driver to indicate that data packet processing has been set up and data transfer can begin.

Input: AX = Function Request code = 0002H DI = Shared interrupt data buffer offset DS = Device-dependent driver's DS value ES = Device-independent driver's DS value (caller) BX,CX,DX, and SI register contents are undefined

ES:DI points to the interrupt data packet structure in which the called device driver will write/return the touch data packet when a complete packet has been accumulated. touch_data struc

status   dw ? ; touch display status x_coord  dw ? ; x coordinate of touch y_coord  dw ? ; y coordinate of touch z_coord  dw ? ; z coordinate of touch x_range  dw ? ; Xmax - Xmin y_range  dw ? ; Ymax - Ymin z_range  dw ? ; Zmax - Zmin

touch_data ends Note: X,Y,Z coordinates are reported in fixed 4096x4096x255 coordinate space. X increases left to right; Y increases top to bottom.

Output: AX = Error return code (if Carry Set, undefined if Carry Clear) ES = Device-independent driver's DS value (caller) BX,CX,DX,SI,DI and DS register contents are undefined

Disable Write
This function is called by the device-independent driver to indicate that data packet processing is no longer supported and that data transfers by way of Process Packet should be stopped until an Enable Read request is processed. Following this call, no further references should be made to the shared interrupt data buffer address previously provided by way of the last Enable Read request.

Input: AX = Function Request code = 0003H DS = Device-dependent driver's DS value ES = Device-independent driver's DS value (caller) BX,CX,DX,SI and DI register contents are undefined Output: AX = Error return code (if Carry Set, undefined if Carry Clear) ES = Device-independent driver's DS value (caller) BX,CX,DX,SI,DI and DS register contents are undefined

Enable Device
This function is used to enable touch data event reporting from the device-dependent driver to the device-independent driver. It does not affect interrupt data processing at the IRQ level (which is shared between PS/2 Mouse and Touch devices); therefore, mouse data event processing and reporting is not affected.

Input: AX = Function Request code = 0004H DS = Device-dependent driver's DS value ES = Device-independent driver's DS value (caller) BX,CX,DX,SI and DI register contents are undefined Output: AX = Error return code (if carry set, undefined if carry clear) ES = device independent driver's DS value (caller) BX,CX,DX,SI,DI and DS register contents are undefined

Disable Device
This function is used to disable Touch data event reporting from the device-dependent driver to the device-independent driver. It does not affect interrupt data processing at the IRQ level (which is shared between PS/2 Mouse and Touch devices); therefore, mouse data event processing and reporting is not affected.

Input: AX = Function Request code = 0004H DS = Device-dependent driver's DS value ES = Device-independent driver's DS value (caller) BX,CX,DX,SI and DI register contents are undefined Output: AX = Error return code (if Carry Set, undefined if Carry Clear) ES = Device-independent driver's DS value (caller) BX,CX,DX,SI,DI and DS register contents are undefined

Set Mouse Emulation State
This function is used to control the way touch data packets are handled by the device-dependent driver. When emulation mode is set to Off, touch data packets are reported to the Touch device-independent driver only as direct X,Y,Z data packets. When mouse emulation mode is set to absolute, the touch data packet is additionally converted into a mouse data packet of absolute X,Y form, and reported to the mouse device-independent driver by way of its Process Packet Absolute IDC entry point. When mouse emulation mode is set to relative, the touch data packet is additionally converted into a mouse data packet of relative dx,dyform, and reported to the mouse device-independent driver by way of its standard Process Packet IDC entry point.

Input: AX = Function Request code = 0006H BX = Emulation mode (0=off 1=absolute 2=relative) DS = Device-dependent driver's DS value ES = Device-independent driver's DS value (caller) CX,DX,DI and SI register contents are undefined Output: AX = Error return code (if Carry Set, undefined if Carry Clear) ES = Device-independent driver's DS value (caller) BX,CX,DX,DI,SI and DS register contents are undefined

Communications from Physical Device Driver to Virtual Device Driver
The physical device driver (PDD) uses touch data packets to communicate with the virtual device driver (VDD). While the virtual mouse device driver can receive mouse data from the Presentation Manager that is correctly adjusted for DOS window sizes and positions, the same is not true for touch data. Normally, therefore, a DOS session receives touch data only when it is running full screen (that is, a non-PM foreground session). In a PM session, all touch data is used to form emulated mouse packets and is reported to the physical mouse device driver. The virtual mouse device driver then receives the emulated mouse data by way of the normal PM route (or physical driver route if exclusive mouse access in On).

The exclusive touch access DOS property, however, permits a DOS window to receive all touch data when running in a PM session. The DOS window must be running maximized (except for text-mode applications where maximizing a window does not cover the full screen) in order to run without modification. Otherwise, the application has to perform the coordinate conversions itself, an impossible task for a DOS program because it has no knowledge of or access to window position and size information.

The VDD entry point is passed to the PDD when the VDD calls VDHOpenPDD with the 16:16 address of VTEventProc as a parameter, as shown in the following code:

/*    VTEventProc - Process event packets from PDD. * * ENTRY *    ulFunc == function code (VTDCMD_REPORT_EVENT) *    f16p1 -> MONREC *    f16p2 -  Not used. * * EXIT *    None. * * USES *    32-bit small-model PASCAL calling/register conventions * * CONTEXT *    Interrupt time * * PSEUDOCODE *    If handle and pointer are valid and touch is enabled, *        add the event to the VDE's buffer. */
 * VTEventProc Function 1 - Process Packet/Event

VOID    VDDENTRY VTEventProc(ULONG ulFunc, F16PVOID f16p1, F16PVOID f16p2; The MONREC pointer points to a structure, as shown in the following example: /*    + PTD-to-VTD communication structures * */

typdef struct {                               // VTDCMD_REPORT_EVENT USHORT           Status; ULONG            TimeStamp; USHORT           x;       USHORT            y;       USHORT            z;    }  QEVENT, * PQEVENT, * *  PPQEVENT;

typedef struct { USHORT      SGId; QEVENT      Qevent; } MONREC, * PMONREC;

Virtual Device Driver to Physical Device Driver Communication
The primary function of this interface is to register the VDD with the PDD so that, later, the VDD can call the PDD back with data, establish the configuration setup (for example, physical mouse is attached or not, Touch display is calibrated or not, and so forth), and device control (such as emulation On or Off, DOS property exclusive access On or Off, and so forth).

The following functions are supported:
 * Register VDD
 * Query configuration
 * Set emulation state
 * Disable
 * Set exclusive access

Function 0: Register VDD - PddRegister
Establishes the VDD entry point for the PDD to call the VDD. /*     PddRegisterVdd - Called when Vdd calls VDHOpenPDD * * Input: *      USHORT  pIBuff.off        VDD's CS *       USHORT  pIBuff.sel        Zero *      USHORT  pOBuff.off        Low 16 bits of EIP for VDD entry point *      USHORT  pOBuff.sel        High 16 bits of EIP for VDD entry point * * Return: *      BOOL success (AX) * * Usage: *      Success = PddEntry( 0, VddEntrySelector, VddEntryOffset); * * Called from: *      PddEntry (seg3) via VdhOpenPdd * */

STATIC VDMFUNC PddQueryConfig( PUSHORT pOFubb);

Function 1: Query Configuration - PddQueryConfig
Returns device configuration information, including device interrupt request (IRQ) level, mouse status (physical mouse present, MOUSE.SYS driver attached and emulation state) and touch status (calibrated or not). /*     PddQueryConfig - Copy device config data to a vdd 16:16 ptr * * Input: *      None. * * Return: *      Configuration data: *              USHORT  size = 7 *              UCHAR   irq *              USHORT  mouse status *              USHORT  touch status *      BOOL success (AX) * * Usage: *      Success = PddEntry( 1, NULL, &ParmsAddr); * * Called from: *      PddEntry (seg3) [QueryType(&TouHardware)] */

STATIC VDMFUNC PddQueryConfig( PUSHORT pOBuff);

Function 2: Set Emulation State - PddSetEmul
Used to switch mouse emulation in the DOS virtual machine Off or On (relative/glass mouse or absolute). /*     PddSetEmul - Set emulation state * * Input: *      Emulation data: *             USHORT  size = 3 *             UCHAR   emul state (0 - off, 1 - absolute, 2 - glass) * * Return: *      BOOL success (AX) * * Usage: *      Success = PddEntry( 2, &DataAddr, NULL); * * Called from: *      PddEntry (seg3) */

STATIC VDMFUNC PddSetEmul( PUSHORT pIBuff);

Function 3: Disable - PddDisable
Used to get information from the VDD that it is unable to load or get from the PDD. /*     PddDisable - * Input: *      None. * * Return: *      BOOL success (AX) * * Usage: *      Success = PddEntry( 3, NULL, NULL); * * Called from: *      PddEntry (seg3) */

STATIC VDMFUNC PddDisable(VOID);

Function 4: Set exclusive access On/Off - PddSetExclAcc
Enables a DOS window to receive full-screen touch data. (Valid for the PM session only.) Mouse emulation is effectively turned Off when exclusive access is on. /*     PddSetExclAcc - Set exclusive access On/Off * * Input: *      Exclusive Access Data: *              USHORT  size = 3 *              UCHAR   exclusive access flag (0 - off, 1 - on) * * Return: *      BOOL success (AX) * * Usage: *      Success = PddEntry( 4,&DataAddr, NULL); * * Called from: */

STATIC VDMFUNC PddSetExclAcc( PUSHORT pIBuff);

Virtual Touch Device Driver Architecture
The following information describes the Virtual Touch Device Driver Architecture.

INT 7Fh Software Interrupt and Function Table Call Handling
Following is the sequence of events when a real-mode program issues a software interrupt that has been hooked by a VDD:
 * 1) At create time, VDD installs an interrupt vector hook (InstallHookVect).
 * 2) The interrupt vector table gets patched with Address A.
 * 3) Address A points to an illegal real-mode instruction (ARPL).
 * 4) The software interrupt causes transfer to Address A.
 * 5) The execution of the ARPL located there causes a trap.
 * 6) The OS/2 operating system fields the trap.
 * 7) OS/2 hooks into the list of procedures registered for this trap by way of InstallHookVect and calls each one in turn.
 * 8) The hook procedures get passed a pointer to Client Register Frame (CRF).
 * 9) The hook procedures process the call, based on registers passed in the CRF.
 * 10) If the hook procedures interrupt, they call VDHPopInt, which fills in the return CS:IP in the CRF.
 * 11) The hook procedures return TRUE if they are interrupted; else, FALSE.
 * 12) OS/2 calls the next procedure in the chain if FALSE; else, it returns to CS:IP as filled in the CRF.

See the following figure for the route from a real-mode application to the protect-mode VDD handler.



With the IBM Touch Display, the interface to the device driver is by way of a call table, the address of which the application obtains by issuing INT 7F with AX=ABCDH and BX=0H. When it has obtained the call table address (CTA), it then calls the individual function it requires by calling the address at (CTA) + 4*(FN-1), where FN is the required device driver function number. This cannot be done in the previous sequence, however, because calls cannot be made directly from the DOS (real-mode) application to the OS/2 (protect-mode) VDD.

The mouse INT 33 driver has a related problem in that it has a BASIC entry point located 2 bytes forward of the actual INT 33 vector address. (The first instruction of the INT 33 handler is a jump over the BASIC entry point code.) Therefore, a BASIC application would obtain Address A and then call (Address A + 2), which could be anything.

To resolve this, the VDD must have a real-mode portion that has a software interrupt handler similar to that provided by the DOS driver. Address A, then, is replaced by the address of this handler (Address B) by the VDD at create time, as well as saving Address A in real-mode.

For the particular case of the IBM Touch Display driver, the call table also must be part of the real-mode portion, enabling calls to its entries to be made directly by real-mode applications, with the interrupt handler setting the address of the table in ES:BX as in the real DOS driver, before calling Address A. If the handler received a call that did not belong to it (AX !=ABCDH), then it would call Address A directly.

The entries in the call table then consist of a common call into a router. The router determines the function number from the address from which it was called, then sets up the registers appropriately before calling Address A, as shown in the following figure.



Physical Touch Device Driver - Virtual Touch Device Driver Interface
The physical Touch device driver - virtual Touch device driver interface is very similar to the physical Mouse device driver - virtual Mouse device driver interface, except that it passes absolute Touch X,Y,Z status data instead of Mouse row,column,status data.

The physical Touch device driver is aware at all times of which session owns the Touch device: When it is a foreground DOS session, it notifies the virtual Touch device driver of the touch events, which are immediately buffered in the virtual driver. The virtual driver then processes the event by updating the INT 7h data structures for the foreground DOS session, as well as handling the touch event user subroutine, if one is registered.

Notice that the specific-case Presentation Manager session is handled differently in the case of the mouse, where the event is sent to the PM single queue by the physical mouse driver. From there, PM notifies the DOS session whenever the mouse pointer is over a windowed DOS session, and performs coordinate conversion on behalf of the windowed session. Also, if an alternate mouse coordinate system is set up in the DOS session, the session must discard any events posted by PM that fall outside the coordinate system but, otherwise, are within the session window.

The Touch Display and its virtual Touch device driver do not have any such relationship between the device and PM, nor is there any architected mechanism for it to do so, because the single queue supports only keyboard and mouse events. This prevents the virtual Touch driver from providing full touch data for windowed DOS sessions or for supporting the Tdixxx API properly for VIO windows.

When a touch event is received while in a PM session, the physical device driver can handle the event only as though it were a normal full-screen OS/ 2 session; in other words, the event passes through the device monitor chain before being buffered in the physical device driver queue. This is because the physical device driver has no information regarding the arrangement of the PM Desktop, location and size of windowed DOS sessions, and so forth, to enable it to directly inform the virtual device driver of the event (correctly tagged, with the target DOS session handle and coordinates converted).

Event Notification
Each time the virtual Touch device driver is notified of a touch event, it might have to notify a DOS session user subroutine. This depends on whether the DOS session has a user subroutine registered by way of INT 7Fh, and whether the call mask conditions match the event.

The user subroutine is called by simulating an interrupt into the DOS session. An interrupt service routine (in the virtual Touch driver) is loaded into each DOS session at create time. This routine services an interrupt (PopInt, ClearIRR, issues SendVEOI, PushRegs), sets up a CRF containing the appropriate values of the registers, and then performs a VDHPushFarCall to the user subroutine. The routine also arms a return hook procedure to gain control after the user subroutine has completed. When the context of the DOS session next becomes current, it executes the user subroutine. When the return hook procedure gains control again, it performs only a PopRegs.

The interrupt number chosen for simulation is the hardware interrupt being used by the physical device driver. For 8516, this is IRQ 12, the same as for the PS/2 Mouse, depending on the ability to choose an interrupt number that will not conflict with another virtual device driver.

The 8516 Touch device and the PS/2 Mouse can simulate and service their own interrupts separately while using the same IRQ 12h, INT 74h. The virtual PIC driver will be able to handle interrupt simulations separately on the same interrupt (function 74h) for both the DOS session and the virtual Touch driver, but it will require that IRQ 12h, INT 74h is handled as a sharedinterrupt in the VDDs that simulate and service this interrupt.

Algorithms to Improve Touch Selection
In addition to the straightforward way of setting the selection-detection flag on Push Harder or Lift Off (where the snapshot X,Y value when crossing a given Z threshold is used directly), the X,Y,Z packets can be further processed to enhance the repeatability and accuracy of the X,Y report. Following is a list of these data processing algorithms: The algorithms are activated by setting the appropriate bit in the selection-detection mechanism Type parameter of Function 6 "Set Selection Mechanism". Only one algorithm can be active at any given time, in either Push Harder or Lift Off modes. Click locking was introduced primarily to facilitate the Presentation Manager's mouse-emulation mode, but it was found equally useful in the DOS environment.
 * Single-touch
 * Stable region (also called Back-in-the-Stack algorithm)
 * Click locking

Accuracy of the X,Y Report
Touch accuracy (or lack of it) is a primary reason for the need to improve Touch selection. There are many factors that affect Touch accuracy, including:


 * Style of touch
 * As the screen is touched, from the point of touch down to lift off, there can be appreciable movement of the reported X,Y position, even though the intent is to keep the contact point stationary. This can depend on the way the screen is touched; for example, a rapid stab at the screen ordinarily produces more variation than a slower, lighter touch.
 * On-screen touch threshold
 * Lowering the on-screen touch threshold makes the system not only more sensitive to touch but also to external unwanted noise, such as mechanical vibration.
 * Filter cut-off frequency
 * Increasing the system's low pass cut-off frequency can increase the system' s responsiveness to fast touches, but it does so at the expense of not being able to filter out unwanted noise, variation, and movement.

Single-Touch Algorithm
The single touch algorithm is designed to provide more consistent touch-down X,Y coordinates over a wide range of applied touch speed and pressure.

The single-touch algorithm prevents the snapshot X,Y data (taken at the first point of contact) being used when the subsequent data reports are moving away rapidly from the initial position. Rather, it ensures that the data reports have settled within a consistent area for a given number of reports. The size of the area and number of reports are determined by additional (optional) parameters.

The algorithm checks each point against the subsequent point; if the second differs from the first by an amount within the defined tolerance, a count is incremented. If not, the count is set to 0. Only when the count reaches the defined minimum is the data considered settledand the X,Y report given with the status of selection detected.

As the number of reports and tolerance parameters are tightened, so is the requirement for more controlled, slow, and deliberate touches. Lightly tapping or quickly stabbing the screen are less likely to trigger the algorithm, because of either insufficient data or too much variation within the data. For this reason, this algorithm is less likely to be of use in an untrained user or public kiosk type of environment where user frustration could result. Applications designed for such environments generally can avoid the effects of inaccuracy and repeatability by having more simply designed screens with large, widely spaced targets.

If    status == touch-down single_touch X,Y = current X,Y touch_detected = single_touch_sent = FALSE count = RESET_VALUE return
 * Pseudocode for the Single-Touch Algorithm

If    status == on_screen if    selection_method == lift_off return

update_single_touch_xy

if    signal_touch_sent == FALSE && touch_detected = TRUE current X,Y = single_touch X,Y signal_touch_sent = TRUE return

If    status == lift_off if    selection_method == lift_off update_single_touch X,Y current X,Y = single_touch X,Y return

Procedure update_single_touch_xy

if    absolute(current X,Y - single_touch X,Y) < tolerance single_touch X,Y = ( single_touch X,Y + current X,Y) / 2 count -- if (count==0) set touch_detected

else single_touch X,Y = current X,Y count = RESET_VALUE endif endproc.

Back-in-the-Stack Algorithm
The Back-in-the-Stack (BIST) algorithm provides for detailed selection of an item (down to pel level at 640 x 480 resolution), even in the presence of varying X,Y data packets when the selection needs to be made.

For example, it might be relatively easy to adjust the touch contact so that the required (small) item is identified, but then much more difficult to actually perform the selection, either by lifting off or pressing harder, without involuntarily moving the X,Y position and thereby selecting the wrong item.

The BIST algorithm gets around this potential problem by exploiting the natural way in which such a selection would be made: usually the touch contact position is adjusted until the required item is identified, held momentarily, then the selection gesture made. Thus, instead of taking the snapshot X,Y position at the time the gesture is recognized (the time that the Z value exceeds the push-harder threshold or a lift-off event status is reported), it looks backinto a circularbuffer (a form of stack containing the Nmost recent X,Y,Z reports, where the oldest contents are continually being overwritten by the newest) to find the plateau region where the touch was held on the required item.

After having found a plateau region of sufficient length, the X,Y values of the data report containing the selection-detected status are taken from the average of the X,Y values of the reports in the stable region. In this way, the X,Y value reported is relatively immuneto any variations that take place in X,Y between the actual finding of the item and trying to select it. The following figure illustrates this technique: |  * C  |    **       * o |      *       *    *           * o |      *     *  **** ***** * *** * r |        *  *             * *     * d |          *                       * i |         *                         * n |                                    * * a |                                       * t |                                        * e |                                         *  <  Lift off |   \

|         |               |                              Time ---> Manipulation  Hold on item  Select item by         to identify    to select     lift off item Notice the typical way in which the X,Y position tends to slideaway from the required selection point (thereby making selection of the required item impossible by normal means) as the selection gesture is made by releasing the touch force.

Without the BIST algorithm, the smallest size a selection item can be is restricted to approximately twice the anticipated X,Y movement, from selection to lift off.

What the BIST algorithm provides, therefore, is the ability to track back through a short history of the data to determine that a selection point was, indeed, being held just prior to lift off. In this way, the selection item size is limited by the amount of X,Y jitter while a touch is being held steady.

An alternative use for the BIST algorithm is cancelling a selection when, otherwise, cancellation would be inevitable: this is the case where the selection method is lift off, and there is no dead area on the screen for the user to move to and lift off without selecting anything. Wherever the user decides to lift off, something will be selected. What, then, does the user do if the screen is touched by accident, or touched, followed by a decision to cancel the operation?

In either case, all the user must do is lift off in a long, exaggerated swiping motion. This fills up the stack (circular buffer) with continually varying data so that there is no plateau region for the algorithm to find. Detailed selection in the manner described, and/or the method of not- selecting, of course, is restricted to experienced users. Both are operations that require some degree of practice, and in the case of the ability to not-select, the knowledge that the facility even exists (since a full-screen select-sensitive application screen, presumably, would leave no room for help instructions).


 * Pseudocode for the Back-in-the-Stack Algorithm

Main Routine If status == on-screen put X,Y into circular buffer If selection method == Lift Off Return Else    /* Must be push harder */ If ( z < Push Harder Threshold ) Return Else Call Send_Stable_Data Endif Endif Else If status == touch-down flush circular buffer clear flags Else    /* lift-off */ If selection method == Lift Off Call Send_Stable_Data Endif Endif

Send_stable_data Procedure Send_Stable_Data If already sent Return Else Call Check_Buffer_For_Stable_Region If Stable Region Detect flag Current X,Y = Stable X,Y Set flags Return Else Return Endif Endif EndProc

Check_Buffer_For_Stable_Region Procedure Check_Buffer_For_Stable_Region Stable Ref Point X,Y = Buffer Head X,Y Reset count, buffer index While points left in buffer Get buffer X,Y If ( Modulus( buffer X,Y - Stable Ref Point X,Y ) < Tolerance                count ++                 If count >= Stable Region Size                    Stable Region X,Y = Average X,Y over stable region                    Set Stable Region Detect flag                    Return                 Endif              Else                 Stable Ref Point X,Y = current X,Y                 Reset count, buffer index              Endif           EndWhile        Endproc

Click Locking
Click locking is the process by which the touch (X,Y) coordinate locks onto a value before being sent to the system as emulated mouse data.

Note: Click locking affects touch data only when it is sent as emulated mouse data and does not interfere with the normal use of an IBM PS/2 Mouse, if one is attached to the IBM Touch Display, or the data is sent in full touch pointing mode.

Click locking is performed because some actions with a clicked mouse button require that little movement of the mouse pointer itself take place. Click locking makes double clicking using the Touch display easier, because there is no need to maintain the touch position at exactly the same point between clicks.

The following examples of this can be found in the OS/2 Presentation Manager:
 * Clicking on an icon to bring up the system menu
 * Double clicking to activate the window

Clicking on an icon, when attempted with the Touch display's emulating the mouse, occasionally can result in the icon's moving a few pels, because the PM Desktop misinterprets the click down with associated movement as a drag operation to move the icon. PM decides that if the movement is more than a few pels, it must be a click with drag rather than a simple click. Thus, even a single click action sometimes can be unsuccessful.

The double-click action is more difficult: even if the first click can be made without moving the icon, the second click must be done at the same position. PM permits a small movement of 6 pels in the X direction and 8 pels in the Y direction. With a great deal of practice, this condition can be satisfied, but perhaps with only a 20% success rate. Click locking attempts to minimize the difficulty of maintaining the X,Y position while button clicking. While mainly applicable to PM, the click- locking technique is useful also in the DOS 4.0 shell and any application (usually in graphics mode) that uses a mouse.

The following click-lock options can be chosen:
 * No click locking
 * Single click locking
 * Double click locking

No Click Locking
Using this option, click locking can be turned off altogether, in which case, the system sees the touch coordinates directly as mouse coordinates.

Single Click Locking
This option locks the X,Y coordinates as soon as the button-down threshold has been exceeded. All subsequent touch coordinates are then reported to the system with this X,Y value when sent as emulated mouse data.

Normal reporting of X,Y coordinates resumes:
 * After the click-lock time has been exceeded
 * If the touch coordinate moves outside the click-lock area
 * If the touch is removed from the screen

Double Click Locking
This option is the same as single click locking, except that the conditions for reporting X,Y data are:
 * After the click-lock time has been exceeded
 * If the touch coordinate moves outside the click-lock area
 * If the button-down threshold is exceeded for a second time, the touch having been taken below the button-up threshold in the interim.

The third condition enables the X,Y coordinates of two successive touches to be locked at the same value. The touch need not be removed from the screen completely; it is sufficient just to go below the button-up threshold.

Click-Lock Area
This value determines the size of one side of a square that defines the click-lock area. The center of the square is located at the X,Y position at which the coordinates become locked. When the touch coordinates move outside the click-lock area, normal X,Y reporting is resumed.

The click-lock value is in pels, and, therefore, varies with screen resolution if a click-lock area of a given physical dimension is required. A large value makes double clicking at a point very easy, but it also makes immediate minor adjustment and close manipulation by dragging slightly more cumbersome.

Click-Lock Time
This value determines the time that is permitted to elapse between the time the coordinates first become locked and when normal X,Y reporting is resumed.

A large value makes double clicking a less hurried process but also makes immediate minor adjustments and close manipulation by dragging slightly more cumbersome.

Pseudocode for Click Locking
Constants: X_limit = limit of allowed movement in X direction Y_limit = limit of allowed movement in Y direction timeout = limit of time between successive clicks click_type = number of successive clicks to lock over

Variables: sd_count = number of successive clicks being locked over sd_time = system time at which timeout will occur sd_X    = initial button down X position sd_Y    = initial button down Y position X       = current reported X position Y       = current reported Y position

Initial state: sd_count = 0

On entry to the procedure, the X,Y values are set to the current X,Y coordinate report. A bit in a status word (selection       detection bit) reflects the binary state of the emulated mouse button (1= button down 0= button up).

/* Check if click locking active and still valid: if so, lock the coordinate, else reset the process */

If sd_count != 0

/* If click locking currently active */

If sd_time > current time && modulus(x - sd_x) < x_limit && modulus(y - sd_x) < y_limit

/* If not timed out and within lock area, */ /* force current X,Y position to first click position */ X = sd_X Y = sd_Y

If button going up                && (sd_count >= click_type)

/* If the 'button' is being released and required */ /* number of clicks reached */ sd_count = 0      /* Reset the click locking process */ Endif

Else

/* Timed out or moved outside lock area: reset click locking */ sd_count = 0 Endif Endif

/* Check if button going down to increment sd_count, thereby starting click locking if it was previously 0, or incrementing towards the required number of clicks if not */

If button going down

/* Reinitialise timeout time on each button down */

sd_time = current time + timeout

If sd_count == 0

/* If this is the first button down, set the lock coordinates to the current X,Y values */

sd_X = X             sd_Y = Y

Endif

sd_count++        /* Increment click count */

Endif