def main(argv):
    last_time = 0

    deltas = {}

    d = evemu.Device(argv[1], create=False)
    for e in d.events():

        if not e.matches("EV_SYN", "SYN_REPORT"):
            print("        %s %s %d" % (evemu.event_get_name(e.type), \
                                        evemu.event_get_name(e.type, e.code), \
                                        e.value))
            continue

        time = usec(e.sec, e.usec)
        dt = (time - last_time) / 1000
        last_time = time
        print("%4dms  ---- %s %s ----" % (dt, evemu.event_get_name(e.type), \
                                          evemu.event_get_name(e.type, e.code)))

        deltas[dt] = dict.get(deltas, dt, 0) + 1

    print("\nDistribution of deltas in ms:")
    for key, value in dict.iteritems(deltas):
        print("  %dms: %d" % (key, value))
def main(argv):
    d = evemu.Device(argv[1], create=False)

    xres = 1.0 * d.get_abs_resolution("ABS_MT_POSITION_X")
    yres = 1.0 * d.get_abs_resolution("ABS_MT_POSITION_Y")
    # Assume Apple trackpad resolutions
    if xres == 0 or yres == 0:
        print("WARNING: Using hardcoded resolutions")
        xres = 94
        yres = 90

    width, height = None, None
    ow, oh = 0, 0

    for e in d.events():
        if e.matches("EV_ABS", "ABS_MT_WIDTH_MAJOR"):
            width = e.value
        elif e.matches("EV_ABS", "ABS_MT_WIDTH_MINOR"):
            height = e.value
        elif e.matches("EV_SYN", "SYN_REPORT"):
            if width == None or height == None:
                continue
            w = width / xres
            h = height / yres
            if w == ow and h == oh:
                continue
            ow = w
            oh = h
            print("width: {} height {} phys: {}x{}mm".format(
                width, height, w, h))
Beispiel #3
0
    def test_play_and_record(self):
        """
        Verifies that a Device and play back prerecorded events.
        """
        device = evemu.Device(self.get_device_file())
        devnode = device.devnode
        events_file = self.get_events_file()
        # device.record() calls evemu_record() and is thus missing the
        # description that the input file has
        with open(events_file) as e:
            indata = extract_events(strip_comments(e.readlines()))

        recording_started = Event()
        q = Queue()
        record_process = Process(target=record,
                                 args=(recording_started, devnode, q))
        record_process.start()
        recording_started.wait(100)
        device.play(open(events_file))

        outdata = strip_comments(q.get())
        record_process.join()

        self.assertEquals(len(indata), len(outdata))
        fuzz = re.compile("E: \d+\.\d+ (.*)")
        for i in range(len(indata)):
            lhs = fuzz.match(indata[i])
            self.assertTrue(lhs)
            rhs = fuzz.match(outdata[i])
            self.assertTrue(rhs)
            self.assertEquals(lhs.group(1), rhs.group(1))
def main(argv):
    d = evemu.Device(argv[1], create=False)

    pmax = d.get_abs_maximum("ABS_PRESSURE")
    pmin = d.get_abs_minimum("ABS_PRESSURE")

    pressure = pmin
    time_offset = -1

    print("#!/usr/bin/gnuplot")
    print("# This is a self-executing gnuplot file")
    print("#")
    print("set xlabel \"time\"")
    print("set ylabel \"pressure\"")
    print("set style data lines")
    print("plot '-' using 1:2 title 'pressure'")

    for e in d.events():
        if time_offset < 0:
            time_offset = time_to_us(e.sec, e.usec)

        if e.matches("EV_ABS", "ABS_PRESSURE"):
            t = time_to_us(e.sec, e.usec) - time_offset
            print("%f %d" % (t, e.value))

    print("e")
    print("pause -1")
Beispiel #5
0
 def test_read_events_twice(self):
     device = evemu.Device(self.get_device_file(), create=False)
     events_file = self.get_events_file()
     with open(events_file) as ef:
         e1 = [(e.type, e.code, e.value) for e in device.events(ef)]
         e2 = [(e.type, e.code, e.value) for e in device.events(ef)]
         self.assertEquals(len(e1), len(e2))
         self.assertEquals(e1, e2)
Beispiel #6
0
def main(argv):
    d = evemu.Device(argv[1], create=False)

    locations = {}
    x, y = 0, 0

    for e in d.events():
        if e.matches("EV_ABS", "ABS_X"):
            x = e.value
        elif e.matches("EV_ABS", "ABS_Y"):
            y = e.value
        elif e.matches("EV_SYN", "SYN_REPORT"):
            val = locations.get((x, y), 0)
            locations[(x, y)] = val + 1

    xmax = d.get_abs_maximum("ABS_X")
    xmin = d.get_abs_minimum("ABS_X")
    ymax = d.get_abs_maximum("ABS_Y")
    ymin = d.get_abs_minimum("ABS_Y")

    # adjust for out-of-range coordinates
    xmax = max([x for (x, y) in locations.keys()] + [xmax])
    ymax = max([y for (x, y) in locations.keys()] + [ymax])
    xmin = min([x for (x, y) in locations.keys()] + [xmin])
    ymin = min([y for (x, y) in locations.keys()] + [ymin])

    w = xmax - xmin
    h = ymax - ymin
    stride = w

    xs = [x for (x, y) in locations.keys()]
    ys = [y for (x, y) in locations.keys()]
    xs.sort()
    ys.sort()

    xs = set(range(xmin, xmax)) - set(xs)
    ys = set(range(ymin, ymax)) - set(ys)

    # xs and ys contain all x/y coordinates that were never reached anywhere
    imgdata = [255] * (stride * (h + 1))

    for x in xs:
        px = x - xmin
        for py in range(0, h):
            imgdata[py * stride + px] = 0

    for y in ys:
        py = y - ymin
        for px in range(0, w):
            imgdata[py * stride + px] = 0

    im = Image.new('L', (w, h + 1))
    im.putdata(imgdata)
    im.save(OUTPUT_FILE)
Beispiel #7
0
def record(recording_started, device_node, q):
    """
    Runs the recorder in a separate process because the evemu API is a
    blocking API.
    """
    device = evemu.Device(device_node)
    with tempfile.TemporaryFile(mode='rt') as event_file:
        recording_started.set()
        device.record(event_file, 1000)
        event_file.flush()
        event_file.seek(0)
        outdata = event_file.readlines()
        q.put(outdata)
def main(argv):
    slot = 0
    slots = [[0, 0], [0, 0]]
    tracking_ids = [-1, -1]
    tracking_ids_old = [-1, -1]
    distances = []
    mm = []
    horiz = []
    vert = []

    d = evemu.Device(argv[1], create=False)
    width = d.get_abs_maximum("ABS_MT_POSITION_X") - d.get_abs_minimum("ABS_MT_POSITION_X")
    height = d.get_abs_maximum("ABS_MT_POSITION_Y") - d.get_abs_minimum("ABS_MT_POSITION_Y")
    xres = max(1.0, d.get_abs_resolution("ABS_MT_POSITION_X") * 1.0)
    yres = max(1.0, d.get_abs_resolution("ABS_MT_POSITION_Y") * 1.0)
    print "Touchpad dimensions: %dx%dmm (%dx%d units)" % (width/xres, height/yres, width, height)

    for e in d.events():
        if e.matches("EV_ABS", "ABS_MT_SLOT"):
            slot = e.value
        elif e.matches("EV_ABS", "ABS_MT_TRACKING_ID"):
            tracking_ids[slot] = e.value
        elif e.matches("EV_ABS", "ABS_MT_POSITION_X"):
            slots[slot][0] = e.value
        elif e.matches("EV_ABS", "ABS_MT_POSITION_Y"):
            slots[slot][1] = e.value
        elif e.matches("EV_SYN", "SYN_REPORT"):
            if tracking_ids[0] != -1 and tracking_ids[1] != -1 and \
                (tracking_ids_old[0] == -1 or tracking_ids_old[1] == -1):
                dist = math.hypot(slots[0][0] - slots[1][0],
                                  slots[0][1] - slots[1][1])
                distances.append(dist)

                dist = math.hypot(slots[0][0]/xres - slots[1][0]/xres,
                                  slots[0][1]/yres - slots[1][1]/yres)
                mm.append(dist)
                h = abs(slots[0][0]/xres - slots[1][0]/xres)
                horiz.append(h)
                v = abs(slots[0][1]/yres - slots[1][1]/yres)
                vert.append(v)

                print "New 2fg touch: distance %dmm (h %dmm v %dmm)" % (dist, h, v)

            tracking_ids_old[0] = tracking_ids[0]
            tracking_ids_old[1] = tracking_ids[1]

    print "Max distance: %dmm, %d units" % (max(mm), max(distances))
    print "Min distance %dmm, %d units" % (min(mm), min(distances))

    print "Max distance: %dmm horiz %dmm vert" % (max(horiz), max(vert))
    print "Min distance %dmm horiz, %dmm vert" % (min(horiz), min(vert))
