Hello community,

here is the log from the commit of package libratbag for openSUSE:Factory 
checked in at 2019-11-12 11:56:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libratbag (Old)
 and      /work/SRC/openSUSE:Factory/.libratbag.new.2990 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libratbag"

Tue Nov 12 11:56:13 2019 rev:6 rq:747443 version:0.11

Changes:
--------
--- /work/SRC/openSUSE:Factory/libratbag/libratbag.changes      2019-08-13 
13:14:46.165512569 +0200
+++ /work/SRC/openSUSE:Factory/.libratbag.new.2990/libratbag.changes    
2019-11-12 11:58:05.783514282 +0100
@@ -1,0 +2,11 @@
+Mon Nov 11 20:04:08 UTC 2019 - ma...@marix.org
+
+- Update to version 0.11:
+  * Added and improved devices:
+    + Logitech MX Master, MX Master 3, MX Master AMZ
+    + Logitech G305
+    + Logitech G502 Hero wireless
+    + Logitech G602, G604
+    + Steelseries Kinzu v3 
+
+-------------------------------------------------------------------

Old:
----
  libratbag-0.10.tar.xz

New:
----
  libratbag-0.11.tar.xz

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

Other differences:
------------------
++++++ libratbag.spec ++++++
--- /var/tmp/diff_new_pack.qgFhCx/_old  2019-11-12 11:58:06.451514994 +0100
+++ /var/tmp/diff_new_pack.qgFhCx/_new  2019-11-12 11:58:06.459515002 +0100
@@ -18,7 +18,7 @@
 
 
 Name:           libratbag
-Version:        0.10
+Version:        0.11
 Release:        0
 Summary:        Configuration library for gaming mice
 License:        MIT

++++++ _service ++++++
--- /var/tmp/diff_new_pack.qgFhCx/_old  2019-11-12 11:58:06.491515037 +0100
+++ /var/tmp/diff_new_pack.qgFhCx/_new  2019-11-12 11:58:06.491515037 +0100
@@ -2,7 +2,7 @@
   <service name="obs_scm" mode="disabled">
     <param name="url">https://github.com/libratbag/libratbag.git</param>
     <param name="scm">git</param>
-    <param name="revision">v0.10</param>
+    <param name="revision">v0.11</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="changesgenerate">enable</param>
     <param name="versionrewrite-pattern">v(.*)</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.qgFhCx/_old  2019-11-12 11:58:06.519515066 +0100
+++ /var/tmp/diff_new_pack.qgFhCx/_new  2019-11-12 11:58:06.519515066 +0100
@@ -1,4 +1,4 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/libratbag/libratbag.git</param>
-              <param 
name="changesrevision">ab3f1df06e684d610927522ce4a7fdc8e204e141</param></service></servicedata>
\ No newline at end of file
+              <param 
name="changesrevision">ce377fc36c2c35ab79446a580aa2141a4c7eff01</param></service></servicedata>
\ No newline at end of file

++++++ libratbag-0.10.tar.xz -> libratbag-0.11.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/.circleci/config.yml 
new/libratbag-0.11/.circleci/config.yml
--- old/libratbag-0.10/.circleci/config.yml     2019-08-02 03:19:16.000000000 
+0200
+++ new/libratbag-0.11/.circleci/config.yml     2019-11-05 02:06:27.000000000 
+0100
@@ -239,5 +239,3 @@
           filters:
               branches:
                 only: master
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/data/devices/data-parse-test.py 
new/libratbag-0.11/data/devices/data-parse-test.py
--- old/libratbag-0.10/data/devices/data-parse-test.py  2019-08-02 
03:19:16.000000000 +0200
+++ new/libratbag-0.11/data/devices/data-parse-test.py  2019-11-05 
02:06:27.000000000 +0100
@@ -169,7 +169,7 @@
 
 
 def check_section_hidpp20(section):
-    permitted = ['DeviceIndex']
+    permitted = ['DeviceIndex', 'Quirk']
     for key in section.keys():
         assertIn(key, permitted)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libratbag-0.10/data/devices/logitech-MX-Master-3.device 
new/libratbag-0.11/data/devices/logitech-MX-Master-3.device
--- old/libratbag-0.10/data/devices/logitech-MX-Master-3.device 1970-01-01 
01:00:00.000000000 +0100
+++ new/libratbag-0.11/data/devices/logitech-MX-Master-3.device 2019-11-05 
02:06:27.000000000 +0100
@@ -0,0 +1,5 @@
+# Logitech MX Master 3
+[Device]
+Name=Logitech MX Master 3
+DeviceMatch=bluetooth:046d:b023;usb:046d:4082
+Driver=hidpp20
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libratbag-0.10/data/devices/logitech-MX-Master.device 
new/libratbag-0.11/data/devices/logitech-MX-Master.device
--- old/libratbag-0.10/data/devices/logitech-MX-Master.device   2019-08-02 
03:19:16.000000000 +0200
+++ new/libratbag-0.11/data/devices/logitech-MX-Master.device   2019-11-05 
02:06:27.000000000 +0100
@@ -1,5 +1,5 @@
 # Logitech MX Master
 [Device]
 Name=Logitech MX Master
-DeviceMatch=usb:046d:4041;bluetooth:046d:b012;usb:046d:4060;bluetooth:046d:b017
+DeviceMatch=usb:046d:4041;bluetooth:046d:b012;usb:046d:4060;bluetooth:046d:b017;bluetooth:046d:b01e;usb:046d:4071
 Driver=hidpp20
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/data/devices/logitech-g305.device 
new/libratbag-0.11/data/devices/logitech-g305.device
--- old/libratbag-0.10/data/devices/logitech-g305.device        1970-01-01 
01:00:00.000000000 +0100
+++ new/libratbag-0.11/data/devices/logitech-g305.device        2019-11-05 
02:06:27.000000000 +0100
@@ -0,0 +1,7 @@
+[Device]
+Name=Logitech Gaming Mouse G305
+DeviceMatch=usb:046d:4074
+Driver=hidpp20
+
+[Driver/hidpp20]
+Quirk=G305
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libratbag-0.10/data/devices/logitech-g502-hero-wireless.device 
new/libratbag-0.11/data/devices/logitech-g502-hero-wireless.device
--- old/libratbag-0.10/data/devices/logitech-g502-hero-wireless.device  
1970-01-01 01:00:00.000000000 +0100
+++ new/libratbag-0.11/data/devices/logitech-g502-hero-wireless.device  
2019-11-05 02:06:27.000000000 +0100
@@ -0,0 +1,4 @@
+[Device]
+Name=Logitech G502 Hero Wireless
+DeviceMatch=usb:046d:407f;usb:046d:c08d
+Driver=hidpp20
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/data/devices/logitech-g602.device 
new/libratbag-0.11/data/devices/logitech-g602.device
--- old/libratbag-0.10/data/devices/logitech-g602.device        2019-08-02 
03:19:16.000000000 +0200
+++ new/libratbag-0.11/data/devices/logitech-g602.device        2019-11-05 
02:06:27.000000000 +0100
@@ -6,3 +6,4 @@
 
 [Driver/hidpp20]
 DeviceIndex=1
