Skip to content

Instantly share code, notes, and snippets.

@vurpo
Last active May 27, 2022 12:20
Show Gist options
  • Save vurpo/6fc229421368a68c9bdccec2103bb7ff to your computer and use it in GitHub Desktop.
Save vurpo/6fc229421368a68c9bdccec2103bb7ff to your computer and use it in GitHub Desktop.
https://github.com/StollD/linux-surface-fix-eraser but modified to also disable the touch screen when the pen is near the screen
#!/usr/bin/env python3
"""
Copyright 2019 StollD, 2019 vurpo
Original: https://github.com/StollD/linux-surface-fix-eraser
Licensed under GNU GPL version 3
"""
import os
import os.path
import sys
from errno import ENOENT
from evdev import InputDevice, UInput
from evdev.events import InputEvent
from evdev.ecodes import BTN_TOUCH, BTN_TOOL_PEN, BTN_TOOL_RUBBER, EV_KEY
from signal import signal, SIGINT
# Automatically discover the device
for name in os.listdir('/dev/input'):
if not name.startswith('event'):
continue
tmpdev = InputDevice('/dev/input/' + name)
if 'uinput' in tmpdev.name or 'Virtual Stylus' in tmpdev.name:
continue
keys = tmpdev.capabilities().get(EV_KEY)
if keys == None:
continue
# detect the pen input device
if BTN_TOOL_PEN in keys and BTN_TOOL_RUBBER in keys:
device = '/dev/input/' + name
continue
# detect the touch screen
if BTN_TOUCH in keys:
touchdevice = '/dev/input/' + name
continue
if device != None and touchdevice != None:
print('Found event: ' + device + ' and touch device ' + touchdevice)
else:
print('No event found! Exiting.')
sys.exit(-ENOENT)
dev = InputDevice(device)
tdev = InputDevice(touchdevice)
virt = UInput.from_device(dev, name=dev.name + ' Virtual Stylus')
def handleExit(s, f):
dev.ungrab()
sys.exit(0)
# Take over complete control over the device - no events will be passed to
# other listeners. They are relayed to the virtual stylus created above.
signal(SIGINT, handleExit)
dev.grab()
for event in dev.read_loop():
# When putting the pen down, grab the touch screen device's input
# and when lifting the pen, ungrab it
#
# Because of the other bug mentioned below, this also works with
# the eraser end of the pen.
if event.code == BTN_TOOL_PEN:
if event.value == 1:
try:
tdev.grab()
except:
pass
else:
try:
tdev.ungrab()
except:
pass
# When putting the eraser down, IPTS first sends an event that puts
# down the Pen, and after that puts down the eraser. As far as the
# system is concerned, you put down BOTH, the eraser and the pen.
#
# To fix this, we wait for all eraser events, and inject an event that
# lifts up the pen again, before relaying the event to put down the
# eraser.
if event.code == BTN_TOOL_RUBBER:
e = InputEvent(event.sec, event.usec, EV_KEY, BTN_TOOL_PEN, 0)
virt.write_event(e)
virt.syn()
virt.write_event(event)
dev.ungrab()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment