rotate.py 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #!/usr/bin/env python2.7
  2. #######
  3. # Note: This is intended for the Kaby Lake HP Spectre x360. It was tested on model 13t-w000,
  4. # but should work on any tablet with the same touchscreen (name: ''ELAN0732:00 04F3:2493')
  5. # If it doesn't work, check the output of 'xinput --list', and replace the touchscreen id,
  6. # trackpad name, and pen (if applicable) at the top of the script with your values.
  7. from time import sleep
  8. from os import path as op
  9. import sys
  10. from subprocess import check_call, check_output
  11. from glob import glob
  12. # Your device names go here if different.
  13. TOUCHSCREEN = 'pointer:ELAN2514:00 04F3:2592'
  14. TOUCHPAD = 'SynPS/2 Synaptics TouchPad'
  15. PEN = 'ELAN2514:00 04F3:2592 Pen (0)'
  16. disable_touchpads = True
  17. def bdopen(fname):
  18. return open(op.join(basedir, fname))
  19. def read(fname):
  20. return bdopen(fname).read()
  21. for basedir in glob('/sys/bus/iio/devices/iio:device*'):
  22. if 'accel' in read('name'):
  23. break
  24. else:
  25. sys.stderr.write("Can't find an accellerator device!\n")
  26. sys.exit(1)
  27. scale = float(read('in_accel_scale'))
  28. g = 7.0 # (m^2 / s) sensibility, gravity trigger
  29. STATES = [
  30. {'rot': 'normal', 'coord': '1 0 0 0 1 0 0 0 1', 'touchpad': 'enable',
  31. 'check': lambda x, y: y <= -g},
  32. {'rot': 'inverted', 'coord': '-1 0 1 0 -1 1 0 0 1', 'touchpad': 'disable',
  33. 'check': lambda x, y: y >= g},
  34. {'rot': 'left', 'coord': '0 -1 1 1 0 0 0 0 1', 'touchpad': 'disable',
  35. 'check': lambda x, y: x >= g},
  36. {'rot': 'right', 'coord': '0 1 0 -1 0 1 0 0 1', 'touchpad': 'disable',
  37. 'check': lambda x, y: x <= -g},
  38. ]
  39. def rotate(state):
  40. s = STATES[state]
  41. check_call(['xrandr', '-o', s['rot']])
  42. check_call(['xinput', 'set-prop', TOUCHSCREEN, 'Coordinate Transformation Matrix',] + s['coord'].split())
  43. if "Pen (0)" in check_output(['xinput', '--list']):
  44. check_call(['xinput', 'set-prop', PEN, 'Coordinate Transformation Matrix',] + s['coord'].split())
  45. if disable_touchpads:
  46. check_call(['xinput', s['touchpad'], TOUCHPAD])
  47. def read_accel(fp):
  48. fp.seek(0)
  49. return float(fp.read()) * scale
  50. if __name__ == '__main__':
  51. accel_x = bdopen('in_accel_x_raw')
  52. accel_y = bdopen('in_accel_y_raw')
  53. current_state = None
  54. check_call(['sudo','-u','root','touch','/tmp/tabletmode'])
  55. while True:
  56. x = read_accel(accel_x)
  57. y = read_accel(accel_y)
  58. for i in range(4):
  59. if i == current_state:
  60. continue
  61. if STATES[i]['check'](x, y):
  62. current_state = i
  63. rotate(i)
  64. break
  65. if STATES[current_state]['rot'] != 'normal':
  66. check_call(['onboard &'], shell=True)
  67. else:
  68. check_call(['killall onboard || true'], shell=True)
  69. check_call(['inotifywait','/tmp/tabletmode'])