+Quirk=G602
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/data/devices/logitech-g604.device 
new/libratbag-0.11/data/devices/logitech-g604.device
--- old/libratbag-0.10/data/devices/logitech-g604.device        1970-01-01 
01:00:00.000000000 +0100
+++ new/libratbag-0.11/data/devices/logitech-g604.device        2019-11-05 
02:06:27.000000000 +0100
@@ -0,0 +1,4 @@
+[Device]
+Name=Logitech G604
+DeviceMatch=usb:046d:4085;bluetooth:046d:b024
+Driver=hidpp20
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libratbag-0.10/data/devices/steelseries-kinzu-v3.device 
new/libratbag-0.11/data/devices/steelseries-kinzu-v3.device
--- old/libratbag-0.10/data/devices/steelseries-kinzu-v3.device 1970-01-01 
01:00:00.000000000 +0100
+++ new/libratbag-0.11/data/devices/steelseries-kinzu-v3.device 2019-11-05 
02:06:27.000000000 +0100
@@ -0,0 +1,11 @@
+[Device]
+Name=SteelSeries Kinzu V3
+DeviceMatch=usb:1038:1388
+Driver=steelseries
+
+[Driver/steelseries]
+DeviceVersion=1
+Buttons=3
+Leds=0
+DpiList=400;800;1600;2000
+MacroLength=0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/meson.build 
new/libratbag-0.11/meson.build
--- old/libratbag-0.10/meson.build      2019-08-02 03:19:16.000000000 +0200
+++ new/libratbag-0.11/meson.build      2019-11-05 02:06:27.000000000 +0100
@@ -1,5 +1,5 @@
 project('libratbag', 'c',
-       version : '0.10',
+       version : '0.11',
        license : 'MIT/Expat',
        default_options : [ 'c_std=gnu99', 'warning_level=2' ],
        meson_version : '>= 0.40.0')
@@ -285,6 +285,7 @@
        'data/devices/logitech-MX-Ergo.device',
        'data/devices/logitech-MX-Master.device',
        'data/devices/logitech-MX-Master-2S.device',
+       'data/devices/logitech-MX-Master-3.device',
        'data/devices/logitech-MX518.device',
        'data/devices/logitech-T650.device',
        'data/devices/logitech-Wireless-Touchpad.device',
@@ -294,6 +295,7 @@
        'data/devices/logitech-g300.device',
        'data/devices/logitech-g302.device',
        'data/devices/logitech-g303.device',
+       'data/devices/logitech-g305.device',
        'data/devices/logitech-g402.device',
        'data/devices/logitech-g403-hero.device',
        'data/devices/logitech-g403-wireless.device',
@@ -302,12 +304,14 @@
        'data/devices/logitech-g5.device',
        'data/devices/logitech-g500.device',
        'data/devices/logitech-g500s.device',
+       'data/devices/logitech-g502-hero-wireless.device',
        'data/devices/logitech-g502-hero.device',
        'data/devices/logitech-g502-proteus-core.device',
        'data/devices/logitech-g502-proteus-spectrum.device',
        'data/devices/logitech-g600.device',
        'data/devices/logitech-g602.device',
        'data/devices/logitech-g603.device',
+       'data/devices/logitech-g604.device',
        'data/devices/logitech-g7.device',
        'data/devices/logitech-g700-wireless.device',
        'data/devices/logitech-g700.device',
@@ -326,6 +330,7 @@
        'data/devices/logitech-MX-Vertical.device',
        'data/devices/roccat-kone-xtd.device',
        'data/devices/steelseries-kinzu-v2.device',
+       'data/devices/steelseries-kinzu-v3.device',
        'data/devices/steelseries-rival-310.device',
        'data/devices/steelseries-rival-600.device',
        'data/devices/steelseries-rival.device',
@@ -609,6 +614,19 @@
    c_source,
    name_prefix: '_',
    c_args : ['-Wno-missing-prototypes', '-Wno-format-nonliteral'],
