diff options
author | Stephen M. Webb <stephen.webb@canonical.com> | 2011-11-30 15:11:37 -0500 |
---|---|---|
committer | Stephen M. Webb <stephen.webb@canonical.com> | 2011-11-30 15:11:37 -0500 |
commit | 6dea9767c0fd3a716095da2c56e5f3bb78b79cf2 (patch) | |
tree | e1f401cd10a4ace3a8d4fd5c81d1aad3fc50f0fd /python | |
parent | 64dac9f4a2a637419b7a8b4385760283f005a4e0 (diff) |
Replaced the original convoluted set of python classes with a single Device class.
Diffstat (limited to 'python')
-rw-r--r-- | python/Makefile.am | 2 | ||||
-rw-r--r-- | python/evemu/__init__.py | 255 | ||||
-rw-r--r-- | python/evemu/data.py | 60 | ||||
-rw-r--r-- | python/evemu/device.py | 353 | ||||
-rw-r--r-- | python/evemu/script.py | 66 | ||||
-rw-r--r-- | python/evemu/testing/result.py | 11 | ||||
-rw-r--r-- | python/evemu/testing/runner.py | 8 | ||||
-rw-r--r-- | python/evemu/testing/testcase.py | 20 | ||||
-rw-r--r-- | python/evemu/tests/test_base.py | 5 | ||||
-rw-r--r-- | python/evemu/tests/test_data.py | 0 | ||||
-rw-r--r-- | python/evemu/tests/test_device.py | 305 | ||||
-rw-r--r-- | python/evemu/tests/test_device2.py | 223 | ||||
-rw-r--r-- | python/evemu/tests/test_script.py | 29 | ||||
-rw-r--r-- | python/evemu/tests/test_util.py | 54 | ||||
-rw-r--r-- | python/evemu/tests/test_wrapper.py | 48 | ||||
-rw-r--r-- | python/evemu/util.py | 99 | ||||
-rw-r--r-- | python/evemu/wrapper.py | 66 |
17 files changed, 504 insertions, 1100 deletions
diff --git a/python/Makefile.am b/python/Makefile.am index 4b33e2c..5a17793 100644 --- a/python/Makefile.am +++ b/python/Makefile.am @@ -34,4 +34,4 @@ evemu-test-runner: evemu-test-runner.in Makefile BUILT_SOURCES = evemu-test-runner EXTRA_DIST = evemu-test-runner.in $(wildcard evemu/test*) -CLEAN_FILES = $(BUILD_SOURCES) +CLEANFILES = $(BUILT_SOURCES) diff --git a/python/evemu/__init__.py b/python/evemu/__init__.py index 8b13789..0ac7dce 100644 --- a/python/evemu/__init__.py +++ b/python/evemu/__init__.py @@ -1 +1,256 @@ +""" +The evemu module provides the Python interface to the kernel-level input device +raw events. +""" + +# Copyright 2011 Canonical Ltd. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranties of +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. + +from ctypes.util import find_library + +import ctypes +import evemu.base +import evemu.const +import glob +import os +import re +import stat + +__all__ = ["Device"] + + +class Device(object): + """ + Encapsulates a raw kernel input event device, either an existing one as + reported by the kernel or a pseudodevice as created through a .prop file. + """ + + def __init__(self, f): + """ + Initializas an evemu Device. + + args: + f -- a file object or filename string for either an existing input + device node (/dev/input/eventNN) or an evemu prop file that can be used + to create a pseudo-device node. + """ + + if type(f).__name__ == 'str': + self._file = open(f, 'r+b') + elif type(f).__name__ == 'file': + self._file = f + else: + raise TypeError("expected file or file name") + + self._is_propfile = True + if stat.S_ISCHR(os.fstat(self._file.fileno()).st_mode): + self._is_propfile = False + elif self._file.read(3) == 'N: ': + self._file.seek(0) + else: + raise TypeError("file must be a device special or prop file") + + self._evemu = evemu.base.EvEmuBase(find_library(evemu.const.LIB)) + self._uinput = None + + libevemu_new = self._evemu.get_lib().evemu_new + libevemu_new.restype = ctypes.c_void_p + self._evemu_device = libevemu_new("") + + if self._is_propfile: + fs = self._evemu._call0(self._evemu.get_c_lib().fdopen, + self._file.fileno(), + 'r') + self._evemu._call(self._evemu.get_lib().evemu_read, + self._evemu_device, + fs) + self._uinput = os.open(evemu.const.UINPUT_NODE, os.O_WRONLY) + self._file = self._create_devnode() + else: + self._evemu._call(self._evemu.get_lib().evemu_extract, + self._evemu_device, + self._file.fileno()) + + def __del__(self): + if self._is_propfile: + self._file.close() + self._evemu._call(self._evemu.get_lib().evemu_destroy, + self._uinput) + + def _create_devnode(self): + self._evemu._call(self._evemu.get_lib().evemu_create, + self._evemu_device, + self._uinput) + return open(self._find_newest_devnode(self.name), 'r+') + + def _find_newest_devnode(self, target_name): + newest_node = (None, float(0)) + for sysname in glob.glob("/sys/class/input/event*/device/name"): + with open(sysname) as f: + name = f.read().rstrip() + if name == target_name: + ev = re.search("(event\d+)", sysname) + if ev: + devname = os.path.join("/dev/input", ev.group(1)) + ctime = os.stat(devname).st_ctime + if ctime > newest_node[1]: + newest_node = (devname, ctime) + return newest_node[0] + + def describe(self, prop_file): + """ + Gathers information about the input device and prints it + to prop_file. This information can be parsed later when constructing + a Device to create a virtual input device with the same properties. + + Scripts that use this method need to be run as root. + """ + if type(prop_file).__name__ != 'file': + raise TypeError("expected file") + + fs = self._evemu._call0(self._evemu.get_c_lib().fdopen, + prop_file.fileno(), + "w") + self._evemu._call(self._evemu.get_lib().evemu_write, + self._evemu_device, + fs) + self._evemu.get_c_lib().fflush(fs) + + def play(self, events_file): + """ + Replays an event sequence, as provided by the events_file, + through the input device. The event sequence must be in + the form created by the record method. + + Scripts that use this method need to be run as root. + """ + if type(events_file).__name__ != 'file': + raise TypeError("expected file") + + fs = self._evemu._call0(self._evemu.get_c_lib().fdopen, + events_file.fileno(), + "r") + self._evemu._call(self._evemu.get_lib().evemu_play, + fs, + self._file.fileno()) + + def record(self, events_file, timeout=10000): + """ + Captures events from the input device and prints them to the + events_file. The events can be parsed by the play method, + allowing a virtual input device to emit the exact same event + sequence. + + Scripts that use this method need to be run as root. + """ + if type(events_file).__name__ != 'file': + raise TypeError("expected file") + + fs = self._evemu._call0(self._evemu.get_c_lib().fdopen, + events_file.fileno(), + "w") + self._evemu._call(self._evemu.get_lib().evemu_record, + fs, + self._file.fileno(), + timeout) + self._evemu.get_c_lib().fflush(fs) + + @property + def version(self): + return self._evemu._call(self._evemu.get_lib().evemu_get_version, + self._evemu_device) + + @property + def devnode(self): + """ + Gets the name of the /dev node of the input device. + """ + return self._file.name + + @property + def name(self): + """ + Gets the name of the input device (as reported by the device). + """ + func = self._evemu.get_lib().evemu_get_name + func.restype = ctypes.c_char_p + return self._evemu._call(func, self._evemu_device) + + @property + def id_bustype(self): + return self._evemu._call(self._evemu.get_lib().evemu_get_id_bustype, + self._evemu_device) + + @property + def id_vendor(self): + return self._evemu._call(self._evemu.get_lib().evemu_get_id_vendor, + self._evemu_device) + + @property + def id_product(self): + return self._evemu._call(self._evemu.get_lib().evemu_get_id_product, + self._evemu_device) + + @property + def id_version(self): + return self._evemu._call(self._evemu.get_lib().evemu_get_id_version, + self._evemu_device) + + def get_abs_minimum(self, event_code): + return self._evemu._call(self._evemu.get_lib().evemu_get_abs_minimum, + self._evemu_device, + int(event_code)) + + def get_abs_maximum(self, event_code): + return self._evemu._call(self._evemu.get_lib().evemu_get_abs_maximum, + self._evemu_device, + event_code) + + def get_abs_fuzz(self, event_code): + return self._evemu._call(self._evemu.get_lib().evemu_get_abs_fuzz, + self._evemu_device, + event_code) + + def get_abs_flat(self, event_code): + return self._evemu._call(self._evemu.get_lib().evemu_get_abs_flat, + self._evemu_device, + event_code) + + def get_abs_resolution(self, event_code): + return self._evemu._call(self._evemu.get_lib().evemu_get_abs_resolution, + self._evemu_device, + event_code) + + def has_prop(self, event_code): + return self._evemu._call(self._evemu.get_lib().evemu_has_prop, + self._evemu_device, + event_code) + + def has_event(self, event_type, event_code): + """ + This method's 'even_type' parameter is expected to mostly take the + value for EV_ABS (i.e., 0x03), but may on occasion EV_KEY (i.e., 0x01). + If the former, then the even_code parameter will take the same values + as the methods above (ABS_*). However, if the latter, then the legal + values will be BTN_*. + + The reason for including the button data, is that buttons are sometimes + used to simulate gestures for a higher number of touches than are + possible with just 2-touch hardware. + """ + return self._evemu._call(self._evemu.get_lib().evemu_has_event, + self._evemu_device, + event_type, + event_code) diff --git a/python/evemu/data.py b/python/evemu/data.py deleted file mode 100644 index 502ed50..0000000 --- a/python/evemu/data.py +++ /dev/null @@ -1,60 +0,0 @@ -import ctypes - -from evemu import const - - -ABS_CNT = const.ABS_MAX + 1 - - -class InputIdStruct(ctypes.Structure): - """ - Data structure based on input_id in linux/uinput.h. - """ - _fields_ = [ - ("bustype", ctypes.c_uint), - ("vendor", ctypes.c_uint), - ("product", ctypes.c_uint), - ("version", ctypes.c_uint), - ] - - -class InputAbsInfoStruct(ctypes.Structure): - """ - Data structure based on input_absinfo in XXX. - """ - _fields_ = [ - ("value", ctypes.c_ulong), - ("minimum", ctypes.c_ulong), - ("maximum", ctypes.c_ulong), - ("fuzz", ctypes.c_ulong), - ("flat", ctypes.c_ulong), - ("resolution", ctypes.c_ulong), - ] - - -class EvEmuDeviceStruct(ctypes.Structure): - """ - Data structure based on evemu_device in evemu-impl.h. - """ - _fields_ = [ - ("version", ctypes.c_uint), - ("name", ctypes.c_byte * const.UINPUT_MAX_NAME_SIZE), - ("id", InputIdStruct), - ("prop", ctypes.c_ubyte * const.EVPLAY_NBYTES), - ("mask", ctypes.c_ubyte), - ("pbytes", ctypes.c_int), - ("mbytes", ctypes.c_int * const.EV_CNT), - ("abs", InputAbsInfoStruct * ABS_CONT), - ] -""" -struct evemu_device { - unsigned int version; // - char name[UINPUT_MAX_NAME_SIZE]; // string, max size - struct input_id id; // struct input_id from linux/uinput.h - unsigned char prop[EVPLAY_NBYTES]; // - unsigned char mask[EV_CNT][EVPLAY_NBYTES]; // doubly indexed array... first index is what type, second field is a bitmask - int pbytes // - int mbytes[EV_CNT]; // array of integers - struct input_absinfo abs[ABS_CNT]; // array structures -}; -""" diff --git a/python/evemu/device.py b/python/evemu/device.py deleted file mode 100644 index 03d04ac..0000000 --- a/python/evemu/device.py +++ /dev/null @@ -1,353 +0,0 @@ -import ctypes -import os - -from evemu import base -from evemu import const -from evemu import exception -from evemu import util - - -class EvEmuDevice(base.EvEmuBase): - """ - A wrapper class for the evemu device fucntions. - - For the methods with the @property decorator, as well as the the get_* and - has_* methods, the following notes apply: - - The medhod parameters 'event_type' and 'event_code' take their meanings - from the input event system in linux (the input_event struct defined in - linux/input.h). - - Ordinarily, to know a code, one must first know the type. However, in our - case, we mostly just case about multi-touch. Since MT data only uses - EV_ABS, it is understood that methods without a type are implicitly - expecting a context of EV_ABS. - - As such, for those methods, the valid codes are the ABS_* values listed in - the evemu.const module. - - @event_type: one of the EV_* constants - - @event_code: a code related to the event type - """ - def __init__(self, library): - super(EvEmuDevice, self).__init__(library) - # the path to the node that will be the virtual device - self._node = "" - # the stream produced by fopen (used to open the virtual device - # description file) - self._device_file_stream = None - # the python variable that holds the reference to the C pointer for the - # device data structure; ctypes handles the byref internals via the - # _as_parameter_ method magic - self._device_pointer = None - # the file descriptor used by ioctl to create the virtual device - self._uinput_fd = None - try: - self._new() - except exception.EvEmuError, error: - self.delete() - raise error - - def __del__(self): - self.delete() - try: - self.close_device_file_stream() - self.set_device_file_stream(None) - except exception.NullFileHandleError, error: - # If there's no filehandle, there's nothing we can do, so move - # along, folks... nothing to see here! - pass - self.destroy() - self.close() - # XXX is this code necessary? if so, it might need to be fixed... - #if self.get_node_name(): - # print self.get_node_name() - # if os.path.exists(self.get_node_name()): - # print "unlinking %s ..." % self.get_node_name() - # os.unlink(self.get_node_name()) - - def _new(self): - device_new = self.get_lib().evemu_new - device_new.restype = ctypes.c_void_p - # The C API expects a device name to be passed, however, it doesn't do - # anything with it, so we're not going to provide it as an option in - # the Python API. - self._device_pointer = device_new("") - - def _get_device_struct(self): - pointer = self.get_device_pointer() - import pdb;pdb.set_trace() - - @property - def _as_parameter_(self): - return self.get_deivce_pointer() - - def get_lib(self): - return self._lib - - def get_device_pointer(self): - return self._device_pointer - - def get_device_file_stream(self): - return self._device_file_stream - - def set_device_file_stream(self, stream): - self._device_file_stream = stream - - def _close_device_file_stream(self): - if self.get_device_pointer() is None: - raise exception.NullFileHandleError( - "Cannot close an undefined file pointer!") - self._call( - self.get_c_lib().fclose, - self.get_device_file_stream()) - - def close_device_file_stream(self): - try: - self._close_device_file_stream() - pass - except exception.EvEmuError, error: - self.delete() - raise error - - def set_node_name(self, node_name): - self._node = node_name - - def get_node_name(self): - return self._node - - def delete(self): - """ - Frees up the memory associated with the pointer (and deletes the - pointer). - - This is done when: - * uncessessfully attempting to create a new device data structure - * unsuccessfully attempting to read the device description file - * unsuccessfully attempting to open the UINPUT_NODE for writing - - Note that when uncsuccessfully calling evemu_create, just the close - operation is performed, nothing else. - """ - if self.get_device_pointer(): - self._call(self.get_lib().evemu_delete, self.get_device_pointer()) - self._device_pointer = None - - def destroy(self): - """ - Deletes the /dev/device/eventXX device that was created. - - This is done when: - * successfully setup up the eventXX device, after all the work is done - - Note that when uncsuccessfully calling evemu_create, just the close - operation is performed, nothing else. - """ - if self._uinput_fd: - self._call(self.get_lib().evemu_destroy, self._uinput_fd) - - def close(self): - """ - Closes the uinput device. - - This is done when: - * unsuccessfully calling evemu_create - """ - if self._uinput_fd: - os.close(self._uinput_fd) - self._uinput_fd = None - - def _read(self, filename): - file_pointer = self._call0( - self.get_c_lib().fopen, filename, "r") - self.set_device_file_stream(file_pointer) - self._call( - self.get_lib().evemu_read, - self.get_device_pointer(), - self.get_device_file_stream()) - - def read(self, filename): - """ - Pre-load the device structure with data from the virtual device - description file. - """ - try: - self._read(filename) - except exception.EvEmuError, error: - self.delete() - raise error - - def _open_uinput(self): - self._uinput_fd = os.open(const.UINPUT_NODE, os.O_WRONLY) - - def _create(self): - self._call( - self.get_lib().evemu_create, - self.get_device_pointer(), - self._uinput_fd) - - def create_node(self, device_file): - # load device data from the virtual device description file into the - # data structure referenced by the device pointer - self.read(device_file) - # create the node - try: - self._open_uinput() - except exception.EvEmuError, error: - self.delete() - raise error - # populate the new node with data from the device pointer - try: - self._create() - self.set_node_name(util.get_last_device()) - except exception.EvEmuError, error: - self.close() - raise error - - def _write(self, filename): - # XXX what about writing to stdout? let's do that later; open a bug for - # supporting writing to stdout... - file_pointer = self._call0( - self.get_c_lib().fopen, filename, "w+") - self.set_device_file_stream(file_pointer) - self._call( - self.get_lib().evemu_write, - self.get_device_pointer(), - self.get_device_file_stream()) - self.close_device_file_stream() - - def write(self, filename): - """ - Whatever data has been stored in the struct will get written to the - passed file. - """ - try: - self._write(filename) - except exception.EvEmuError, error: - self.delete() - raise error - - def _extract(self, device_node): - file_descriptor = os.open(device_node, os.O_RDONLY) - self._call( - self.get_lib().evemu_extract, - self.get_device_pointer(), - file_descriptor) - os.close(file_descriptor) - - def extract(self, device_node): - """ - A linux input device node is opened and read, storing all the retrieved - data in the device data structure. - """ - try: - self._extract(device_node) - except exception.EvEmuError, error: - self.delete() - raise error - - def _record(self, device_node): - pass - - def record(self, device_node): - pass - - def _play(self, device_node, events_file): - pass - - def play(self, device_node, events_file): - pass - - # Property methods - @property - def version(self): - return self._call( - self.get_lib().evemu_get_version, - self.get_device_pointer()) - - @property - def name(self): - func = self.get_lib().evemu_get_name - func.restype = ctypes.c_char_p - return self._call(func, self.get_device_pointer()) - - @property - def id_bustype(self): - return self._call( - self.get_lib().evemu_get_id_bustype, - self.get_device_pointer()) - - @property - def id_vendor(self): - return self._call( - self.get_lib().evemu_get_id_vendor, - self.get_device_pointer()) - - @property - def id_product(self): - return self._call( - self.get_lib().evemu_get_id_product, - self.get_device_pointer()) - - @property - def id_version(self): - return self._call( - self.get_lib().evemu_get_id_version, - self.get_device_pointer()) - - # Getter methods - def get_abs_minimum(self, event_code): - return self._call( - self.get_lib().evemu_get_abs_minimum, - self.get_device_pointer(), - int(event_code)) - - def get_abs_maximum(self, event_code): - return self._call( - self.get_lib().evemu_get_abs_maximum, - self.get_device_pointer(), - event_code) - - def get_abs_fuzz(self, event_code): - return self._call( - self.get_lib().evemu_get_abs_fuzz, - self.get_device_pointer(), - event_code) - - def get_abs_flat(self, event_code): - return self._call( - self.get_lib().evemu_get_abs_flat, - self.get_device_pointer(), - event_code) - - def get_abs_resolution(self, event_code): - return self._call( - self.get_lib().evemu_get_abs_resolution, - self.get_device_pointer(), - event_code) - - # Haser methods ;-) - def has_prop(self, event_code): - return self._call( - self.get_lib().evemu_has_prop, - self.get_device_pointer(), - event_code) - - def has_event(self, event_type, event_code): - """ - This method's 'even_type' parameter is expected to mostly take the - value for EV_ABS (i.e., 0x03), but may on occasion EV_KEY (i.e., 0x01). - If the former, then the even_code parameter will take the same values - as the methods above (ABS_*). However, if the latter, then the legal - values will be BTN_*. - - The reason for including the button data, is that buttons are sometimes - used to simulate gestures for a higher number of touches than are - possible with just 2-touch hardware. - """ - return self._call( - self.get_lib().evemu_has_event, - self.get_device_pointer(), - event_type, - event_code) diff --git a/python/evemu/script.py b/python/evemu/script.py deleted file mode 100644 index ee0cb44..0000000 --- a/python/evemu/script.py +++ /dev/null @@ -1,66 +0,0 @@ -import os -import sys - - -class EvEmu(object): - """ - This class wraps the functionality offerened by the evemu utility programs. - """ - def __init__(self, library=""): - """ - """ - pass - - def describe(self, path_to_touch_device): - """ - The describe gathers information about the input device and prints it - to stdout. This information can be parsed by the create_device to - create a virtual input device with the same properties. - - Scripts that use this method need to be run as root. - """ - fd = open(path_to_touch_device, "r") - device = self._wrapper.evemu_new(0) - # XXX check for device being not none, err out if so - data = self._wrapper.evemu_extract(device, fd) - # XXX check for data being not none, err out if so - fd.close() - # XXX I don't like writing to stdout by default with a library. I'd - # prefer that this were an option. For now, we'll duplicate the scripts - # and keep it as is... - self._wrapper.evemu_write(device, sys.stdout) - return data - - def create_device(self, device_description_file): - """ - The create_device method creates a virtual input device based on the - provided description-file. This description will have been created by - the describe method. The create_device method then creates a new input - device with uinput and prints the name and the device file to stdout. - - Scripts that use this method need to be run as root. - """ - if self._virtual_device: - return self._virtual_device - - def record(self): - """ - This method captures events from the input device and prints them to - stdout. The events can be parsed by the play method, allowing a virtual - input device created with the create_device method to emit the exact - same event sequence. - - Scripts that use this method need to be run as root. - """ - - def play(self, device_description_file="", events_file=""): - """ - The play method replays the event sequence, as provided by the - events-file, through the input device. The event sequence must be in - the form created by the record method. - - Scripts that use this method need to be run as root. - """ - device_fd = os.open(device_description_file, os.O_WRONLY) - events_fd = os.open(events_file, os.O_WRONLY) - self._wrapper.play(device_fd, events_fd) diff --git a/python/evemu/testing/result.py b/python/evemu/testing/result.py index e3480cd..d824b36 100644 --- a/python/evemu/testing/result.py +++ b/python/evemu/testing/result.py @@ -6,7 +6,14 @@ except ImportError: # Python 2.4, 2.5, 2.6 from unittest import _TextTestResult as TextTestResult -from evemu import util + +def get_test_directory(): + from evemu import tests + return tests.__path__[0] + + +def get_test_module(): + return get_test_directory().replace("/", ".") class CustomTestResult(TextTestResult): @@ -31,7 +38,7 @@ class CustomTestResult(TextTestResult): this_class = module_and_class.split(".")[-1] self.current_class = this_class if self.last_module != self.current_module: - heading = "\n%s.%s" % (util.get_test_module(), this_module) + heading = "\n%s.%s" % (get_test_module(), this_module) self.stream.writeln(heading) if self.last_class != self.current_class: self.stream.writeln(" %s" % this_class) diff --git a/python/evemu/testing/runner.py b/python/evemu/testing/runner.py index f5662a2..d7bf814 100644 --- a/python/evemu/testing/runner.py +++ b/python/evemu/testing/runner.py @@ -1,10 +1,14 @@ import os import unittest -from evemu import util from evemu.testing import result +def get_test_directory(): + from evemu import tests + return tests.__path__[0] + + class CustomTestRunner(unittest.TextTestRunner): """ This is only needed for Python 2.6 and lower. @@ -51,7 +55,7 @@ def get_runner(): def run_tests(): loader = unittest.TestLoader() - suite = get_suite(loader, util.get_test_directory()) + suite = get_suite(loader, get_test_directory()) get_runner().run(suite) diff --git a/python/evemu/testing/testcase.py b/python/evemu/testing/testcase.py index 0301adb..35b7a0b 100644 --- a/python/evemu/testing/testcase.py +++ b/python/evemu/testing/testcase.py @@ -4,7 +4,11 @@ import unittest from evemu import const from evemu import exception -from evemu import util + + +def get_top_directory(): + import evemu + return evemu.__path__[0] def skip(message): @@ -49,7 +53,7 @@ class BaseTestCase(unittest.TestCase): else: library = const.LOCAL_LIB self.library = library - basedir = util.get_top_directory() + basedir = get_top_directory() self.data_dir = os.path.join(basedir, "..", "..", "data") self.device = None @@ -64,15 +68,3 @@ class BaseTestCase(unittest.TestCase): def get_events_file(self): return os.path.join(self.data_dir, "ntrig-dell-xt2.event") - def create_testing_device(self, device_class=None): - """ - This is a conveneince test function for tests that need a device. Have - this method be called in each test (as opposed to once in the setUp - method) also allows for use to check device counts before and after - device creation. - """ - from evemu.device import EvEmuDevice - if not device_class: - device_class = EvEmuDevice - self.device = device_class(self.library) - self.device.create_node(self.get_device_file()) diff --git a/python/evemu/tests/test_base.py b/python/evemu/tests/test_base.py index 60f8eed..0b72abd 100644 --- a/python/evemu/tests/test_base.py +++ b/python/evemu/tests/test_base.py @@ -7,12 +7,15 @@ from evemu.testing import testcase class EvEmuBaseTestCase(testcase.BaseTestCase): - def test_initialize(self): + def test_so_library_found(self): wrapper = EvEmuBase(self.library) # Make sure that the library loads self.assertNotEqual( wrapper._lib._name.find("libutouch-evemu"), -1) + + def test_c_symbols_found(self): # Make sure that the expected functions are present + wrapper = EvEmuBase(self.library) for function_name in const.API: function = getattr(wrapper._lib, function_name) self.assertTrue(function is not None) diff --git a/python/evemu/tests/test_data.py b/python/evemu/tests/test_data.py deleted file mode 100644 index e69de29..0000000 --- a/python/evemu/tests/test_data.py +++ /dev/null diff --git a/python/evemu/tests/test_device.py b/python/evemu/tests/test_device.py deleted file mode 100644 index 65112fd..0000000 --- a/python/evemu/tests/test_device.py +++ /dev/null @@ -1,305 +0,0 @@ -import ctypes -import os -import tempfile -import unittest - -from evemu import const -from evemu import exception -from evemu import util -from evemu.device import EvEmuDevice -from evemu.testing import testcase - - -class EvEmuDeviceTestCase(testcase.BaseTestCase): - - def test_initialize_error_new(self): - class FakeDevice(EvEmuDevice): - def _new(self): - raise exception.EvEmuError("Error new'ing in init!") - self.assertRaises( - exception.EvEmuError, self.create_testing_device, FakeDevice) - - def test_initialize(self): - self.create_testing_device() - self.assertTrue(self.device._device_pointer is not None) - - def test_get_lib(self): - self.create_testing_device() - lib = self.device.get_lib() - self.assertTrue(lib is not None) - - def test_get_device_file_stream(self): - self.create_testing_device() - self.device._device_file_stream = 1234 - self.assertEqual(self.device.get_device_file_stream(), 1234) - - def test_set_device_file_stream(self): - self.create_testing_device() - self.device.set_device_file_stream(1234) - self.assertEqual(self.device._device_file_stream, 1234) - - @testcase.skip("Test not implemented") - def test_close_device_file_stream_error_close(self): - pass - - @testcase.skip("Test not implemented") - def test_close_device_file_stream(self): - pass - - def test_get_device_pointer(self): - self.create_testing_device() - pointer = self.device.get_device_pointer() - self.assertEqual(type(pointer), int) - - def test_read_error(self): - class FakeDevice(EvEmuDevice): - def _read(self, *args, **kwds): - raise exception.EvEmuError("Error calling lib in _read") - def create_node(self, *args): - pass - self.create_testing_device(FakeDevice) - self.assertRaises( - exception.EvEmuError, self.device.read, self.get_device_file()) - - # XXX finish unit test - def test_read(self): - pass - - def test_create_node_error_uinput(self): - class FakeDevice(EvEmuDevice): - def _open_uinput(self, *args, **kwds): - raise exception.EvEmuError("Error calling lib in _uinput") - def _new(self): - pass - def read(self, *args): - pass - def delete(self): - pass - device = FakeDevice(self.library) - self.assertRaises( - exception.EvEmuError, - device.create_node, - self.get_device_file()) - - def test_create_node_error_create(self): - class FakeDevice(EvEmuDevice): - def _create(self, *args, **kwds): - raise exception.EvEmuError("Error calling lib in _create") - def _open_uinput(self, *args, **kwds): - pass - def _new(self): - pass - def read(self, *args): - pass - def close(self): - pass - device = FakeDevice(self.library) - self.assertRaises( - exception.EvEmuError, - device.create_node, - self.get_device_file()) - - def test_create_node(self): - device_count_before = len(util.get_all_device_numbers()) - self.create_testing_device() - device_count_after = len(util.get_all_device_numbers()) - self.assertEqual(device_count_before + 1, device_count_after) - - def test_write(self): - # prep a temp file to hold the written data - self.create_testing_device() - (output_fd, filename) = tempfile.mkstemp() - self.device.write(filename) - os.close(output_fd) - # now test the data to make sure the write happened correctly - file_object = open(filename) - data = file_object.read() - file_object.close() - # correct length - self.assertEqual(len(data), 840) - # value looks as expected - expected = "N: N-Trig-MultiTouch-Virtual-Device\n" - self.assertTrue(data.startswith(expected)) - # files are identicatl - file_object = open(self.get_device_file()) - expected_data = file_object.read() - file_object.close() - self.assertEqual(data, expected_data) - - def test_extract(self): - """ - This test does the following in order to test device data extraction: - - 1) uses the virtual device created during setUp as the target for the - extraction of device data, - - 2) writes the device data (stored in the device data structure in the - evemu_extract library function) to a tempfile, and - - 3) checks the .prop file and the tempfile to see that the values they - have stored are identical. - - """ - - # get the device node for the virtual device created as part of the - # test - self.create_testing_device() - node = self.device.get_node_name() - # extract the device info from the node, saving it to the device data - # structure - self.device.extract(node) - # prep a temp file to hold the written data - (output_fd, filename) = tempfile.mkstemp() - # write the device data structure contents to a file and compare with - # the device .prop file that was used to create the virtual device to - # begin with; they should be identical - self.device.write(filename) - os.close(output_fd) - # then, now test the data to make sure the write happened correctly - file_object = open(filename) - data = file_object.read() - file_object.close() - # do the checks - file_object = open(self.get_device_file()) - expected_data = file_object.read() - file_object.close() - # the evemu_extract library function doesn't generate a P: - # (properties) line on kernels older than 2.6.38, so this test only - # compares the lines that will be the same across supported kernels. - self.assertEqual( - data.splitlines()[0:1], - expected_data.splitlines()[0:1]) - self.assertEqual( - data.splitlines()[-28:-1], - expected_data.splitlines()[-28:-1]) - - @testcase.skip("Implementation not complete.") - def test_record(self): - pass - - @testcase.skip("Implementation not complete.") - def test_play(self): - pass - - -class EvEmuDevicePropertyTestCase(testcase.BaseTestCase): - - def get_ev_abs_codes(self): - return const.absolute_axes.values() - - def test_version(self): - self.create_testing_device() - self.assertEqual(self.device.version, 0) - - def test_name(self): - self.create_testing_device() - self.assertEqual(self.device.name, "N-Trig-MultiTouch-Virtual-Device") - - def test_id_bustype(self): - self.create_testing_device() - self.assertEqual(self.device.id_bustype, 3) - - def test_id_vendor(self): - self.create_testing_device() - self.assertEqual(hex(self.device.id_vendor), "0x1b96") - - def test_id_product(self): - self.create_testing_device() - self.assertEqual(self.device.id_product, 1) - - def test_id_version(self): - self.create_testing_device() - self.assertEqual(self.device.id_version, 272) - - -class EvEmuDeviceGetterTestCase(testcase.BaseTestCase): - - def test_get_abs_minimum(self): - self.create_testing_device() - expected = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ] - results = [self.device.get_abs_minimum(x) - for x in const.absolute_axes.values()] - self.assertEqual(results, expected) - - def test_get_abs_maximum(self): - self.create_testing_device() - expected = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9600, 7200, 0, 0, 0, 0, - 7200, 1, 7200, 0, 9600, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9600, - 0, 0, - ] - # Skipping the entry for ABS_CNT; some times it's 0, sometimes a very - # large negative number. - results = [self.device.get_abs_maximum(x) - for x in const.absolute_axes.values()] - self.assertEqual(results[:-1], expected[:-1]) - - def test_get_abs_fuzz(self): - self.create_testing_device() - expected = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 78, 0, 0, 0, 0, 150, - 0, 78, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, - ] - results = [self.device.get_abs_fuzz(x) - for x in const.absolute_axes.values()] - self.assertEqual(results, expected) - - def test_get_abs_flat(self): - self.create_testing_device() - expected = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ] - results = [self.device.get_abs_flat(x) - for x in const.absolute_axes.values()] - self.assertEqual(results, expected) - - def test_get_abs_resolution(self): - self.create_testing_device() - expected = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ] - results = [self.device.get_abs_resolution(x) - for x in const.absolute_axes.values()] - self.assertEqual(results, expected) - - def test_has_prop(self): - self.create_testing_device() - expected = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ] - results = [self.device.has_prop(x) - for x in const.absolute_axes.values()] - self.assertEqual(results, expected) - - def test_has_event_ev_abs(self): - self.create_testing_device() - expected = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, - ] - results = [self.device.has_event(const.event_types["EV_ABS"], x) - for x in const.absolute_axes.values()] - self.assertEqual(results, expected) - - def test_has_event_ev_key(self): - self.create_testing_device() - expected = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ] - results = [self.device.has_event(const.event_types["EV_KEY"], x) - for x in const.buttons.values()] - self.assertEqual(results, expected) - - -if __name__ == "__main__": - unittest.main() diff --git a/python/evemu/tests/test_device2.py b/python/evemu/tests/test_device2.py new file mode 100644 index 0000000..a22858f --- /dev/null +++ b/python/evemu/tests/test_device2.py @@ -0,0 +1,223 @@ + +from evemu.testing import testcase +from multiprocessing import Process, Queue, Event + +import evemu +import os +import re +import tempfile +import unittest + + +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() 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) + + +class DeviceActionTestCase(testcase.BaseTestCase): + """ + Verifies the high-level Device functions (create, describe, play, record). + """ + + 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/event10") + + 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/event10")) + + 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()) + + 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())) + + 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 = 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() as t: + d.describe(t) + + # read in the temporary file and compare to the original + t.flush() + t.seek(0) + newdata = t.readlines() + self.assertEquals(data, newdata) + + 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() + with open(events_file) as e: + indata = 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 = 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)) + + +class DevicePropertiesTestCase(testcase.BaseTestCase): + """ + Verifies the workings of the various device property accessors. + """ + + def setUp(self): + super(DevicePropertiesTestCase, self).setUp() + self._device = evemu.Device(self.get_device_file()) + + def tearDown(self): + del self._device + super(DevicePropertiesTestCase, self).tearDown() + + def test_version(self): + self.assertEqual(self._device.version, 0) + + def test_name(self): + self.assertEqual(self._device.name, "N-Trig-MultiTouch-Virtual-Device") + + def test_id_bustype(self): + self.assertEqual(self._device.id_bustype, 3) + + def test_id_vendor(self): + self.assertEqual(hex(self._device.id_vendor), "0x1b96") + + def test_id_product(self): + self.assertEqual(self._device.id_product, 1) + + def test_id_version(self): + self.assertEqual(self._device.id_version, 272) + + def test_get_abs_minimum(self): + expected = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ] + results = [self._device.get_abs_minimum(x) + for x in evemu.const.absolute_axes.values()] + self.assertEqual(results, expected) + + def test_get_abs_maximum(self): + expected = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9600, 7200, 0, 0, 0, 0, + 7200, 1, 7200, 0, 9600, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9600, + 0, 0, + ] + # Skipping the entry for ABS_CNT; some times it's 0, sometimes a very + # large negative number. + results = [self._device.get_abs_maximum(x) + for x in evemu.const.absolute_axes.values()] + self.assertEqual(results[:-1], expected[:-1]) + + def test_get_abs_fuzz(self): + expected = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 78, 0, 0, 0, 0, 150, + 0, 78, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, + ] + results = [self._device.get_abs_fuzz(x) + for x in evemu.const.absolute_axes.values()] + self.assertEqual(results, expected) + + def test_get_abs_flat(self): + expected = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ] + results = [self._device.get_abs_flat(x) + for x in evemu.const.absolute_axes.values()] + self.assertEqual(results, expected) + + def test_get_abs_resolution(self): + expected = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ] + results = [self._device.get_abs_resolution(x) + for x in evemu.const.absolute_axes.values()] + self.assertEqual(results, expected) + + def test_has_prop(self): + expected = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ] + results = [self._device.has_prop(x) + for x in evemu.const.absolute_axes.values()] + self.assertEqual(results, expected) + + def test_has_event_ev_abs(self): + expected = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, + 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + ] + results = [self._device.has_event(evemu.const.event_types["EV_ABS"], x) + for x in evemu.const.absolute_axes.values()] + self.assertEqual(results, expected) + + def test_has_event_ev_key(self): + expected = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ] + results = [self._device.has_event(evemu.const.event_types["EV_KEY"], x) + for x in evemu.const.buttons.values()] + self.assertEqual(results, expected) + + +if __name__ == "__main__": + unittest.main() diff --git a/python/evemu/tests/test_script.py b/python/evemu/tests/test_script.py deleted file mode 100644 index b8889c4..0000000 --- a/python/evemu/tests/test_script.py +++ /dev/null @@ -1,29 +0,0 @@ -import unittest - -from evemu.script import EvEmu -from evemu.testing import testcase - - -class EvEmuTestCase(testcase.BaseTestCase): - - def setUp(self): - super(EvEmuTestCase, self).setUp() - self.evemu = EvEmu(library=self.library) - - def test_describe(self): - pass - - def test_create_device(self): - # Load the device file - pass - - def test_record(self): - pass - - def test_play(self): - #self.evemu.play(self.get_events_file(), self.get_device_file()) - pass - - -if __name__ == "__main__": - unittest.main() diff --git a/python/evemu/tests/test_util.py b/python/evemu/tests/test_util.py deleted file mode 100644 index 7bc5076..0000000 --- a/python/evemu/tests/test_util.py +++ /dev/null @@ -1,54 +0,0 @@ -import unittest - -from evemu import util -from evemu.testing import testcase - - -class CommandsTestCase(testcase.Non26BaseTestCase): - - def test_lsinput_raw(self): - results = util.lsinput_raw() - self.assertIn("/dev/input/event", results) - self.assertIn("bustype", results) - self.assertIn("name", results) - self.assertIn("product", results) - self.assertIn("version", results) - - def test_lsinput(self): - # let's just check the first one - result = util.lsinput()[0] - self.assertEqual(result.get("device"), "/dev/input/event0") - self.assertTrue(result.get("bustype") is not None) - self.assertTrue(result.get("name") is not None) - self.assertTrue(result.get("product") is not None) - self.assertTrue(result.get("version") is not None) - - -class DevicesTestCase(testcase.Non26BaseTestCase): - - def test_get_all_device_numbers(self): - result = util.get_all_device_numbers() - self.assertTrue(result != []) - - def test_get_all_device_names(self): - result = util.get_all_device_names() - self.assertTrue(result != []) - - def test_get_last_device_number(self): - self.assertTrue(isinstance(util.get_last_device_number(), int)) - - def test_get_last_device(self): - result = util.get_last_device() - self.assertIn("/dev/input/event", result) - - def test_get_next_device(self): - last_device = util.get_last_device() - next_device = util.get_next_device() - self.assertIn("/dev/input/event", next_device) - self.assertEqual( - (int(last_device[-1]) + 1) % 10, - int(next_device[-1])) - - -if __name__ == "__main__": - unittest.main() diff --git a/python/evemu/tests/test_wrapper.py b/python/evemu/tests/test_wrapper.py deleted file mode 100644 index dcd51c4..0000000 --- a/python/evemu/tests/test_wrapper.py +++ /dev/null @@ -1,48 +0,0 @@ -import unittest - -from evemu import util -from evemu.testing import testcase -from evemu.wrapper import EvEmuWrapper - - -class EvEmuWrapperTestCase(testcase.BaseTestCase): - - def setUp(self): - super(EvEmuWrapperTestCase, self).setUp() - self.wrapper = EvEmuWrapper(self.library) - - def tearDown(self): - if self.wrapper.device: - self.wrapper.device.destroy() - super(EvEmuWrapperTestCase, self).tearDown() - - def test_initialize(self): - self.assertTrue(self.wrapper.device is not None) - self.assertTrue(self.wrapper.get_device() is not None) - - def test_create_already_created(self): - pass - - def test_create(self): - self.wrapper.create(self.get_device_file()) - device_list = util.get_all_device_names() - self.assertTrue("N-Trig-MultiTouch-Virtual-Device" in device_list) - - @testcase.skip("Implemnentation not complete") - def test_read(self): - # XXX finish unit test - result = self.wrapper.read(self.get_device_file()) - # XXX need to do checks against the result - - @testcase.skip("Implemnentation not complete") - def test_extract(self): - # XXX finish unit test - result = self.wrapper.extract(self.get_device_file()) - print "\nfilename: %s" % self.get_device_file() - import os - print "exists? %s" % str(os.path.exists(self.get_device_file())) - print "result:\n%s" % result - - -if __name__ == "__main__": - unittest.main() diff --git a/python/evemu/util.py b/python/evemu/util.py deleted file mode 100644 index e86fcb1..0000000 --- a/python/evemu/util.py +++ /dev/null @@ -1,99 +0,0 @@ -import os -import re -import subprocess - -from evemu import const - - -def lsinput_raw(): - command_parts = ["lsinput"] - try: - # Python 2.7 - output = subprocess.check_output(command_parts) - except AttributeError: - # Python 2.4, 2.5, 2.6 - output = subprocess.Popen( - command_parts, stdout=subprocess.PIPE).communicate()[0] - return output - - -def lsinput(): - devices = [] - data = {} - for line in lsinput_raw().splitlines(): - line = line.strip() - if line.startswith("/dev/input"): - if data: - devices.append(data) - data = {} - data["device"] = line - else: - key = line[:7].strip() - value = line[10:].strip() - if key == "name": - # trim the quotes - value = value[1:-1] - if key: - data[key] = value - if data: - devices.append(data) - return devices - - -def get_top_directory(): - import evemu - return evemu.__path__[0] - - -def get_test_directory(): - from evemu import tests - return tests.__path__[0] - - -def get_test_module(): - return get_test_directory().replace("/", ".") - - -def get_all_device_numbers(): - numbers = [] - for index in xrange(const.MAX_EVENT_NODE): - path = const.DEVICE_PATH_TEMPLATE % index - if os.path.exists(path): - numbers.append(index) - return numbers - - -def get_all_device_names(): - names = [] - for device_number in get_all_device_numbers(): - filename = const.DEVICE_NAME_PATH_TEMPLATE % device_number - if os.path.exists(filename): - file_handle = open(filename) - #names.append({"name": file_handle.read(), "id": device_number}) - names.append(file_handle.read().strip()) - file_handle.close() - return names - - -def get_last_device_number(): - """ - Get the last used device node number. - """ - return get_all_device_numbers()[-1] - - -def get_last_device(): - """ - Get the last used device node. - """ - return const.DEVICE_PATH_TEMPLATE % get_last_device_number() - - -def get_next_device(): - """ - Get the next availne device node. - """ - next_number = get_last_device_number() + 1 - if next_number > const.MAX_EVENT_NODE: - raise EvEmuError("device count exceeded MAX_EVENT_NODE") - return const.DEVICE_PATH_TEMPLATE % next_number diff --git a/python/evemu/wrapper.py b/python/evemu/wrapper.py deleted file mode 100644 index 8f9ab4c..0000000 --- a/python/evemu/wrapper.py +++ /dev/null @@ -1,66 +0,0 @@ -import ctypes -import os -import tempfile - -from evemu import base -from evemu import const -from evemu import device -from evemu.exception import ExecutionError - - -class EvEmuWrapper(base.EvEmuBase): - """ - This class wraps the functionality offered by several of the evemu command - line tools. - """ - def __init__(self, library=""): - """ - This method allocates a new evemu device structure and initializes - all fields to zero. - """ - super(EvEmuWrapper, self).__init__(library) - self.device = device.EvEmuDevice(library) - - def __del__(self): - del(self.device) - - @property - def _as_parameter_(self): - return self.get_device() - - def get_device(self): - return self.device.get_device_pointer() - - def create(self, device_file): - self.device.create_node(device_file) - - # XXX maybe this isn't needed at this level of abstraction... - def delete(self): - """ - Frees up the memory associated with the pointer (and deletes the - pointer). - - See the docstring for EvEmuDevice.delete for more info. - """ - self.device.delete() - - # XXX maybe this isn't needed at this level of abstraction... - def destroy(self): - """ - Deletes the /dev/device/eventXX device that was created. - - See the docstring for EvEmuDevice.destroy for more info. - """ - self.device.destroy() - - def describe(self, device_path, output_file): - """ - """ - self.device.extract(device_path) - self.device.write(output_file) - - def play(self): - pass - - def record(self): - pass |