Hey!
I found a solution!
Disclaimer: I know this is a
terrible hack, but it's the only way i found to get my touchscreen to
work with Kivy on Raspberyy Pi. Also I don't know if this applies to
Linux in general or if it's just an issue with the rpi-port of Kivy.T
his is a individual solution for my use case. This breaks
mouse-input and disables anything else except touchscreen. it's fine though because my
embedded pi-project has no mouse connected.This solution ignores any calibration files or tslib-drivers. You have to do the calibration manually, but it's not so hard
First step: disable all input devices in ~/.kivy/config.ini except the touchscreen (make backup)
[input]
# comment out 'probesysfs' stuff
egalax = hidinput,/dev/input/event0 #replace event number with your own
Ok,
the problem is: Kivy doesn't recognize the EV_KEY code BTN_TOUCH (330)
sent by the touchscreen (verify with evtest). So I edited the
kivy/input/providers/hidinput.py:
(BACKUP)In the routine
process_as_mouse(), add the marked lines before the definition of
"buttons". This simply converts the key-code from a touch to a
left-click, so kivy recognizes it.
def process_as_mouse(...):
[...]
elif ev_type == EV_KEY:
### MOD: convert the egalax BTN_TOUCH to a mouse left click
if ev_code == 330: ## Add this
ev_code = 272 ##Add this
buttons = {
272: 'left',
273: 'right',
274: 'middle',
275: 'side',
276: 'extra',
277: 'forward',
278: 'back',
279: 'task'}
I tested everything with the
touchtracer demo
from the kivy examples, which is extremely helpful, because with the
crosshair you see every touch even it is outside the visible screen-area
So after the modification above, you should be able to see the
input from the touchscreen when you touch it. But the position is total
rubbish, because we now emulate a mouse, and a mouse gives relative
position values, while a touchscreen gives absolute values.
Now the calibration: use
evtest
to find out your min and max values for each axis and write them down.
also take note if the x and y axes are swapped and if they need to be
inverted (minimum-X is
left, minimum-Y is
bottom)
add these values to .kivy/config.ini:
[input]
# comment out 'probesysfs' stuff
egalax = hidinput,/dev/input/event0,min_position_x=200,max_position_x=1950,min_position_y=0,max_position_y=2000,swap_axes=1,invert_y=1,invert_x=1
### insert your values
again edit hidinput.py to add the 'swap_axes' option, which is not supported initially
class HIDInputMotionEventProvider(MotionEventProvider):
### MOD: add 'swap_axes' to possible options
options = ('min_position_x', 'max_position_x',
'min_position_y', 'max_position_y',
'min_pressure', 'max_pressure',
'invert_x', 'invert_y', 'swap_axes')
then in routine _thread_run():
def _thread_run(self, **kwargs):
[...]
range_min_position_x = 0
range_max_position_x = 2048
range_min_position_y = 0
range_max_position_y = 2048
range_min_pressure = 0
range_max_pressure = 255
invert_x = int(bool(drs('invert_x', 0)))
invert_y = int(bool(drs('invert_y', 0)))
### Add the following
swap_axes = int(bool(drs('swap_axes',0)))
min_position_x = int(drs('min_position_x',0))
max_position_x = int(drs('max_position_x',0))
min_position_y = int(drs('min_position_y',0))
max_position_y = int(drs('max_position_y',0))
this makes the calibration values available in the program (no idea why this isn't the case in the first place...)
Last step: in routine process_as_mouse():
def process_as_mouse(tv_sec, tv_usec, ev_type, ev_code, ev_value):
######## DELETE THIS:
elif ev_type == EV_REL:
if ev_code == 0:
point['x'] = \
min(1., max(0., point['x'] + ev_value / 1000.))
elif ev_code == 1:
point['y'] = \
min(1., max(0., point['y'] - ev_value / 1000.))
###### AND REPLACE WITH THIS:
elif ev_type == EV_ABS: #IMPORTANT, TS gives absolute position
if ev_code == 0:
if swap_axes:
val = normalize(ev_value,
min_position_y,
max_position_y)
if invert_y:
val = 1. - val
point['y'] = val
else:
val = normalize(ev_value,
min_position_x,
max_position_x)
if invert_x:
val = 1. - val
point['x'] = val
elif ev_code == 1:
if swap_axes:
val = normalize(ev_value,
min_position_x,
max_position_x)
if invert_x:
val = 1. - val
point['x'] = val
else:
val = normalize(ev_value,
min_position_y,
max_position_y)
if invert_y:
val = 1. - val
point['y'] = val
have
a close look at the indentation and correct if necessary.(i wrote this
post on windows and created the py-file on linux, so the copy&paste
messed up somehow)
save and try the touchtracer demo. this should work now (at least it works for me on raspberry)
keep in mind we changed a kivy-specific file, so this will most likely be reverted, when kivy is updated.
Also excuse my grammar ;)
Hope this helps
Regards, Spritkopf