+   extra_files: [ i_source ] + src_libratbag ,
+   dependencies: deps_libratbag + wrapper_deps,
+   include_directories : include_directories('src', 'tools'),
+   install: false,
+)
+
+i_source = join_paths(meson.source_root(), 'src', 'hidpp.i')
+c_source = swig_gen.process(i_source)
+shared_library(
+   'hidpp',
+   c_source,
+   name_prefix: '_',
+   c_args : ['-Wno-missing-prototypes', '-Wno-format-nonliteral'],
    extra_files: [ i_source ] + src_libratbag ,
    dependencies: deps_libratbag + wrapper_deps,
    include_directories : include_directories('src', 'tools'),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/meson.build.orig 
new/libratbag-0.11/meson.build.orig
--- old/libratbag-0.10/meson.build.orig 1970-01-01 01:00:00.000000000 +0100
+++ new/libratbag-0.11/meson.build.orig 2019-11-05 02:06:27.000000000 +0100
@@ -0,0 +1,640 @@
+project('libratbag', 'c',
+       version : '0.10',
+       license : 'MIT/Expat',
+       default_options : [ 'c_std=gnu99', 'warning_level=2' ],
+       meson_version : '>= 0.40.0')
+
+# The DBus API version. Increase this every time the DBus API changes.
+# No backwards/forwards guarantee, clients are expected to understand
+# whatever ratbagd speaks or bail out. This should be removed if we ever
+# finish the API and declare it stable.
+ratbagd_api_version = 1
+
+# We use libtool-version numbers because it's easier to understand.
+# Before making a release, the libratbag_so_* and liblur_so_*
+# numbers should be modified. The components are of the form C:R:A.
+# a) If binary compatibility has been broken (eg removed or changed interfaces)
+#    change to C+1:0:0.
+# b) If interfaces have been changed or added, but binary compatibility has
+#    been preserved, change to C+1:0:A+1
+# c) If the interface is the same as the previous version, change to C:R+1:A
+liblur_so_c=3
+liblur_so_r=3
+liblur_so_a=0
+
+# convert to sonames
+liblur_so_version = '@0@.@1@.@2@'.format((liblur_so_c-liblur_so_a),
+                                        liblur_so_a, liblur_so_r)
+
+# Compiler setup
+cc = meson.get_compiler('c')
+cflags = ['-Wno-unused-parameter',
+         '-fvisibility=hidden',
+         '-Wmissing-prototypes',
+         '-Wformat', # required by format-security
+         '-Werror=format-security',
+         '-Wstrict-prototypes']
+add_project_arguments(cflags, language: 'c')
+
+# Initialize config.h, to be added to in the various options below, config.h
+# is generated at the end of this file
+config_h = configuration_data()
+config_h.set('_GNU_SOURCE', '1')
+config_h.set_quoted('RATBAG_VERSION', meson.project_version())
+config_h.set('RATBAGD_API_VERSION', ratbagd_api_version)
+libratbag_data_dir = join_paths(get_option('prefix'),
+                               get_option('datadir'),
+                               'libratbag')
+libratbag_data_dir_devel = join_paths(meson.source_root(), 'data', 'devices')
+config_h.set_quoted('LIBRATBAG_DATA_DIR', libratbag_data_dir)
+
+# Coverity breaks because it doesn't define _Float128 correctly, you'll end
+# up with a bunch of messages in the form:
+# "/usr/include/stdlib.h", line 133: error #20: identifier "_Float128" is
+#           undefined
+#   extern _Float128 strtof128 (const char *__restrict __nptr,
+#          ^
+# We don't use float128 ourselves, it gets pulled in from math.h or
+# something, so let's just define it as uint128 and move on.
+# Unfortunately we can't detect the coverity build at meson configure
+# time, we only know it fails at runtime. So make this an option instead, to
+# be removed when coverity fixes this again.
+if get_option('coverity')
+        config_h.set('_Float128', '__uint128_t')
+        config_h.set('_Float32', 'int')
+        config_h.set('_Float32x', 'int')
+        config_h.set('_Float64', 'long')
+        config_h.set('_Float64x', 'long')
+endif
+
+# dependencies
+pkgconfig = import('pkgconfig')
+dep_udev = dependency('libudev')
+dep_libevdev = dependency('libevdev')
+dep_glib = dependency('glib-2.0')
+dep_json_glib = dependency('json-glib-1.0')
+dep_lm = cc.find_library('m')
+dep_unistring = cc.find_library('unistring')
+
+if get_option('logind-provider') == 'elogind'
+       dep_logind = dependency('libelogind', version : '>=227')
+else
+       dep_logind = dependency('libsystemd', version : '>=227')
+endif
+
+enable_systemd = get_option('systemd')
+if enable_systemd
+       dep_systemd = dependency('systemd')
+endif
+
+#### libutil.a ####
+src_libutil = [
+       'src/libratbag-util.c',
+       'src/libratbag-util.h'
+]
+
+deps_libutil = [
+       dep_udev,
+]
+
+lib_libutil = static_library('util',
+       src_libutil,
+       dependencies : deps_libutil
+)
+dep_libutil = declare_dependency(link_with: lib_libutil)
+
+### libhidpp.a ####
+src_libhidpp = [
+       'src/hidpp-generic.h',
+       'src/hidpp-generic.c',
+       'src/hidpp10.h',
+       'src/hidpp10.c',
+       'src/hidpp20.h',
+       'src/hidpp20.c',
+       'src/usb-ids.h'
+]
+
+deps_libhidpp = [ dep_lm ]
+
+lib_libhidpp = static_library('hidpp',
+       src_libhidpp,
+       dependencies : deps_libhidpp)
+dep_libhidpp = declare_dependency(link_with: lib_libhidpp)
+
+### liblur ####
+#
+# liblur is the library to handle logitech unifying receivers.
+#
+install_headers('src/liblur.h')
+
+src_liblur = [
+       'src/liblur.c',
+       'src/liblur.h'
+]
+
+deps_liblur = [
+       dep_libutil,
+       dep_libhidpp,
+]
+
+lur_mapfile = 'src/liblur.sym'
+lur_version_flag = 
'-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), lur_mapfile)
+lib_liblur = shared_library('lur',
+       src_liblur,
+       include_directories : include_directories('.'),
+       dependencies : deps_liblur,
+       version : liblur_so_version,
+       link_args : lur_version_flag,
+       link_depends : lur_mapfile,
+       install : true,
+)
+
+dep_liblur = declare_dependency(link_with: lib_liblur)
+
+pkgconfig.generate (
+        filebase: 'liblur',
+        name: 'Liblur',
+        description: 'Logitech Unifying Receiver configuration library',
+        version: meson.project_version(),
+        libraries: lib_liblur
+)
+
+#### libratbag.so ####
+#
+# libratbag is an internal-only library and the bit that does the actual
+# work talking to the mouse. it's used by ratbagd.
+src_libratbag = [
+       'src/libratbag-enums.h',
+       'src/libratbag.h',
+       'src/driver-etekcity.c',
+       'src/driver-hidpp20.c',
+       'src/driver-hidpp10.c',
+       'src/driver-logitech-g300.c',
+       'src/driver-logitech-g600.c',
+       'src/driver-roccat.c',
+       'src/driver-gskill.c',
+       'src/driver-steelseries.c',
+       'src/driver-test.c',
+       'src/libratbag.c',
+       'src/libratbag.h',
+       'src/libratbag-data.c',
+       'src/libratbag-data.h',
+       'src/libratbag-hidraw.c',
+       'src/libratbag-hidraw.h',
+       'src/libratbag-private.h',
+       'src/libratbag-test.c',
+       'src/libratbag-test.h',
+       'src/usb-ids.h'
+]
+
+deps_libratbag = [
+       dep_udev,
+       dep_libevdev,
+       dep_glib,
+       dep_json_glib,
+       dep_libutil,
+       dep_libhidpp,
+]
+
+lib_libratbag = static_library('ratbag',
+       src_libratbag,
+       include_directories : include_directories('.'),
+       dependencies : deps_libratbag,
+)
+
+dep_libratbag = declare_dependency(
+       link_with : lib_libratbag,
+       dependencies : deps_libratbag
+)
+
+#### libshared.a ####
+src_libshared = [
+       'tools/shared.c',
+       'tools/shared.h'
+]
+
+deps_libshared = [
+       dep_udev,
+       dep_libevdev,
+]
+lib_libshared = static_library('shared',
+       src_libshared,
+       dependencies : deps_libshared,
+       include_directories : include_directories('src')
+)
+dep_libshared = declare_dependency(link_with: lib_libshared)
+
+#### hidpp10-dump-page ####
+src_hidpp10_dump_page = [ 'tools/hidpp10-dump-page.c' ]
+executable('hidpp10-dump-page',
+       src_hidpp10_dump_page,
+       dependencies : [ dep_libhidpp ],
+       include_directories : include_directories('src'),
+       install : false,
+)
+
+#### hidpp20-dump-page ####
+src_hidpp20_dump_page = [ 'tools/hidpp20-dump-page.c' ]
+executable('hidpp20-dump-page',
+       src_hidpp20_dump_page,
+       dependencies : [ dep_libhidpp ],
+       include_directories : include_directories('src'),
+       install : false,
+)
+
+#### hidpp20-reset ####
+src_hidpp20_reset = [ 'tools/hidpp20-reset.c' ]
+executable('hidpp20-reset',
+       src_hidpp20_reset,
+       dependencies : [ dep_libhidpp ],
+       include_directories : include_directories('src'),
+       install : false,
+)
+
+#### lur-command ####
+#
+# A tool to access and manipulate logitech unifying receivers.
+src_lur_command = [ 'tools/lur-command.c' ]
+executable('lur-command',
+       src_lur_command,
+       dependencies : [ dep_libshared, dep_liblur ],
+       include_directories : include_directories('src'),
+       install : true,
+)
+
+man_config = configuration_data()
+
+man_config.set('version', meson.project_version())
+
+man_lur_command = configure_file (
+       input: 'tools/lur-command.man',
+       output: 'lur-command.1',
+       configuration: man_config,
+       install : true,
+       install_dir : join_paths(get_option('mandir'), 'man1')
+)
+
+#### data files ####
+# list ordered by git ls-files data/devices/*.device
+data_files = files(
+       'data/devices/etekcity-scroll-alpha.device',
+       'data/devices/gskill-MX-780.device',
+       'data/devices/logitech-M325.device',
+       'data/devices/logitech-M570.device',
+       'data/devices/logitech-M705.device',
+       'data/devices/logitech-MX-Ergo.device',
+       'data/devices/logitech-MX-Master.device',
+       'data/devices/logitech-MX-Master-2S.device',
+       'data/devices/logitech-MX518.device',
+       'data/devices/logitech-T650.device',
+       'data/devices/logitech-Wireless-Touchpad.device',
+       'data/devices/logitech-g-pro-wireless.device',
+       'data/devices/logitech-g-pro.device',
+       'data/devices/logitech-g102-g203.device',
+       'data/devices/logitech-g300.device',
+       'data/devices/logitech-g302.device',
+       'data/devices/logitech-g303.device',
+       'data/devices/logitech-g402.device',
+       'data/devices/logitech-g403-hero.device',
+       'data/devices/logitech-g403-wireless.device',
+       'data/devices/logitech-g403.device',
+       'data/devices/logitech-g5-2007.device',
+       'data/devices/logitech-g5.device',
+       'data/devices/logitech-g500.device',
+       'data/devices/logitech-g500s.device',
+       'data/devices/logitech-g502-hero.device',
+       'data/devices/logitech-g502-proteus-core.device',
+       'data/devices/logitech-g502-proteus-spectrum.device',
+       'data/devices/logitech-g600.device',
+       'data/devices/logitech-g602.device',
+       'data/devices/logitech-g603.device',
+       'data/devices/logitech-g7.device',
+       'data/devices/logitech-g700-wireless.device',
+       'data/devices/logitech-g700.device',
+       'data/devices/logitech-g700s.device',
+       'data/devices/logitech-g703-hero.device',
+       'data/devices/logitech-g703.device',
+       'data/devices/logitech-g9.device',
+       'data/devices/logitech-g900.device',
+       'data/devices/logitech-g903-hero.device',
+       'data/devices/logitech-g903.device',
+       'data/devices/logitech-g9x-[Call-of-Duty-MW3-Edition].device',
+       'data/devices/logitech-g9x-[Original].device',
+       'data/devices/logitech-Marathon-M705.device',
+       'data/devices/logitech-MX-Anywhere2.device',
+       'data/devices/logitech-MX-Anywhere2S.device',
+       'data/devices/logitech-MX-Vertical.device',
+       'data/devices/roccat-kone-xtd.device',
+       'data/devices/steelseries-kinzu-v2.device',
+       'data/devices/steelseries-rival-310.device',
+       'data/devices/steelseries-rival-600.device',
+       'data/devices/steelseries-rival.device',
+       'data/devices/steelseries-sensei-310.device',
+       'data/devices/steelseries-sensei-raw.device',
+)
+
+install_data(data_files,
+            install_dir : join_paths(get_option('datadir'), 'libratbag'))
+
+data_parse_test = find_program(join_paths(meson.source_root(), 
'data/devices/data-parse-test.py'))
+test('data-parse-test', data_parse_test, args:  data_files)
+
+duplicate_test = find_program(join_paths(meson.source_root(), 
'data/devices/duplicate-check.py'))
+test('duplicate-test', duplicate_test, args : data_files)
+
+#### tests ####
+enable_tests = get_option('tests')
+if enable_tests
+       dep_check = dependency('check', version: '>= 0.9.10')
+
+       config_h.set('BUILD_TESTS', '1')
+
+       test_context = executable('test-context',
+                                 ['test/test-context.c'],
+                                 dependencies : [ dep_libratbag, dep_check ],
+                                 include_directories : 
include_directories('src'),
+                                 install : false)
+       test_device = executable('test-device',
+                                ['test/test-device.c'],
+                                dependencies : [ dep_libratbag, dep_check ],
+                                include_directories : 
include_directories('src'),
+                                install : false)
+       test_util = executable('test-util',
+                                ['test/test-util.c'],
+                                dependencies : [ dep_libratbag, dep_check ],
+                                include_directories : 
include_directories('src'),
+                                install : false)
+       test_iconv_helper = executable('test-iconv-helper',
+                               ['test/test-iconv-helper.c'],
+                               dependencies : [ dep_libratbag,
+                                                dep_check,
+                                                dep_libutil],
+                               include_directories : 
include_directories('src'),
+                               install : false)
+       test('test-context', test_context)
+       test('test-device', test_device)
+       test('test-util', test_util)
+       test('test-iconv-helper', test_iconv_helper)
+
+       valgrind = find_program('valgrind')
+       valgrind_suppressions_file = join_paths(meson.source_root(), 'test', 
'valgrind.suppressions')
+       add_test_setup('valgrind',
+                      exe_wrapper : [
+                              valgrind,
+                              '--leak-check=full',
+                              '--quiet',
+                              '--error-exitcode=3',
+                              '--suppressions=' + valgrind_suppressions_file ],
+                      timeout_multiplier: 5)
+endif
+
+#### ratbagd ####
+#
+# The main item of this repo, a DBus server that uses libratbag to talk to
+# the mice. The DBus API is the public-facing API.
+#
+src_ratbagd = [
+       'src/shared-macro.h',
+       'src/shared-rbtree.h',
+       'src/shared-rbtree.c',
+       'ratbagd/ratbagd.h',
+       'ratbagd/ratbagd.c',
+       'ratbagd/ratbagd-led.c',
+       'ratbagd/ratbagd-button.c',
+       'ratbagd/ratbagd-device.c',
+       'ratbagd/ratbagd-profile.c',
+       'ratbagd/ratbagd-resolution.c',
+       'ratbagd/ratbagd-test.c',
+       'ratbagd/ratbagd-json.c',
+       'ratbagd/ratbagd-json.h',
+       'src/libratbag-util.h',
+       'src/libratbag-util.c',
+]
+
+deps_ratbagd = [
+       dep_udev,
+       dep_logind,
+       dep_libratbag,
+       dep_unistring,
+]
+
+executable('ratbagd',
+          src_ratbagd,
+          dependencies : deps_ratbagd,
+          include_directories : include_directories('src'),
+          install : true,
+)
+
+install_man('ratbagd/ratbagd.8')
+
+#### ratbagd_devel ####
+#
+# A development ratbagd server that owns a different name on the bus
+# (org.freedesktop.ratbag_devel1). This server is used by ratbagdctl.devel.
+#
+
+config_ratbagd_devel = configuration_data()
+dbus_devel_policy = configure_file(input : 
'dbus/org.freedesktop.ratbag_devel1.conf.in',
+                                  output : 
'org.freedesktop.ratbag_devel1.conf',
+                                  configuration : config_ratbagd_devel)
+
+# This is a hack. We always install the devel policy file into
+# /etc/dbus-1/system.d, independent of any prefixes we use otherwise.
+# This should never be used outside of developer machines anyway, but
+# installations on those may use different prefixes for building.
+# This is not set in stone, suggest something better if you can.
+dbussystemdir = join_paths('/', get_option('sysconfdir'), 'dbus-1', 'system.d')
+
+executable('ratbagd.devel',
+          src_ratbagd,
+          dependencies : deps_ratbagd,
+          include_directories : include_directories('src'),
+          install : false,
+          c_args : ['-DRATBAG_DBUS_INTERFACE="ratbag_devel1"',
+                    '-DDBUS_POLICY_SRC="@0@/@1@"'.format(meson.build_root(), 
dbus_devel_policy),
+                    '-DDBUS_POLICY_DST="@0@/@1@"'.format(dbussystemdir, 
dbus_devel_policy),
+                    '-DDISABLE_COREDUMP=1'],
+)
+
+
+#### unit file ####
+if enable_systemd
+       unitdir = get_option('systemd-unit-dir')
+       if unitdir == ''
+               libdir = get_option('libdir')
+               default_unitdir = 
dep_systemd.get_pkgconfig_variable('systemdsystemunitdir')
+               # Fedora uses lib64 but systemd is in lib. Hack around this so 
it
+               # works out of the box.
+               intended_unitdir = join_paths(get_option('prefix'), 
get_option('libdir'), 'systemd')
+               if get_option('prefix') == '/usr' and intended_unitdir != 
default_unitdir
+                       message('''
+                       systemd unitdir libdir mismatch detected, changing 
unitdir to
+                               @0@
+                       or specify with
+                               mesonconf -Dsystemd-unit-dir=<path>
+
+                       See https://github.com/libratbag/libratbag/issues/188
+                       '''.format(default_unitdir))
+                       unitdir = default_unitdir
+               else
+                       unitdir = intended_unitdir
+               endif
+       endif
+endif
+
+config_bindir = configuration_data()
+config_bindir.set('bindir', join_paths(get_option('prefix'), 
get_option('bindir')))
+
+if enable_systemd
+       configure_file(input : 'ratbagd/ratbagd.service.in',
+                       output : 'ratbagd.service',
+                       configuration : config_bindir,
+                       install_dir : unitdir)
+endif
+
+dbusdir = get_option('dbus-root-dir')
+if dbusdir == ''
+       dbusdir = join_paths(get_option('prefix'), get_option('datadir'), 
'dbus-1')
+endif
+
+configure_file(input : 'dbus/org.freedesktop.ratbag1.service.in',
+              output : 'org.freedesktop.ratbag1.service',
+              configuration : config_bindir,
+              install_dir : join_paths(dbusdir, 'system-services'))
+
+dbusgroup = get_option('dbus-group')
+if dbusgroup == ''
+       # grant everybody access by default
+       access = 'context="default"'
+else
+       # grant access to members of the specified group only
+       access = 'group="@0@"'.format(dbusgroup)
+endif
+
+config_dbusaccess = configuration_data()
+config_dbusaccess.set('access', access)
+
+configure_file(input : 'dbus/org.freedesktop.ratbag1.conf.in',
+              output : 'org.freedesktop.ratbag1.conf',
+              configuration : config_dbusaccess,
+              install_dir : join_paths(dbusdir, 'system.d'))
+
+#### tools ####
+
+if meson.version().version_compare('<0.48.0')
+  python = import('python3')
+  py3 = python.find_python()
+else
+  pymod = import('python')
+  py3 = pymod.find_installation()
+endif
+
+config_ratbagctl = configuration_data()
+config_ratbagctl.set('RATBAGD_API_VERSION', ratbagd_api_version)
+config_ratbagctl.set('version', meson.project_version())
+
+ratbagctl_in = configure_file(input : 'tools/ratbagctl.in.in',
+                             output : 'ratbagctl.in',
+                             configuration: config_ratbagctl)
+
+# ratbagctl is the commandline tool to interact with ratbagd over DBus.
+custom_target('ratbagctl',
+  output : 'ratbagctl',
+  input : [ratbagctl_in, 'tools/ratbagd.py'],
+  build_by_default : true,
+  command : [py3, join_paths(meson.source_root(), 'tools', 'merge_ratbagd.py'),
+                               '@INPUT@',
+                               '--output', '@OUTPUT@'],
+  install: true,
+  install_dir: get_option('bindir'))
+
+man_ratbagctl = configure_file (
+       input: 'tools/ratbagctl.1',
+       output: 'ratbagctl.1',
+       configuration: man_config,
+       install : true,
+       install_dir : join_paths(get_option('mandir'), 'man1')
+)
+
+config_ratbagctl_devel = configuration_data()
+config_ratbagctl_devel.set('MESON_BUILD_ROOT', meson.build_root())
+config_ratbagctl_devel.set('LIBRATBAG_DATA_DIR', libratbag_data_dir_devel)
+config_ratbagctl_devel.set('RATBAGD_API_VERSION', ratbagd_api_version)
+
+configure_file(input : 'tools/toolbox.py',
+              output : 'toolbox.py',
+              configuration : config_ratbagctl_devel)
+# ratbagctl.devel starts a custom ratbagd and interacts with that over DBus
+configure_file(input : 'tools/ratbagctl.devel.in',
+              output : 'ratbagctl.devel',
+              configuration : config_ratbagctl_devel)
+# ratbagctl.test starts a custom ratbagd and interacts with that over DBus
+configure_file(input : 'tools/ratbagctl.test.in',
+              output : 'ratbagctl.test',
+              configuration : config_ratbagctl_devel)
+
+env_test = environment()
+env_test.set('LIBRATBAG_DATA_DIR', libratbag_data_dir_devel)
+ratbagctl_test = find_program(join_paths(meson.build_root(), 'ratbagctl.test'))
+test('ratbagctl-test', ratbagctl_test, args: ['-v'], env : env_test)
+
+# ratbag-command uses Swig bindings to call libratbag directly
+swig = find_program('swig')
+swig_gen = generator(
+    swig,
+    output: ['@BASENAME@.c'],
+    arguments: ['-python', '-py3', '-o', './@OUTPUT@',
+                '-outdir', '.',
+                '-I' + join_paths(meson.source_root(), 'src'),
+                '-I' + join_paths(meson.source_root(), 'tools'),
+                '@INPUT@'],
+)
+
+# From python 3.8 we neeed python3-embed
+dep_python3 = dependency('python3-embed', required: false)
+if not dep_python3.found()
+       dep_python3 = dependency('python3')
+endif
+
+wrapper_deps = [
+    dep_python3,
+    dep_libratbag,
+    dep_libshared,
+]
+
+i_source = join_paths(meson.source_root(), 'src', 'libratbag.i')
+c_source = swig_gen.process(i_source)
+shared_library(
+   'libratbag',
+   c_source,
+   name_prefix: '_',
+   c_args : ['-Wno-missing-prototypes', '-Wno-format-nonliteral'],
+   extra_files: [ i_source ] + src_libratbag ,
+   dependencies: deps_libratbag + wrapper_deps,
+   include_directories : include_directories('src', 'tools'),
+   install: false,
+)
+
+# ratbagc is the layer that maps ratbagctl to the swig bindings
+ratbagc_py_conf = configuration_data()
+ratbagc_py_conf.set('LIBRATBAG_DATA_DIR', libratbag_data_dir_devel)
+ratbagc_py = configure_file(input: 'tools/ratbagc.py.in',
+                           output: 'ratbagc.py',
+                           configuration: ratbagc_py_conf)
+
+# ratbag-command is a commandline tool with the UI as ratbagctl but instead
+# of connecting to ratbagd over DBus, it uses libratbag directly. This is a
+# development tool for protocol debugging etc.
+custom_target('ratbag-command',
+  output : 'ratbag-command',
+  input : [ratbagctl_in, ratbagc_py],
+  build_by_default : true,
+  command : [py3, join_paths(meson.source_root(), 'tools', 'merge_ratbagd.py'),
+                               '@INPUT@',
+                               '--output', '@OUTPUT@'],
+  install: false)
+
+#### output files ####
+configure_file(output: 'config.h', install: false, configuration: config_h)
+
+subdir('doc')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/release.sh 
new/libratbag-0.11/release.sh
--- old/libratbag-0.10/release.sh       2019-08-02 03:19:16.000000000 +0200
+++ new/libratbag-0.11/release.sh       2019-11-05 02:06:27.000000000 +0100
@@ -90,13 +90,11 @@
 #
 check_modules_specification() {
 
-if [ x"$MODFILE" = x ]; then
-    if [ x"${INPUT_MODULES}" = x ]; then
-       echo ""
-       echo "Error: no modules specified (blank command line)."
-       usage
-       exit 1
-    fi
+if [ x"${INPUT_MODULES}" = x ]; then
+    echo ""
+    echo "Error: no modules specified (blank command line)."
+    usage
+    exit 1
 fi
 
 }
@@ -112,7 +110,7 @@
 To: $list_to
 Cc: $list_cc
 
-libratbag $tag_name is out.
+$pkg_name $tag_name is out.
 
 The list of interesting changes are:
 
@@ -129,44 +127,13 @@
 The libratbag project does not generate tarballs for releases, you can
 grab one directly from github:
 
-https://github.com/libratbag/libratbag/archive/$tag_name/$tarball
+https://github.com/libratbag/$pkg_name/archive/$tag_name/$tarball
 
 RELEASE
     done
 }
 
 #------------------------------------------------------------------------------
