import RPi.GPIO as GPIO
import time

KeyboardLeftControl  =   1 ## 0x01     
KeyboardLeftShift    =   2 ## 0x02
KeyboardLeftAlt      =   4 ## 0x04
KeyboardLeftMeta     =   8 ## 0x08
KeyboardRightControl =  16 ## 0x10
KeyboardRightShift   =  32 ## 0x20
KeyboardRightAlt     =  64 ## 0x40
KeyboardRightMeta    = 128 ## 0x80

OldKeys = [0,0,0,0,0,0]
EndKeys = [0,0,0,0,0,0]
    
def report_keyboard(c,k):
    with open('/dev/hidg0', 'rb+') as fk:
        fk.write((c).to_bytes(1, byteorder='big')+    \
                 (0).to_bytes(1, byteorder='big')+    \
                 (k[0]).to_bytes(1, byteorder='big')+ \
                 (k[1]).to_bytes(1, byteorder='big')+ \
                 (k[2]).to_bytes(1, byteorder='big')+ \
                 (k[3]).to_bytes(1, byteorder='big')+ \
                 (k[4]).to_bytes(1, byteorder='big')+ \
                 (k[5]).to_bytes(1, byteorder='big'))

MouseButton1 = 1 ## left
MouseButton2 = 2 ## right
MouseButton3 = 4 ## middle

def report_mouse(b,x,y,w):
    if x<0:
        x=x+256
    if y<0:
        y=y+256
    if w<0:
        w=w+256
    with open('/dev/hidg1', 'rb+') as fm:
        fm.write((b).to_bytes(1, byteorder='big')+ \
                 (x).to_bytes(1, byteorder='big')+ \
                 (y).to_bytes(1, byteorder='big')+ \
                 (w).to_bytes(1, byteorder='big'))

def cmp(a, b):
    return (a > b) - (a < b) 

GPIO.setmode(GPIO.BCM)

GPIO.setup(10, GPIO.OUT)
GPIO.setup(11, GPIO.OUT)
GPIO.setup(12, GPIO.OUT)
GPIO.setup(13, GPIO.OUT)

GPIO.setup(20, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(21, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(22, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(23, GPIO.IN, pull_up_down = GPIO.PUD_UP)

while True:

   NewKeys = [0,0,0,0,0,0]
   Keys = 0

   MouseX=0
   MouseY=0
   MouseW=0
   Mouse=0
   
   GPIO.output(13, 1)
   GPIO.output(11, 1)
   GPIO.output(12, 1)
   GPIO.output(10, 0)

   if(GPIO.input(20) == 0):
      MouseX = -8
      Mouse+=1
   if(GPIO.input(21) == 0):
      MouseX = 8
      Mouse+=1
   if(GPIO.input(22) == 0):
      MouseY = -8
      Mouse+=1
   if(GPIO.input(23) == 0):
      MouseY = 8
      Mouse+=1

   GPIO.output(10, 1)
   GPIO.output(13, 1)
   GPIO.output(12, 1)
   GPIO.output(11, 0)

   if(GPIO.input(20) == 0):
      NewKeys[Keys] = 15
      Keys+=1
   if(GPIO.input(21) == 0):
      NewKeys[Keys] = 14
      Keys+=1
   if(GPIO.input(22) == 0):
      NewKeys[Keys] = 13
      Keys+=1
   if(GPIO.input(23) == 0):
      NewKeys[Keys] = 12 
      Keys+=1

   GPIO.output(10, 1)
   GPIO.output(11, 1)
   GPIO.output(13, 1)
   GPIO.output(12, 0)

   if(GPIO.input(20) == 0):
      NewKeys[Keys] = 11
      Keys+=1
   if(GPIO.input(21) == 0):
      NewKeys[Keys] = 10 
      Keys+=1
   if(GPIO.input(22) == 0):
      NewKeys[Keys] = 9 
      Keys+=1
   if(GPIO.input(23) == 0):
      NewKeys[Keys] = 8 
      Keys+=1

   GPIO.output(10, 1)
   GPIO.output(11, 1)
   GPIO.output(12, 1)
   GPIO.output(13, 0)

   if(GPIO.input(20) == 0):
      NewKeys[Keys] = 7 
      Keys+=1
   if(GPIO.input(21) == 0):
      NewKeys[Keys] = 6 
      Keys+=1
   if(GPIO.input(22) == 0):
      NewKeys[Keys] = 5 
      Keys+=1
   if(GPIO.input(23) == 0):
      NewKeys[Keys] = 4 
      Keys+=1

   if cmp(OldKeys,NewKeys) != 0:
      report_keyboard(0,NewKeys)
      OldKeys = NewKeys  

   if Mouse > 0:
      report_mouse(0,MouseX,MouseY,MouseW)

   time.sleep (0.01)
      
GPIO.cleanup()