Beispiel #9
0
    def test_describe(self):
        """
        Verifies that a device description can be correctly extracted from a
        Device.
        """
        # Get original description
        with open(self.get_device_file()) as f:
            data = strip_comments(f.readlines())

        # Create a pseudo device with that description
        d = evemu.Device(self.get_device_file())

        # get the description to a temporary file
        with tempfile.TemporaryFile(mode='rt') as t:
            d.describe(t)

            # read in the temporary file and compare to the original
            t.flush()
            t.seek(0)
            newdata = strip_comments(t.readlines())
            self.assertEquals(data, newdata)
def main(argv):
    slots = []
    xres, yres = 1, 1

    d = evemu.Device(argv[1], create=False)
    nslots = d.get_abs_maximum("ABS_MT_SLOT") + 1
    slots = [Slot() for _ in range(0, nslots)]
    print("Tracking %d slots" % nslots)

    slot = 0
    for e in d.events():
        s = slots[slot]
        if e.matches("EV_ABS", "ABS_MT_SLOT"):
            slot = e.value
            s = slots[slot]
            s.dirty = True
        elif e.matches("EV_ABS", "ABS_MT_TRACKING_ID"):
            if e.value == -1:
                s.state = SlotState.END
            else:
                s.state = SlotState.BEGIN
        elif e.matches("EV_ABS", "ABS_MT_POSITION_X"):
            s.x = e.value
            s.dirty = True
        elif e.matches("EV_ABS", "ABS_MT_POSITION_Y"):
            s.y = e.value
            s.dirty = True
        elif e.matches("EV_SYN", "SYN_REPORT"):

            if (slots[0].state == SlotState.END and slots[0].near_enough_to(slots[1])) or \
                    (slots[1].state == SlotState.END and slots[1].near_enough_to(slots[0])):
                print("{:2d}.{:06d}: possible slot jump".format(e.sec, e.usec))

            for sl in slots:
                if sl.state == SlotState.BEGIN:
                    sl.state = SlotState.UPDATE
                elif sl.state == SlotState.END:
                    sl.state = SlotState.NONE
Beispiel #11
0
def main(argv):
    d = evemu.Device(argv[1], create=False)

    pressure = None
    dpressure = None
    vals = []

    for e in d.events():
        if e.matches("EV_ABS", "ABS_MT_TRACKING_ID"):
            if e.value == -1:
                pressure = None
                dpressure = None
        elif e.matches("EV_ABS", "ABS_PRESSURE"):
            if pressure is not None:
                dpressure = e.value - pressure
            pressure = e.value
        elif e.matches("EV_SYN", "SYN_REPORT"):
            if dpressure is not None and abs(dpressure) <= 2:
                continue
            vals.append((pressure, dpressure))

    print("Pressure deltas <= 2 are filtered")
    for p, dp in vals:
        print("Pressure: {} delta {}".format(p, dp))
Beispiel #12
0
 def test_construct_from_prop_file_file_nocreate(self):
     """
     Verifies a device can be constructed from an evemu prop file file
     object, without creating a uinput device.
     """
     d = evemu.Device(open(self.get_device_file()), create=False)
Beispiel #13
0
 def test_construct_from_prop_file_file(self):
     """
     Verifies a device can be constructed from an evemu prop file file
     object.
     """
     d = evemu.Device(open(self.get_device_file()))
Beispiel #14
0
 def test_construct_from_prop_file_name(self):
     """
     Verifies a device can be constructed from an evemu prop file name.
     """
     d = evemu.Device(self.get_device_file())