-#                      Function: read_modfile
-#------------------------------------------------------------------------------
-#
-# Read the module names from the file and set a variable to hold them
-# This will be the same interface as cmd line supplied modules
-#
-read_modfile() {
-
-    if [ x"$MODFILE" != x ]; then
-       # Make sure the file is sane
-       if [ ! -r "$MODFILE" ]; then
-           echo "Error: module file '$MODFILE' is not readable or does not 
exist."
-           exit 1
-       fi
-       # read from input file, skipping blank and comment lines
-       while read line; do
-           # skip blank lines
-           if [ x"$line" = x ]; then
-               continue
-           fi
-           # skip comment lines
-           if echo "$line" | $GREP -q "^#" ; then
-               continue;
-           fi
-           INPUT_MODULES="$INPUT_MODULES $line"
-       done <"$MODFILE"
-    fi
-    return 0
-}
-
-#------------------------------------------------------------------------------
 #                      Function: print_epilog
 #------------------------------------------------------------------------------
 #
@@ -216,46 +183,6 @@
 }
 
 #------------------------------------------------------------------------------
-#                      Function: get_section
-#------------------------------------------------------------------------------
-# Code 'return 0' on success
-# Code 'return 1' on error
-# Sets global variable $section
-get_section() {
-    local module_url
-    local full_module_url
-
-    # Obtain the git url in order to find the section to which this module 
belongs
-    full_module_url=`git config --get remote.$remote_name.url | sed 
's:\.git$::'`
-    if [ $? -ne 0 ]; then
-       echo "Error: unable to obtain git url for remote \"$remote_name\"."
-       return 1
-    fi
-
-    # The last part of the git url will tell us the section. Look for xorg 
first
-    echo "$full_module_url"
-    module_url=`echo "$full_module_url" | $GREP -o "libratbag/.*"`
-    if [ $? -eq 0 ]; then
-       module_url=`echo $module_url | cut -d'/' -f2,3`
-    else
-       echo "Error: unable to locate a valid project url from 
\"$full_module_url\"."
-       echo "Cannot establish url as one of libratbag"
-       cd $top_src
-       return 1
-    fi
-
-    # Find the section (subdirs) where the tarballs are to be uploaded
-    # The module relative path can be app/xfs, xserver, or mesa/drm for example
-    section=`echo $module_url | cut -d'/' -f1`
-    if [ $? -ne 0 ]; then
-       echo "Error: unable to extract section from $module_url first field."
-       return 1
-    fi
-
-    return 0
-}
-
-#------------------------------------------------------------------------------
 #                      Function: process_module
 #------------------------------------------------------------------------------
 # Code 'return 0' on success to process the next module
