mouseman.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. #
  4. """Logictech MouseMan serial protocol.
  5. http://www.softnco.demon.co.uk/SerialMouse.txt
  6. """
  7. from twisted.internet import protocol
  8. class MouseMan(protocol.Protocol):
  9. """
  10. Parser for Logitech MouseMan serial mouse protocol (compatible
  11. with Microsoft Serial Mouse).
  12. """
  13. state = 'initial'
  14. leftbutton=None
  15. rightbutton=None
  16. middlebutton=None
  17. leftold=None
  18. rightold=None
  19. middleold=None
  20. horiz=None
  21. vert=None
  22. horizold=None
  23. vertold=None
  24. def down_left(self):
  25. pass
  26. def up_left(self):
  27. pass
  28. def down_middle(self):
  29. pass
  30. def up_middle(self):
  31. pass
  32. def down_right(self):
  33. pass
  34. def up_right(self):
  35. pass
  36. def move(self, x, y):
  37. pass
  38. horiz=None
  39. vert=None
  40. def state_initial(self, byte):
  41. if byte & 1<<6:
  42. self.word1=byte
  43. self.leftbutton = byte & 1<<5
  44. self.rightbutton = byte & 1<<4
  45. return 'horiz'
  46. else:
  47. return 'initial'
  48. def state_horiz(self, byte):
  49. if byte & 1<<6:
  50. return self.state_initial(byte)
  51. else:
  52. x=(self.word1 & 0x03)<<6 | (byte & 0x3f)
  53. if x>=128:
  54. x=-256+x
  55. self.horiz = x
  56. return 'vert'
  57. def state_vert(self, byte):
  58. if byte & 1<<6:
  59. # short packet
  60. return self.state_initial(byte)
  61. else:
  62. x = (self.word1 & 0x0c)<<4 | (byte & 0x3f)
  63. if x>=128:
  64. x=-256+x
  65. self.vert = x
  66. self.snapshot()
  67. return 'maybemiddle'
  68. def state_maybemiddle(self, byte):
  69. if byte & 1<<6:
  70. self.snapshot()
  71. return self.state_initial(byte)
  72. else:
  73. self.middlebutton=byte & 1<<5
  74. self.snapshot()
  75. return 'initial'
  76. def snapshot(self):
  77. if self.leftbutton and not self.leftold:
  78. self.down_left()
  79. self.leftold=1
  80. if not self.leftbutton and self.leftold:
  81. self.up_left()
  82. self.leftold=0
  83. if self.middlebutton and not self.middleold:
  84. self.down_middle()
  85. self.middleold=1
  86. if not self.middlebutton and self.middleold:
  87. self.up_middle()
  88. self.middleold=0
  89. if self.rightbutton and not self.rightold:
  90. self.down_right()
  91. self.rightold=1
  92. if not self.rightbutton and self.rightold:
  93. self.up_right()
  94. self.rightold=0
  95. if self.horiz or self.vert:
  96. self.move(self.horiz, self.vert)
  97. def dataReceived(self, data):
  98. for c in data:
  99. byte = ord(c)
  100. self.state = getattr(self, 'state_'+self.state)(byte)