Beispiel #15
0
 def test_construct_from_dev_node_file(self):
     """
     Verifies a Device can be constructed from an existing input device node
     file object.
     """
     d = evemu.Device(open("/dev/input/event0"))
Beispiel #16
0
 def test_construct_from_dev_node_name(self):
     """
     Verifies a Device can be constructed from an existing input device node
     name.
     """
     d = evemu.Device("/dev/input/event0")
Beispiel #17
0
def parse_recordings_file(path):
    print("# processing {}".format(path))
    vels = []

    d = evemu.Device(path, create=False)

    if not d.has_event("EV_ABS", "ABS_MT_SLOT"):
        print("# single touch only, skipping")
        return None

    nslots = d.get_abs_maximum("ABS_MT_SLOT") + 1
    slots = [Slot() for _ in range(0, nslots)]
    xres = 1.0 * d.get_abs_resolution("ABS_MT_POSITION_X")
    yres = 1.0 * d.get_abs_resolution("ABS_MT_POSITION_Y")
    slot = 0
    for e in d.events():
        s = slots[slot]
        if e.matches("EV_ABS", "ABS_MT_SLOT"):
            slot = e.value
            s = slots[slot]
            s.dirty = True
        elif e.matches("EV_ABS", "ABS_MT_TRACKING_ID"):
            if e.value == -1:
                s.state = SlotState.END
            else:
                s.state = SlotState.BEGIN
                s.time = e.sec * 1e6 + e.usec
                s.dx = 0
                s.dy = 0
            s.dirty = True
        elif e.matches("EV_ABS", "ABS_MT_POSITION_X"):
            if s.state == SlotState.UPDATE:
                s.dx = e.value - s.x
            s.x = e.value
            s.dirty = True
        elif e.matches("EV_ABS", "ABS_MT_POSITION_Y"):
            if s.state == SlotState.UPDATE:
                s.dy = e.value - s.y
            s.y = e.value
            s.dirty = True
        elif e.matches("EV_SYN", "SYN_REPORT"):
            for sl in slots:
                if sl.state != SlotState.NONE and sl.dirty:
                    t = e.sec * 1e6 + e.usec
                    sl.dt = t - sl.time
                    sl.time = t

                if  sl.state == SlotState.UPDATE and sl.dirty:
                    dist = math.hypot(sl.dx/xres, sl.dy/yres) # in mm
                    dt = sl.dt # in µs
                    vel = 1000 * dist/dt # mm/ms == m/s
                    vel = 1000 * vel # mm/s
                    vels.append(vel)
                    # print("{}".format(vel))

                if sl.state == SlotState.BEGIN:
                    sl.state = SlotState.UPDATE
                elif sl.state == SlotState.END:
                    sl.state = SlotState.NONE
                sl.dirty = False

    nevents = len(vels)
    maxvel = max(vels)
    print("# Number of data points: {}".format(nevents))
    print("# Highest velocity: {} mm/s".format(maxvel))

    # divide into buckets for each 10mm/s increment
    increment = 10
    nbuckets = int(maxvel/increment) + 1
    buckets = [0] * nbuckets
    print("# Starting with {} buckets".format(nbuckets))
    min_events = 5
    for v in vels:
        bucket = int(v/increment)
        buckets[bucket] += 1

    reduced_nevents = nevents
    for i in range(len(buckets) - 1, -1, -1):
        if buckets[i] >= min_events:
            break
        reduced_nevents -= buckets[i]
        # make sure we don't drop more than 5% of the data
        if nevents * 0.95 > reduced_nevents:
            break

    print("# Reducing to {} buckets ({} required per bucket)".format(i + 1, min_events))
    del buckets[i+1:]

    nevents_new = sum(buckets)
    print("# Left with {} data points ({:.1f}% of data)".format(nevents_new, 100.0 * nevents_new/nevents))

    speed = increment
    total_percent = 0
    datapoints = {}

    for b in buckets:
        percent = 100.0 * b/nevents_new
        total_percent += percent
        datapoints[speed] = {
            "speed" : speed,
            "nevents" : b,
            "percent" : percent,
            "total-percent" : total_percent,
        }

        #print(".. {}mm/s: {:5} events, {:.1f}% {:.1f}% total".format(speed, b, percent, total_percent))
        speed += increment

    return datapoints
