Multi-touch HID minidriver problems

Hi,

Any HID minidriver expert out there?

I developed a virtual multi-touch HID minidriver that reports touch points data to windows HID class driver. I have an app that sends touch points data to the minidriver. I uses MTScratchpadWMTouch(from WDK) to see the visualized touch points. I have two problems in the minidriver:

Problem 1. When I send a single touch point (DOWN) data to the driver, the touch point is seen on the MTScratchpadWMTouch window, but if I send a second touch point DOWN data while the first touch point is still in DOWN state, the second point is not shown on the window. The data buffer that are reported by IOCTL_HID_READ_REPORT is:
first point (DOWN) in Hex:
03 07 10 27 10 27 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
first and second points (DOWN) in Hex:
03 07 10 27 10 27 01 00 00 00 00 07 88 13 88 13 02 00 00 00 00 02
where report_id=3,
contact_id1=1, in_range1=1, tip_switch1=1, valid_touch1=1, x1=10000, y1=10000, width1=0, height1=0,
contact_id2=2, in_range2=1, tip_switch2=1, valid_touch2=1, x2=5000, y2=5000, width2=0, height2=0

Problem 2. A point can’t be moved to a new location (new x and y) while it is in DOWN state (in_range=1, tip_switch=1, valid_touch=1). To move it, I have to change its state to UP(in_range=0, tip_switch=0, valid_touch=1) followed by DOWN state to a new location.

Any thoughts? Thanks.

Below is the report descriptor for my virtual multi-touch device:

HID_REPORT_DESCRIPTOR VirtualTouchScreenReportDescriptor =
{
// Custom Control collection
0x06, 0x00, 0xFF, // Usage Page (Vender Defined Usage Page)
0x09, 0x01, // Usage (Vendor Usage 0x01)
0xA1, 0x01, // Collection (Application)
0x85, CONTROL_FEATURE_REPORT_ID, // REPORT_ID (1)
0x09, 0x01, // Usage (Vendor Usage 0x01)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF,0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (0x08)
0x95, 0x01, // Report Count (0x01)
0xB1, 0x00, // Feature (Data,Ary,Abs)
0x09, 0x01, // Usage (Vendor Usage 0x01)
0x75, 0x08, // Report Size (0x08)
0x95, CUSTOM_INPUT_REPORT_BYTES, // Report Count (0x01)
0x81, 0x00, // Input (Data,Ary,Abs)
0xC0, // End Collection

// Mouse collection
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x02, // Usage (Mouse)
0xA1, 0x01, // Collection (Application)
0x85, MOUSE_REPORT_ID, // Report ID (2)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection (Physical)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button 1)
0x29, 0x03, // Usage Maximum (Button 3)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x95, 0x03, // Report Count (3)
0x75, 0x01, // Report Size (1)
0x81, 0x02, // Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
0x95, 0x01, // Report Count (1)
0x75, 0x05, // Report Size (5)
0x81, 0x01, // Input (Cnst,Ary,Abs)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x7F, // Logical Maximum (32767)
0x75, 0x10, // Report Size (16)
0x95, 0x02, // Report Count (2)
0x81, 0x02, // Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x38, // Usage (Wheel)
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (127)
0x75, 0x08, // Report Size (8)
0x95, 0x01, // Report Count (1)
0x81, 0x06, // Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit)
0x75, 0x08, // Report Size (8)
0x95, 0x04, // Report Count (4)
0x81, 0x01, // Input (Cnst,Ary,Abs)
0xC0, // End Collection
0xC0, // End Collection

// Touch Screen collection
0x05, 0x0D, // Usage_Page (Digitizer)
0x09, 0x04, // Usage (Touch Screen)
0xA1, 0x01, // Collection (Application)
0x85, TOUCHSCREEN_REPORT_ID, // Report Id (3)
0x05, 0x0D, // Usage Page (Digitizer)
0x09, 0x22, // Usage (Finger)
0xA1, 0x02, // Collection (Logical)
0x09, 0x32, // Usage (In Range)
0x09, 0x42, // Usage (Tip Switch)
0x09, 0x47, // Usage (Touch Valid)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x03, // Report Count (3)
0x81, 0x02, // Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
0x75, 0x01, // Report Size (1)
0x95, 0x05, // Report Count (5)
0x81, 0x01, // Input (Cnst,Ary,Abs)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x30, // Usage (X)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x7F, // Logical Maximum (32767)
0x35, 0x00, // Physical Minimum (0)
0x45, 0x00, // Physical Maximum (0)
0x65, 0x00, // Unit (None)
0x55, 0x0F, // Unit Exponent (-1)
0x75, 0x10, // Report Size (16)
0x95, 0x01, // Report Count (1)
0x81, 0x02, // Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
0x09, 0x31, // Usage (Y)
0x81, 0x02, // Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
0x05, 0x0D, // Usage Page (Digitizer)
0x09, 0x51, // Usage (Contact Id)
0x75, 0x08, // Report Size (8)
0x95, 0x01, // Report Count (1)
0x81, 0x02, // Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
0x09, 0x60, // Usage (Width)
0x09, 0x61, // Usage (Height)
0x75, 0x10, // Report Size (16)
0x95, 0x02, // Report Count (2)
0x81, 0x02, // Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
0xC0, // End Collection
0xA1, 0x02, // Collection (Logical)
0x09, 0x32, // Usage (In Range)
0x09, 0x42, // Usage (Tip Switch)
0x09, 0x47, // Usage (Touch Valid)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x03, // Report Count (3)
0x81, 0x02, // Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
0x75, 0x01, // Report Size (1)
0x95, 0x05, // Report Count (5)
0x81, 0x01, // Input (Cnst,Ary,Abs)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x30, // Usage (X)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x7F, // Logical Maximum (32767)
0x35, 0x00, // Physical Minimum (0)
0x45, 0x00, // Physical Maximum (0)
0x65, 0x00, // Unit (None)
0x55, 0x0F, // Unit Exponent (-1)
0x75, 0x10, // Report Size (16)
0x95, 0x01, // Report Count (1)
0x81, 0x02, // Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
0x09, 0x31, // Usage (Y)
0x81, 0x02, // Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
0x05, 0x0D, // Usage Page (Digitizer)
0x09, 0x51, // Usage (Contact Id)
0x75, 0x08, // Report Size (8)
0x95, 0x01, // Report Count (1)
0x81, 0x02, // Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
0x09, 0x60, // Usage (Width)
0x09, 0x61, // Usage (Height)
0x75, 0x10, // Report Size (16)
0x95, 0x02, // Report Count (2)
0x81, 0x02, // Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
0xC0, // End Collection
0x05, 0x0D, // Usage_Page (Digitizer)
0x09, 0x54, // Usage (Contact Count)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x0A, // Logical Maximum (10)
0x75, 0x08, // Report Size (8)
0x95, 0x01, // Report Count (1)
0x81, 0x02, // Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
0x09, 0x55, // Usage (Contact Count Maximum)
0xB1, 0x02, // Feature (Data,Var,Abs)
0xC0, // End Collection

// Device Configuration Collection
0x09, 0x0E, // Usage (Device Configuration)
0xA1, 0x01, // Collection (Application)
0x85, CONFIG_FEATURE_REPORT_ID, // Report Id (4)
0x09, 0x23, // Usage (Device Settings)
0xA1, 0x02, // Collection (Logical)
0x09, 0x52, // Usage (Device Mode)
0x09, 0x53, // Usage (Device Id)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x0A, // Logical Maximum (10)
0x75, 0x08, // Report Size (8)
0x95, 0x02, // Report Count (2)
0xB1, 0x02, // Feature (Data,Var,Abs)
0xC0, // End Collection
0xC0 // End Collection
};