← Back to team overview

multi-touch-dev team mailing list archive

Re: script to detect MT devices

 

* Henrik Rydberg <rydberg@xxxxxxxxxxx> [2010-08-18 14:03 +0200]:
> On 08/18/2010 01:56 PM, Duncan McGreggor wrote:
> > Marc's script looks nice, but I was waiting to get a resolution to the
> > shell script/device/kernel issue before making some suggestions. Looks
> > like the script you attached is an updated version that cleverly works
> > around the issue.
> > 
> > Running the script no longer results in a traceback; I get results now.
> > However, not all the results I expected. My expectations may be awry due
> > to not knowing what the script outputs for other N-trig-based hardware.
> > 
> > Here's what I get:
> > 
> > Found device(s):
> > SynPS/2 Synaptics TouchPad: /dev/input/event6
> > N-Trig Pen: /dev/input/event9
> > 
> > Here's what I would expect (Henrik can correct my assumptions):
> > 
> > Found device(s):
> > SynPS/2 Synaptics TouchPad: /dev/input/event6
> > N-Trig Pen: /dev/input/event9
> > N-Trig MultiTouch: /dev/input/event10
> > N-Trig Touchscreen: /dev/input/event11
> 
> Unfortunately the python code is not correct - I get false positives on my
> machine. It seems the split is over word, whereas the shell script splits on bits.

Thanks for the review and the update which included checking the LONG_BIT
of the underlying system. I have fixed and updated the Python script
accordingly, attached to this message. Enjoy once again!

-- 
Marc Tardif <marc.tardif@xxxxxxxxxxxxx>
Freenode: cr3, Jabber: cr3@xxxxxxxxxx
1024D/72679CAD 09A9 D871 F7C4 A18F AC08 674D 2B73 740C 7267 9CAD
#!/usr/bin/env python

import os
import sys

from glob import glob
from optparse import OptionParser
from subprocess import Popen, PIPE


# See linux/input.h
ABS_MT_POSITION_X = 0x35


class Input(object):

    def __init__(self, path):
        self.path = path

    @property
    def device(self):
        base = os.path.basename(self.path)
        return os.path.join("/dev", "input", base)

    @property
    def name(self):
        path = os.path.join(self.path, "device", "name")
        return read_line(path)

    def get_capabilities(self):
        path = os.path.join(self.path, "device", "capabilities", "abs")
        line = read_line(path)
        capabilities = []
        long_bit = getconf("LONG_BIT")
        for i, word in enumerate(line.split(" ")):
            word = int(word, 16)
            subcapabilities = [bool(word & 1<<i) for i in range(long_bit)]
            capabilities[:0] = subcapabilities

        return capabilities

    def has_capability(self, capability):
        capabilities = self.get_capabilities()
        return len(capabilities) > capability and capabilities[capability]


def getconf(var):
    output = Popen(["getconf", var], stdout=PIPE).communicate()[0]
    return int(output)

def get_inputs(path):
    event_glob = os.path.join(path, "event*")
    for event_path in glob(event_glob):
        yield Input(event_path)

def read_line(path):
    f = open(path)
    try:
        return f.readline().strip()
    finally:
        f.close()

def main(args):
    usage = "Usage: %prog [OPTIONS]"
    parser = OptionParser(usage=usage)
    parser.add_option("-c", "--capability",
        type="int",
        default=ABS_MT_POSITION_X,
        help="Capability to look for, defaults to %default")
    parser.add_option("-i", "--input",
        metavar="FILE",
        default="/sys/class/input",
        help="Input sysfs directory, defaults to %default")
    (options, args) = parser.parse_args(args)

    inputs = get_inputs(options.input)
    inputs = [i for i in inputs if i.has_capability(options.capability)]

    if inputs:
        print "Found device%s:" % (len(inputs) > 1 and "s" or "")
        for input in inputs:
            print "%s: %s" % (input.name, input.device)

        return 0
    else:
        print "No capable devices found..."
        return 1

if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))

Follow ups

References