Solution 1:

Short answer

tabcal.exe ClearCal DisplayID=\\.\DISPLAY1

Long answer

You won't find an official list of command-line parameters for tabcal.exe anywhere, but I hope this is of use to someone. This information is brought to you by Process Monitor (my go-to utility to understand what a process was told to do via command line arguments as well as what's it's doing to other processes, the file system, and registry) and liberal use of the Google.

Here's what I believe I've figured out:

ClearCal

              resets calibration data for a given device
              requires DisplayID

LinCal

              runs calibration
              (if ClearCal isn't specified, default function is LinCal)
              requires DisplayID if you have more than one device with pen and/or touch capabilities
              may require DeviceKind if you have both pen and touch digitizers on a single display

DisplayID=\\.\DISPLAY1

              one-based display index associated with the touch screen
              (If you have two displays it's 1 or 2; value matches multi-display identification number in Display Control Panel)

Quiet

              Suppresses message boxes
              E.g., if you do LinCal, your changes will be saved rather than being prompted if you'd like to save
              E.g., if you have an error with your command-line arguments, you won't receive a message indicating that

DeviceKind={touch,pen}

              Seemingly optional argument to ClearCal and LinCal to indicate the type of digitizer
              (I suspect it may be required if you have both on the same display but my digitizer supports only touch.)

{validate,novalidate}

              Optional argument to LinCal to prevent or accept registration of calibration marks that are way off from the crosshairs
              If unspecified, the default is validate

XGridPts=
YGridPts=

              Optional arguments (if used both required) to LinCal to specify X and Y coordinates of crosshairs for calibration.
              Values are a comma-delimited list without spaces of the zero-based pixel coordinates
              (e.g., for a 1920×1080, display X values 0-1919 and Y values 0-1079 are accepted; some examples are below)
              If unspecified, calibration points default to four unless previously specified (values are retrieved from HKLM:\SYSTEM\CurrentControlSet\Control\TabletPC\LinearityData)

Export

              Optional argument to LinCal to export calibration data to a file.
              Output file is in directory from which tabcal was called, named 'caldatan.txt', where n is a zero-based auto-incrementing number
              Contents of file are the name of the digitizer, a line break, and the same hex string written to the registry value in HKLM:\SYSTEM\CurrentControlSet\Control\TabletPC\LinearityData
              (I haven't found a corresponding Import function.)

Other stuff I've learned

There are three registry subkeys which contain calibration data:

  • HKLM:\SYSTEM\CurrentControlSet\Control\TabletPC\LinearityData
  • HKLM:\SYSTEM\CurrentControlSet\Control\TabletPC\UserLinearityData
  • HKLM:\SYSTEM\CurrentControlSet\Enum\HID\VID_xxxx&&PID_xxxx&Colxx\(non-deterministic)\Device Parameters

The first two may contain a binary value named vid_xxxxpid_xxxx&colxx containing the calibration data for that specific device as well as XGridPts and YGridPts values if you calibrated with more than 4 touch points.

The Enum\HID subkey that has the same VID/PID/Col values in its name as the LinearityData value will have a value named LinearityData with the same data as the above.

If you delete all of these registry values, you will have reset the calibration data, but the change doesn't take effect until that data is read back in by the system, either on the subsequent boot or when the wisptis.exe user process is restarted. (An orderly restart of the Tablet PC Input Service doesn't do it even though it stops and restarts the wisptis.exe processes. Go figure.)

A much easier way to do this is to run the following command (which requires elevation) which deletes those keys and effects the change immediately:

tabcal.exe ClearCal DeviceKind=touch DisplayID=\\.\DISPLAY1

This is the exact command that is run when a user selects "Reset..." from the Tablet PC Settings Control Panel on my test system. If you have a pen-input device or a different display configuration, your command may differ slightly. (If you have UAC enabled, before allowing the Reset action you can open the Details pane to see the full command-line to be executed. Alternatively, you could pull that info from Process Monitor.)

As you already determined, you can then re-calibrate the touchscreen using a derivative of one of the following commands depending on the size of your display and your specific requirements:

# Default touch calibration (4 points unless someone's previously specified XGridPts/YGridPts)
tabcal.exe lincal novalidate devicekind=touch
tabcal.exe lincal novalidate devicekind=pen

# Example 25-point touch calibration for 1920×1080 display
tabcal.exe lincal novalidate devicekind=touch XGridPts=10,485,960,1435,1910 YGridPts=10,275,540,805,1070

# Example 121-point pen calibration (from a Microsoft Surface forum)
tabcal.exe lincal novalidate devicekind=pen XGridPts=10,60,110,360,660,960,1260,1560,1810,1860,1910 YGridPts=10,60,110,200,330,490,650,810,970,1020,1070

Solution 2:

I ran tabcal through strings. The list below may be possible switches. I do not know what they do.

LinCal
ShowCursor
Quiet
NoValidate
SaveFiles
Export
UserLinCal
ClearCal
NoDesktop
XInterval=
YInterval=
XGridPts=
YGridPts=
DeviceName=
DevicePath=
DisplayID=
DeviceKind=
UserSid=
UserSid=%s %s
RunAs
TabCalSingleInstance

Solution 3:

Additional information:

On Windows 10, instead of restarting wisptis.exe, you have to kill DWM.exe (it restarts automatically) for the new values from the registry to take effect (if you don't use TabCal.exe).

Also of note, if you change the calibration data manually in the registry, you should emit the Windows message SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, NULL, "TabletPCDigitizerMappingChanged") as TabCal does to notify any client that calibration values have changed.

Solution 4:

Thank you so much for everyone's work in this thread! I was able to use this information to solve a y-axis inversion problem with a new touchscreen. I created the custom calibration test using the following code:

tabcal lincal novalidate DeviceKind=touch DisplayID=\\.\DISPLAY1 XGridPts=99,1265 YGridPts=99,667

This successfully inverted my y-axis points and allowed me to use the new touchscreen normally. This was used on a 1366 by 768 display so edit according to your display size.