123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- #!/usr/bin/python
- #
- # YAPTB Bluetooth keyboard emulation service
- # keyboard copy client.
- # Reads local key events and forwards them to the btk_server DBUS service
- #
- # Adapted from www.linuxuser.co.uk/tutorials/emulate-a-bluetooth-keyboard-with-the-raspberry-pi
- #
- #
- import os #used to all external commands
- import sys # used to exit the script
- import dbus
- import dbus.service
- import dbus.mainloop.glib
- import time
- import evdev # used to get input from the keyboard
- from evdev import *
- import keymap # used to map evdev input to hid keodes
- #Define a client to listen to local key events
- class Keyboard():
- def __init__(self):
- #the structure for a bt keyboard input report (size is 10 bytes)
- self.state=[
- 0xA1, #this is an input report
- 0x01, #Usage report = Keyboard
- #Bit array for Modifier keys
- [0, #Right GUI - Windows Key
- 0, #Right ALT
- 0, #Right Shift
- 0, #Right Control
- 0, #Left GUI
- 0, #Left ALT
- 0, #Left Shift
- 0], #Left Control
- 0x00, #Vendor reserved
- 0x00, #rest is space for 6 keys
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00]
- print "setting up DBus Client"
- self.bus = dbus.SystemBus()
- self.btkservice = self.bus.get_object('org.yaptb.btkbservice','/org/yaptb/btkbservice')
- self.iface = dbus.Interface(self.btkservice,'org.yaptb.btkbservice')
- print "waiting for keyboard"
- #keep trying to key a keyboard
- have_dev = False
- while have_dev == False:
- try:
- #try and get a keyboard - should always be event0 as
- #we're only plugging one thing in
- self.dev = InputDevice("/dev/input/event0")
- have_dev=True
- except OSError:
- print "Keyboard not found, waiting 3 seconds and retrying"
- time.sleep(3)
- print "found a keyboard"
- def change_state(self,event):
- evdev_code=ecodes.KEY[event.code]
- modkey_element = keymap.modkey(evdev_code)
- if modkey_element > 0:
- if self.state[2][modkey_element] == 0:
- self.state[2][modkey_element] = 1
- else:
- self.state[2][modkey_element] = 0
- else:
- #Get the keycode of the key
- hex_key = keymap.convert(ecodes.KEY[event.code])
- #Loop through elements 4 to 9 of the inport report structure
- for i in range(4,10):
- if self.state[i]== hex_key and event.value == 0:
- #Code 0 so we need to depress it
- self.state[i] = 0x00
- elif self.state[i] == 0x00 and event.value == 1:
- #if the current space if empty and the key is being pressed
- self.state[i]=hex_key
- break
- #poll for keyboard events
- def event_loop(self):
- for event in self.dev.read_loop():
- #only bother if we hit a key and its an up or down event
- if event.type==ecodes.EV_KEY and event.value < 2:
- self.change_state(event)
- self.send_input()
- #forward keyboard events to the dbus service
- def send_input(self):
- bin_str=""
- element=self.state[2]
- for bit in element:
- bin_str += str(bit)
- self.iface.send_keys(int(bin_str,2),self.state[4:10])
- if __name__ == "__main__":
- print "Setting up keyboard"
- kb = Keyboard()
- print "starting event loop"
- kb.event_loop()
|