| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
"""Logictech MouseMan serial protocol. |
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
from twisted.internet import protocol |
|---|
| 11 |
|
|---|
| 12 |
class 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 |
|
|---|
| 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) |
|---|