@@ -299,26 +226,27 @@
     current_branch=`git branch | $GREP "\*" | sed -e "s/\* //"`
     remote_name=`git config --get branch.$current_branch.remote`
     remote_branch=`git config --get branch.$current_branch.merge | cut -d'/' 
-f3,4`
-    remote_url_root="https://github.com/libratbag/libratbag/archive";
     echo "Info: working off the \"$current_branch\" branch tracking the remote 
\"$remote_name/$remote_branch\"."
 
-    # Obtain the section
-    get_section
-    if [ $? -ne 0 ]; then
-       cd $top_src
-       return 1
-    fi
-
     # Find out the tarname from meson.build
     pkg_name=$($GREP '^project(' meson.build | sed 
's|project(\([^\s,]*\).*|\1|' | sed "s/'//g")
-    pkg_version=$($GREP -m 1 '^        version : ' meson.build | sed 's|       
version : \([^\s,]*\).*|\1|' | sed "s/'//g")
+    pkg_version=$($GREP -m 1 '^[        ]*version \?: ' meson.build | sed 's|[ 
 ]*version \?: \([^\s,]*\).*|\1|' | sed "s/'//g")
     tar_name="$pkg_name-$pkg_version"
     targz=$tar_name.tar.gz
-    tag_name=$(echo "v$pkg_version" | sed 's|.0$||')
+    # libratbag tags with v0.3 but piper user just 0.3
+    case `git describe` in
+           v*)
+                   tag_name=$(echo "v$pkg_version" | sed 's|\.0$||')
+                   ;;
+           *)
+                   tag_name=$(echo "$pkg_version" | sed 's|\.0$||')
+                   ;;
+    esac
+    remote_url_root="https://github.com/libratbag/$pkg_name/archive";
 
     # Now get the tarballs from github directly to compute their checksum
     remote_targz_url=$remote_url_root/$tag_name/$targz