Beispiel #18
0
def main(argv):
    deltas = []
    x, y = None, None
    dx, dy = 0, 0
    max_delta = [0, 0, 0]

    d = evemu.Device(argv[1], create=False)
    width = d.get_abs_maximum("ABS_MT_POSITION_X") - d.get_abs_minimum("ABS_MT_POSITION_X")
    height = d.get_abs_maximum("ABS_MT_POSITION_Y") - d.get_abs_minimum("ABS_MT_POSITION_Y")
    diag = veclen(width, height)
    xres = d.get_abs_resolution("ABS_MT_POSITION_X") * 1.0
    yres = d.get_abs_resolution("ABS_MT_POSITION_Y") * 1.0
    print "Touchpad dimensions: %dx%dmm" % (width/xres, height/yres)
    print "Touchpad diagonal: %.2f (0.25 == %.2f)" % (diag, 0.25 * diag)

    diag = veclen(width/xres, height/yres)
    print "Touchpad diagonal: %.2fmm (0.25 == %.2fmm)" % (diag, 0.25 * diag)

    slot = 0

    for e in d.events():
        if e.matches("EV_ABS", "ABS_MT_SLOT"):
            slot = e.value
        elif slot != 0:
            continue

        if e.matches("EV_ABS", "ABS_MT_TRACKING_ID"):
            if e.value == -1 and len(deltas) > 0:
                vdeltas = [ veclen(x/xres, y/xres) for (x, y) in deltas]
                print("%d.%d: %d deltas, average %.2f, max %.2f, total distance %.2f in mm" %
                        (e.sec, e.usec, len(vdeltas), mean(vdeltas), max(vdeltas), sum(vdeltas)))

                xdeltas = [abs(x/xres) for (x, y) in deltas]
                ydeltas = [abs(y/yres) for (x, y) in deltas]
                print("... x: average %.2fmm, max %.2fmm, total distance %.2fmm" %
                        (mean(xdeltas), max(xdeltas), sum(xdeltas)))
                print("... y: average %.2fmm, max %.2fmm, total distance %.2fmm" %
                        (mean(ydeltas), max(ydeltas), sum(ydeltas)))
                max_delta[0] = max(max_delta[0], max(vdeltas))
                max_delta[1] = max(max_delta[1], max(xdeltas))
                max_delta[2] = max(max_delta[2], max(ydeltas))
            else:
                deltas = []
                x, y = None, None
                dx, dy = 0, 0
        elif e.matches("EV_ABS", "ABS_MT_POSITION_X"):
            if x != None:
                dx = e.value - x
            x = e.value
        elif e.matches("EV_ABS", "ABS_MT_POSITION_Y"):
            if y != None:
                dy = e.value - y
            y = e.value
        elif e.matches("EV_SYN", "SYN_REPORT"):
            if dx != 0 and dy != 0:
                deltas.append((dx, dy))
            dx, dy = 0, 0

    print("Maximum recorded delta: %.2fmm" % (max_delta[0]))
    print("... x: %.2fmm" % max_delta[1])
    print("... y: %.2fmm" % max_delta[2])
    return
 def setUp(self):
     self.d = evemu.Device(evemu_path, create=False)
def is_rel_device(path):
        d = evemu.Device(argv[1], create=False)
        return d.has_event("EV_REL", "REL_X")
def is_abs_device(path):
        d = evemu.Device(argv[1], create=False)
        return d.has_event("EV_ABS", "ABS_X")
Beispiel #22
0
 def test_read_events(self):
     device = evemu.Device(self.get_device_file(), create=False)
     events_file = self.get_events_file()
     with open(events_file) as ef:
         events = [e for e in device.events(ef)]
         self.assertTrue(len(events) > 1)
Beispiel #23
0
# Command line:
#   export PYTHONPATH=/path/to/evemu/python
#   python convert-old-dumps-to-1.1.py myEvent.desc [myEvent.events]
#

# Make sure the print statement is disabled and the function is used.
from __future__ import print_function

import os
import re
import sys

import evemu


def usage(args):
    print("%s mydev.desc [mydev.events]" % os.path.basename(args[0]))
    return 1


