STYLE Some feedback prompted me to add commentary.

Documented what the heck I meant by 'ptx', 'lsi', etc. etc.  Also where
the numbers came from, but the simplest answer is that you start a
simple dump of the registers to your console while holding the device
in your hand and you rotate it to the various positions, writing down
the numbers you see and then tuning as necessary.  Programming as an
empirical science, not a theoretical one.

Also: I have a really (REALLY) silly script that lets me see all the
projects currently underway in my ~/Projects directory, and it looks for
the DESCRIPTION.md file.  So that's what you're getting.
This commit is contained in:
Elf M. Sternberg 2018-02-12 18:34:01 -08:00
parent ea81a9d141
commit 6d67d72d2c
2 changed files with 21 additions and 6 deletions

1
DESCRIPTION.md Normal file
View File

@ -0,0 +1 @@
A series of tools for making the Surface Pro 3 usable under Linux.

View File

@ -32,6 +32,7 @@ def find_accelerometers():
return (os.path.join(dpath[0], 'in_accel_x_raw'), return (os.path.join(dpath[0], 'in_accel_x_raw'),
os.path.join(dpath[0], 'in_accel_y_raw')) os.path.join(dpath[0], 'in_accel_y_raw'))
x_accel_path, y_accel_path = find_accelerometers() x_accel_path, y_accel_path = find_accelerometers()
@ -42,24 +43,36 @@ def refreshtouch():
def countdisplays(): def countdisplays():
return int(len([l for l in subprocess.check_output(['xrandr', '--current']).splitlines() return int(len([l for l in subprocess.check_output(['xrandr', '--current']).splitlines()
if MONITOR_CONNECTED_RE.search(l)])) if MONITOR_CONNECTED_RE.search(l)]))
# Landscape # Landscape
# The 'X' means to read the 'x_accel_path' register, since that's what
# we need to determine landscape (ls) or portrait (pt) mode. 'N' is
# 'Normal' and 'I' is 'Inverted.' The magic numbers for the 'X' are
# around a 65536-based device register; I'm guessing Poel worked with
# them by just dumping them to the screen while tilting the screen
# this way and that. They seem to work just fine.
def lsx(thex, they): return thex >= 65000 or thex <= 650 def lsx(thex, they): return thex >= 65000 or thex <= 650
def lsn(thex, they): return they <= 65000 and they >= 64000 def lsn(thex, they): return they <= 65000 and they >= 64000
def lsi(thex, they): return they >= 650 and they <= 1100 def lsi(thex, they): return they >= 650 and they <= 1100
# Portrait # Portrait: L for "Left" and R for "Right."
def ptx(thex, they): return not lsx(thex, they) def ptx(thex, they): return not lsx(thex, they)
def ptl(thex, they): return thex >= 800 and thex <= 1000 def ptl(thex, they): return thex >= 800 and thex <= 1000
def ptr(thex, they): return thex >= 64500 and thex <=64700 def ptr(thex, they): return thex >= 64500 and thex <= 64700
# It's a little odd that X labels it 'left' when you've just turned # It's a little odd that X labels it 'left' when you've just turned
# the tablet to the right, and vice versa, but that's the convention, # the tablet to the right, and vice versa, but that's the convention,
# I guess. # I guess.
Transform = namedtuple('Tranform', ['name', 'mode', 'matrix', 'xrule', 'yrule']) Transform = namedtuple('Tranform', ['name', 'mode', 'matrix', 'xrule', 'yrule'])
transforms = [ transforms = [
Transform('normal', 0, '1 0 0 0 1 0 0 0 1', lsx, lsn), Transform('normal', 0, '1 0 0 0 1 0 0 0 1', lsx, lsn),
Transform('inverted', 1, '-1 0 1 0 -1 1 0 0 1', lsx, lsi), Transform('inverted', 1, '-1 0 1 0 -1 1 0 0 1', lsx, lsi),
@ -81,14 +94,14 @@ def manage_orientation_and_palm_rejection(options):
int_displays = countdisplays() int_displays = countdisplays()
time.sleep(1.0/freq) time.sleep(1.0/freq)
if int_displays == 1: if int_displays == 1:
# Check accelerometers # Check accelerometers
# Do we need to check the touch_devices list every time? I # Do we need to check the touch_devices list every time? I
# think we do; the list will change dynamically if we # think we do; the list will change dynamically if we
# dynamically load the stylus driver after the system has # dynamically load the stylus driver after the system has
# booted. # booted.
touch_devices = filter(lambda n: DIGITIZER_RE.match(n), touch_devices = filter(lambda n: DIGITIZER_RE.match(n),
subprocess.check_output(['xinput', '--list', '--name-only']).splitlines()) subprocess.check_output(['xinput', '--list', '--name-only']).splitlines())
with open(x_accel_path, 'r') as fx: with open(x_accel_path, 'r') as fx:
with open(y_accel_path, 'r') as fy: with open(y_accel_path, 'r') as fy:
thex = float(fx.readline()) thex = float(fx.readline())
@ -104,7 +117,7 @@ def manage_orientation_and_palm_rejection(options):
current_orientation = check.name current_orientation = check.name
refreshtouch() refreshtouch()
break break
# Palm rejection (sort-of): # Palm rejection (sort-of):
pen_devices = [p for p in touch_devices if PEN_RE.search(p)] pen_devices = [p for p in touch_devices if PEN_RE.search(p)]
pen_status = bool([p for p in pen_devices if is_in(p)]) pen_status = bool([p for p in pen_devices if is_in(p)])
@ -113,5 +126,6 @@ def manage_orientation_and_palm_rejection(options):
currently_proximate = pen_status currently_proximate = pen_status
os.system("xinput %s '%s'" % (xinput_statemap[pen_status], devicename)) os.system("xinput %s '%s'" % (xinput_statemap[pen_status], devicename))
if __name__ == '__main__': if __name__ == '__main__':
manage_orientation_and_palm_rejection(sys.argv[1:]) manage_orientation_and_palm_rejection(sys.argv[1:])