-    echo "downloading the tarbal from $remote_targz_url"
+    echo "downloading the tarball from $remote_targz_url"
     curl $remote_targz_url > $targz
 
     # Obtain the top commit SHA which should be the version bump
@@ -513,13 +441,6 @@
        exit 1
        ;;
     *)
-       if [ x"${MODFILE}" != x ]; then
-           echo ""
-           echo "Error: specifying both modules and --modfile is not permitted"
-           echo ""
-           usage
-           exit 1
-       fi
        INPUT_MODULES="${INPUT_MODULES} $1"
        ;;
     esac
@@ -530,9 +451,6 @@
 # If no modules specified (blank cmd line) display help
 check_modules_specification
 
-# Read the module file and normalize input in INPUT_MODULES
-read_modfile
-
 # Loop through each module to release
 # Exit on error if --no-quit no specified
 process_modules
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/src/driver-hidpp20.c 
new/libratbag-0.11/src/driver-hidpp20.c
--- old/libratbag-0.10/src/driver-hidpp20.c     2019-08-02 03:19:16.000000000 
+0200
+++ new/libratbag-0.11/src/driver-hidpp20.c     2019-11-05 02:06:27.000000000 
+0100
@@ -412,11 +412,11 @@
        struct hidpp20_profile *profile;
        struct hidpp20_led *h_led;
        struct hidpp20_rgb_device_info device_info;
-       struct hidpp20_rgb_cluster_info *cluster_info;
+       struct hidpp20_rgb_cluster_info cluster_info;
        int rc;
 
        hidpp20_rgb_effects_get_device_info(drv_data->dev, &device_info);
-       cluster_info = &drv_data->led_infos.color_leds_8071[led->index];
+       cluster_info = drv_data->led_infos.color_leds_8071[led->index];
        profile = &drv_data->profiles->profiles[led->profile->index];
        h_led = &profile->leds[led->index];
 
@@ -437,7 +437,7 @@
 
        /* pre-filled, only override if unknown */
        if (led->type == RATBAG_LED_TYPE_UNKNOWN)
-               led->type = 
hidpp20_led_get_location_mapping(cluster_info->location);
+               led->type = 
hidpp20_led_get_location_mapping(cluster_info.location);
        led->color.red = h_led->color.red;
        led->color.green = h_led->color.green;
        led->color.blue = h_led->color.blue;
@@ -449,10 +449,10 @@
        else
                led->colordepth = RATBAG_LED_COLORDEPTH_RGB_888;
 
