New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[input]Provider matching for input postproc calibration #5870
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
c64c00f
Add option to match calibration rules by provider instead of a specif…
231f7b5
Add comments for input calibration by provider.
a6e61e1
Improvement to comments for provider calibration.
40bfe36
Simplify logic for matching providers for calibration.
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,22 +26,45 @@ | |
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. | ||
|
||
You can also match calibration rules to devices based on their provider type. | ||
This is useful when probesysfs is used to match devices. For example:: | ||
|
||
[input] | ||
mtdev_%(name)s = probesysfs,provider=mtdev | ||
|
||
Then to apply calibration to any mtdev device, you can assign rules to the | ||
provider name enclosed by parentheses:: | ||
|
||
[postproc:calibration] | ||
(mtdev) = xratio=0.3333,xoffset=0.3333 | ||
|
||
Calibrating devices like this means the device's path doesn't need to be | ||
configured ahead of time. Note that with this method, all mtdev inputs will | ||
have the same calibration applied to them. For this reason, matching by | ||
provider will typically be useful when expecting only one input device. | ||
''' | ||
|
||
__all__ = ('InputPostprocCalibration', ) | ||
|
||
from kivy.config import Config | ||
from kivy.logger import Logger | ||
from kivy.input import providers | ||
from kivy.input.factory import MotionEventFactory | ||
from kivy.input.motionevent import MotionEvent | ||
|
||
|
||
class InputPostprocCalibration(object): | ||
'''Recalibrate the inputs. | ||
|
||
The configuration must go within a section named `postproc:calibration`. | ||
Within the section, you must have line like:: | ||
Within the section, you must have a line like:: | ||
|
||
devicename = param=value,param=value | ||
|
||
If you wish to match by provider, you must have a line like:: | ||
|
||
(provider) = param=value,param=value | ||
|
||
:Parameters: | ||
`xratio`: float | ||
Value to multiply X | ||
|
@@ -58,6 +81,7 @@ def __init__(self): | |
super(InputPostprocCalibration, self).__init__() | ||
self.devices = {} | ||
self.frame = 0 | ||
self.provider_map = self._get_provider_map() | ||
if not Config.has_section('postproc:calibration'): | ||
return | ||
default_params = {'xoffset': 0, 'yoffset': 0, 'xratio': 1, 'yratio': 1} | ||
|
@@ -74,6 +98,33 @@ def __init__(self): | |
params[key] = float(value) | ||
self.devices[device_key] = params | ||
|
||
def _get_provider_map(self): | ||
"""Iterates through all registered input provider names and finds the | ||
respective MotionEvent subclass for each. Returns a dict of MotionEvent | ||
subclasses mapped to their provider name. | ||
""" | ||
provider_map = {} | ||
for input_provider in MotionEventFactory.list(): | ||
if not hasattr(providers, input_provider): | ||
continue | ||
|
||
p = getattr(providers, input_provider) | ||
for m in p.__all__: | ||
event = getattr(p, m) | ||
if issubclass(event, MotionEvent): | ||
provider_map[event] = input_provider | ||
|
||
return provider_map | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is what provider_map looks like:
|
||
|
||
def _get_provider_key(self, event): | ||
"""Returns the provider key for the event if the provider is configured | ||
for calibration. | ||
""" | ||
input_type = self.provider_map.get(event.__class__) | ||
key = '({})'.format(input_type) | ||
if input_type and key in self.devices: | ||
return key | ||
|
||
def process(self, events): | ||
# avoid doing any processing if there is no device to calibrate at all. | ||
if not self.devices: | ||
|
@@ -86,14 +137,20 @@ def process(self, events): | |
# end events having been already processed | ||
if etype == 'end': | ||
continue | ||
if event.device not in self.devices: | ||
|
||
if event.device in self.devices: | ||
dev = event.device | ||
else: | ||
dev = self._get_provider_key(event) | ||
if not dev: | ||
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] | ||
params = self.devices[dev] | ||
event.sx = event.sx * params['xratio'] + params['xoffset'] | ||
event.sy = event.sy * params['yratio'] + params['yoffset'] | ||
event.ud['calibration:frame'] = frame | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only called once in __init__, and I was unsure if MotionEventFactory.list() might ever change its output after this. Can anyone confirm?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Touch providers are supposed/assumed to be registered before all of this already, while it would be cool to be allow to enable/disable them at runtime, this is currently not really possible anyway, so no worries here.