def setup_driver(): """ """ sys.stdout.write("Setting up driver. . . ") # pressure sensitive pen tablet area with 2 stylus buttons and no eraser cap_pen = { ecodes.EV_KEY: [ ecodes.BTN_TOUCH, ecodes.BTN_TOOL_PEN, ecodes.BTN_STYLUS, ecodes.BTN_STYLUS2 ], ecodes.EV_ABS: [ (ecodes.ABS_X, AbsInfo(0, 0, main.settings['pen_max_x'], 0, 0, main.settings['resolution']) ), # value,min,max,fuzz,flat,resolu. (ecodes.ABS_Y, AbsInfo(0, 0, main.settings['pen_max_y'], 0, 0, main.settings['resolution'])), (ecodes.ABS_PRESSURE, AbsInfo(0, 0, main.settings['pen_max_z'], 0, 0, 0)), ] } main.vpen = UInput(events=cap_pen, name=main.settings['pen_device_name'], version=0x3) print("Done!") # INFO --------------------- print("\tTablet model name {}".format(main.settings['model_name'])) if main.settings['enable_buttons'] and main.settings['buttons'] > 0: print("\tButtons ENABLED ({})".format( main.settings['buttons'])) else: print("\tButtons disabled ({})".format( main.settings['buttons'])) if main.settings['enable_scrollbar'] and main.settings['scrollbar'] > 0: print("\tScrollbar ENABLED ({})".format( main.settings['scrollbar'])) else: print("\tScrollbar disabled ({})".format( main.settings['scrollbar'])) if main.settings['enable_notifications']: print("\tDesktop notifications ENABLED") else: print("\tDesktop notifications disabled") if main.settings['enable_multi_monitor']: print("\tMulti Monitor Setup ENABLED") else: print("\tMulti Monitor Setup disabled")
def __init__(self): print('initializing udev_evdev_emit') #several of these cap mappings are fake and just intended to ensure that Godot sees us as a valid controller #actual mappings: volup = BTN_0; voldown = BTN_1; app button = BTN_2; daydream button = BTN_3; touchpad button = BTN_4 cap = { e.EV_KEY : [e.BTN_A, e.BTN_THUMBL, e.BTN_TRIGGER, e.BTN_0, e.BTN_1, e.BTN_2, e.BTN_3, e.BTN_4], e.EV_ABS : [(e.ABS_X, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)), (e.ABS_Y, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)), (e.ABS_HAT0X, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)), (e.ABS_GAS, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)), (e.ABS_RUDDER, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0))]} self.ui = UInput(cap, name="daydream controller", version=0x3)
def update_device(new_device): global device global virtual_device if device is not None: device.ungrab() device.close() device = None virtual_device.close() virtual_device = None new_device.grab() # Prevent xorg from overriding cursor pos cap = new_device.capabilities() virtual_device = UInput({ EV_KEY: cap[EV_KEY], EV_ABS: [(0, AbsInfo(value=0, min=0, max=display_size[0], fuzz=0, flat=0, resolution=1)), (1, AbsInfo(value=0, min=0, max=display_size[1], fuzz=0, flat=0, resolution=1)), (24, AbsInfo(value=0, min=0, max=cap[EV_ABS][2][1].max, fuzz=0, flat=0, resolution=0))] }) for key in cap[EV_KEY]: key_mapping[key] = key print("Using device %s" % new_device.name) cap = new_device.capabilities() print(" - Max X: %s\n - Max Y: %s\n - %s button(s)" % (cap[3][0][1].max, cap[3][1][1].max, len( list( filter(lambda key: key != BTN_TOOL_PEN and key != BTN_TOUCH, cap[EV_KEY]))))) if BTN_TOOL_PEN in cap[EV_KEY]: print(" - Hover available") if BTN_TOUCH in cap[EV_KEY]: print(" - Has BTN_TOUCH feature - %s pressure steps" % (cap[3][2][1].max + 1)) global max_pressure max_pressure = cap[3][2][1].max device = new_device
def pointer_handler(): global ui2 global xsession global factor xsession = False ui2 = None factor = 5 global xFactor global yFactor xFactor = yFactor = 0 cap = { e.EV_KEY : [e.BTN_LEFT, e.BTN_RIGHT, e.BTN_MIDDLE], e.EV_ABS : [ (e.ABS_X, AbsInfo(value=0, min=0, max=255,fuzz=0, flat=0, resolution=0)) , (e.ABS_Y, AbsInfo(0, 0, 255, 0, 0, 0)) , (e.ABS_MT_POSITION_X, (0, 128, 255, 0)) ] } #capture current mouse coordinates. TODO If user uses a real mouse/touchpad input could confuses x = 20 y = 20 try: ui2 = UInput(cap, name='virtual-mouse', version=0x3) #it's unknown but needs 2 times to work :S ui2 = UInput(cap, name='virtual-mouse', version=0x3) except: logger.warning("no uinput was defined (for MOUSE virtual device)") pass #just to avoid init effect of cursor, joystick.py puts the cursor #ui2.write(e.EV_ABS, e.ABS_X, 0) #ui2.write(e.EV_ABS, e.ABS_Y, HEIGHT) #ui2.syn() while True: #logger.debug("%s %s" % (xFactor,yFactor)) if x+xFactor<WIDTH and x+xFactor >=0: x=x+xFactor if y+yFactor<HEIGHT and y+yFactor >=0: y=y+yFactor if ui2: ui2.write(e.EV_ABS, e.ABS_X, x) ui2.write(e.EV_ABS, e.ABS_Y, HEIGHT-y) ui2.syn() logger.debug("x: %s y: %s, xF: %s yF: %s" % (x,y,xFactor,yFactor)) time.sleep(0.01)
def get_pen(): cap_pen = { ecodes.EV_KEY: [ ecodes.BTN_TOUCH, ecodes.BTN_TOOL_PEN, ecodes.BTN_STYLUS, ecodes.BTN_STYLUS2 ], ecodes.EV_ABS: [ (ecodes.ABS_X, AbsInfo(0, 0, PEN_MAX_X, 0, 0, RESOLUTION)), #value, min, max, fuzz, flat, resolution (ecodes.ABS_Y, AbsInfo(0, 0, PEN_MAX_Y, 0, 0, RESOLUTION)), (ecodes.ABS_PRESSURE, AbsInfo(0, 0, PEN_MAX_Z, 0, 0, 0)), ], } return UInput(events=cap_pen, name="kamvas-pen", version=0x3)
class GameportJoystick: caps = { e.EV_KEY: [e.BTN_TRIGGER, e.BTN_THUMB], e.EV_ABS: [(e.ABS_X, AbsInfo(value=0, min=0, max=1024, fuzz=0, flat=0, resolution=0)), (e.ABS_Y, AbsInfo(value=0, min=0, max=1024, fuzz=0, flat=0, resolution=0)), (e.ABS_HAT0X, AbsInfo(value=0, min=-1, max=1, fuzz=0, flat=0, resolution=0)), (e.ABS_HAT0Y, AbsInfo(value=0, min=-1, max=1, fuzz=0, flat=0, resolution=0))], } def __init__(self, name="Gameport Joystick"): self.name = name self.ui = UInput(events=GameportJoystick.caps, name=name) def write(self, type, key, value): self.ui.write(type, key, value) self.ui.syn() def pressAndHoldTriggerButton(self): toggle = 0 for i in range(1000): self.ui.write(e.EV_KEY, e.BTN_TRIGGER, toggle) self.ui.syn() toggle = 1 - toggle
def __init__(self, can_id): self.can_id = can_id axis_cap = AbsInfo(-32700, 32700, 0, 0, 0, 0) self._ev = UInput( name='vjoy', events={ ecodes.EV_ABS: [(ecodes.ABS_X, axis_cap), (ecodes.ABS_Y, axis_cap), (ecodes.ABS_Z, axis_cap)], ecodes.EV_KEY: [ecodes.BTN_TRIGGER, ecodes.BTN_TOP, ecodes.BTN_TOP2] })
def __init__(self): logger.info('Plugin evdev_mouse initializing...') super().__init__() width=1920 height=1080 cap = { ecodes.EV_KEY: [ ecodes.BTN_LEFT, ecodes.BTN_MIDDLE, ecodes.BTN_RIGHT, ], ecodes.EV_REL: [ ecodes.REL_WHEEL, ecodes.REL_HWHEEL, ], ecodes.EV_ABS: [ (ecodes.ABS_X, AbsInfo(value=0, min=0, max=width, fuzz=0, flat=0, resolution=0)), (ecodes.ABS_Y, AbsInfo(value=0, min=0, max=height, fuzz=0, flat=0, resolution=0)), (ecodes.ABS_PRESSURE, AbsInfo(value=0, min=0, max=70, fuzz=0, flat=0, resolution=0)), ], } self.__mouse = UInput(cap, name='xHID evdev pointer', version=0x1, vendor=0x1, product=0x1, props=[]) self.__onscreen = False
try: import RPi.GPIO as gpio except ImportError: exit("Install: sudo pip install RPi.GPIO") try: import smbus except ImportError: exit("Install: sudo apt-get install python-smbus") os.system("sudo modprobe uinput") CAPABILITIES = { e.EV_ABS : ( (e.ABS_X, AbsInfo(value=0, min=0, max=800, fuzz=0, flat=0, resolution=1)), (e.ABS_Y, AbsInfo(value=0, min=0, max=480, fuzz=0, flat=0, resolution=1)), ), e.EV_KEY : [ e.BTN_TOUCH, ] } PIDFILE = "/var/run/touch.pid" try: pid = os.fork() if pid > 0: sys.exit(0)
found = 1 ttyFileName = file ard = serial.Serial() ard.port = "/dev/"+ttyFileName ard.baudrate = 38400 try: ard.open() except Exception, e: print "error open serial port: " + str(e) exit() cap = { e.EV_KEY : [e.BTN_TOUCH, e.BTN_TOOL_PEN, e.BTN_STYLUS, e.BTN_STYLUS2], e.EV_ABS : [ (e.ABS_X, AbsInfo(value=1, min=90, max=1650, fuzz=0, flat=0, resolution=1)), (e.ABS_Y, AbsInfo(value=2, min=100, max=1400, fuzz=0, flat=0, resolution=1)), (e.ABS_PRESSURE, AbsInfo(value=3, min=9, max=240, fuzz=0, flat=0, resolution=1)) ], e.EV_MSC: [e.MSC_SCAN], } minX=90 maxX=1650 minY=100 maxY=1400 # example to ingore 2nd monitor on right #monOneX=1920
PEN_MAX_Y = 27300 # 31750 PEN_MAX_Z = 8192 # 2048 #pressure msc = 1 # specify capabilities for a virtual device # one for each device: # pen/pad, and buttons # pressure sensitive pen tablet area with 2 stylus buttons and no eraser cap_pen = { ecodes.EV_KEY: [ ecodes.BTN_TOUCH, ecodes.BTN_TOOL_PEN, ecodes.BTN_MOUSE, ecodes.BTN_LEFT, ecodes.BTN_RIGHT, ecodes.BTN_MIDDLE ], ecodes.EV_ABS: [ (ecodes.ABS_X, AbsInfo(0, 0, PEN_MAX_X, 0, 0, 5080)), # value, min, max, fuzz, flat, resolution (ecodes.ABS_Y, AbsInfo(0, 0, PEN_MAX_Y, 0, 0, 5080)), (ecodes.ABS_PRESSURE, AbsInfo(0, 0, 2048, 0, 0, 0)), ] # , # ecodes.EV_MSC: [ecodes.MSC_SCAN], #not sure why, but it appears to be needed } # buttons must be defined in the same sequential order as in the Linux specs # https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h cap_btn = { ecodes.EV_KEY: [ ecodes.KEY_MINUS, ecodes.KEY_EQUAL, ecodes.KEY_E, ecodes.KEY_LEFTBRACE, ecodes.KEY_RIGHTBRACE, ecodes.KEY_LEFTCTRL, ecodes.KEY_S, ecodes.KEY_LEFTSHIFT, ecodes.KEY_Z, ecodes.KEY_LEFTALT, ecodes.KEY_SPACE, ecodes.KEY_UP, ecodes.KEY_LEFT, ecodes.KEY_RIGHT, ecodes.KEY_DOWN, ecodes.BTN_MOUSE, ecodes.BTN_LEFT, ecodes.BTN_RIGHT,
ABS_MT_POSITION_Y, \ BTN_TOUCH, \ ABS_X, \ ABS_Y, \ ABS_PRESSURE, \ ABS_MT_PRESSURE TMIN = 0.01 XMAX = 1920 YMAX = 1080 TRACKIDMAX = 65535 RES = 10 cap = { EV_KEY: [BTN_TOUCH], EV_ABS: [(ABS_X, AbsInfo(value=0, min=0, max=XMAX, fuzz=0, flat=0, resolution=RES)), (ABS_Y, AbsInfo(0, 0, YMAX, 0, 0, RES)), (ABS_PRESSURE, AbsInfo(0, 0, 255, 0, 0, 0)), (ABS_MT_TRACKING_ID, AbsInfo(0, 0, TRACKIDMAX, 0, 0, 0)), (ABS_MT_PRESSURE, AbsInfo(0, 0, 255, 0, 0, 0)), (ABS_MT_POSITION_X, AbsInfo(0, 0, XMAX, 0, 0, RES)), (ABS_MT_POSITION_Y, AbsInfo(0, 0, YMAX, 0, 0, RES))] } class FakeTouchscreen: def __init__(self): if not os.path.exists('/dev/uinput'): print 'error /dev/uinput does not exist. cannot make device' self.d = None return self.d = UInput(cap, name='Fake Touchscreen', version=0x3)
from evdev import UInput, AbsInfo, ecodes as e cap = { e.EV_KEY : [e.KEY_A, e.KEY_B], e.EV_ABS : [ (e.ABS_X, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)), (e.ABS_Y, AbsInfo(0, 0, 255, 0, 0, 0)), #(e.ABS_MT_POSITION_X, (0, 255, 128, 0)), ], e.EV_MSC: [e.MSC_SCAN], #not sure why, but it appears to be needed } ui = UInput(events=cap, name='example-device-2', version=0x3) print(ui) print(ui.capabilities()) ui.write(e.EV_ABS, e.ABS_X, 20) ui.write(e.EV_ABS, e.ABS_Y, 20) ui.syn()
def __init__(self): BaseDriver.__init__(self) self.input_dev = None self.create_node = True self.bustype = "BUS_USB" self.name = "Microsoft X-Box 360 pad" self.vendor = 0x45e self.product = 0x28e self.version = 272 self.phys = "joydrv/virtpad" + Xbox360._init_cnt.__str__() self.bits_ev = "(null) (null) (null)" Xbox360._init_cnt += 1 self.capabilities = { ecodes.EV_KEY: [ ecodes.BTN_A, ecodes.BTN_B, ecodes.BTN_X, ecodes.BTN_Y, ecodes.BTN_TL, ecodes.BTN_TR, ecodes.BTN_TL2, ecodes.BTN_TR2, ecodes.BTN_SELECT, ecodes.BTN_START, ecodes.BTN_THUMBL, ecodes.BTN_THUMBR, ecodes.BTN_DPAD_UP, ecodes.BTN_DPAD_DOWN, ecodes.BTN_DPAD_LEFT, ecodes.BTN_DPAD_RIGHT, ecodes.BTN_MODE, ], ecodes.EV_ABS: [(ecodes.ABS_HAT0X, AbsInfo(value=0, min=-1, max=1, fuzz=0, flat=0, resolution=0)), (ecodes.ABS_HAT0Y, AbsInfo(value=0, min=-1, max=1, fuzz=0, flat=0, resolution=0)), (ecodes.ABS_X, AbsInfo(value=128, min=0, max=255, fuzz=1, flat=0, resolution=0)), (ecodes.ABS_Y, AbsInfo(value=128, min=0, max=255, fuzz=1, flat=0, resolution=0)), (ecodes.ABS_RX, AbsInfo(value=128, min=0, max=255, fuzz=1, flat=0, resolution=0)), (ecodes.ABS_RY, AbsInfo(value=128, min=0, max=255, fuzz=1, flat=0, resolution=0))] }
from evdev import UInput, AbsInfo, ecodes as e import keymap gpio_keymap = keymap.debug() # set device capabilities cap_key = [] for key in gpio_keymap: cap_key.append(gpio_keymap[key]['ecode']) cap = { e.EV_KEY: cap_key, e.EV_ABS: [(e.ABS_X, AbsInfo(0, 0, 255, 0, 0, 0)), (e.ABS_Y, AbsInfo(0, 0, 255, 0, 0, 0))] } ui = UInput(cap, name='gpio-pad', version=0x1) # print device capabilities print(ui) print(ui.capabilities()) # move mouse cursor ui.write(e.EV_ABS, e.ABS_X, 20) ui.write(e.EV_ABS, e.ABS_Y, 20) ui.syn() print('Done!')
#Pi Zero, 1, 2, OR 3 - (Versions A+/B+) AVAILABLE_PINS = (3,5,7,11,13,15,19,21,23,29,31,33,35,37, 8,10,12,16,18,22,24,26,32,36,38,40) #Pi 1 (Versions A/B) if GPIO.RPI_INFO['P1_REVISION'] < 3: AVAILABLE_PINS = (3,5,7,11,13,15,19,21,23, 8,10,12,16,18,22,24,26) AVAILABLE_PINS_STRING = ', '.join(map(str, AVAILABLE_PINS)) JOYSTICK_AXIS = AbsInfo( value = 0, min = -255, max = 255, fuzz = 0, flat = 15, resolution = 0 ) DEVICE_LIST = [ 'Joypad 1', 'Joypad 2', 'Joypad 3', 'Joypad 4', 'Keyboard', 'Commands' ] BUTTON_LIST =[ ('Start Button', e.BTN_START),
parser.add_argument('-c', '--calibration', default=[500, 300, 3600, 3800], nargs=4, type=int, help='Set the 4-part calibration') parser.add_argument('-o', '--outrange', default=[0, 0, 4095, 4095], nargs=4, type=int, help='Set the 4-par output range') args = parser.parse_args() print(args) # UINPUT INIT -------------------------------------------------------------- #os.system("sudo modprobe uinput") EVENT_X_MAX = args.outrange[2] EVENT_Y_MAX = args.outrange[3] events = { e.EV_KEY : [e.BTN_TOUCH], e.EV_ABS : [ (e.ABS_X, AbsInfo(value=0, min=0, max=EVENT_X_MAX, fuzz=0, flat=0, resolution=0)), (e.ABS_Y, AbsInfo(value=0, min=0, max=EVENT_Y_MAX, fuzz=0, flat=0, resolution=0)), (e.ABS_PRESSURE, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)) ] } try: ui = UInput(events, name="touchmouse", bustype=e.BUS_USB) except UInputError: print("Couldn't create uinput - make sure you are running with sudo!") exit(0) # GPIO INIT ---------------------------------------------------------------- irqPin = 24 gpio.setwarnings(False)
frame = np.array(img) frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB) time.sleep(0.010) ret, jpeg = cv.imencode('.jpg', frame) return jpeg.tobytes() screenCap = ScreenCap() app = Flask(__name__) socketio = SocketIO(app) cap = { e.EV_KEY: [e.BTN_DIGI, e.BTN_TOOL_PEN, e.BTN_TOUCH, e.BTN_STYLUS, e.BTN_STYLUS2], e.EV_ABS: [(e.ABS_X, AbsInfo(value=0, min=0, max=1920, fuzz=0, flat=0, resolution=1)), (e.ABS_Y, AbsInfo(value=0, min=0, max=1080, fuzz=0, flat=0, resolution=1)), (e.ABS_PRESSURE, AbsInfo(value=0, min=0, max=2047, fuzz=0, flat=0, resolution=0))], e.EV_MSC: [e.MSC_SCAN] } ui = UInput(cap, name="virtual tablet") def gen(): while True: frame = screenCap.capture() yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
def run_evdev(): # Define the events that will be triggered by the custom xinput device that we will create pen_events = { # Defining a pressure sensitive pen tablet area with 2 stylus buttons and no eraser ecodes.EV_KEY: get_required_ecodes(), ecodes.EV_ABS: [ #AbsInfo input: value, min, max, fuzz, flat, resolution (ecodes.ABS_X, AbsInfo(0, 0, args['pen']['max_x'], 0, 0, args['pen']['resolution'])), (ecodes.ABS_Y, AbsInfo(0, 0, args['pen']['max_y'], 0, 0, args['pen']['resolution'])), (ecodes.ABS_PRESSURE, AbsInfo(0, 0, args['pen']['max_pressure'], 0, 0, 0)), (ecodes.ABS_TILT_X, AbsInfo(0, 0, args['pen']['max_tilt_x'], 0, 0, 0)), (ecodes.ABS_TILT_Y, AbsInfo(0, 0, args['pen']['max_tilt_y'], 0, 0, 0)), ], } # Try to get a reference to the USB we need dev = usb.core.find(idVendor=args['<usb_vendor_id>'], idProduct=args['<usb_product_id>']) if not dev: raise Exception( "Could not find device. The device may be unavailable or already open" ) # Forcefully claim the interface from any other script that might have been using it for cfg in dev: for interface in cfg: if dev.is_kernel_driver_active(interface.index): dev.detach_kernel_driver(interface.index) usb.util.claim_interface(dev, interface.index) if not args['--quiet-mode']: print("grabbed interface {}".format(interface.index)) # The method needs to be called or otherwise the tablet may not be in the correct mode # and no output might be seen from the first endpoint after a tablet reboot read_tablet_info(dev) # Seems like we need to try and read atleast once from the second endpoint on the device # or else the output from the first endpoint may get blocked on a tablet reboot try: endpoint_1 = dev[0][(1, 0)][0] data = dev.read(endpoint_1.bEndpointAddress, endpoint_1.wMaxPacketSize) except: pass # Create a virtual pen in /dev/input/ so that it shows up as a XInput device global vpen vpen = UInput(events=pen_events, name=args['<xinput_name>'], version=0x3) # Get a reference to the end that the tablet's output will be read from usb_endpoint = dev[0][(0, 0)][0] xinput_map_to_display() # Read the tablet output in an infinite loop while True: try: # Read data from the USB data = dev.read(usb_endpoint.bEndpointAddress, usb_endpoint.wMaxPacketSize) # Only calculate these values if the event is a pen event and not tablet event if data[1] in [128, 129, 130, 131, 132, 133]: # Calculate the values pen_x = (data[3] << 8) + (data[2]) pen_y = (data[5] << 8) + data[4] pen_pressure = (data[7] << 8) + data[6] pen_tilt_x = data[10] >= 128 and (data[10] - 256) or data[10] pen_tilt_y = data[11] >= 128 and (data[11] - 256) or data[11] # Send data to the Xinput device so that cursor responds vpen.write(ecodes.EV_ABS, ecodes.ABS_X, pen_x) vpen.write(ecodes.EV_ABS, ecodes.ABS_Y, pen_y) vpen.write(ecodes.EV_ABS, ecodes.ABS_PRESSURE, pen_pressure) vpen.write(ecodes.EV_ABS, ecodes.ABS_TILT_X, pen_tilt_x) vpen.write(ecodes.EV_ABS, ecodes.ABS_TILT_Y, pen_tilt_y) if args['--print-calculated-data'] and not args['--quiet-mode']: print("X {} Y {} PRESS {} ".format( pen_x, pen_y, pen_pressure, ), end='\r') # Reset any actions because this code means that nothing is happening if data[1] == 128: run_action('') # Pen click if data[1] == 129: run_action(args['actions'].get('pen_touch', '')) # Pen button 1 if data[1] == 130: run_action(args['actions'].get('pen_button_1', '')) # Pen button 1 with pen touch if data[1] == 131: run_action(args['actions'].get('pen_button_1_touch', '')) # Pen button 2 if data[1] == 132: run_action(args['actions'].get('pen_button_2', '')) # Pen button 2 with pen touch if data[1] == 133: run_action(args['actions'].get('pen_button_2_touch', '')) # Tablet buttons if data[1] == 224: global previous_tablet_btn if data[4]: btn_index = int(math.log(data[4], 2)) if previous_tablet_btn != data[4] and args['actions'].get( 'tablet_buttons', ''): run_action( args['actions']['tablet_buttons'][btn_index]) previous_tablet_btn = btn_index else: run_action('') previous_tablet_btn = 0 # Scrollbar if data[1] == 240: global previous_scrollbar_state scrollbar_state = data[5] if scrollbar_state: if previous_scrollbar_state: if scrollbar_state > previous_scrollbar_state: run_action(args['actions'].get( 'tablet_scrollbar_increase', '')) elif scrollbar_state < previous_scrollbar_state: run_action(args['actions'].get( 'tablet_scrollbar_decrease', '')) if scrollbar_state != previous_scrollbar_state and args[ 'actions'].get('tablet_scrollbar', ''): run_action( args['actions']['tablet_scrollbar'][scrollbar_state - 1]) else: run_action('') previous_scrollbar_state = scrollbar_state # Dispatch the evdev events vpen.syn() if args['--print-usb-data']: print_raw_data(data, 6) except usb.core.USBError as e: if e.args[0] == 19: vpen.close() raise Exception('Device has been disconnected') # The usb read probably timed out for this cycle. Thats ok data = None
# Configure UInput device # Maximum position possible minxpos = 60 minypos = 135 maxxpos = 19993 maxypos = 13847 minpressure = 0 # 19 maxpressure = 255 # Initialise UInput device cap = { e.EV_KEY : (e.BTN_TOUCH, e.BTN_STYLUS2), e.EV_ABS : [ # N.B.: There appears to be a mapping bug here; setting min to max results in # setting max when reading back ui capabilities. (e.ABS_PRESSURE, AbsInfo(value=minpressure, min=maxpressure, max=0, fuzz=0, flat=0, resolution=0)), (e.ABS_X, AbsInfo(value=minxpos, min=maxxpos, max=0, fuzz=0, flat=0, resolution=0)), (e.ABS_Y, AbsInfo(value=minxpos, min=maxypos, max=0, fuzz=0, flat=0, resolution=0))] } ui = UInput(cap, name='boogie-board-sync') try: while True: data = list(bytearray(sock.recv(1024))) if len(data) != 14 or data[0] != 192 or data[1] != 1 or data[2] != 161: continue xpos = data[4] | data[5] << 8 ypos = data[6] | data[7] << 8 touch = data[10] & 0x01 stylus = (data[10] & 0x02) >> 1 pressure = touch * (data[8] | data[9] << 8)
for c in pen_codes: temp.extend([ecodes.ecodes[x] for x in c.split("+")]) pen_codes = temp temp = [] for c in btn_codes: temp.extend([ecodes.ecodes[x] for x in c.split("+")]) btn_codes = temp pen_events = { ecodes.EV_KEY: pen_codes, ecodes.EV_ABS: [ #AbsInfo input: value, min, max, fuzz, flat (ecodes.ABS_X, AbsInfo(0, 0, config["pen"]["max_x"], 0, 0, config["pen"]["resolution_x"])), (ecodes.ABS_Y, AbsInfo(0, 0, config["pen"]["max_y"], 0, 0, config["pen"]["resolution_y"])), (ecodes.ABS_PRESSURE, AbsInfo(0, 0, config["pen"]["max_pressure"], 0, 0, 0)) ], } btn_events = {ecodes.EV_KEY: btn_codes} # Find the device dev = usb.core.find(idVendor=config["vendor_id"], idProduct=config["product_id"]) # Select end point for reading second interface [2] for actual data # I don't know what [0] and [1] are used for
for c in pen_codes: temp.extend([ecodes.ecodes[x] for x in c.split("+")]) pen_codes = temp temp = [] for c in btn_codes: temp.extend([ecodes.ecodes[x] for x in c.split("+")]) btn_codes = temp pen_events = { ecodes.EV_KEY: pen_codes, ecodes.EV_ABS: [ #AbsInfo input: value, min, max, fuzz, flat (ecodes.ABS_X, AbsInfo(0, 0, config['pen']['max_x'], 0, 0, config["pen"]["resolution_x"])), (ecodes.ABS_Y, AbsInfo(0, 0, config['pen']['max_y'], 0, 0, config["pen"]["resolution_y"])), (ecodes.ABS_PRESSURE, AbsInfo(0, 0, config['pen']['max_pressure'], 0, 0, 0)) ], } btn_events = {ecodes.EV_KEY: btn_codes} # Find the device dev = usb.core.find(idVendor=config["vendor_id"], idProduct=config["product_id"]) # Select end point for reading second interface [2] for actual data # I don't know what [0] and [1] are used for
def setup_driver(): """ """ sys.stdout.write("Setting up driver. . . ") # pressure sensitive pen tablet area with: 2 stylus buttons, no eraser, tilt cap_pen = { ecodes.EV_KEY: [ecodes.BTN_TOUCH, ecodes.BTN_TOOL_PEN,ecodes.BTN_STYLUS, ecodes.BTN_STYLUS2], ecodes.EV_ABS: [ # value,min,max,fuzz,flat,resolution (ecodes.ABS_X,AbsInfo(0,0,main.settings['pen_max_x'],0,0,main.settings['resolution'])), (ecodes.ABS_Y,AbsInfo(0,0,main.settings['pen_max_y'],0,0,main.settings['resolution'])), (ecodes.ABS_PRESSURE, AbsInfo(0,0,main.settings['pen_max_z'],0,0,0)), (ecodes.ABS_TILT_X, AbsInfo(0,main.settings['pen_min_tilt'],main.settings['pen_max_tilt'],0,0,0)), (ecodes.ABS_TILT_Y, AbsInfo(0,main.settings['pen_min_tilt'],main.settings['pen_max_tilt'],0,0,0)), ] } main.vpen = UInput(events=cap_pen, name=main.settings['pen_device_name'], version=0x3) print("Done!") # INFO --------------------- print("\tTablet model name {}".format(main.settings['model_name'])) if main.settings['enable_buttons'] and main.settings['buttons'] > 0 : print("\tButtons ENABLED ({})".format( main.settings['buttons'])) else: print("\tButtons disabled ({})".format( main.settings['buttons'])) # scrollbar if main.settings['enable_scrollbar']: print("\tScrollbar ENABLED ({})".format( main.settings['scrollbar'])) if main.settings['scrollbar_reverse']: print("\t\tReversed: {}".format( main.settings['scrollbar_reverse'])) else: print("\tScrollbar disabled ({})".format( main.settings['scrollbar'])) # notifications if main.settings['enable_notifications']: print("\tNotifications: ENABLED") if main.settings['buttons_notifications']: print("\t\tfor buttons ENABLED") else: print("\t\tfor buttons disabled") if main.settings['scrollbar_notifications']: print("\t\tfor scrollbar ENABLED") else: print("\t\tfor scrollbar disabled") else: print("\tNotifications disabled") if main.settings['screen']: print("\tScreen Enabled ({}x{})".format( main.settings['screen_width'], main.settings['screen_height'])) print("\tCurrent Monitor Setup {}".format( main.settings['monitor_setup'])) if main.settings['enable_multi_monitor']: print("\tMulti Monitor Setup ENABLED") else: print("\tMulti Monitor Setup disabled") if main.settings['enable_xrandr']: print("\tCalling xrandr ENABLED") else: print("\tCalling xrandr disabled") else: print("\tScreen disabled") if main.settings['debug_mode']: print("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") print("\t\t\t< DEBUG MODE ENABLED >") print("Enabled by default. You can disable it by setting debug_mode = false") print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") pf = platform.uname() print("\nSYSTEM: {} {} ({} {})".format( pf.system, pf.release, pf.machine, pf.processor)) print("{}".format(pf.version)) devices = [InputDevice(path) for path in list_devices()] for device in devices: if device.name == main.settings['pen_device_name']: try: path = device.path except: path = device.fn print("\nDEVICE: {} ({})".format(path, device.phys)) print("{}".format(device.info)) print("\n{}".format(main.endpoint)) # DEBUG print("\nTABLET CAPABILITIES:") caps = device.capabilities(verbose=True) for cap in caps: print(caps[cap]) print("\nVPEN:") print(main.vpen) print("\nXINPUT:") cmd='xinput list --short | grep "Tablet Monitor Pen"' try: sp.run(cmd, shell=True, check=True) except sp.CalledProcessError as e: run_error(e, cmd)
class DS4Device(Device): capabilities = { e.EV_KEY: [ e.BTN_WEST, # Square e.BTN_SOUTH, # Cross e.BTN_EAST, # Circle e.BTN_NORTH, # Triangle e.BTN_TL, # L1 e.BTN_TR, # R1 e.BTN_TL2, # L2 e.BTN_TR2, # R2 e.BTN_SELECT, # Share e.BTN_START, # Options e.BTN_THUMBL, # L3 e.BTN_THUMBR, # R3 e.BTN_MODE, # PS ], e.EV_ABS: [ (e.ABS_X, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=5, resolution=0)), (e.ABS_Y, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=5, resolution=0)), # right stick X (e.ABS_RX, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=5, resolution=0)), # right stick Y (e.ABS_RY, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=5, resolution=0)), # L2 (e.ABS_Z, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=5, resolution=0)), # R2 (e.ABS_RZ, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=5, resolution=0)), # dpad_left, dpad_right (e.ABS_HAT0X, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)), # dpad_up, dpad_down (e.ABS_HAT0Y, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)), ] } buttons = { 'main-button': e.BTN_MODE, 'back-button': e.BTN_SELECT, 'start-button': e.BTN_START, 'left-stick-press': e.BTN_THUMBL, 'right-stick-press': e.BTN_THUMBR, 'left-bumper': e.BTN_TL, # 'left-trigger': e.BTN_TL2, 'right-bumper': e.BTN_TR, # 'right-trigger': e.BTN_TR2, 'y-button': e.BTN_NORTH, 'x-button': e.BTN_EAST, 'a-button': e.BTN_SOUTH, 'b-button': e.BTN_WEST, } dpad = { 'up-button': e.ABS_HAT0Y, 'right-button': e.ABS_HAT0X, 'down-button': e.ABS_HAT0Y, 'left-button': e.ABS_HAT0X, } axes = { 'left-stick-X': e.ABS_X, 'left-stick-Y': e.ABS_Y, 'right-stick-X': e.ABS_RX, 'right-stick-Y': e.ABS_RY, } def __init__(self, device, addr): super().__init__(device, addr) self.type = "Sony Computer Entertainment Wireless Controller" self._ui = UInput( events=self.capabilities, name=self.type, vendor=1356, product=1476, version=273, bustype=e.BUS_USB, ) def send(self, key, value): if key in self.buttons: logger.debug( f'Sending button event::{e.keys[self.buttons[key]]}: {value}') self._ui.write(e.EV_KEY, self.buttons[key], value) self._ui.syn() elif key in self.dpad: if key in {'up-button', 'left-button'}: value = 0 if value else 127 else: value = 255 if value else 127 logger.debug( f'Sending axis event::{e.ABS[self.dpad[key]]}: {value}') self._ui.write(e.EV_ABS, self.dpad[key], value) self._ui.syn() elif key in self.axes: coord = round(127 * value) + 127 logger.debug( f'Sending axis event::{e.ABS[self.axes[key]]}: {coord}') self._ui.write(e.EV_ABS, self.axes[key], coord) self._ui.syn()
class emulatedDevice(object): cap = { e.EV_KEY: [e.BTN_MOUSE, e.BTN_WHEEL, e.BTN_MIDDLE, e.BTN_RIGHT, e.BTN_SIDE, e.KEY_ZOOM, e.KEY_ZOOMIN, e.KEY_ZOOMOUT, e.KEY_ZOOMRESET, e.KEY_LEFTCTRL, e.KEY_SLASH, e.KEY_RIGHTBRACE, e.KEY_LEFT, e.KEY_UP, e.KEY_RIGHT, e.KEY_DOWN], e.EV_ABS: [ (e.ABS_X, AbsInfo(value=0, min=0, max=1023, fuzz=0, flat=0, resolution=0)), (e.ABS_Y, AbsInfo(value=0, min=0, max=599, fuzz=0, flat=0, resolution=0)) ], e.EV_REL: [ e.REL_WHEEL, e.REL_HWHEEL ], e.EV_MSC: [e.MSC_SCAN] } def __init__(self, id): print('Creating emulated touch device #%d' % id) self.id = id self.dev = UInput(self.cap, name='pytouchd-emutouchdev-%d' % id, version=0x0001) self.state = (0, 0, 0) # (x, y, which key pressed) self.keydownstamp = None self.movebuffer = [] def close(self): global debug if debug: print('Closing emulated touch device #%d' % self.id) self.dev.close() del(self) def release(self, key=None, quiet=False): global debug if not self.state[2] and key is None: return if debug and not quiet: print('REL #%d' % self.id) if key is None: key = self.state[2] noupdate = True else: noupdate = False self.dev.write(e.EV_KEY, key, 0) self.dev.syn() if not noupdate: self.state = (self.state[0], self.state[1], 0) def press(self, key=e.BTN_MOUSE, quiet=False, *, value=1): global debug if not key in self.cap[e.EV_KEY]: raise ValueError('Keycode %d is not valid!' % key) if debug and not quiet: print('PRS #%d, %d' % (self.id, key)) self.dev.write(e.EV_KEY, key, value) self.dev.syn() self.state = (self.state[0], self.state[1], key) def move(self, x, y, quiet=False): global debug if debug and not quiet: print('MOV #%d, (%d, %d)' % (self.id, x, y)) self.dev.write(e.EV_ABS, e.ABS_X, x) self.dev.write(e.EV_ABS, e.ABS_Y, y) self.dev.syn() self.state = (x, y, self.state[2]) def scroll(self, amount, horizontal=False): if horizontal: wheel = e.REL_HWHEEL else: wheel = e.REL_WHEEL self.dev.write(e.EV_REL, wheel, amount) self.dev.syn() def runBuffer(self): global debug if debug: print('BUF #%d' % self.id) for event in self.movebuffer: # TODO new-old handle function self.handle(event, True) self.movebuffer = []
class X360Device(Device): capabilities = { e.EV_KEY: [ e.BTN_Y, e.BTN_X, e.BTN_A, e.BTN_B, e.BTN_THUMBL, e.BTN_THUMBR, e.BTN_SELECT, e.BTN_START, e.BTN_MODE, e.BTN_TRIGGER_HAPPY1, e.BTN_TRIGGER_HAPPY2, e.BTN_TRIGGER_HAPPY3, e.BTN_TRIGGER_HAPPY4, e.BTN_TL, # e.BTN_TL2,#Replaced by Axis e.BTN_TR, # e.BTN_TR2,#Replaced by Axis ], e.EV_ABS: [ (e.ABS_X, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)), (e.ABS_Y, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)), (e.ABS_Z, AbsInfo(value=0, min=0, max=511, fuzz=0, flat=0, resolution=0)), # Left Trigger (e.ABS_RZ, AbsInfo(value=0, min=0, max=511, fuzz=0, flat=0, resolution=0)), # Right Trigger (e.ABS_RX, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)), (e.ABS_RY, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)), (e.ABS_HAT0X, AbsInfo(value=0, min=-1, max=1, fuzz=0, flat=0, resolution=0)), # DPAD X (e.ABS_HAT0Y, AbsInfo(value=0, min=-1, max=1, fuzz=0, flat=0, resolution=0)), # DPAD Y ], } buttons = { 'main-button': e.BTN_MODE, 'back-button': e.BTN_SELECT, 'start-button': e.BTN_START, 'left-stick-press': e.BTN_THUMBL, 'right-stick-press': e.BTN_THUMBR, 'left-bumper': e.BTN_TL, # 'left-trigger': e.BTN_TL2, 'right-bumper': e.BTN_TR, # 'right-trigger': e.BTN_TR2, 'y-button': e.BTN_Y, 'x-button': e.BTN_X, 'a-button': e.BTN_A, 'b-button': e.BTN_B, } axes = { 'left-stick-X': e.ABS_X, 'left-stick-Y': e.ABS_Y, 'right-stick-X': e.ABS_RX, 'right-stick-Y': e.ABS_RY, 'left-trigger': e.ABS_Z, 'right-trigger': e.ABS_RZ, } dpad = { 'up-button': e.ABS_HAT0Y, 'right-button': e.ABS_HAT0X, 'down-button': e.ABS_HAT0Y, 'left-button': e.ABS_HAT0X, } def __init__(self, device, addr): super().__init__(device, addr) self.type = "Microsoft X-Box One pad" self._ui = UInput( events=self.capabilities, name=self.type, vendor=0x045e, product=0x02d1, #0x028e, version=0x0110, bustype=e.BUS_USB, ) def send(self, key, value): if key in self.buttons: logger.debug( f'Sending button event::{e.keys[self.buttons[key]]}: {value}') self._ui.write(e.EV_KEY, self.buttons[key], value) self._ui.syn() elif key in self.dpad: if key in {'up-button', 'left-button'}: value = -1 if value else 0 else: value = 1 if value else 0 logger.debug( f'Sending axis event::{e.ABS[self.dpad[key]]}: {value}') self._ui.write(e.EV_ABS, self.dpad[key], value) self._ui.syn() elif 'trigger' in key: coord = round(value * 511) logger.debug( f'Sending axis event::{e.ABS[self.axes[key]]}: {coord}') self._ui.write(e.EV_ABS, self.axes[key], coord) self._ui.syn() elif key in self.axes: coord = round(127 * value) + 127 logger.debug( f'Sending axis event::{e.ABS[self.axes[key]]}: {coord}') self._ui.write(e.EV_ABS, self.axes[key], coord) self._ui.syn()
maxxpos = 19780 maxypos = 13442 minpressure = 0 maxpressure = 255 # Initialise UInput device cap = { e.EV_KEY: (e.BTN_TOUCH, e.BTN_STYLUS2), e.EV_ABS: [ # N.B.: There appears to be a mapping bug here; setting min to max results in # setting max when reading back ui capabilities. (e.ABS_PRESSURE, AbsInfo(value=minpressure, min=0, max=maxpressure, fuzz=0, flat=0, resolution=0)), (e.ABS_X, AbsInfo(value=minxpos, min=minxpos, max=maxxpos, fuzz=0, flat=0, resolution=0)), (e.ABS_Y, AbsInfo(value=minypos, min=minypos, max=maxypos, fuzz=0, flat=0,
class X360Device(Device): capabilities = { e.EV_KEY: [ e.BTN_Y, e.BTN_X, e.BTN_A, e.BTN_B, e.BTN_THUMBL, e.BTN_THUMBR, e.BTN_SELECT, e.BTN_START, e.BTN_MODE, e.BTN_TRIGGER_HAPPY1, e.BTN_TRIGGER_HAPPY2, e.BTN_TRIGGER_HAPPY3, e.BTN_TRIGGER_HAPPY4, e.BTN_TL, e.BTN_TL2, e.BTN_TR, e.BTN_TR2, ], e.EV_ABS: [ (e.ABS_X, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)), (e.ABS_Y, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)), (e.ABS_RX, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)), (e.ABS_RY, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)), ], } buttons = { 'main-button': e.BTN_MODE, 'back-button': e.BTN_SELECT, 'start-button': e.BTN_START, 'left-stick-press': e.BTN_THUMBL, 'right-stick-press': e.BTN_THUMBR, 'left-bumper': e.BTN_TL, 'left-trigger': e.BTN_TL2, 'right-bumper': e.BTN_TR, 'right-trigger': e.BTN_TR2, 'up-button': e.BTN_TRIGGER_HAPPY3, 'right-button': e.BTN_TRIGGER_HAPPY2, 'down-button': e.BTN_TRIGGER_HAPPY4, 'left-button': e.BTN_TRIGGER_HAPPY1, 'y-button': e.BTN_Y, 'x-button': e.BTN_X, 'a-button': e.BTN_A, 'b-button': e.BTN_B, } axes = { 'left-stick-X': e.ABS_X, 'left-stick-Y': e.ABS_Y, 'right-stick-X': e.ABS_RX, 'right-stick-Y': e.ABS_RY, } def __init__(self, device, addr): super().__init__(device, addr) self.type = "Xbox 360 Controller" self._ui = UInput( events=self.capabilities, name=self.type, vendor=0x045e, product=0x028e, version=0x0110, bustype=e.BUS_USB, ) def send(self, key, value): if key in self.buttons: logger.debug( f'Sending button event::{e.keys[self.buttons[key]]}: {value}') self._ui.write(e.EV_KEY, self.buttons[key], value) self._ui.syn() elif key in self.axes: coord = round(127 * value) + 127 logger.debug( f'Sending axis event::{e.ABS[self.axes[key]]}: {coord}') self._ui.write(e.EV_ABS, self.axes[key], coord) self._ui.syn()
import evdev from evdev import ecodes as e from evdev import AbsInfo, UInput import time from random import randint # devices = [evdev.InputDevice(path) for path in evdev.list_devices()] # device = devices[10]#huion tablet # ui = UInput.from_device(device, name="virtual tablet") cap = { e.EV_KEY: [e.BTN_DIGI, e.BTN_TOOL_PEN, e.BTN_TOUCH, e.BTN_STYLUS, e.BTN_STYLUS2], e.EV_ABS: [(e.ABS_X, AbsInfo(value=0, min=0, max=8340, fuzz=0, flat=0, resolution=79)), (e.ABS_Y, AbsInfo(value=0, min=0, max=4680, fuzz=0, flat=0, resolution=79)), (e.ABS_PRESSURE, AbsInfo(value=0, min=0, max=2047, fuzz=0, flat=0, resolution=0))], e.EV_MSC: [e.MSC_SCAN] } ui = UInput(cap, name="my tablet") # print(ui.capabilities(verbose=True)) while True: inp = input() ui.write(e.EV_ABS, e.ABS_X, randint(1000, 2000)) ui.write(e.EV_ABS, e.ABS_Y, randint(1000, 2000))
from evdev import UInput, ecodes, AbsInfo # Establish usb communication with device import usb import yaml path = os.path.join(os.path.dirname(__file__), "config.yaml") # Loading tablet configuration with open(path, "r") as f: config = yaml.load(f, Loader=yaml.FullLoader) pen_events = { ecodes.EV_KEY: [ecodes.BTN_TOOL_PEN, ecodes.BTN_TOUCH], ecodes.EV_ABS: [(ecodes.ABS_X, AbsInfo(value=0, min=0, max=config['pen']['max_x'], fuzz=0, flat=0, resolution=config["pen"]["resolution_x"])), (ecodes.ABS_Y, AbsInfo(value=0, min=0, max=config['pen']['max_y'], fuzz=0, flat=0, resolution=config["pen"]["resolution_y"])), (ecodes.ABS_PRESSURE, AbsInfo(value=0, min=0, max=config['pen']['max_pressure'], fuzz=0, flat=0,