summaryrefslogtreecommitdiff
path: root/cursorpen.py
blob: 0fd35267e18588c28a80328235220c5ad0c33af7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/env python
#
#  cursorpen.py
#
#  this is the original prototype I made for this idea, taking code from 
#  https://github.com/Wazzaps/fingerpaint and modifying to work across
#  the whole desktop. 
#  
#  Use of this is not recommended, as this program is slow and inefficient
#  compared to the C program, however it should still work.
#  

import sys
from pynput.mouse import Button, Controller
from screeninfo import get_monitors
import subprocess as sp
import evdev
import contextlib
import pyudev
import screeninfo

scale = 1.5

@contextlib.contextmanager
def lock_pointer(devname):
    sp.call(['xinput', 'disable', devname])
    try:
        yield
    finally:
        sp.call(['xinput', 'enable', devname])

def get_touchpad(udev):
    for device in get_touchpads(udev):
        dev_name = get_device_name(device).strip('"')
        print('Using touchpad:', dev_name, file=sys.stderr)
        try:
            return evdev.InputDevice(device.device_node), dev_name
        except PermissionError:
            permission_error()
    return None, None

def get_touchpads(udev):
    for device in udev.list_devices(ID_INPUT_TOUCHPAD='1'):
        if device.device_node is not None and device.device_node.rpartition('/')[2].startswith('event'):
            yield device


def get_device_name(dev):
    while dev is not None:
        name = dev.properties.get('NAME')
        if name:
            return name
        else:
            dev = next(dev.ancestors, None)



def move_mouse(posx, posy):
    x = (monitor.width * posx - monitor.width*0.4) * scale
    y = (monitor.height * posy - monitor.height*0.1) * scale
    #x = (monitor.width * posx) 
    #y = (monitor.height * posy)
    mouse.position = (x, y)

def loop(touchpad):
    x_absinfo = touchpad.absinfo(evdev.ecodes.ABS_X)
    y_absinfo = touchpad.absinfo(evdev.ecodes.ABS_Y)
    val_range = (x_absinfo.max - x_absinfo.min, y_absinfo.max - y_absinfo.min)

    posx, posy = 0, 0
    while True:
        event = touchpad.read_one()
        if event:
            #print(posx, posy)
            if event.type == evdev.ecodes.EV_ABS:
                if event.code == evdev.ecodes.ABS_X:
                    posx = (event.value - x_absinfo.min) / val_range[0]
                if event.code == evdev.ecodes.ABS_Y:
                    posy = (event.value - y_absinfo.min) / val_range[1]
            move_mouse(posx, posy)

            if event.type == evdev.ecodes.EV_KEY:
                if event.code == evdev.ecodes.BTN_TOUCH and event.value == 0:
                    mouse.click(Button.left, 1)
                if event.code == evdev.ecodes.BTN_LEFT:
                    if event.value:
                        mouse.press(Button.left)
                    else:
                        mouse.release(Button.left)
                if event.code == evdev.ecodes.BTN_RIGHT:
                    if event.value:
                        mouse.press(Button.right)
                    else:
                        mouse.release(Button.right)



mouse = Controller()
monitor = get_monitors()[0]
udev = pyudev.Context()
touchpad, devname = get_touchpad(udev)
print(touchpad.path)
if touchpad is None:
    print('No touchpad found', file=sys.stderr)
    exit(1)

with lock_pointer(devname):
    loop(touchpad)