Data injection


The driver can process touches from both physical hardware and virtual devices whereby the touch data is injected into the driver via the API, using the following APIs:

Function Description 
TBApiInjectTouch Simple interface to post co-ordinate data into the driver
TBApiPostHIDPacket    This API is available from UPDD version 7.1.21 and allows data to be passed to the driver in the format of an HID data packet, i.e. a format that might be used by a physical device such as a touchscreen or keyboard.
Data passed to the driver can either be processed normally by the driver, as though from a connected physical device or, on Windows only, passed directly to the operating system as though it comes from a physical device.

These interfaces are useful to support a device where the hardware is being controlled by other software. Similarly, an application can be used to drive the system pointer without a physical device being used.

The API require an active device is configured in the driver.  In cases whereby UPDD is not supporting an actual physical device, and therefore no active device exist, UPDD also supports virtual devices to allow for an active device to exist for the purposes of these APIs.

To use a virtual device, you will first need a driver with support for a virtual device. For want of a better name, we have named the virtual device 'Generic, Virtual'.

Then use the adddevice option in upddutils to add an instance of such a device, e.g. upddutils adddevice 1

A new device setting is used in conjunction with virtual devices. “virtual_device” will by default have a value of 1 (meaning true).

The UPDD Console will show a virtual device as connected (OK) in this case. A program can set this value to 0 (meaning false) to have the status show disconnected (NOK).

This option is supported for all controller types but only a value of 1 has an effect, this forces the device into a connected state so that devices being used in this way are listed as working in user interfaces and to programs using the API.

TBApiInjectTouch

Please note that certain aspects of the active controller need to be considered when injecting data, one being the defined co-ordinate range, which in the case of the Generic, Virtual device is 0 - 1024 for both X and Y.  These values are held in settings calx0, calx1, caly0 and caly1.  For other devices they can be viewed using the upddutils [device n] get "*" command.

Posting raw data packets

In addition to the above API to inject complete touch data it is also possible to post raw touch data to an active touch device using the API TBApiPostPacketBytes in the raw data format configured for the physical device.

We use this API to playback captured data using upddutils recordraw to help troubleshoot reported touch issues for a given controller configuration.

Example TBApiInjectTouch code

The code sample below is a test function that can either draw a circle or simulate a 4 point calibration sequence - this is a code fragment and not a complete solution!

int DoSelfTest(const vector<string>& aArgs)

{
  if (aArgs.size() != 3) 
    return(Usage());
  }
  if (aArgs[2] != "circle" && aArgs[2] != "calibrate")
  {
    return(Usage());
  } 

  int t;
  sscanf(aArgs[1].c_str(), "%d", &t); 
  Sleep(t * 1000);

  double x, y;

  if (aArgs[2] == "circle")
  {
    for (int a = 0; a < 360; a++)
    {
      double r = a * 3.141592 / 180;
      x = 512 + (cos(r) * 300);
      y = 512 + (sin(r) * 300);
      TBApiInjectTouch(gSelectedDevice, (int)x, (int)y, 0, 1);
      Sleep(20);
    }
    TBApiInjectTouch(gSelectedDevice, (int)x, (int)y, 0, 0);
    return(0);
  } 

  // calib point 1
  int margin = 1023 / 10; 
  for (int n = 0; n < 50; n++)
  {
    x = margin;
    y = margin;
    TBApiInjectTouch(gSelectedDevice, (int)x, (int)y, 0, 1);
    Sleep(20);
  }
  TBApiInjectTouch(gSelectedDevice, (int)x, (int)y, 0, 0);
  Sleep(1000); 

  // calib point 2
  for (int n = 0; n < 50; n++)
  {
    x = 1023 - margin;
    y = margin;
    TBApiInjectTouch(gSelectedDevice, (int)x, (int)y, 0, 1);
    Sleep(20);
  }
  TBApiInjectTouch(gSelectedDevice, (int)x, (int)y, 0, 0);
  Sleep(1000); 

  // calib point 3
  for (int n = 0; n < 50; n++)
  {
    x = margin;
    y = 1023 - margin;
    TBApiInjectTouch(gSelectedDevice, (int)x, (int)y, 0, 1);
    InternalApiSleep(20);
  }
  TBApiInjectTouch(gSelectedDevice, (int)x, (int)y, 0, 0);
  Sleep(1000);

  
// calib point 4
  for (int n = 0; n < 50; n++)
  {
    x = 1023 - margin;
    y = 1023 - margin;
    TBApiInjectTouch(gSelectedDevice, (int)x, (int)y, 0, 1);
    Sleep(20);
  }
  TBApiInjectTouch(gSelectedDevice, (int)x, (int)y, 0, 0);
  return(0);
}

TBApiPostHIDPacket

The API definition is as follows:

 

Arguments   Description 
 aHandle A UPDD device handle. This indicates the UPDD device instance that will process the passed data.
  • For keyboard data this is ignored.
  • When using direct mode the device instance is used only to determine which monitor to direct the data to.
  • When using direct mode with mouse data this is ignored.
Typically a UPDD virtual device instance will be created, using the API TBAPIAddDevice or upddutils adddevice in the cases where a device handle is needed, but it is also possible to use this  in conjunction with a UPDD device instance related to a connected physical device.
 aDirect A Boolean value. When true(1) data is passed without additional processing to the OS via a virtual HID device. This is only available on Windows.
 aPacket The raw data of the HID packet. In the HID protocol the type of device is identified by a report ID. Five device types are available and defined by their report IDs as shown in upddapi.h


  HID reports use an HID report descriptor format  that can be difficult to interpret without detailed knowledge of the protocol, so to simplify this a C struct representation of report (data packet) is used as shown in updd api.h.



Return value True (1) on success, otherwise false (0).
Using the API A detailed description of the HID protocol is outside the scope of this document. The usage is illustrated by the source of an example Visual Studio 2019 project post_hid available from here.
Example project  

The post_hid example illustrates the use of all 5 available device types. Its operation is explained in the comments.
To run, install UPDD, then build the project.
The program accepts two arguments, the first specifies the mode(s) to be tested as one or more single characters, e.g. tmkp or tp where
   t = touch screen
   p = pen
   m = touch mouse
   r = regular mouse
   k = keyboard

The second, optional argument, indicates whether direct or indirect mode is to be used. The default if not specified is direct  mode.
Note: Before running, either a physical or virtual device must be active in UPDD, even if the test mode does not need it, such as keyboard mode.

The supplied project is set up for 64 bit support and if used unchanged it will build / run from inside Visual Studio 2019.

We have received a customer report that opening in a newer version of Visual Studio updates the project file and drops the working directory setting, which should be set as follows:

If running outside Visual Studio, you should set the working directory to c:\program files\updd