Hello community,

here is the log from the commit of package python-evdev for openSUSE:Factory 
checked in at 2018-08-29 12:26:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-evdev (Old)
 and      /work/SRC/openSUSE:Factory/.python-evdev.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-evdev"

Wed Aug 29 12:26:24 2018 rev:3 rq:631923 version:1.1.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-evdev/python-evdev.changes        
2018-06-29 22:34:44.886087855 +0200
+++ /work/SRC/openSUSE:Factory/.python-evdev.new/python-evdev.changes   
2018-08-29 12:26:25.275556810 +0200
@@ -1,0 +2,9 @@
+Tue Aug 28 08:00:44 UTC 2018 - [email protected]
+
+- Update to version 1.1.0
+  * Add support for handling force-feedback effect uploads.
+  * Fix typo preventing force-feedback effects that need left
+    coefficients from working.
+- Add _service file to fetch source from Git.
+
+-------------------------------------------------------------------

Old:
----
  v1.0.0.tar.gz

New:
----
  _service
  v1.1.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-evdev.spec ++++++
--- /var/tmp/diff_new_pack.yIr3H0/_old  2018-08-29 12:26:25.879558134 +0200
+++ /var/tmp/diff_new_pack.yIr3H0/_new  2018-08-29 12:26:25.883558143 +0200
@@ -19,7 +19,7 @@
 %define modname evdev
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-evdev
-Version:        1.0.0
+Version:        1.1.0
 Release:        0
 Summary:        Python bindings to the Linux input handling subsystem
 License:        BSD-3-Clause

++++++ _service ++++++
<services>
  <service name="obs_scm" mode="disabled">
    <param name="url">https://github.com/gvalkov/python-evdev.git</param>
    <param name="scm">git</param>
    <param name="revision">v1.1.0</param>
    <param name="versionformat">@PARENT_TAG@</param>
    <param name="versionrewrite-pattern">v(.*)</param>
  </service>
  <service name="set_version" mode="disabled" />
</services>
++++++ v1.0.0.tar.gz -> v1.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-evdev-1.0.0/docs/changelog.rst 
new/python-evdev-1.1.0/docs/changelog.rst
--- old/python-evdev-1.0.0/docs/changelog.rst   2018-06-02 00:42:45.000000000 
+0200
+++ new/python-evdev-1.1.0/docs/changelog.rst   2018-08-27 21:11:25.000000000 
+0200
@@ -1,6 +1,14 @@
 Changelog
 ---------
 
+1.1.0 (Aug 27, 2018)
+====================
+
+- Add support for handling force-feedback effect uploads (many thanks to 
`@ndreys`).
+
+- Fix typo preventing ff effects that need left coefficients from working.
+
+
 1.0.0 (Jun 02, 2018)
 ====================
 
@@ -335,6 +343,7 @@
 .. _`@isia`:    https://github.com/isia
 .. _`@forsenonlhaimaisentito`: https://github.com/forsenonlhaimaisentito
 .. _`@paulo-raca`: https://github.com/paulo-raca
+.. _`@ndreys`: https://github.com/ndreys
 
 .. _issue21121: http://bugs.python.org/issue21121
 .. _`#63`:      https://github.com/gvalkov/python-evdev/issues/63
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-evdev-1.0.0/docs/conf.py 
new/python-evdev-1.1.0/docs/conf.py
--- old/python-evdev-1.0.0/docs/conf.py 2018-06-02 00:42:45.000000000 +0200
+++ new/python-evdev-1.1.0/docs/conf.py 2018-08-27 21:11:25.000000000 +0200
@@ -60,7 +60,7 @@
 # built documents.
 #
 # The full version, including alpha/beta/rc tags.
-release = '1.0.0'
+release = '1.1.0'
 
 # The short X.Y version.
 version = release
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-evdev-1.0.0/docs/install.rst 
new/python-evdev-1.1.0/docs/install.rst
--- old/python-evdev-1.0.0/docs/install.rst     2018-06-02 00:42:45.000000000 
+0200
+++ new/python-evdev-1.1.0/docs/install.rst     2018-08-27 21:11:25.000000000 
+0200
@@ -10,7 +10,10 @@
     <a href="https://www.archlinux.org/packages/extra/x86_64/python-evdev/";>
       <img height="30px" 
src="_static/pacifica-icon-set/distributor-logo-archlinux.png">
     </a>
-    <a href="https://packages.ubuntu.com/artful/python-evdev";>
+    <a 
href="https://packages.debian.org/search?searchon=names&keywords=python-evdev";>
+      <img height="30px" 
src="_static/pacifica-icon-set/distributor-logo-debian.png">
+    </a>
+    <a 
href="https://packages.ubuntu.com/search?suite=default&section=all&arch=any&keywords=python-evdev&searchon=names";>
       <img height="30px" 