if __name__ == "__main__":
    if len(sys.argv) < 2:
        exit(usage(sys.argv))
    file_desc = sys.argv[1]
    d = evemu.Device(file_desc, create=False)
    d.describe(sys.stdout)
    if len(sys.argv) > 2:
        with open(sys.argv[2]) as f:
            for e in d.events(f):
                print(e)
def main(argv):
    slots = []
    xres, yres = 1, 1

    parser = argparse.ArgumentParser(description="Measure delta between event frames for each slot")
    parser.add_argument("--use-mm", action='store_true', help="Use mm instead of device deltas")
    parser.add_argument("--use-st", action='store_true', help="Use ABS_X/ABS_Y instead of device deltas")
    parser.add_argument("--use-absolute", action='store_true', help="Use absolute coordinates, not deltas")
    parser.add_argument("path", metavar="recording",
                        nargs=1, help="Path to evemu recording")
    args = parser.parse_args()

    d = evemu.Device(args.path[0], create=False)
    nslots = d.get_abs_maximum("ABS_MT_SLOT") + 1
    print("Tracking %d slots" % nslots)
    if nslots > 10:
        nslots = 10
        print("Capping at %d slots" % nslots)

    slots = [Slot() for _ in range(0, nslots)]

    marker_begin_slot = "   ++++++    | "
    marker_end_slot =   "   ------    | "
    marker_empty_slot = " *********** | "
    marker_no_data =    "             | "

    if args.use_mm:
        xres = 1.0 * d.get_abs_resolution("ABS_MT_POSITION_X")
        yres = 1.0 * d.get_abs_resolution("ABS_MT_POSITION_Y")
        marker_empty_slot = " ************* | "
        marker_no_data =    "               | "
        marker_begin_slot = "    ++++++     | "
        marker_end_slot =   "    ------     | "

    if args.use_st:
        print("Warning: slot coordinates on FINGER/DOUBLETAP change may be incorrect")

    slot = 0
    for e in d.events():
        s = slots[slot]
        if args.use_st:
            # Note: this relies on the EV_KEY events to come in before the
            # x/y events, otherwise the last/first event in each slot will
            # be wrong.
            if e.matches("EV_KEY", "BTN_TOOL_FINGER"):
                slot = 0
                s = slots[slot]
                s.dirty = True
                if e.value:
                    s.state = SlotState.BEGIN
                else:
                    s.state = SlotState.END
            elif e.matches("EV_KEY", "BTN_TOOL_DOUBLETAP"):
                slot = 1
                s = slots[slot]
                s.dirty = True
                if e.value:
                    s.state = SlotState.BEGIN
                else:
                    s.state = SlotState.END
            elif e.matches("EV_ABS", "ABS_X"):
                if s.state == SlotState.UPDATE:
                    s.dx = e.value - s.x
                s.x = e.value
                s.dirty = True
            elif e.matches("EV_ABS", "ABS_Y"):
                if s.state == SlotState.UPDATE:
                    s.dy = e.value - s.y
                s.y = e.value
                s.dirty = True
        else:
            if e.matches("EV_ABS", "ABS_MT_SLOT"):
                slot = e.value
                s = slots[slot]
                s.dirty = True
            elif e.matches("EV_ABS", "ABS_MT_TRACKING_ID"):
                if e.value == -1:
                    s.state = SlotState.END
                else:
                    s.state = SlotState.BEGIN
                    s.dx = 0
                    s.dy = 0
                s.dirty = True
            elif e.matches("EV_ABS", "ABS_MT_POSITION_X"):
                if s.state == SlotState.UPDATE:
                    s.dx = e.value - s.x
                s.x = e.value
                s.dirty = True
            elif e.matches("EV_ABS", "ABS_MT_POSITION_Y"):
                if s.state == SlotState.UPDATE:
                    s.dy = e.value - s.y
                s.y = e.value
                s.dirty = True

        if e.matches("EV_SYN", "SYN_REPORT"):
            print("{:2d}.{:06d}: ".format(e.sec, e.usec), end='')
            for sl in slots:
                if sl.state == SlotState.NONE:
                    print(marker_empty_slot, end='')
                elif sl.state == SlotState.BEGIN:
                    print(marker_begin_slot, end='')
                elif sl.state == SlotState.END:
                    print(marker_end_slot, end='')
                elif not sl.dirty:
                    print(marker_no_data, end='')
                else:
                    if sl.dx != 0 and sl.dy != 0:
                        t = math.atan2(sl.dx, sl.dy)
                        t += math.pi # in [0, 2pi] range now

                        if t == 0:
                            t = 0.01;
                        else:
                            t = t * 180.0 / math.pi

                        directions = [ '↖↑', '↖←', '↙←', '↙↓', '↓↘', '→↘', '→↗', '↑↗']
                        direction = "{:3.0f}".format(t)
                        direction = directions[int(t/45)]
                    else:
                        direction = '..'

                    if args.use_mm:
                        sl.dx /= xres
                        sl.dy /= yres
                        print("{} {:+3.2f}/{:+03.2f} | ".format(direction, sl.dx, sl.dy), end='')
                    elif args.use_absolute:
                        print("{} {:4d}/{:4d} | ".format(direction, sl.x, sl.y), end='')
                    else:
                        print("{} {:4d}/{:4d} | ".format(direction, sl.dx, sl.dy), end='')
                if sl.state == SlotState.BEGIN:
                    sl.state = SlotState.UPDATE
                elif sl.state == SlotState.END:
                    sl.state = SlotState.NONE

                sl.dirty = False
            print("")
    def __init__(self, args=False):
        self.args = args
        self.device = evemu.Device("encoder.props")

        # Sleep 1s to be sure that the go app opens the file device
        time.sleep(1)