-       for (int i = 0; i < cluster_info->num_effects; i++) {
+       for (int i = 0; i < cluster_info.num_effects; i++) {
                struct hidpp20_rgb_effect_info ei;
                rc = hidpp20_rgb_effects_get_effect_info(drv_data->dev,
-                                                        cluster_info->index,
+                                                        cluster_info.index,
                                                         i, &ei);
                if (rc < 0)
                        break;
@@ -859,7 +859,8 @@
        unsigned int default_rate = 500;
        int rc;
 
-       if (drv_data->capabilities & HIDPP_CAP_RESOLUTION_2200) {
+       if ((drv_data->capabilities & HIDPP_CAP_RESOLUTION_2200) &&
+           (drv_data->capabilities & HIDPP_CAP_SWITCHABLE_RESOLUTION_2201) == 
0) {
                uint16_t resolution;
                uint8_t flags;
 
@@ -928,6 +929,9 @@
        h_profile = &drv_data->profiles->profiles[profile->index];
        h_profile->dpi[resolution->index] = dpi;
 
+       if (resolution->is_default)
+               h_profile->default_dpi = resolution->index;
+
        return RATBAG_SUCCESS;
 }
 
@@ -1302,6 +1306,11 @@
                break;
        }
        case HIDPP_PAGE_COLOR_LED_EFFECTS: {
+               /* The 8070 feauture implemented in the G602 doesn't follow the 
spec,
+                * so we ignore it */
+               if (ratbag_device_data_hidpp20_get_quirk(device->data) == 
HIDPP20_QUIRK_G602)
+                       break;
+
                log_debug(ratbag, "device has color effects\n");
                drv_data->capabilities |= HIDPP_CAP_COLOR_LED_EFFECTS_8070;
 
@@ -1513,6 +1522,7 @@
                       struct hidpp20drv_data *drv_data)
 {
        struct ratbag_profile *profile;
+       bool active_profile = false;
 
        ratbag_device_init_profiles(device,
                                    drv_data->num_profiles,
@@ -1522,6 +1532,18 @@
 
        ratbag_device_for_each_profile(device, profile)
                hidpp20drv_read_profile(profile);
+
+       if (drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100) {
+               /* Fallback to the first profile if no profile is active */
+               list_for_each(profile, &device->profiles, link)
+                       if (profile->is_active)
+                               active_profile = true;
+
+               if (!active_profile && device->num_profiles >= 1) {
+                       profile = ratbag_device_get_profile(device, 0);
+                       profile->is_active = true;
+               }
+       }
 }
 
 static int
@@ -1560,10 +1582,15 @@
                goto err;
        }
 
+       dev->quirk = ratbag_device_data_hidpp20_get_quirk(device->data);
+
        drv_data->dev = dev;
 
        log_debug(device->ratbag, "'%s' is using protocol v%d.%d\n", 
ratbag_device_get_name(device), dev->proto_major, dev->proto_minor);
 
+       if(dev->quirk != HIDPP20_QUIRK_NONE)
+               log_debug(device->ratbag, "'%s' is quirked (%s)\n", 
ratbag_device_get_name(device), hidpp20_get_quirk_string(dev->quirk));
+
        /* add some defaults that will be overwritten by the device */
        drv_data->num_profiles = 1;
        drv_data->num_resolutions = 1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/src/hidpp.i 
new/libratbag-0.11/src/hidpp.i
--- old/libratbag-0.10/src/hidpp.i      1970-01-01 01:00:00.000000000 +0100
+++ new/libratbag-0.11/src/hidpp.i      2019-11-05 02:06:27.000000000 +0100
@@ -0,0 +1,23 @@
+/* wrapping libratbag functions from hidpp*.h using SWIG. */
+
+%module hidpp
+%{
+       /* the resulting C file should be built as a python extension */
+       #define SWIG_FILE_WITH_INIT
+       /*  Includes the header in the wrapper code */
+       #include <shared.h>
+       #include <hidpp-generic.h>
+       #include <hidpp20.h>
+%}
+#define __attribute__(x)
+#define _Static_assert(a,b)
+
+
+/*  Parse the header file to generate wrappers */
+%include "stdint.i"
+%include "cpointer.i"
+%pointer_functions(int, intp);
+%pointer_functions(uint8_t, uint8_tp);
+%pointer_functions(uint16_t, uint16_tp);
+%include "hidpp-generic.h"
+%include "hidpp20.h"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/src/hidpp10.c 
new/libratbag-0.11/src/hidpp10.c
--- old/libratbag-0.10/src/hidpp10.c    2019-08-02 03:19:16.000000000 +0200
+++ new/libratbag-0.11/src/hidpp10.c    2019-11-05 02:06:27.000000000 +0100
@@ -833,6 +833,20 @@
                          "unable to find the profile at (%d,%d) in the 
directory\n",
                          page, offset);
                break;
+       case PROFILE_TYPE_FACTORY:
+               /* Factory profile is selected and profile switching is
+                * disabled. Let's switch to the first profile because the
+                * factory profile doesn't help anywone */
+               res = hidpp10_set_current_profile(dev, 0);
+               if (res == 0) {
+                       hidpp_log_info(&dev->base, "switched from factory 
profile to 0\n");
+                       *current_profile = 0;
+                       return 0;
+               }
+
+               hidpp_log_error(&dev->base,
+                               "current profile is factory profile but 
switching to 0 failed.\n");
+               break;
        default:
                hidpp_log_error(&dev->base,
                          "Unexpected value: %02x\n",
@@ -2737,8 +2751,7 @@
 
        hidpp10_get_optical_sensor_settings(dev, &reflect);
 
-       hidpp10_get_current_profile(dev, &current_profile);
-       return 0;
+       return hidpp10_get_current_profile(dev, &current_profile);
 }
 
 struct hidpp10_device*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/src/hidpp20.c 
new/libratbag-0.11/src/hidpp20.c
--- old/libratbag-0.10/src/hidpp20.c    2019-08-02 03:19:16.000000000 +0200
+++ new/libratbag-0.11/src/hidpp20.c    2019-11-05 02:06:27.000000000 +0100
@@ -48,7 +48,6 @@
 {
        static char numeric[8];
        const char *str;
-#define CASE_RETURN_STRING(a) case a: return #a; break
 
        switch(feature)
        {
@@ -99,11 +98,22 @@
                str = numeric;
                break;
        }
-#undef CASE_RETURN_STRING
 
        return str;
 }
 
+const char*
+hidpp20_get_quirk_string(enum hidpp20_quirk quirk)
+{
+       switch (quirk) {
+       CASE_RETURN_STRING(HIDPP20_QUIRK_NONE);
+       CASE_RETURN_STRING(HIDPP20_QUIRK_G305);
+       CASE_RETURN_STRING(HIDPP20_QUIRK_G602);
+       }
+
+       abort();
+}
+
 static int
 hidpp20_request_command_allow_error(struct hidpp20_device *device, union 
hidpp20_message *msg,
                                    bool allow_error)
@@ -1073,8 +1083,8 @@
        info->effect_index = msg.msg.parameters[1];
 
        info->location = get_unaligned_be_u16(&msg.msg.parameters[2]);
-       info->num_effects = get_unaligned_be_u16(&msg.msg.parameters[4]);
-       info->persistency_caps = get_unaligned_be_u16(&msg.msg.parameters[6]);
+       info->num_effects = msg.msg.parameters[4];
+       info->persistency_caps = msg.msg.parameters[5];
 
        return 0;
 }
@@ -1432,6 +1442,11 @@
                .msg.parameters[0] = sensor->index,
        };
 
+       if (device->quirk == HIDPP20_QUIRK_G602) {
+               msg.msg.parameters[0] = 1;
+               i = 0;
+       }
+
        rc = hidpp20_request_command(device, &msg);
        if (rc)
                return rc;
@@ -1443,6 +1458,9 @@
               get_unaligned_be_u16(&msg.msg.parameters[i]) != 0) {
                uint16_t value = get_unaligned_be_u16(&msg.msg.parameters[i]);
 
+               if (device->quirk == HIDPP20_QUIRK_G602 && i == 2)
+                       value += 0xe000;
+
                if (value > 0xe000) {
                        sensor->dpi_steps = value - 0xe000;
                } else {
@@ -1472,6 +1490,9 @@
                .msg.parameters[0] = sensor->index,
        };
 
+       if (device->quirk == HIDPP20_QUIRK_G602)
+               msg.msg.parameters[0] = 1;
+
        rc = hidpp20_request_command(device, &msg);
        if (rc)
                return rc;
@@ -1551,6 +1572,9 @@
                .msg.parameters[0] = sensor->index,
        };
 
+       if (device->quirk == HIDPP20_QUIRK_G602)
+               msg.msg.parameters[0] = 1;
+
        set_unaligned_be_u16(&msg.msg.parameters[1], dpi);
 
        feature_index = hidpp_root_get_feature_idx(device,
@@ -1634,7 +1658,7 @@
 #define HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G402     0x01
 #define HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G303     0x02
 #define HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G900     0x03
-#define HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G903_HERO        0x04
+#define HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G915     0x04
 #define HIDPP20_ONBOARD_PROFILES_MACRO_TYPE_G402       0x01
 
 #define HIDPP20_USER_PROFILES_G402                     0x0000
@@ -2054,7 +2078,7 @@
        if ((info->profile_format_id != 
HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G402) &&
            (info->profile_format_id != 
HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G303) &&
            (info->profile_format_id != 
HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G900) &&
-           (info->profile_format_id != 
HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G903_HERO)) {
+           (info->profile_format_id != 
HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G915)) {
                hidpp_log_error(&device->base,
                                "Profile layout not supported: 0x%02x.\n",
                                info->profile_format_id);
@@ -2602,6 +2626,15 @@
                                                  HIDPP20_USER_PROFILES_G402,
                                                  profiles->sector_size,
                                                  data);
+
+       if (rc && device->quirk != HIDPP20_QUIRK_G305) {
+               /* The G305 has a bug where it throws an ERR_INVALID_ARGUMENT
+                  if the sector has not been written to yet. If this happens
+                  we will read the ROM profiles.*/
+               read_userdata = false;
+               goto read_profiles;
+       }
+
        if (rc < 0)
                return rc; // ignore_clang_sa_mem_leak
 
@@ -2635,6 +2668,7 @@
                read_userdata = false;
        }
 