src="_static/pacifica-icon-set/distributor-logo-ubuntu.png">
     </a>
     <a href="https://apps.fedoraproject.org/packages/python3-evdev";>
@@ -24,7 +27,7 @@
     --!>
     </div>
 
-Consult the relevant documentation of your OS package manager for installation 
instructions.
+Consult the documentation of your OS package manager for installation 
instructions.
 
 
 From source
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-evdev-1.0.0/docs/tutorial.rst 
new/python-evdev-1.1.0/docs/tutorial.rst
--- old/python-evdev-1.0.0/docs/tutorial.rst    2018-06-02 00:42:45.000000000 
+0200
+++ new/python-evdev-1.1.0/docs/tutorial.rst    2018-08-27 21:11:25.000000000 
+0200
@@ -362,3 +362,75 @@
 
 
 .. _`async/await`:  https://docs.python.org/3/library/asyncio-task.html
+
+Create ``uinput`` device capable of recieving FF-effects
+========================================================
+
+::
+
+    import asyncio
+    from evdev import UInput, categorize, ecodes
+
+    cap = {
+       ecodes.EV_FF:  [ecodes.FF_RUMBLE ],
+       ecodes.EV_KEY: [ecodes.KEY_A, ecodes.KEY_B]
+    }
+
+    ui = UInput(cap, name='test-controller', version=0x3)
+
+    async def print_events(device):
+        async for event in device.async_read_loop():
+            print(categorize(event))
+
+            # Wait for an EV_UINPUT event that will signal us that an
+            # effect upload/erase operation is in progress.
+            if event.type != ecodes.EV_UINPUT:
+                pass
+
+            if event.code == ecodes.UI_FF_UPLOAD:
+                upload = device.begin_upload(event.value)
+                upload.retval = 0
+
+                print(f'[upload] effect_id: {upload.effect_id}, type: 
{upload.effect.type}')
+                device.end_upload(upload)
+
+            elif event.code == ecodes.UI_FF_ERASE:
+                erase = device.begin_erase(event.value)
+                print(f'[erase] effect_id {erase.effect_id}')
+
+                erase.retval = 0
+                device.end_erase(erase)
+
+    asyncio.ensure_future(print_events(ui))
+    loop = asyncio.get_event_loop()
+    loop.run_forever()
+
+
+Injecting an FF-event into first FF-capable device found
+========================================================
+
+::
+
+    from evdev import ecodes, InputDevice, ff
+
+    # Find first EV_FF capable event device (that we have permissions to use).
+    for name in evdev.list_devices():
+        dev = InputDevice(name)
+        if ecodes.EV_FF in dev.capabilities():
+            break
+
+    rumble = ff.Rumble(strong_magnitude=0x0000, weak_magnitude=0xffff)
+    effect_type = ff.EffectType(ff_rumble_effect=rumble)
+    duration_ms = 1000
+
+    effect = ff.Effect(
+        ecodes.FF_RUMBLE, -1, 0,
+        ff.Trigger(0, 0),
+        ff.Replay(duration_ms, 0),
+        ff.EffectType(ff_rumble_effect=rumble)
+    )
+
+    repeat_count = 1
+    effect_id = dev.upload_effect(effect)
+    dev.write(e.EV_FF, effect_id, repeat_count)
+    dev.erase_effect(effect_id)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-evdev-1.0.0/evdev/ff.py 
new/python-evdev-1.1.0/evdev/ff.py
--- old/python-evdev-1.0.0/evdev/ff.py  2018-06-02 00:42:45.000000000 +0200
+++ new/python-evdev-1.1.0/evdev/ff.py  2018-08-27 21:11:25.000000000 +0200
@@ -8,6 +8,7 @@
 _u16 = ctypes.c_uint16
 _u32 = ctypes.c_uint32
 _s16 = ctypes.c_int16
+_s32 = ctypes.c_int32
 
 class Replay(ctypes.Structure):
     '''
@@ -100,7 +101,7 @@
         ('right_saturation', _u16),
         ('left_saturation', _u16),
         ('right_coeff', _s16),
-        ('left_foeff', _s16),
+        ('left_coeff', _s16),
         ('deadband', _u16),
         ('center', _s16),
     ]
@@ -167,6 +168,21 @@
         ('u', EffectType)
     ]
 
+class UInputUpload(ctypes.Structure):
+    _fields_ = [
+        ('request_id', _u32),
+        ('retval', _s32),
+        ('effect', Effect),
+        ('old', Effect),
+    ]
+
+class UInputErase(ctypes.Structure):
+    _fields_ = [
+        ('request_id', _u32),
+        ('retval', _s32),
+        ('effect_id', _u32),
+    ]
+
 # ff_types = {
 #     ecodes.FF_CONSTANT,
 #     ecodes.FF_PERIODIC,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-evdev-1.0.0/evdev/genecodes.py 
new/python-evdev-1.1.0/evdev/genecodes.py
--- old/python-evdev-1.0.0/evdev/genecodes.py   2018-06-02 00:42:45.000000000 
+0200
+++ new/python-evdev-1.1.0/evdev/genecodes.py   2018-08-27 21:11:25.000000000 
+0200
@@ -20,7 +20,7 @@
 
 
 #-----------------------------------------------------------------------------
-macro_regex = r'#define 
+((?:KEY|ABS|REL|SW|MSC|LED|BTN|REP|SND|ID|EV|BUS|SYN|FF)_\w+)'
+macro_regex = r'#define 
+((?:KEY|ABS|REL|SW|MSC|LED|BTN|REP|SND|ID|EV|BUS|SYN|FF|UI_FF)_\w+)'
 macro_regex = re.compile(macro_regex)
 
 uname = list(os.uname()); del uname[1]
@@ -34,6 +34,7 @@
 #include <dev/evdev/input.h>
 #else
 #include <linux/input.h>
+#include <linux/uinput.h>
 #endif
 
 /* Automatically generated by evdev.genecodes */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-evdev-1.0.0/evdev/input.c 
new/python-evdev-1.1.0/evdev/input.c
--- old/python-evdev-1.0.0/evdev/input.c        2018-06-02 00:42:45.000000000 
+0200
+++ new/python-evdev-1.1.0/evdev/input.c        2018-08-27 21:11:25.000000000 
+0200
@@ -381,6 +381,11 @@
                 effect->u.constant.envelope.attack_level,
                 effect->u.constant.envelope.fade_length,
                 effect->u.constant.envelope.fade_level);
+
+    case FF_RUMBLE:
+        fprintf(stderr, "  rumble: (%d, %d)\n",
+               effect->u.rumble.strong_magnitude,
+               effect->u.rumble.weak_magnitude);
         break;
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-evdev-1.0.0/evdev/uinput.c 
new/python-evdev-1.1.0/evdev/uinput.c
--- old/python-evdev-1.0.0/evdev/uinput.c       2018-06-02 00:42:45.000000000 
+0200
+++ new/python-evdev-1.1.0/evdev/uinput.c       2018-08-27 21:11:25.000000000 
+0200
@@ -69,7 +69,7 @@
 
 
 static PyObject *
-uinput_create(PyObject *self, PyObject *args) {
+uinput_setup(PyObject *self, PyObject *args) {
     int fd, len, i, abscode;
     uint16_t vendor, product, version, bustype;
 
@@ -89,6 +89,8 @@
     uidev.id.version = version;
     uidev.id.bustype = bustype;
 
+    uidev.ff_effects_max = FF_MAX_EFFECTS;
+
     len = PyList_Size(absinfo);
     for (i=0; i<len; i++) {
         // item -> (ABS_X, 0, 255, 0, 0, 0, 0)
@@ -113,6 +115,22 @@
     /*         goto on_err; */
     /* } */
 
+    Py_RETURN_NONE;
+
+    on_err:
+        _uinput_close(fd);
+        PyErr_SetFromErrno(PyExc_IOError);
+        return NULL;
+}
+
+static PyObject *
+uinput_create(PyObject *self, PyObject *args)
+{
+    int fd;
+
+    int ret = PyArg_ParseTuple(args, "i", &fd);
+    if (!ret) return NULL;
+
     if (ioctl(fd, UI_DEV_CREATE) < 0)
         goto on_err;
 
@@ -206,6 +224,25 @@
         return NULL;
 }
 
+int _uinput_begin_upload(int fd, struct uinput_ff_upload *upload)
+{
+    return ioctl(fd, UI_BEGIN_FF_UPLOAD, upload);
+}
+
+int _uinput_end_upload(int fd, struct uinput_ff_upload *upload)
+{
+    return ioctl(fd, UI_END_FF_UPLOAD, upload);
+}
+
+int _uinput_begin_erase(int fd, struct uinput_ff_erase *upload)
+{
+    return ioctl(fd, UI_BEGIN_FF_ERASE, upload);
+}
+
+int _uinput_end_erase(int fd, struct uinput_ff_erase *upload)
+{
+    return ioctl(fd, UI_END_FF_ERASE, upload);
+}
 
 #define MODULE_NAME "_uinput"
 #define MODULE_HELP "Python bindings for parts of linux/uinput.c"
@@ -214,6 +251,9 @@
     { "open",  uinput_open, METH_VARARGS,
       "Open uinput device node."},
 
+    { "setup",  uinput_setup, METH_VARARGS,
+      "Set an uinput device up."},
+
     { "create",  uinput_create, METH_VARARGS,
       "Create an uinput device."},
 
@@ -228,7 +268,7 @@
 
     { "set_phys", uinput_set_phys, METH_VARARGS,
       "Set physical path"},
-      
+
     { NULL, NULL, 0, NULL}
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-evdev-1.0.0/evdev/uinput.py 
new/python-evdev-1.1.0/evdev/uinput.py
--- old/python-evdev-1.0.0/evdev/uinput.py      2018-06-02 00:42:45.000000000 
+0200
+++ new/python-evdev-1.1.0/evdev/uinput.py      2018-08-27 21:11:25.000000000 
+0200
@@ -8,6 +8,8 @@
 from evdev import _uinput
 from evdev import ecodes, util, device
 from evdev.events import InputEvent
+import evdev.ff as ff
+import ctypes
 
 try:
     from evdev.eventio_async import EventIO
@@ -131,6 +133,8 @@
         # Set phys name
         _uinput.set_phys(self.fd, phys)
 
+        _uinput.setup(self.fd, name, vendor, product, version, bustype, 
absinfo)
+
         # Set device capabilities.
         for etype, codes in events.items():
             for code in codes:
@@ -149,7 +153,11 @@
                 _uinput.enable(self.fd, etype, code)
 
         # Create the uinput device.
-        _uinput.create(self.fd, name, vendor, product, version, bustype, 
absinfo)
+        _uinput.create(self.fd)
+
+        self.dll = ctypes.CDLL(_uinput.__file__)
+        self.dll._uinput_begin_upload.restype = ctypes.c_int
+        self.dll._uinput_end_upload.restype = ctypes.c_int
 
         #: An :class:`InputDevice <evdev.device.InputDevice>` instance
         #: for the fake input device. ``None`` if the device cannot be
@@ -206,6 +214,35 @@
 
         return self.device.capabilities(verbose, absinfo)
 
+    def begin_upload(self, effect_id):
+        upload = ff.UInputUpload()
+        upload.effect_id = effect_id
+
+        if self.dll._uinput_begin_upload(self.fd, ctypes.byref(upload)):
+            raise UInputError('Failed to begin uinput upload: ' +
+                              os.strerror())
+
+        return upload
+
+    def end_upload(self, upload):
+        if self.dll._uinput_end_upload(self.fd, ctypes.byref(upload)):
+            raise UInputError('Failed to end uinput upload: ' +
+                              os.strerror())
+
+    def begin_erase(self, effect_id):
+        erase = ff.UInputErase()
+        erase.effect_id = effect_id
+
+        if self.dll._uinput_begin_erase(self.fd, ctypes.byref(erase)):
+            raise UInputError('Failed to begin uinput erase: ' +
+                              os.strerror())
+        return erase
+
+    def end_erase(self, erase):
+        if self.dll._uinput_end_erase(self.fd, ctypes.byref(erase)):
+            raise UInputError('Failed to end uinput erase: ' +
+                              os.strerror())
+
     def _verify(self):
         '''
         Verify that an uinput device exists and is readable and writable
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-evdev-1.0.0/setup.cfg 
new/python-evdev-1.1.0/setup.cfg
--- old/python-evdev-1.0.0/setup.cfg    2018-06-02 00:42:45.000000000 +0200
+++ new/python-evdev-1.1.0/setup.cfg    2018-08-27 21:11:25.000000000 +0200
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 1.0.0
+current_version = 1.1.0
 message = Bump version: {current_version} -> {new_version}
 commit = True
 tag = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-evdev-1.0.0/setup.py 
new/python-evdev-1.1.0/setup.py
--- old/python-evdev-1.0.0/setup.py     2018-06-02 00:42:45.000000000 +0200
+++ new/python-evdev-1.1.0/setup.py     2018-08-27 21:11:25.000000000 +0200
@@ -44,7 +44,7 @@
 #-----------------------------------------------------------------------------
 kw = {
     'name':                 'evdev',
-    'version':              '1.0.0',
+    'version':              '1.1.0',
 
     'description':          'Bindings to the Linux input handling subsystem',
     'long_description':     open(pjoin(here, 'README.rst')).read(),
@@ -70,6 +70,7 @@
         headers = [
             '/usr/include/linux/input.h',
             '/usr/include/linux/input-event-codes.h',
+            '/usr/include/linux/uinput.h',
         ]
 
     headers = [header for header in headers if os.path.isfile(header)]


Reply via email to