Beispiel #26
0
 def setUp(self):
     super(DevicePropertiesTestCase, self).setUp()
     self._device = evemu.Device(self.get_device_file())
def main(argv):
    d = evemu.Device(argv[1], create=False)
    offsets = {}
    offset = 2

    #     timestamp  count  star   separator
    print('Legend:')
    print('  time, count of keys down, * to mark <3ms timestamp')
    print('  + .... key down, | .... key is down, ^ .... key up')
    print(' ' * 12 + '   ' + ' ' + ' |', end='')
    for c in range(ord('a'), ord('z') + 1):
        print('{}'.format(chr(c)), end='')
        offsets[offset] = chr(c)
        offset += 1

    for c in range(ord('0'), ord('9') + 1):
        print('{}'.format(chr(c)), end='')
        offsets[offset] = chr(c)
        offset += 1

    offset += 1
    print(' Spc Bksp Del Ret LShf RShf', end='')
    offsets[offset + 2] = 'space'
    offset += 4
    offsets[offset + 2] = 'backspace'
    offset += 5
    offsets[offset + 1] = 'delete'
    offset += 4
    offsets[offset + 1] = 'enter'
    offset += 4
    offsets[offset + 2] = 'leftshift'
    offset += 5
    offsets[offset + 2] = 'rightshift'
    offset += 5
    print('')

    max_offset = offset

    char = ['^', '+', '|', ' ']

    down = {}
    last_down = {}
    bounce = False
    for e in d.events():
        if e.matches('EV_SYN', 'SYN_REPORT'):
            line = []
            line.append('{:06d}.{:06d}'.format(e.sec, e.usec))
            line.append(' {} '.format(len(down)))

            time = e.sec * 1000000 + e.usec
            if bounce:
                line.append('*')
                bounce = False
            else:
                line.append(' ')

            line.append('|')
            for i in range(2, max_offset):
                try:
                    line.append(char[down[offsets[i]]])
                except KeyError:
                    line.append(' ')
            print(''.join(line))

            for key in down:
                if down[key] == DOWN:
                    down[key] = IS_DOWN
                elif down[key] == UP:
                    down[key] = NONE

            d2 = {}
            for key in down.keys():
                value = down[key]
                if value != NONE:
                    d2[key] = value
            down = d2

        if not e.matches('EV_KEY'):
            continue

        key = evemu.event_get_name(e.type, e.code)
        key = key[4:].lower()  # remove KEY_ prefix
        down[key] = e.value

        if e.value:
            time = e.sec * 1000000 + e.usec
            if (key in last_down) and (time - last_down[key] < 70000):  # 70 ms
                bounce = True
            else:
                last_down[key] = time