+read_profiles:
        for (i = 0; i < profiles->num_profiles; i++) {
                if (read_userdata) {
                        hidpp_log_debug(&device->base, "Parsing profile %u\n", 
i);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/src/hidpp20.h 
new/libratbag-0.11/src/hidpp20.h
--- old/libratbag-0.10/src/hidpp20.h    2019-08-02 03:19:16.000000000 +0200
+++ new/libratbag-0.11/src/hidpp20.h    2019-11-05 02:06:27.000000000 +0100
@@ -51,6 +51,12 @@
        uint8_t type;
 };
 
+enum hidpp20_quirk {
+       HIDPP20_QUIRK_NONE,
+       HIDPP20_QUIRK_G305,
+       HIDPP20_QUIRK_G602,
+};
+
 struct hidpp20_device {
        struct hidpp_device base;
        unsigned int index;
@@ -58,12 +64,17 @@
        unsigned proto_minor;
        unsigned feature_count;
        struct hidpp20_feature *feature_list;
+       enum hidpp20_quirk quirk;
 };
 
 int hidpp20_request_command(struct hidpp20_device *dev, union hidpp20_message 
*msg);
 
+#define CASE_RETURN_STRING(a) case a: return #a; break
+
 const char *hidpp20_feature_get_name(uint16_t feature);
 
+const char *hidpp20_get_quirk_string(enum hidpp20_quirk quirk);
+
 /* -------------------------------------------------------------------------- 
*/
 /* generic hidpp20 device operations                                          
*/
 /* -------------------------------------------------------------------------- 
*/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/src/libratbag-data.c 
new/libratbag-0.11/src/libratbag-data.c
--- old/libratbag-0.10/src/libratbag-data.c     2019-08-02 03:19:16.000000000 
+0200
+++ new/libratbag-0.11/src/libratbag-data.c     2019-11-05 02:06:27.000000000 
+0100
@@ -33,6 +33,7 @@
 #include "libratbag.h"
 #include "libratbag-private.h"
 #include "libratbag-data.h"
+#include "hidpp20.h"
 
 #define GROUP_DEVICE "Device"
 
@@ -54,6 +55,7 @@
 
 struct data_hidpp20 {
        int index;
+       enum hidpp20_quirk quirk;
 };
 
 struct data_hidpp10 {
@@ -152,6 +154,7 @@
        const char *group = "Driver/hidpp20";
        GError *error = NULL;
        int num;
+       char *str;
 
        data->hidpp20.index = -1;
 
@@ -160,6 +163,15 @@
                data->hidpp20.index = num;
        if (error)
                g_error_free(error);
+
+       str = g_key_file_get_string(keyfile, group, "Quirk", NULL);
+       data->hidpp20.quirk = HIDPP20_QUIRK_NONE;
+       if (str) {
+               if (streq(str, "G305"))
+                       data->hidpp20.quirk = HIDPP20_QUIRK_G305;
+               else if(streq(str, "G602"))
+                       data->hidpp20.quirk = HIDPP20_QUIRK_G602;
+       }
 }
 
 static void
@@ -562,6 +574,14 @@
        return data->hidpp20.index;
 }
 
+enum hidpp20_quirk
+ratbag_device_data_hidpp20_get_quirk(const struct ratbag_device_data *data)
+{
+       assert(data->drivertype == HIDPP20);
+
+       return data->hidpp20.quirk;
+}
+
 /* SteelSeries */
 
 int
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/src/libratbag-data.h 
new/libratbag-0.11/src/libratbag-data.h
--- old/libratbag-0.10/src/libratbag-data.h     2019-08-02 03:19:16.000000000 
+0200
+++ new/libratbag-0.11/src/libratbag-data.h     2019-11-05 02:06:27.000000000 
+0100
@@ -80,6 +80,9 @@
 int
 ratbag_device_data_hidpp20_get_index(const struct ratbag_device_data *data);
 
+enum hidpp20_quirk
+ratbag_device_data_hidpp20_get_quirk(const struct ratbag_device_data *data);
+
 /* SteelSeries */
 
 /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/src/libratbag.c 
new/libratbag-0.11/src/libratbag.c
--- old/libratbag-0.10/src/libratbag.c  2019-08-02 03:19:16.000000000 +0200
+++ new/libratbag-0.11/src/libratbag.c  2019-11-05 02:06:27.000000000 +0100
@@ -322,7 +322,7 @@
 }
 
 static inline bool
-ratbag_test_driver(struct ratbag_device *device,
+ratbag_try_driver(struct ratbag_device *device,
                   const struct input_id *dev_id,
                   const char *driver_name,
                   const struct ratbag_test_device *test_device)
@@ -377,9 +377,9 @@
        if (dev_id->vendor != USB_VENDOR_ID_LOGITECH)
                return false;
 
-       rc = ratbag_test_driver(device, dev_id, "hidpp20", NULL);
+       rc = ratbag_try_driver(device, dev_id, "hidpp20", NULL);
        if (!rc)
-               rc = ratbag_test_driver(device, dev_id, "hidpp10", NULL);
+               rc = ratbag_try_driver(device, dev_id, "hidpp10", NULL);
 
        return rc;
 }
@@ -401,7 +401,7 @@
 
        if (driver_name) {
                log_debug(device->ratbag, "device assigned driver %s\n", 
driver_name);
-               rc = ratbag_test_driver(device, dev_id, driver_name, 
test_device);
+               rc = ratbag_try_driver(device, dev_id, driver_name, 
test_device);
        } else {
                rc = ratbag_driver_fallback_logitech(device, dev_id);
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/test.py new/libratbag-0.11/test.py
--- old/libratbag-0.10/test.py  1970-01-01 01:00:00.000000000 +0100
+++ new/libratbag-0.11/test.py  2019-11-05 02:06:27.000000000 +0100
@@ -0,0 +1,41 @@
+#!/usr/bin/env python3
+
+from gi.repository import Gio, GLib
+
+dbus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None)
+print(dbus)
+
+ratbag1 = "org.freedesktop.ratbag1"
+object_path = "/" + ratbag1.replace('.', '/')
+
+interface = f"{ratbag1}.Manager"
+
+print(interface, object_path)
+
+
+proxy = Gio.DBusProxy.new_sync(dbus,
+                               Gio.DBusProxyFlags.NONE,
+                               None,
+                               ratbag1,
+                               object_path,
+                               interface,
+                               None)
+print(proxy)
+
+print(proxy.get_name_owner())
+
+print(proxy.get_cached_property("APIVersion"))
+
+print(proxy.get_cached_property_names())  # empty list if insufficient 
permissions
+
+print(proxy.get_flags())
+
+print(proxy.get_name())
+print(proxy.get_interface_name())
+
+try:
+    print(proxy.dummy())  # raises access denied exception if called with 
unsufficient permissions
+except GLib.Error as e:
+    print(e.domain, e.code, e.message)
+else:
+    raise Exception('Program logic failed')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libratbag-0.10/tools/ratbagd.py 
new/libratbag-0.11/tools/ratbagd.py
--- old/libratbag-0.10/tools/ratbagd.py 2019-08-02 03:19:16.000000000 +0200
+++ new/libratbag-0.11/tools/ratbagd.py 2019-11-05 02:06:27.000000000 +0100
@@ -520,7 +520,7 @@
 
     @GObject.Property
     def is_active(self):
-        """Returns True if the profile is currenly active, false otherwise."""
+        """Returns True if the profile is currently active, false otherwise."""
         return self._active
 
     def set_active(self):


Reply via email to