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