Table Of Contents
Source code for kivy.input.postproc.calibration
'''
Calibration
===========
.. versionadded:: 1.9.0
Recalibrate input device to a specific range / offset.
Let's say you have 3 1080p displays, the 2 firsts are multitouch. By default,
both will have mixed touch, the range will conflict with each others: the 0-1
range will goes to 0-5760 px (remember, 3 * 1920 = 5760.)
To fix it, you need to manually reference them. For example::
[input]
left = mtdev,/dev/input/event17
middle = mtdev,/dev/input/event15
# the right screen is just a display.
Then, you can use the calibration postproc module::
[postproc:calibration]
left = xratio=0.3333
middle = xratio=0.3333,xoffset=0.3333
Now, the touches from the left screen will be within 0-0.3333 range, and the
touches from the middle screen will be within 0.3333-0.6666 range.
'''
__all__ = ('InputPostprocCalibration', )
from kivy.config import Config
from kivy.logger import Logger
[docs]class InputPostprocCalibration(object):
'''Recalibrate the inputs.
The configuration must go within a section named `postproc:calibration`.
Within the section, you must have line like::
devicename = param=value,param=value
:Parameters:
`xratio`: float
Value to multiply X
`yratio`: float
Value to multiply Y
`xoffset`: float
Value to add to X
`yoffset`: float
Value to add to Y
'''
def __init__(self):
super(InputPostprocCalibration, self).__init__()
self.devices = {}
self.frame = 0
if not Config.has_section('postproc:calibration'):
return
default_params = {'xoffset': 0, 'yoffset': 0, 'xratio': 1, 'yratio': 1}
for device_key, params_str in Config.items('postproc:calibration'):
params = default_params.copy()
for param in params_str.split(','):
param = param.strip()
if not param:
continue
key, value = param.split('=', 1)
if key not in ('xoffset', 'yoffset', 'xratio', 'yratio'):
Logger.error(
'Calibration: invalid key provided: {}'.format(key))
params[key] = float(value)
self.devices[device_key] = params
def process(self, events):
# avoid doing any processing if there is no device to calibrate at all.
if not self.devices:
return events
self.frame += 1
frame = self.frame
for etype, event in events:
# frame-based logic below doesn't account for
# end events having been already processed
if etype == 'end':
continue
if event.device not in self.devices:
continue
# some providers use the same event to update and end
if 'calibration:frame' not in event.ud:
event.ud['calibration:frame'] = frame
elif event.ud['calibration:frame'] == frame:
continue
params = self.devices[event.device]
event.sx = event.sx * params['xratio'] + params['xoffset']
event.sy = event.sy * params['yratio'] + params['yoffset']
event.ud['calibration:frame'] = frame
return events