1
0
forked from drath/libratbag

Compare commits

...

70 Commits
v0.6 ... v0.9

Author SHA1 Message Date
Benjamin Tissoires
7da53c61cf meson.build: libratbag 0.9
- convert Logitech devices to the commit API (those compatible)
- fixes for ratbag-command regarding LEDs (still few caveats left)
- some coverity fixes
- a brand new lur-command man page

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-06-06 15:26:37 +02:00
Benjamin Tissoires
714c0d5330 hidpp20: reset the LEDs before writing to it
We somehow now know how to write effects.
No need to carry around some left overs from previous configurations.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-06-06 15:03:47 +02:00
Benjamin Tissoires
dc92abb5e5 tools: replace tabs by spaces in ratbag-command usage
It's a mix of tabs and spaces. Let's use spaces to keep the formatting.

And move "switch-etekcity" back to the end, it's a special case.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-06-06 15:03:47 +02:00
Benjamin Tissoires
b0c515b59d tools: allow to set more than one setting for the LEDs
Or we will take the defaults that are not intuitive (like white color
when setting to on).

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-06-06 15:03:47 +02:00
Benjamin Tissoires
8e6c13832e hidpp20: led: document the internal structure and match the documentation
Shouldn't change the behavior, but this allows adding the other effects
found in the documentation.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-06-06 15:03:47 +02:00
Benjamin Tissoires
e33f655f61 hidpp20: do not waste memory
Currently we only support mice with 2 LEDs in the profile. No need
to have 32 placeholders.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-06-06 15:03:47 +02:00
Benjamin Tissoires
8e8b7b0611 hidpp20: make sure we read/write correct endianness to the device
rate is big endian, so we need to convert it.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-06-06 15:03:47 +02:00
Benjamin Tissoires
d28f2f0123 hidpp20: keep function names consistent
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-06-06 15:03:47 +02:00
Benjamin Tissoires
a8eea870f5 hidpp20: make sure we check all modes in the switch statement
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-06-06 15:03:47 +02:00
Benjamin Tissoires
7e12e45311 hidpp20-drv: no need to use doubles
We are using a uint in the end, so better have proper order in the
multiplications/divisions than using doubles.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-06-06 15:03:47 +02:00
Benjamin Tissoires
b31c1d5ff3 tools: ratbag-command: have only one function to dump the LED settings
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-06-06 15:03:47 +02:00
Benjamin Tissoires
f6949458b7 tools: make led a first class citizen of ratbag-command
Allows to follow the usage message: we do not need to provide the
currently active profile.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-06-06 15:03:47 +02:00
Benjamin Tissoires
15dd6b4f2b hidpp20: color effects, fix endianness
We are receiving big endian, thus the weird power of two locations.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-06-06 15:03:47 +02:00
Stephen Kitt
7afd59149c Add lur-command manpage
This is copied from the Debian package.

Signed-off-by: Stephen Kitt <steve@sk2.org>
2017-05-30 14:11:48 +10:00
Stephen Kitt
a47f506293 Fix ratbag-command manpage
* Description capitalisation
* Grammar
* Hyphen encoding
* --version

Signed-off-by: Stephen Kitt <steve@sk2.org>
2017-05-30 14:11:48 +10:00
Benjamin Tissoires
f243abb65c release.sh: remove unreachable test now that we switched to meson
and I must say, why would you not run this script in the current
directory.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-05-29 17:29:12 +10:00
Benjamin Tissoires
a4b177436d hidpp20: take into account sectors on 16bits
First part of fixing #122.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-05-29 10:33:33 +10:00
Benjamin Tissoires
8367569236 hidpp10: fix coverity issue
profile->dpi_modes[i].led[] is an array of boolean.
Given that the callers (hidpp10_fill_dpi_modes_*()) already are doing the
comparison against 0x02, I guess this is just copy/paste error.

Fixes #152

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-05-29 10:32:08 +10:00
Benjamin Tissoires
5bbb2b28ea hidpp20drv: switch to the commit API
I do not like duplicating ratbag_old_write_profile() into each driver,
but, heh.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-05-29 09:15:07 +10:00
bentiss
2b92ab6dd6 hidpp20drv: fix segfault with G502 (#163)
When using the G502 without RGB LEDs, the feature 8070 is not here.
And this segfaults :)

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-05-24 11:52:56 +03:00
Christian Kellner
c05c3dcaa3 tools: consistently call led mode "breathing"
Rename "breath" in the help text and reporting for the led mode to
"breathing". The actual command to set the mode was already called
that way.

Signed-off-by: Christian Kellner <christian@kellner.me>
2017-05-24 09:05:15 +10:00
Benjamin Tissoires
bf20845249 meson.build: libratbag 0.8
- coverity fixes
- new --version to ratbag-command
- cleaning up the meson build tools

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-05-09 14:55:15 +02:00
Peter Hutterer
eb01399f26 tools: fix OOB for LED color parsing
Let's not forget about the null-terminator, he feels lonely otherwise.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-09 10:14:47 +02:00
Peter Hutterer
c815654c94 tools: add --version to ratbag-command
Behold, the glory of our version number!

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-09 09:24:41 +02:00
Peter Hutterer
f1ce908b50 meson: quote the libratbag version properly
Otherwise ETOOMANYDECIMALSEPARATORS, confusion, mayham, anarchy, the lot.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-09 09:24:41 +02:00
Peter Hutterer
fb07204d9f meson: drop garbage argument from configure_file
Unsurprisingly, meson does not support the ratbag keyword argument. Though it
should, because we're great. But anyway, this lead to the argument being
ignored which means it didn't get an 'input' argument, which means that
libratbag-version.h.in was ignored. And since it all works anyway (Behold! The
magic! Ooooh! Aaaah!) we can just drop that file.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-09 09:24:41 +02:00
Peter Hutterer
1e5648b11d tools: terminate option list with a zero entry
Because, well, that's what we're supposed to do. Unless you want to think
outside the (array) box, but that has never helped anyone, has it?

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-09 09:24:41 +02:00
Peter Hutterer
0902e3420f tools: replace getopt magic number 2 with 'optional_argument'
So *that's* what 2 means...

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-09 09:24:41 +02:00
Peter Hutterer
698d8ab365 Replace ifndef include guards with pragma once
Now that we use meson exclusively and meson uses this for its config.h, you
wouldn't get around it anyway. Besides, the main compilers support it and
libratbag is too niche to worry about others.

This also *adds* the pragma to tools/shared.h where it was previously missing,
and changes it to be the top statement in hidpp-generic.h

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-05 09:02:15 +02:00
Peter Hutterer
ad1fa22196 hidpp10: fix out-of-bounds access
sizeof() gives us twice as many elements as we have indices for on this 16-bit
array.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-02 09:52:59 +02:00
Peter Hutterer
04ebd96bb7 roccat: fix the neverending story^Wtimeout
If we don't change count, the value of count < MAX_RETRY is always true.

Coverity is a champ, isn't it?

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-02 09:52:59 +02:00
Peter Hutterer
09b5ae14b1 liblur: fix memory leak
Rather than having a bunch of gotos just define a cleanup for this device and
let the magic do the rest.

Found by coverity

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-02 09:52:59 +02:00
Peter Hutterer
8aa127186c gskill: fix memory leak
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-02 09:52:59 +02:00
Peter Hutterer
a962082173 hidpp20: constify a helper function
Just because we can

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-02 09:52:59 +02:00
Peter Hutterer
5c0dbe4d5c hidpp20: fix dereference before null check
Found by coverity

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-02 09:52:59 +02:00
Peter Hutterer
5934816b11 tools: check for negative index coming from argv
Coverity is unhappy.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-02 09:52:59 +02:00
Peter Hutterer
28dd84713f Reset the button action struct to zero before use
A semi false-positive from Coverity, because action.macro is unset. Doesn't
matter because we never use it, but having it zeroed is the nice thing to do
(and what we do in the other functions).

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-02 09:52:59 +02:00
Peter Hutterer
11b31cf9bd Fix a comment typo
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-02 09:52:59 +02:00
Peter Hutterer
dfd2d88953 tools: fix coverity warnings
Assigned but not used.

Found by coverity

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-02 09:52:59 +02:00
Peter Hutterer
6a097bd691 meson: drop -g, the meson buildtype option takes care of that
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-02 09:49:34 +02:00
Peter Hutterer
2776d1ce8e meson: use warning_level=2 instead of manual -Wall -Wextra
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-02 09:49:34 +02:00
Peter Hutterer
0834b210ca Remove now-obsolete autogen.sh script
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-26 08:26:07 +02:00
Peter Hutterer
cc41adbbf9 gitignore: drop build/ from gitignore again
As pointed out elsewhere, the build directory is decided by the user and
should thus be a user-specific gitignore configuration.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-26 08:26:07 +02:00
Peter Hutterer
63a666025f Update gitignore for meson
Drop all automake detritus, leave only the default build directory meson
suggests

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-25 08:11:40 +02:00
Peter Hutterer
08ce9773dd Remove liblur.pc.in
Should've been removed with b8ed1ea

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-24 10:11:38 +02:00
Peter Hutterer
f745734d90 meson: generate the libratbag.pc file through configure_file
pkgconfig.generate() does not (yet) have a parameter for setting custom
variables - we need that for pkgdatadir to point to the SVG files. Swap to
using configure_file with the old .pc.in file that was forgotten in the tree
anyway.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-24 10:11:38 +02:00
Benjamin Tissoires
5443083b1d meson.build: libratbag 0.7
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-04-20 11:59:48 +02:00
Benjamin Tissoires
cc19496699 Fix release.sh for meson
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-04-20 11:59:48 +02:00
Peter Hutterer
b595691c5e meson: break up the two long error messages
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-20 11:28:05 +02:00
Peter Hutterer
7d784a1a91 doc: use USE_MDFILE_AS_MAINPAGE to include the README.md as mainpage
Supported as of doxygen 1.8.3 (Dec 2012), see
http://www.stack.nl/~dimitri/doxygen/manual/changelog.html#log_1_8_3

Fixes #145

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-20 11:28:05 +02:00
Peter Hutterer
a664042f64 meson: add doxygen input files to source list
To rebuild the documentation when either changes

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-20 11:28:05 +02:00
Benjamin Tissoires
5bc4470a8c Fix warning: ‘x’ may be used uninitialized in this function
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-04-20 11:20:07 +02:00
Peter Hutterer
b8ed1ea3a4 Remove autotools build system
And thus drop the code to parse the top_srcdir from the arguments to the
symbols-leak-test, not the env.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-19 14:40:57 +02:00
Peter Hutterer
f2ad49cf20 Add meson build file
For a builddir called 'builddir', the following commands are sufficient now:

    meson builddir
    ninja -C builddir
    sudo ninja -C builddir install

Meson only needs to be run once after checkout or after the removal of the
builddir.

Fixes https://github.com/libratbag/libratbag/issues/142

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-19 14:40:57 +02:00
Peter Hutterer
fd6a9e73ed test: always run the symbols-leak-test
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-19 14:40:57 +02:00
Peter Hutterer
db57a8e7b6 test: pass TOP_SRCDIR via the env or as $1
Prep work for meson, even though we'll eventuall drop the env bit. This just
removes the extra symbols-leak-test.in step.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-19 14:40:57 +02:00
Peter Hutterer
2a35bf009f configure.ac: drop "auto" detection of test dependencies
Always build the tests, if someone doesn't want it disable it with a configure
flag but at least be explicit about it.

Justification: any developer should build the full stack as intended by
default. Distributions may disable bits and pieces, but they shouldn't rely on
auto-detection to figure it out, they should explicity disable those bits they
don't want.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-04 10:00:38 +02:00
Peter Hutterer
42d49d74ab configure.ac: drop "auto" detection of doxygen dependencies
Always build the documentation, if someone doesn't want it disable it with a
configure flag but at least be explicit about it.

Justification: any developer should build the full stack as intended by
default. Distributions may disable bits and pieces, but they shouldn't rely on
auto-detection to figure it out, they should explicity disable those bits they
don't want.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-04 10:00:38 +02:00
Peter Hutterer
a9f34249fc configure.ac: remove an erroneous quotation mark
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-04 10:00:38 +02:00
Peter Hutterer
1ce59bcc1f doc: drop the custom INPUT to doxygen
Not necessary, we have it in the doxygen.in
2017-04-03 09:55:53 +02:00
Peter Hutterer
bb35821c45 tools: fix signed vs unsigned comparison warnings
And use this to start using C99 variable style, for pure loop variables it's
better to have them declared in the loop itself.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-03 09:55:53 +02:00
Peter Hutterer
bbec42c426 tools: include config.h for ratbag-command
And that then pulls in _GNU_SOURCE for us

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-03 09:55:53 +02:00
Peter Hutterer
cb487a6d1a tools: fix compiler warning 'no previous prototype'
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-03 09:55:53 +02:00
Peter Hutterer
7fdcf62bf2 tools: fix compiler warning
../tools/shared.c:132:1: warning: ‘static’ is not at beginning of declaration [-Wold-style-declaration]

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-03 09:55:53 +02:00
Peter Hutterer
f82c1119bf tools: fix Makefile, it's SOURCES, not SOURCeS
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-04-03 09:55:53 +02:00
Peter Hutterer
f60f8a12ab tools: fix string parsing for LED colors 2017-03-31 15:07:01 +10:00
Peter Hutterer
fd348d456d tools: add missing LED_OFF switch case
And add the missing break
2017-03-31 15:07:01 +10:00
Peter Hutterer
0f73a97bc8 tools: move variable declaration up
We do C99, but not this :)
2017-03-31 15:07:01 +10:00
Peter Hutterer
7783f50110 tools: fix unused variable warnings 2017-03-31 15:07:01 +10:00
Benjamin Tissoires
b85fcd0cee hwdb: add missing G900 over USB entry
Allows to have the nice picture

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2017-03-22 11:49:19 +01:00
49 changed files with 937 additions and 864 deletions

42
.gitignore vendored
View File

@@ -1,7 +1,5 @@
*.o
*.pc
*.la
*.lo
*.swp
*~
*.sig
@@ -10,44 +8,4 @@
*.patch
*.rej
*.trs
Makefile
Makefile.in
aclocal.m4
autom4te.cache/
config.guess
config.h
config.h.in
config.log
config.status
config.sub
configure
depcomp
install-sh
libtool
ltmain.sh
missing
stamp-h1
.libs/
.deps/
src/libratbag-version.h
doc/libratbag.doxygen
doc/html
tags
test-driver
compile
m4
symbols-leak-test
symbols-leak-test.log
test-build-cxx
test-build-linker
test-build-pedantic-c99
test-build-std-gnuc90
test-iconv-helper
test-suite.log
test-context
test-device
test-*.log
ratbag-command
hidpp10-dump-page
hidpp20-dump-page
lur-command

View File

@@ -1,6 +0,0 @@
SUBDIRS = src doc test tools hwdb data
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
valgrind:
(cd test; $(MAKE) valgrind)

View File

@@ -1,5 +1,3 @@
/*!@mainpage
libratbag
=========
@@ -67,6 +65,28 @@ Source
git clone https://github.com/libratbag/libratbag.git
Building
--------
libratbag uses the meson build system, see http://mesonbuild.com which in
turn uses ninja to invoke the compiler (`ninja` may be `ninja-build` on your
distribution). From a fresh git checkout, run the
following commands to init the repository:
meson builddir --prefix=/usr/
And to build or re-build after code-changes, run:
ninja -C builddir
sudo ninja -C builddir install
Note: 'builddir' is the build output directory and can be changed to any
other directory name. To set configure-time options, use e.g.
mesonconf builddir -Denable-documentation=no
Run 'mesonconf builddir' to list the options.
Bugs
----
@@ -100,5 +120,3 @@ libratbag is licensed under the MIT license.
See the COPYING file for the full license information.
[![Build Status](https://semaphoreci.com/api/v1/projects/7905244a-c0b5-468b-9071-d846de3ce9f1/545192/badge.svg)](https://semaphoreci.com/libratbag/libratbag)
*/

View File

@@ -1,9 +0,0 @@
#!/bin/sh
test -n "$srcdir" || srcdir=`dirname "$0"`
test -n "$srcdir" || srcdir=.
(
cd "$srcdir" &&
autoreconf --force -v --install
) || exit
test -n "$NOCONFIGURE" || "$srcdir/configure" "$@"

View File

@@ -1,164 +0,0 @@
AC_PREREQ([2.64])
m4_define([libratbag_major_version], [0])
m4_define([libratbag_minor_version], [6])
m4_define([libratbag_micro_version], [0])
m4_define([libratbag_version],
[libratbag_major_version.libratbag_minor_version.libratbag_micro_version])
AC_INIT([libratbag],
[libratbag_version],
[],
[libratbag],
[])
AC_SUBST([LIBRATBAG_VERSION_MAJOR], [libratbag_major_version])
AC_SUBST([LIBRATBAG_VERSION_MINOR], [libratbag_minor_version])
AC_SUBST([LIBRATBAG_VERSION_MICRO], [libratbag_micro_version])
AC_SUBST([LIBRATBAG_VERSION], [libratbag_version])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz])
# Before making a release, the LIBRATBAG_LT_VERSION and LIBLUR_LT_VERSION
# strings should be modified.
# The strings 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
LIBRATBAG_LT_VERSION=4:0:0
LIBLUR_LT_VERSION=3:2:0
AC_SUBST(LIBRATBAG_LT_VERSION)
AC_SUBST(LIBLUR_LT_VERSION)
AM_SILENT_RULES([yes])
AC_USE_SYSTEM_EXTENSIONS
# Check for programs
AC_PROG_CC_C99
AC_PROG_CXX # Only used by build C++ test
AC_PROG_GREP
# Initialize libtool
LT_PREREQ([2.2])
LT_INIT
PKG_PROG_PKG_CONFIG()
PKG_CHECK_MODULES(LIBUDEV, [libudev])
PKG_CHECK_MODULES(LIBEVDEV, [libevdev])
if test "x$GCC" = "xyes"; then
GCC_CXXFLAGS="-Wall -Wextra -Wno-unused-parameter -g -fvisibility=hidden"
GCC_CFLAGS="$GCC_CXXFLAGS -Wmissing-prototypes -Wstrict-prototypes"
fi
AC_SUBST(GCC_CFLAGS)
AC_SUBST(GCC_CXXFLAGS)
AC_ARG_WITH(udev-base-dir, AS_HELP_STRING([--with-udev-base-dir=DIR], [where udev base directory is]))
if test -n "$with_udev_base_dir" ; then
UDEV_BASE_DIR="$with_udev_base_dir"
else
UDEV_BASE_DIR="$prefix/lib/udev"
fi
AC_SUBST(UDEV_BASE_DIR)
AC_ARG_ENABLE([documentation],
[AC_HELP_STRING([--enable-documentation],
[Enable building the documentation (default=auto)])],
[build_documentation="$enableval"],
[build_documentation="auto"])
if test "x$build_documentation" = "xyes" -o "x$build_documentation" = "xauto"; then
AC_PATH_PROG(DOXYGEN, doxygen)
if test "x$DOXYGEN" = "x"; then
if test "x$build_documentation" = "xyes"; then
AC_MSG_ERROR([Documentation build requested but doxygen not found. Install doxygen or disable the documentation using --disable-documentation])
fi
else
AC_MSG_CHECKING([for compatible doxygen version])
doxygen_version=`$DOXYGEN --version`
AS_VERSION_COMPARE([$doxygen_version], [1.6.0],
[AC_MSG_RESULT([no])
DOXYGEN=""],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([yes])])
if test "x$DOXYGEN" = "x" -a "x$build_documentation" = "xyes"; then
AC_MSG_ERROR([Doxygen $doxygen_version too old. Doxygen 1.6+ required for documentation build. Install required doxygen version or disable the documentation using --disable-documentation])
fi
fi
AC_PATH_PROG(DOT, dot)
if test "x$DOT" = "x"; then
if test "x$build_documentation" = "xyes"; then
AC_MSG_ERROR([Documentation build requested but graphviz's dot not found. Install graphviz or disable the documentation using --disable-documentation])
fi
else
AC_MSG_CHECKING([for compatible dot version])
dot_version=`$DOT -V 2>&1|$GREP -oP '(?<=version\W)@<:@0-9.@:>@*(?=\W(.*))'`
AS_VERSION_COMPARE([$dot_version], [2.26.0],
[AC_MSG_RESULT([no])
DOT=""],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([yes])])
if test "x$DOT" = "x" -a "x$build_documentation" = "xyes"; then
AC_MSG_ERROR([Graphviz dot $dot_version too old. Graphviz 2.26+ required for documentation build. Install required graphviz version or disable the documentation using --disable-documentation])
fi
fi
if test "x$DOXYGEN" != "x" -a "x$DOT" != "x"; then
build_documentation="yes"
else
build_documentation="no"
fi
fi
AC_ARG_ENABLE(tests,
AS_HELP_STRING([--enable-tests], [Build the tests (default=auto)]),
[build_tests="$enableval"],
[build_tests="auto"])
PKG_CHECK_MODULES(CHECK, [check >= 0.9.10], [HAVE_CHECK="yes"], [HAVE_CHECK="no"])
if test "x$build_tests" = "xauto"; then
build_tests="$HAVE_CHECK"
fi
if test "x$build_tests" = "xyes"; then
if test "x$HAVE_CHECK" = "xno"; then
AC_MSG_ERROR([Cannot build tests, check is missing])
fi
AC_PATH_PROG(VALGRIND, [valgrind])
fi
AC_DEFINE(BUILD_TESTS, [1], ["Build the test suite])
AM_CONDITIONAL(HAVE_VALGRIND, [test "x$VALGRIND" != "x"])
AM_CONDITIONAL(BUILD_TESTS, [test "x$build_tests" = "xyes"])
AM_CONDITIONAL(BUILD_DOCS, [test "x$build_documentation" = "xyes"])
AC_CONFIG_FILES([Makefile
data/Makefile
doc/Makefile
doc/libratbag.doxygen
hwdb/Makefile
src/Makefile
src/libratbag.pc
src/libratbag-version.h
src/liblur.pc
test/Makefile
tools/Makefile])
AC_CONFIG_FILES([test/symbols-leak-test],
[chmod +x test/symbols-leak-test])
AC_OUTPUT
AC_MSG_RESULT([
Prefix ${prefix}
udev base directory: ${UDEV_BASE_DIR}
Build documentation ${build_documentation}
Build tests ${build_tests}
Tests use valgrind ${VALGRIND}
])

View File

@@ -1,2 +0,0 @@
libratbagdatadir = $(datadir)/libratbag
dist_libratbagdata_DATA = $(shell find $(top_srcdir)/data -name "*.svg" -printf "%P\n")

View File

@@ -1,38 +0,0 @@
if BUILD_DOCS
noinst_DATA = html/index.html
header_files = \
$(top_srcdir)/src/libratbag.h \
$(top_srcdir)/README.md
style_files = \
style/header.html \
style/footer.html \
style/customdoxygen.css \
style/bootstrap.css
html/index.html: libratbag.doxygen $(header_files) $(diagram_files) $(style_files)
$(AM_V_GEN)(cat $<; \
echo "INPUT = $(header_files)"; \
) | $(DOXYGEN) -
clean-local:
$(AM_V_at)rm -rf html
doc_src= $(shell find html -type f -printf "html/%P\n" 2>/dev/null)
EXTRA_DIST = $(builddir)/html/index.html \
$(doc_src) \
$(diagram_files) \
$(header_files) \
$(style_files)
endif
# make sure doc was built before running dist
dist-hook:
@test -f $(distdir)/html/index.html || (\
echo "******************************************************" && \
echo "Couldn't find documentation files, refusing make dist." && \
echo "Install doxygen to build documentation for tarball." && \
echo "******************************************************" && \
test )

View File

@@ -8,8 +8,9 @@ EXTRACT_ALL = YES
EXTRACT_STATIC = YES
MAX_INITIALIZER_LINES = 0
QUIET = YES
# Keep this list in sync with meson.build
INPUT = @top_srcdir@/src/libratbag.h \
@top_srcdir@/README.txt
@top_srcdir@/README.md
GENERATE_HTML = YES
HTML_TIMESTAMP = YES
USE_MATHJAX = YES
@@ -24,3 +25,4 @@ HTML_HEADER = @top_srcdir@/doc/style/header.html
HTML_FOOTER = @top_srcdir@/doc/style/footer.html
HTML_EXTRA_STYLESHEET = @top_srcdir@/doc/style/customdoxygen.css \
@top_srcdir@/doc/style/bootstrap.css
USE_MDFILE_AS_MAINPAGE = README.md

View File

@@ -180,6 +180,10 @@ mouse:usb:v046dp4011:name:*:
mouse:usb:v046dpc537:name:*:
RATBAG_HIDPP20_INDEX=1
# G900 over USB
mouse:usb:v046dpc081:name:*:
RATBAG_SVG=logitech-g900.svg
# G900 over wireless USB
mouse:usb:v046dpc539:name:*:
RATBAG_DRIVER=hidpp20

View File

@@ -1,9 +0,0 @@
udevrulesdir = $(UDEV_BASE_DIR)/rules.d
udevrules_DATA = 70-libratbag-mouse.rules
hwdbdir = $(UDEV_BASE_DIR)/hwdb.d
hwdb_DATA = 70-libratbag-mouse.hwdb
EXTRA_DIST = \
$(udevrules_DATA) \
$(hwdb_DATA)

403
meson.build Normal file
View File

@@ -0,0 +1,403 @@
project('libratbag', 'c', 'cpp',
version : '0.9.0',
license : 'MIT/Expat',
default_options : [ 'c_std=gnu99', 'warning_level=2' ])
libratbag_version = meson.project_version().split('.')
# 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
libratbag_so_c=4
libratbag_so_r=3
libratbag_so_a=0
liblur_so_c=3
liblur_so_r=3
liblur_so_a=0
# convert to sonames
libratbag_so_version = '@0@.@1@.@2@'.format((libratbag_so_c - libratbag_so_a),
libratbag_so_a, libratbag_so_r)
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')
cpp = meson.get_compiler('cpp')
cppflags = ['-Wno-unused-parameter', '-fvisibility=hidden']
cflags = cppflags + ['-Wmissing-prototypes', '-Wstrict-prototypes']
add_project_arguments(cflags, language: 'c')
add_project_arguments(cppflags, language: 'cpp')
# 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')
# dependencies
pkgconfig = import('pkgconfig')
dep_udev = dependency('libudev')
dep_libevdev = dependency('libevdev')
dep_lm = cc.find_library('m')
#### 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.a ####
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 ####
install_headers('src/libratbag.h')
src_libratbag = [
'src/driver-etekcity.c',
'src/driver-hidpp20.c',
'src/driver-hidpp10.c',
'src/driver-logitech-g300.c',
'src/driver-roccat.c',
'src/driver-gskill.c',
'src/driver-test.c',
'src/libratbag.c',
'src/libratbag.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_libutil,
dep_libhidpp,
]
libratbag_version_h_config = configuration_data()
libratbag_version_h_config.set('LIBRATBAG_VERSION_MAJOR', libratbag_version[0])
libratbag_version_h_config.set('LIBRATBAG_VERSION_MINOR', libratbag_version[1])
libratbag_version_h_config.set('LIBRATBAG_VERSION_MICRO', libratbag_version[2])
libratbag_version_h_config.set_quoted('LIBRATBAG_VERSION', meson.project_version())
libratbag_version_h = configure_file(
output : 'libratbag-version.h',
configuration : libratbag_version_h_config,
install: false,
)
mapfile = 'src/libratbag.sym'
version_flag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile)
lib_libratbag = shared_library('ratbag',
src_libratbag,
include_directories : include_directories('.'),
dependencies : deps_libratbag,
version : libratbag_so_version,
link_args : version_flag,
link_depends : mapfile,
install : true,
)
dep_libratbag = declare_dependency(
link_with : lib_libratbag,
dependencies : deps_libratbag
)
pkgconfigdata = configuration_data()
pkgconfigdata.set('prefix', get_option('prefix'))
pkgconfigdata.set('libdir', get_option('libdir'))
pkgconfigdata.set('datadir', get_option('datadir'))
pkgconfigdata.set('includedir', get_option('includedir'))
pkgconfigdata.set('LIBRATBAG_VERSION', meson.project_version())
pkgconfigfile = configure_file(
input : 'src/libratbag.pc.in',
output : 'libratbag.pc',
configuration : pkgconfigdata,
install : true,
install_dir : get_option('libdir') + '/pkgconfig'
)
#### 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)
#### ratbag-command ####
src_ratbag_command = [ 'tools/ratbag-command.c' ]
deps_ratbag_command = [
dep_libshared,
dep_libratbag,
dep_libevdev
]
executable('ratbag-command',
src_ratbag_command,
dependencies : deps_ratbag_command,
include_directories : include_directories('src'),
install : true,
)
man_config = configuration_data()
man_config.set('version', meson.project_version())
man_ratbag_command = configure_file (
input: 'tools/ratbag-command.man',
output: 'ratbag-command.1',
configuration: man_config,
install : true,
install_dir : join_paths(get_option('mandir'), 'man1')
)
#### 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,
)
#### lur-command ####
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_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')
)
#### hwdb ####
udev_dir = get_option('udev-dir')
if udev_dir == ''
udev_dir = '@0@/lib/udev'.format(get_option('prefix'))
endif
udev_rules_dir = '@0@/rules.d'.format(udev_dir)
udev_hwdb_dir = '@0@/hwdb.d'.format(udev_dir)
install_data('hwdb/70-libratbag-mouse.rules',
install_dir : udev_rules_dir)
install_data('hwdb/70-libratbag-mouse.hwdb',
install_dir : udev_hwdb_dir)
#### svg files ####
svg_files = [
'data/etekcity.svg',
'data/logitech-g300.svg',
'data/logitech-g303.svg',
'data/logitech-g500s.svg',
'data/logitech-g502.svg',
'data/logitech-g700.svg',
'data/logitech-g900.svg',
'data/logitech-mx_master.svg',
'data/roccat-kone-xtd.svg'
]
install_data(svg_files,
install_dir : '@0@/libratbag'.format(get_option('datadir')))
#### tests ####
enable_tests = get_option('enable-tests')
if enable_tests
dep_check = dependency('check', version: '>= 0.9.10')
config_h.set('BUILD_TESTS', '1')
env_test = ['RATBAG_TEST=1']
valgrind_args = [ '--leak-check=full',
'--quiet',
'--error-exitcode=3',
'--suppressions=@0@/test/valgrind.suppressions'.format(meson.current_source_dir()) ]
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_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, env : env_test, valgrind_args : valgrind_args)
test('test-device', test_device, env : env_test, valgrind_args : valgrind_args)
test('test-iconv-helper', test_iconv_helper, env : env_test, valgrind_args : valgrind_args)
executable('test-build-cxx',
['test/build-cxx.cc'],
dependencies : [ dep_libratbag ],
include_directories : include_directories('src'),
cpp_args : ['-Wall', '-Wextra', '-Wno-unused-parameter'],
install : false)
executable('test-build-linker',
['test/build-pedantic.c'],
dependencies : [ dep_libratbag ],
include_directories : include_directories('src'),
install : false)
executable('test-build-gnuc90',
['test/build-pedantic.c'],
dependencies : [ dep_libratbag ],
include_directories : include_directories('src'),
c_args : ['-std=gnu90', '-Werror'],
install : false)
executable('test-build-pedantic',
['test/build-pedantic.c'],
dependencies : [ dep_libratbag ],
include_directories : include_directories('src'),
c_args : ['-std=c99', '-pedantic', '-Werror'],
install : false)
endif
test_symbols_leak = find_program('test/symbols-leak-test')
test('symbols-leak-test',
test_symbols_leak,
args : [ meson.current_source_dir() ])
#### documentation ####
enable_doc = get_option('enable-documentation')
if enable_doc
cmd_doxygen = find_program('doxygen')
cmd_dot = find_program('dot')
v = run_command(cmd_doxygen, ['--version']).stdout()
if not v.version_compare('>=1.8.3')
error('Doxygen $doxygen_version too old. ' +
'Doxygen 1.8.3+ required for documentation build. ' +
'Install required doxygen version or ' +
'disable the documentation using --disable-documentation')
endif
v = run_command(cmd_dot, ['-V']).stderr()
v = v.split(' ')[4]
if v.version_compare('<2.26.0')
error('Graphviz dot $dot_version too old. ' +
'Graphviz 2.26+ required for documentation build. ' +
'Install required graphviz version or ' +
'disable the documentation using --disable-documentation')
endif
doc_config = configuration_data()
doc_config.set('PACKAGE_NAME', meson.project_name())
doc_config.set('PACKAGE_VERSION', meson.project_version())
doc_config.set('top_srcdir', meson.source_root())
doxyfile = configure_file(input : 'doc/libratbag.doxygen.in',
output : 'libratbag.doxygen',
configuration : doc_config,
install : false)
src_doxygen = [ doxyfile,
'src/libratbag.h',
'README.md']
custom_target('doxygen',
input : src_doxygen,
output : [ 'html' ],
command : [ cmd_doxygen, doxyfile ],
install : false,
build_by_default : true)
endif
#### output files ####
configure_file(output: 'config.h', install: false, configuration: config_h)

14
meson_options.txt Normal file
View File

@@ -0,0 +1,14 @@
option('udev-dir',
type: 'string',
default: '',
description: 'udev base directory [default=$prefix/lib/udev]')
option('enable-tests',
type: 'boolean',
value: true,
description: 'Build the tests (default=yes)')
option('enable-documentation',
type: 'boolean',
value: true,
description: 'Build the documentation (default=yes)')

View File

@@ -288,39 +288,6 @@ process_module() {
return 1
fi
# Change directory to be in the git build directory (could be out-of-source)
# More than one can be found when distcheck has run and failed
configNum=`find . -name config.status -type f | wc -l | sed 's:^ *::'`
if [ $? -ne 0 ]; then
echo "Error: failed to locate config.status."
echo "Has the module been configured?"
return 1
fi
if [ x"$configNum" = x0 ]; then
echo "Error: failed to locate config.status, has the module been configured?"
return 1
fi
if [ x"$configNum" != x1 ]; then
echo "Error: more than one config.status file was found,"
echo " clean-up previously failed attempts at distcheck"
return 1
fi
status_file=`find . -name config.status -type f`
if [ $? -ne 0 ]; then
echo "Error: failed to locate config.status."
echo "Has the module been configured?"
return 1
fi
build_dir=`dirname $status_file`
cd $build_dir
if [ $? -ne 0 ]; then
echo "Error: failed to cd to $MODULE_RPATH/$build_dir."
cd $top_src
return 1
fi
# ----- Now in the git module *build* directory ----- #
# Check for uncommitted/queued changes.
check_local_changes
if [ $? -ne 0 ]; then
@@ -342,19 +309,9 @@ process_module() {
return 1
fi
# Run 'make dist/distcheck' to ensure the tarball matches the git module content
# Important to run make dist/distcheck before looking in Makefile, may need to reconfigure
echo "Info: running \"make $MAKE_DIST_CMD\" to create tarballs:"
${MAKE} $MAKEFLAGS $MAKE_DIST_CMD > /dev/null
if [ $? -ne 0 ]; then
echo "Error: \"$MAKE $MAKEFLAGS $MAKE_DIST_CMD\" failed."
cd $top_src
return 1
fi
# Find out the tarname from the makefile
pkg_name=`$GREP '^PACKAGE = ' Makefile | sed 's|PACKAGE = ||'`
pkg_version=`$GREP '^VERSION = ' Makefile | sed 's|VERSION = ||'`
# 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")
tar_name="$pkg_name-$pkg_version"
targz=$tar_name.tar.gz
tag_name=$(echo "v$pkg_version" | sed 's|.0$||')
@@ -497,17 +454,11 @@ Usage: $basename [options] path...
Where "path" is a relative path to a git module, including '.'.
Options:
--dist make 'dist' instead of 'distcheck'; use with caution
--distcheck Default, ignored for compatibility
--dry-run Does everything except tagging and uploading tarballs
--force Force overwriting an existing release
--help Display this help and exit successfully
--no-quit Do not quit after error; just print error message
Environment variables defined by the "make" program and used by release.sh:
MAKE The name of the make command [make]
MAKEFLAGS: Options to pass to all \$(MAKE) invocations
HELP
}
@@ -516,9 +467,6 @@ HELP
#------------------------------------------------------------------------------
#
# Choose which make program to use (could be gmake)
MAKE=${MAKE:="make"}
# Choose which grep program to use (on Solaris, must be gnu grep)
if [ "x$GREP" = "x" ] ; then
if [ -x /usr/gnu/bin/grep ] ; then
@@ -528,23 +476,10 @@ if [ "x$GREP" = "x" ] ; then
fi
fi
# Set the default make tarball creation command
MAKE_DIST_CMD=distcheck
# Process command line args
while [ $# != 0 ]
do
case $1 in
# Use 'dist' rather than 'distcheck' to create tarballs
# You really only want to do this if you're releasing a module you can't
# possibly build-test. Please consider carefully the wisdom of doing so.
--dist)
MAKE_DIST_CMD=dist
;;
# Use 'distcheck' to create tarballs
--distcheck)
MAKE_DIST_CMD=distcheck
;;
# Does everything except uploading tarball
--dry-run)
DRY_RUN=yes

View File

@@ -8,6 +8,18 @@
sudo apt-get update
sudo apt-get install -y valgrind check libevdev-dev libudev-dev doxygen graphviz
autoreconf -ivf
./configure --prefix=$PWD/_build --with-udev-base-dir=$PWD/_build
DISTCHECK_CONFIGURE_FLAGS="--with-udev-base-dir=$PWD/_build" make distcheck
# no meson on 14.04
sudo apt-get install -y python3-pip
sudo pip3 install meson
# ninja on 14.04 is too old
git clone git://github.com/ninja-build/ninja.git
cd ninja
git checkout release
./configure.py --bootstrap
sudo cp ninja /usr/bin/ninja
cd ..
meson builddir
ninja -C builddir test

View File

@@ -1,78 +0,0 @@
lib_LTLIBRARIES = libratbag.la \
liblur.la
noinst_LTLIBRARIES = libhidpp.la \
libutil.la
include_HEADERS = \
libratbag.h \
liblur.h
libratbag_la_SOURCES = \
driver-etekcity.c \
driver-hidpp20.c \
driver-hidpp10.c \
driver-logitech-g300.c \
driver-roccat.c \
driver-gskill.c \
driver-test.c \
libratbag.c \
libratbag.h \
libratbag-hidraw.c \
libratbag-hidraw.h \
libratbag-private.h \
libratbag-test.c \
libratbag-test.h \
usb-ids.h
libratbag_la_LIBADD = \
libhidpp.la \
libutil.la \
$(LIBUDEV_LIBS) $(LIBEVDEV_LIBS)
libratbag_la_CFLAGS = -I$(top_srcdir)/include \
$(LIBUDEV_CFLAGS) \
$(LIBEVDEV_CFLAGS) \
$(GCC_CFLAGS)
EXTRA_libratbag_la_DEPENDENCIES = $(srcdir)/libratbag.sym
libratbag_la_LDFLAGS = -version-info $(LIBRATBAG_LT_VERSION) -shared \
-Wl,--version-script=$(srcdir)/libratbag.sym
liblur_la_SOURCES = \
liblur.c \
liblur.h
liblur_la_LIBADD = \
libhidpp.la \
libutil.la
liblur_la_CFLAGS = \
-I$(top_srcdir)/include \
$(GCC_CFLAGS)
EXTRA_liblur_la_DEPENDENCIES = $(srcdir)/liblur.sym
liblur_la_LDFLAGS = -version-info $(LIBLUR_LT_VERSION) -shared \
-Wl,--version-script=$(srcdir)/liblur.sym
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libratbag.pc \
liblur.pc
AM_CFLAGS = $(GCC_CFLAGS)
DISTCLEANFILES = libratbag-version.h
EXTRA_DIST = libratbag-version.h.in libratbag.sym liblur.sym
# The hidpp libraries are static libraries only for in-tree tools. No API
# stability is guaranteed here.
libhidpp_la_SOURCES = \
hidpp-generic.h \
hidpp-generic.c \
hidpp10.h \
hidpp10.c \
hidpp20.h \
hidpp20.c \
usb-ids.h
libhidpp_la_LDFLAGS = -lm
libutil_la_SOURCES = \
libratbag-util.c \
libratbag-util.h
libutil_la_LIBADD = $(LIBUDEV_LIBS)

View File

@@ -731,8 +731,10 @@ gskill_macro_from_report(struct ratbag_device *device,
ret = ratbag_utf8_from_enc(report->macro_name,
report->macro_name_length, "UTF-16LE",
&macro->macro.name);
if (ret < 0)
if (ret < 0) {
ratbag_button_macro_unref(macro);
return NULL;
}
for (i = 0, event_idx = 0, increment = 1;
i < report->macro_length;

View File

@@ -253,7 +253,7 @@ hidpp20drv_read_led(struct ratbag_led *led)
struct hidpp20_color_led_zone_info *led_info;
struct hidpp20_led *h_led;
if (!(drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100))
if (!(drv_data->capabilities & HIDPP_CAP_COLOR_LED_EFFECTS_8070))
return;
led_info = &drv_data->led_infos[led->index];
@@ -278,8 +278,8 @@ hidpp20drv_read_led(struct ratbag_led *led)
led->color.red = h_led->color.red;
led->color.green = h_led->color.green;
led->color.blue = h_led->color.blue;
led->hz = h_led->rate;
led->brightness = h_led->brightness * 255.0 / 100;
led->hz = h_led->period; /* FIXME: should be ceil(1000.0 / h_led->period), but that would be very small */
led->brightness = h_led->brightness * 255 / 100;
}
static int
@@ -318,8 +318,8 @@ hidpp20drv_write_button_1b04(struct ratbag_button *button,
}
static int
hidpp20drv_write_button_8100(struct ratbag_button *button,
const struct ratbag_button_action *action)
hidpp20drv_update_button_8100(struct ratbag_button *button,
const struct ratbag_button_action *action)
{
struct ratbag_device *device = button->profile->device;
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
@@ -370,14 +370,14 @@ hidpp20drv_write_button_8100(struct ratbag_button *button,
}
static int
hidpp20drv_write_button(struct ratbag_button *button,
hidpp20drv_update_button(struct ratbag_button *button,
const struct ratbag_button_action *action)
{
struct ratbag_device *device = button->profile->device;
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
if (drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100)
return hidpp20drv_write_button_8100(button, action);
return hidpp20drv_update_button_8100(button, action);
if (drv_data->capabilities & HIDPP_CAP_BUTTON_KEY_1b04)
return hidpp20drv_write_button_1b04(button, action);
@@ -386,10 +386,7 @@ hidpp20drv_write_button(struct ratbag_button *button,
}
static int
hidpp20drv_write_led(struct ratbag_led *led,
enum ratbag_led_mode mode,
struct ratbag_color color, unsigned int hz,
unsigned int brightness)
hidpp20drv_update_led(struct ratbag_led *led)
{
struct ratbag_profile *profile = led->profile;
struct ratbag_device *device = profile->device;
@@ -407,7 +404,7 @@ hidpp20drv_write_led(struct ratbag_led *led,
if (!h_led)
return -EINVAL;
switch (mode) {
switch (led->mode) {
case RATBAG_LED_ON:
h_led->mode = HIDPP20_LED_ON;
break;
@@ -421,14 +418,13 @@ hidpp20drv_write_led(struct ratbag_led *led,
h_led->mode = HIDPP20_LED_OFF;
break;
}
h_led->color.red = color.red;
h_led->color.green = color.green;
h_led->color.blue = color.blue;
h_led->rate = hz;
h_led->brightness = brightness / 255.0 * 100;
h_led->color.red = led->color.red;
h_led->color.green = led->color.green;
h_led->color.blue = led->color.blue;
h_led->period = led->hz; /* FIXME: should be 1000 / led->hz, but that would be very small */
h_led->brightness = led->brightness * 100 / 255;
return hidpp20_onboard_profiles_write(drv_data->dev, profile->index,
drv_data->profiles);
return RATBAG_SUCCESS;
}
static int
@@ -548,8 +544,8 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile)
}
static int
hidpp20drv_write_resolution_dpi_8100(struct ratbag_resolution *resolution,
int dpi_x, int dpi_y)
hidpp20drv_update_resolution_dpi_8100(struct ratbag_resolution *resolution,
int dpi_x, int dpi_y)
{
struct ratbag_profile *profile = resolution->profile;
struct ratbag_device *device = profile->device;
@@ -564,12 +560,12 @@ hidpp20drv_write_resolution_dpi_8100(struct ratbag_resolution *resolution,
h_profile = &drv_data->profiles->profiles[profile->index];
h_profile->dpi[index] = dpi;
return hidpp20_onboard_profiles_write(drv_data->dev, profile->index, drv_data->profiles);
return RATBAG_SUCCESS;
}
static int
hidpp20drv_write_resolution_dpi(struct ratbag_resolution *resolution,
int dpi_x, int dpi_y)
hidpp20drv_update_resolution_dpi(struct ratbag_resolution *resolution,
int dpi_x, int dpi_y)
{
struct ratbag_profile *profile = resolution->profile;
struct ratbag_device *device = profile->device;
@@ -579,7 +575,7 @@ hidpp20drv_write_resolution_dpi(struct ratbag_resolution *resolution,
int dpi = dpi_x; /* dpi_x == dpi_y if we don't have the individual resolution cap */
if (drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100)
return hidpp20drv_write_resolution_dpi_8100(resolution, dpi_x, dpi_y);
return hidpp20drv_update_resolution_dpi_8100(resolution, dpi_x, dpi_y);
if (!(drv_data->capabilities & HIDPP_CAP_SWITCHABLE_RESOLUTION_2201))
return -ENOTSUP;
@@ -748,12 +744,6 @@ hidpp20drv_read_profile(struct ratbag_profile *profile, unsigned int index)
profile->is_active = (index == 0);
}
static int
hidpp20drv_write_profile(struct ratbag_profile *profile)
{
return 0;
}
static int
hidpp20drv_init_feature(struct ratbag_device *device, uint16_t feature)
{
@@ -865,6 +855,60 @@ hidpp20drv_init_feature(struct ratbag_device *device, uint16_t feature)
return 0;
}
static int
hidpp20_commit(struct ratbag_device *device)
{
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
struct ratbag_profile *profile;
struct ratbag_button *button;
struct ratbag_led *led;
struct ratbag_resolution *resolution;
int rc;
unsigned int i;
list_for_each(profile, &device->profiles, link) {
if (!profile->dirty)
continue;
for (i = 0; i < profile->resolution.num_modes; i++) {
resolution = &profile->resolution.modes[i];
rc = hidpp20drv_update_resolution_dpi(resolution,
resolution->dpi_x,
resolution->dpi_y);
if (rc)
return RATBAG_ERROR_DEVICE;
}
list_for_each(button, &profile->buttons, link) {
struct ratbag_button_action action = button->action;
if (!button->dirty)
continue;
rc = hidpp20drv_update_button(button, &action);
if (rc)
return RATBAG_ERROR_DEVICE;
}
list_for_each(led, &profile->leds, link) {
if (!led->dirty)
continue;
rc = hidpp20drv_update_led(led);
if (rc)
return RATBAG_ERROR_DEVICE;
}
if (drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100)
hidpp20_onboard_profiles_write(drv_data->dev,
profile->index,
drv_data->profiles);
}
return RATBAG_SUCCESS;
}
static int
hidpp20drv_20_probe(struct ratbag_device *device)
{
@@ -909,12 +953,15 @@ hidpp20_log(void *userdata, enum hidpp_log_priority priority, const char *format
static void
hidpp20drv_remove(struct ratbag_device *device)
{
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
struct hidpp20_device *dev = drv_data->dev;
struct hidpp20drv_data *drv_data;
struct hidpp20_device *dev;
if (!device)
return;
drv_data = ratbag_get_drv_data(device);
dev = drv_data->dev;
ratbag_close_hidraw(device);
if (drv_data->profiles)
@@ -1003,12 +1050,9 @@ struct ratbag_driver hidpp20_driver = {
.id = "hidpp20",
.probe = hidpp20drv_probe,
.remove = hidpp20drv_remove,
.commit = hidpp20_commit,
.read_profile = hidpp20drv_read_profile,
.write_profile = hidpp20drv_write_profile,
.set_active_profile = hidpp20drv_set_current_profile,
.read_button = hidpp20drv_read_button,
.read_led = hidpp20drv_read_led,
.write_button = hidpp20drv_write_button,
.write_resolution_dpi = hidpp20drv_write_resolution_dpi,
.write_led = hidpp20drv_write_led,
};

View File

@@ -303,6 +303,7 @@ roccat_wait_ready(struct ratbag_device *device)
return 2;
msleep(10);
count++;
}
return -ETIMEDOUT;

View File

@@ -149,8 +149,8 @@ struct hidpp20_8070_location_mapping {
static const struct hidpp20_8070_location_mapping hidpp20_8070_location_mapping[] = {
LED_LOC_MAPPING(0, "None", RATBAG_LED_TYPE_UNKNOWN),
LED_LOC_MAPPING(256, "Logo LED", RATBAG_LED_TYPE_LOGO),
LED_LOC_MAPPING(512, "Side LED", RATBAG_LED_TYPE_SIDE),
LED_LOC_MAPPING(1, "Logo LED", RATBAG_LED_TYPE_LOGO),
LED_LOC_MAPPING(2, "Side LED", RATBAG_LED_TYPE_SIDE),
};
const struct ratbag_button_action *

View File

@@ -26,13 +26,12 @@
* https://drive.google.com/folderview?id=0BxbRzx7vEV7eWmgwazJ3NUFfQ28&usp=sharing
*/
#pragma once
#include <stdint.h>
#include <stdarg.h>
#include <stddef.h>
#ifndef HIDPP_GENERIC_H
#define HIDPP_GENERIC_H
#define HIDPP_RECEIVER_IDX 0xFF
#define HIDPP_WIRED_DEVICE_IDX 0x00
@@ -211,5 +210,3 @@ hidpp_get_unaligned_be_u32(uint8_t *buf)
{
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
}
#endif /* HIDPP_GENERIC_H */

View File

@@ -1397,7 +1397,7 @@ hidpp10_profile_set_names(struct hidpp10_device *dev, struct hidpp10_profile *pr
memcpy(metadata->lgs02.marker, "LGS02", sizeof(metadata->lgs02.marker));
hidpp10_uchar8_to_uchar16(metadata->lgs02.name,
profile->name,
sizeof(metadata->lgs02.name));
ARRAY_LENGTH(metadata->lgs02.name));
for (i = 0; i < ARRAY_LENGTH(metadata->lgs02.macro_names); i++) {
hidpp10_uchar8_to_uchar16(metadata->lgs02.macro_names[i],
profile->macro_names[i],
@@ -1525,10 +1525,10 @@ hidpp10_get_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr
profile->dpi_modes[i].yres);
hidpp_log_raw(&dev->base,
"LED status: 1:%s 2:%s 3:%s 4:%s\n",
(profile->dpi_modes[i].led[0] & 0x2) ? "on" : "off",
(profile->dpi_modes[i].led[1] & 0x2) ? "on" : "off",
(profile->dpi_modes[i].led[2] & 0x2) ? "on" : "off",
(profile->dpi_modes[i].led[3] & 0x2) ? "on" : "off");
profile->dpi_modes[i].led[0] ? "on" : "off",
profile->dpi_modes[i].led[1] ? "on" : "off",
profile->dpi_modes[i].led[2] ? "on" : "off",
profile->dpi_modes[i].led[3] ? "on" : "off");
}
hidpp_log_raw(&dev->base, "Angle correction: %d\n", profile->angle_correction);
hidpp_log_raw(&dev->base, "Default DPI mode: %d\n", profile->default_dpi_mode);

View File

@@ -26,8 +26,7 @@
* https://drive.google.com/folderview?id=0BxbRzx7vEV7eWmgwazJ3NUFfQ28&usp=sharing
*/
#ifndef HIDPP_10_H
#define HIDPP_10_H
#pragma once
#include <stdint.h>
#include <stdbool.h>
@@ -695,5 +694,3 @@ hidpp10_get_firmare_information(struct hidpp10_device *dev,
uint8_t *major,
uint8_t *minor,
uint8_t *build_number);
#endif /* HIDPP_10_H */

View File

@@ -555,7 +555,7 @@ hidpp20_color_led_effects_get_zone_info(struct hidpp20_device *device,
return rc;
msg_info = (struct hidpp20_color_led_zone_info *)msg.msg.parameters;
info->location = msg_info->location;
info->location = hidpp_be_u16_to_cpu(msg_info->location);
info->num_effects = msg_info->num_effects;
info->persistency_caps = msg_info->persistency_caps;
@@ -1064,7 +1064,7 @@ int
hidpp20_onboard_profiles_read_memory(struct hidpp20_device *device,
uint8_t read_rom,
uint8_t page,
uint8_t section,
uint16_t section,
uint8_t result[16])
{
uint8_t feature_index;
@@ -1075,13 +1075,13 @@ hidpp20_onboard_profiles_read_memory(struct hidpp20_device *device,
.msg.address = CMD_ONBOARD_PROFILES_MEMORY_READ,
.msg.parameters[0] = read_rom,
.msg.parameters[1] = page,
.msg.parameters[2] = 0,
.msg.parameters[3] = section,
};
if (read_rom > 1)
return -EINVAL;
hidpp_set_unaligned_be_u16(&msg.msg.parameters[2], section);
feature_index = hidpp_root_get_feature_idx(device,
HIDPP_PAGE_ONBOARD_PROFILES);
if (feature_index == 0)
@@ -1101,8 +1101,9 @@ hidpp20_onboard_profiles_read_memory(struct hidpp20_device *device,
static int
hidpp20_onboard_profiles_write_start(struct hidpp20_device *device,
uint8_t page,
uint8_t section)
uint16_t page,
uint16_t section,
uint16_t size)
{
uint8_t feature_index;
int rc;
@@ -1110,13 +1111,12 @@ hidpp20_onboard_profiles_write_start(struct hidpp20_device *device,
.msg.report_id = REPORT_ID_LONG,
.msg.device_idx = device->index,
.msg.address = CMD_ONBOARD_PROFILES_MEMORY_ADDR_WRITE,
.msg.parameters[0] = 0x00,
.msg.parameters[1] = page,
.msg.parameters[2] = 0,
.msg.parameters[3] = section,
.msg.parameters[4] = 0x01,
};
hidpp_set_unaligned_be_u16(&msg.msg.parameters[0], page);
hidpp_set_unaligned_be_u16(&msg.msg.parameters[2], section);
hidpp_set_unaligned_be_u16(&msg.msg.parameters[4], size);
feature_index = hidpp_root_get_feature_idx(device,
HIDPP_PAGE_ONBOARD_PROFILES);
if (feature_index == 0)
@@ -1158,8 +1158,8 @@ hidpp20_onboard_profiles_write_end(struct hidpp20_device *device)
static int
hidpp20_onboard_profiles_write_data(struct hidpp20_device *device,
uint8_t page,
uint8_t section,
uint16_t page,
uint16_t section,
uint8_t *data,
size_t len)
{
@@ -1179,7 +1179,10 @@ hidpp20_onboard_profiles_write_data(struct hidpp20_device *device,
msg.msg.sub_id = feature_index;
rc = hidpp20_onboard_profiles_write_start(device, page, section);
rc = hidpp20_onboard_profiles_write_start(device,
page,
section,
HIDPP20_PAGE_SIZE);
if (rc)
return rc;
@@ -1205,7 +1208,7 @@ hidpp20_onboard_profiles_write_data(struct hidpp20_device *device,
static int
hidpp20_onboard_profiles_write_page(struct hidpp20_device *device,
uint8_t page,
uint16_t page,
uint8_t data[HIDPP20_PAGE_SIZE])
{
uint16_t crc;
@@ -1583,8 +1586,8 @@ hidpp20_onboard_profiles_parse_macro(struct hidpp20_device *device,
}
static unsigned int
hidpp20_onboard_profiles_compute_dict_size(struct hidpp20_device *device,
struct hidpp20_profiles *profiles)
hidpp20_onboard_profiles_compute_dict_size(const struct hidpp20_device *device,
const struct hidpp20_profiles *profiles)
{
unsigned p, num_offset;
@@ -1756,7 +1759,7 @@ hidpp20_onboard_profiles_enable_profile(struct hidpp20_device *device,
hidpp20_onboard_profiles_compute_dict_size(device,
profiles_list));
return hidpp20_onboard_profiles_write_page(device, 0x00, data);
return hidpp20_onboard_profiles_write_page(device, 0x0000, data);
}
union hidpp20_internal_profile {
@@ -1890,26 +1893,36 @@ hidpp20_buttons_from_cpu(struct hidpp20_profile *profile,
}
static void
hidpp20_onboard_profile_read_led(struct hidpp20_led *led,
struct hidpp20_internal_led internal_led)
hidpp20_onboard_profiles_read_led(struct hidpp20_led *led,
struct hidpp20_internal_led internal_led)
{
uint16_t rate = 0;
uint16_t period = 0;
uint8_t brightness = 0;
switch (internal_led.mode) {
led->mode = (enum hidpp20_led_mode)internal_led.mode;
switch (led->mode) {
case HIDPP20_LED_CYCLE:
rate = internal_led.effect.cycle.rate;
brightness = internal_led.effect.cycle.brightness;
period = hidpp_be_u16_to_cpu(internal_led.effect.cycle.period_or_speed);
brightness = internal_led.effect.cycle.intensity;
if (brightness == 0)
brightness = 100;
break;
case HIDPP20_LED_BREATHING:
rate = internal_led.effect.breath.rate;
brightness = internal_led.effect.breath.brightness;
period = hidpp_be_u16_to_cpu(internal_led.effect.breath.period_or_speed);
brightness = internal_led.effect.breath.intensity;
if (brightness == 0)
brightness = 100;
led->color = internal_led.effect.breath.color;
break;
case HIDPP20_LED_ON:
led->color = internal_led.effect.fixed.color;
break;
case HIDPP20_LED_OFF:
break;
}
led->mode = (enum hidpp20_led_mode)internal_led.mode;
led->color = internal_led.color;
led->rate = rate;
led->period = period;
led->brightness = brightness;
}
@@ -1942,7 +1955,7 @@ int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
}
for (i = 0; i < profiles_list->num_leds; i++)
hidpp20_onboard_profile_read_led(&profile->leds[i], pdata.profile.leds[i]);
hidpp20_onboard_profiles_read_led(&profile->leds[i], pdata.profile.leds[i]);
hidpp20_buttons_to_cpu(device, profile, pdata.profile.buttons, profiles_list->num_buttons);
@@ -1962,27 +1975,40 @@ int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
}
static void
hidpp20_onboard_write_profile_led(struct hidpp20_internal_led *internal_led,
struct hidpp20_led *led)
hidpp20_onboard_profiles_write_led(struct hidpp20_internal_led *internal_led,
struct hidpp20_led *led)
{
uint16_t rate = led->rate;
uint16_t period = led->period;
uint8_t brightness = led->brightness;
memset(internal_led, 0, sizeof(*internal_led));
internal_led->mode = (uint8_t)led->mode;
internal_led->color.red = led->color.red;
internal_led->color.blue = led->color.blue;
internal_led->color.green = led->color.green;
switch (led->mode) {
case HIDPP20_LED_CYCLE:
internal_led->effect.cycle.rate = rate;
internal_led->effect.cycle.brightness = brightness;
internal_led->effect.cycle.period_or_speed = hidpp_cpu_to_be_u16(period);
if (brightness < 100)
internal_led->effect.cycle.intensity = brightness;
else
internal_led->effect.cycle.intensity = 0;
break;
case HIDPP20_LED_BREATHING:
internal_led->effect.breath.rate = rate;
internal_led->effect.breath.brightness = brightness;
internal_led->effect.breath.color.red = led->color.red;
internal_led->effect.breath.color.blue = led->color.blue;
internal_led->effect.breath.color.green = led->color.green;
internal_led->effect.breath.period_or_speed = hidpp_cpu_to_be_u16(period);
if (brightness < 100)
internal_led->effect.breath.intensity = brightness;
else
internal_led->effect.breath.intensity = 0;
break;
case HIDPP20_LED_ON:
internal_led->effect.fixed.color.red = led->color.red;
internal_led->effect.fixed.color.blue = led->color.blue;
internal_led->effect.fixed.color.green = led->color.green;
internal_led->effect.fixed.effect = 0;
break;
case HIDPP20_LED_OFF:
break;
}
@@ -2021,7 +2047,7 @@ int hidpp20_onboard_profiles_write(struct hidpp20_device *device,
}
for (i = 0; i < profiles_list->num_leds; i++)
hidpp20_onboard_write_profile_led(&pdata.profile.leds[i], &profile->leds[i]);
hidpp20_onboard_profiles_write_led(&pdata.profile.leds[i], &profile->leds[i]);
hidpp20_buttons_from_cpu(profile, pdata.profile.buttons, profiles_list->num_buttons);

View File

@@ -26,8 +26,7 @@
* https://drive.google.com/folderview?id=0BxbRzx7vEV7eWmgwazJ3NUFfQ28&usp=sharing
*/
#ifndef HIDPP_20_H
#define HIDPP_20_H
#pragma once
#include <stdint.h>
@@ -117,13 +116,6 @@ enum hidpp20_battery_status {
BATTERY_STATUS_INVALID,
};
enum hidpp20_led_mode {
HIDPP20_LED_OFF = 0x00,
HIDPP20_LED_ON = 0x01,
HIDPP20_LED_CYCLE = 0x03,
HIDPP20_LED_BREATHING = 0x0a,
};
/**
* Retrieves the battery level status.
*
@@ -390,26 +382,46 @@ enum hidpp20_led_type {
HIDPP20_LED_SIDE,
};
enum hidpp20_led_mode {
HIDPP20_LED_OFF = 0x00,
HIDPP20_LED_ON = 0x01,
HIDPP20_LED_CYCLE = 0x03,
HIDPP20_LED_BREATHING = 0x0a,
};
enum hidpp20_led_waveform {
HIDPP20_LED_WF_DEFAULT = 0x00,
HIDPP20_LED_WF_SINE = 0x01,
HIDPP20_LED_WF_SQUARE = 0x02,
HIDPP20_LED_WF_TRIANGLE = 0x03,
HIDPP20_LED_WF_SAWTOOTH = 0x04,
HIDPP20_LED_WF_SHARKFIN = 0x05,
HIDPP20_LED_WF_EXPONENTIAL = 0x06,
};
struct hidpp20_internal_led {
uint8_t mode; /* 00 - off; 01 - on; 03 - cycle; 0a - breath */
struct hidpp20_color color;
uint8_t mode; /* enum hidpp20_led_mode */
union {
struct hidpp20_led_fixed {
struct hidpp20_color color;
uint8_t effect;
} __attribute__((packed)) fixed;
struct hidpp20_led_cycle {
uint16_t pad_1;
uint16_t rate; /* 16000 - 20000Hz */
uint8_t brightness; /* 0 - 100 percent */
uint16_t pad_2;
uint8_t unused[5];
uint16_t period_or_speed; /* period in ms, speed is device dependent */
uint8_t intensity; /* 1 - 100 percent, 0 means 100 */
} __attribute__((packed)) cycle;
struct hidpp20_led_breath {
uint16_t rate;
uint8_t pad_1;
uint8_t brightness;
uint8_t pad_2;
uint16_t pad_3;
struct hidpp20_color color;
uint16_t period_or_speed; /* period in ms, speed is device dependent */
uint8_t waveform; /* enum hidpp20_led_waveform */
uint8_t intensity; /* 1 - 100 percent, 0 means 100 */
} __attribute__((packed)) breath;
uint8_t padding[10];
} __attribute__((packed)) effect;
};
_Static_assert(sizeof(struct hidpp20_led_cycle) == 7, "Invalid size");
_Static_assert(sizeof(struct hidpp20_led_fixed) == 4, "Invalid size");
_Static_assert(sizeof(struct hidpp20_led_cycle) == 8, "Invalid size");
_Static_assert(sizeof(struct hidpp20_led_breath) == 7, "Invalid size");
_Static_assert(sizeof(struct hidpp20_internal_led) == 11, "Invalid size");
@@ -418,7 +430,7 @@ typedef uint8_t percent_t;
struct hidpp20_led {
enum hidpp20_led_mode mode;
struct hidpp20_color color;
uint16_t rate;
uint16_t period;
percent_t brightness;
};
@@ -463,7 +475,7 @@ struct hidpp20_profile {
uint16_t dpi[HIDPP20_DPI_COUNT];
union hidpp20_button_binding buttons[32];
union hidpp20_macro_data *macros[32];
struct hidpp20_led leds[32];
struct hidpp20_led leds[HIDPP20_LED_COUNT];
};
struct hidpp20_profiles {
@@ -534,7 +546,7 @@ int
hidpp20_onboard_profiles_read_memory(struct hidpp20_device *device,
uint8_t read_rom,
uint8_t page,
uint8_t section,
uint16_t section,
uint8_t result[16]);
/* -------------------------------------------------------------------------- */
@@ -544,5 +556,3 @@ hidpp20_onboard_profiles_read_memory(struct hidpp20_device *device,
#define HIDPP_PAGE_MOUSE_BUTTON_SPY 0x8110
#endif /* HIDPP_20_H */

View File

@@ -38,6 +38,13 @@
#define _EXPORT_ __attribute__ ((visibility("default")))
#define MAX_DEVICES 6
static inline void
cleanup_hidpp10_device_destroy(struct hidpp10_device **hidpp10_device) {
if (*hidpp10_device)
hidpp10_device_destroy(*hidpp10_device);
}
#define _cleanup_hidpp10_device_destroy_ _cleanup_(cleanup_hidpp10_device_destroy)
struct lur_receiver {
int refcount;
int fd;
@@ -186,7 +193,7 @@ lur_receiver_enumerate(struct lur_receiver *lur,
dev->present = false;
for (i = 0; i < MAX_DEVICES; i++) {
struct hidpp10_device *d;
_cleanup_hidpp10_device_destroy_ struct hidpp10_device *d;
size_t name_size = 64;
char name[name_size];
uint8_t interval, type;
@@ -240,8 +247,6 @@ lur_receiver_enumerate(struct lur_receiver *lur,
dev->present = true;
list_insert(&lur->devices, &dev->node);
}
hidpp10_device_destroy(d);
}
devices = zalloc(MAX_DEVICES * sizeof(*devices));

View File

@@ -23,8 +23,7 @@
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _LIBLUR_H_
#define _LIBLUR_H_ 1
#pragma once
#ifdef __cplusplus
extern "C" {
@@ -268,4 +267,3 @@ lur_device_get_user_data(const struct lur_device *dev);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,13 +0,0 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
datarootdir=@datarootdir@
pkgdatadir=@datadir@/@PACKAGE@
libdir=@libdir@
includedir=@includedir@
Name: Liblur
Description: Logitech Unifying Receiver configuration library
Version: @LIBRATBAG_VERSION@
Cflags: -I${includedir}
Libs: -L${libdir} -llur
Libs.private: -lm -lrt

View File

@@ -1405,7 +1405,7 @@ ratbag_find_hidraw_node(struct ratbag_device *device,
udev_enumerate_add_match_parent(e, parent_udev);
udev_enumerate_scan_devices(e);
udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
_cleanup_udev_device_unref_ struct udev_device *udev_device;
_cleanup_udev_device_unref_ struct udev_device *udev_device = NULL;
path = udev_list_entry_get_name(entry);
udev_device = udev_device_new_from_syspath(udev, path);

View File

@@ -21,8 +21,7 @@
* DEALINGS IN THE SOFTWARE.
*/
#ifndef LIBRATBAG_HIDRAW_H
#define LIBRATBAG_HIDRAW_H
#pragma once
#include <linux/hid.h>
#include <stdint.h>
@@ -186,4 +185,3 @@ ratbag_hidraw_get_keycode_from_consumer_usage(struct ratbag_device *device,
uint16_t
ratbag_hidraw_get_consumer_usage_from_keycode(struct ratbag_device *device,
unsigned keycode);
#endif /* LIBRATBAG_HIDRAW_H */

View File

@@ -21,8 +21,7 @@
* DEALINGS IN THE SOFTWARE.
*/
#ifndef LIBRATBAG_PRIVATE_H
#define LIBRATBAG_PRIVATE_H
#pragma once
#include <linux/input.h>
#include <stdint.h>
@@ -491,5 +490,3 @@ void
ratbag_button_copy_macro(struct ratbag_button *button,
const struct ratbag_button_macro *macro);
#endif /* LIBRATBAG_PRIVATE_H */

View File

@@ -22,8 +22,7 @@
*/
#ifndef LIBRATBAG_TEST_H
#define LIBRATBAG_TEST_H
#pragma once
#include "libratbag.h"
@@ -84,4 +83,3 @@ struct ratbag_test_device {
struct ratbag_device* ratbag_device_new_test_device(struct ratbag *ratbag,
struct ratbag_test_device *test_device);
#endif /* LIBRATBAG_TEST_H */

View File

@@ -144,7 +144,7 @@ ratbag_utf8_from_enc(char *in_buf, size_t in_len, const char *from_enc,
/*
* We *could* dynamically allocate the out buffer. However iconv's
* obnoxious semantics, mainly the fact that it modifies every pointer
* given to it, would make this code a lot larger and complex then it
* given to it, would make this code a lot larger and complex than it
* needs to be for a mouse with blinking lights.
*
* So, since there's no encoding that takes more then 6 bytes per

View File

@@ -21,8 +21,7 @@
* OF THIS SOFTWARE.
*/
#ifndef LIBRATBAG_UTIL_H
#define LIBRATBAG_UTIL_H
#pragma once
#include <stdlib.h>
#include <stdio.h>
@@ -217,4 +216,3 @@ ratbag_utf8_to_enc(char *buf, size_t buf_len, const char *to_enc,
ssize_t
ratbag_utf8_from_enc(char *in_buf, size_t in_len, const char *from_enc,
char **out);
#endif /* LIBRATBAG_UTIL_H */

View File

@@ -1,32 +0,0 @@
/*
* Copyright © 2013 Jonas Ådahl
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef LIBRATBAG_VERSION_H
#define LIBRATBAG_VERSION_H
#define LIBRATBAG_VERSION_MAJOR @LIBRATBAG_VERSION_MAJOR@
#define LIBRATBAG_VERSION_MINOR @LIBRATBAG_VERSION_MINOR@
#define LIBRATBAG_VERSION_MICRO @LIBRATBAG_VERSION_MICRO@
#define LIBRATBAG_VERSION "@LIBRATBAG_VERSION@"
#endif

View File

@@ -1292,7 +1292,7 @@ ratbag_button_set_key(struct ratbag_button *button,
LIBRATBAG_EXPORT enum ratbag_error_code
ratbag_button_disable(struct ratbag_button *button)
{
struct ratbag_button_action action;
struct ratbag_button_action action = {0};
if (!ratbag_device_has_capability(button->profile->device,
RATBAG_DEVICE_CAP_BUTTON_KEY))

View File

@@ -21,8 +21,7 @@
* DEALINGS IN THE SOFTWARE.
*/
#ifndef LIBRATBAG_H
#define LIBRATBAG_H
#pragma once
#ifdef __cplusplus
extern "C" {
@@ -1818,4 +1817,3 @@ ratbag_led_unref(struct ratbag_led *led);
#ifdef __cplusplus
}
#endif
#endif /* LIBRATBAG_H */

View File

@@ -1,9 +1,8 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
datarootdir=@datarootdir@
pkgdatadir=@datadir@/@PACKAGE@
libdir=@libdir@
includedir=@includedir@
datadir=${prefix}/@datadir@
pkgdatadir=${datadir}/libratbag
libdir=${prefix}/@libdir@
includedir=${prefix}/@includedir@
Name: Libratbag
Description: Mouse configuration library

View File

@@ -20,10 +20,7 @@
* OF THIS SOFTWARE.
*/
#ifndef USB_IDS_H
#define USB_IDS_H
#pragma once
#define USB_VENDOR_ID_LOGITECH 0x046d
#endif

View File

@@ -1,70 +0,0 @@
if BUILD_TESTS
AM_CPPFLAGS = -I$(top_srcdir)/include \
-I$(top_srcdir)/src \
$(CHECK_CFLAGS) \
$(LIBEVDEV_CFLAGS)
AM_CFLAGS = $(GCC_CFLAGS)
AM_CXXFLAGS = $(GCC_CXXFLAGS)
TEST_LIBS = $(CHECK_LIBS) $(LIBEVDEV_LIBS) $(top_builddir)/src/libratbag.la
run_tests = \
test-context \
test-device \
test-iconv-helper
build_tests = \
test-build-cxx \
test-build-linker \
test-build-pedantic-c99 \
test-build-std-gnuc90
noinst_PROGRAMS = $(build_tests) $(run_tests)
noinst_SCRIPTS = symbols-leak-test
TESTS = $(run_tests) symbols-leak-test
test_context_SOURCES = test-context.c
test_context_LDADD = $(TEST_LIBS)
test_context_LDFLAGS = -no-install
test_device_SOURCES = test-device.c
test_device_LDADD = $(TEST_LIBS)
test_device_LDFLAGS = -no-install
test_iconv_helper_SOURCES = test-iconv-helper.c
test_iconv_helper_LDADD = $(TEST_LIBS) $(top_builddir)/src/libutil.la
test_iconv_helper_LDFLAGS = -no-install
# build-test only
test_build_pedantic_c99_SOURCES = build-pedantic.c
test_build_pedantic_c99_CFLAGS = -std=c99 -pedantic -Werror
test_build_std_gnuc90_SOURCES = build-pedantic.c
test_build_std_gnuc90_CFLAGS = -std=gnu90 -Werror
# test for linking with the minimal linker flags
test_build_linker_SOURCES = build-pedantic.c
test_build_linker_CFLAGS = -I$(top_srcdir)/src
test_build_linker_LDADD = $(top_builddir)/src/libratbag.la
# test including from C++
test_build_cxx_SOURCES = build-cxx.cc
test_build_cxx_CXXFLAGS = -Wall -Wextra -Wno-unused-parameter $(AM_CXXFLAGS)
AM_TESTS_ENVIRONMENT=RATBAG_TEST=1; export RATBAG_TEST;
if HAVE_VALGRIND
VALGRIND_FLAGS=--leak-check=full \
--quiet \
--error-exitcode=3 \
--suppressions=$(srcdir)/valgrind.suppressions
valgrind:
$(MAKE) check-TESTS LOG_COMPILER="$(VALGRIND)" LOG_FLAGS="$(VALGRIND_FLAGS)" CK_FORK=no USING_VALGRIND=yes
check: valgrind
endif
endif
EXTRA_DIST=valgrind.suppressions

13
test/symbols-leak-test.in → test/symbols-leak-test Normal file → Executable file
View File

@@ -2,16 +2,21 @@
### simple check for exported symbols
TOP_SRCDIR="$1"
if [ -z "$TOP_SRCDIR" ]; then
echo "usage: $0 path/to/top_srcdir"
exit 1
fi
# make bash exit if any command will exit with non-0 return value
set -e
# make sure the paths are alright
cd `dirname $0`
diff -a -u \
<(cat @top_srcdir@/src/libratbag.sym | \
<(cat "$TOP_SRCDIR"/src/libratbag.sym | \
grep '^\s\+ratbag_.*' | \
sed -e 's/^\s\+\(.*\);/\1/' | sort) \
<(cat @top_srcdir@/src/*.c | \
<(cat "$TOP_SRCDIR"/src/*.c | \
grep LIBRATBAG_EXPORT -A 1 | grep '^ratbag_.*' | \
sed -e 's/(.*//' | sort)

View File

@@ -1,32 +0,0 @@
noinst_PROGRAMS = hidpp10-dump-page hidpp20-dump-page
bin_PROGRAMS = ratbag-command lur-command
noinst_LTLIBRARIES = libshared.la
AM_CPPFLAGS = -I$(top_srcdir)/include \
-I$(top_srcdir)/src \
-I$(top_builddir)/src # for libratbag-version.h
libshared_la_SOURCES = \
shared.c \
shared.h
libshared_la_CFLAGS = $(LIBUDEV_LIBS) $(LIBEVDEV_CFLAGS)
libshared_la_LIBADD = $(LIBUDEV_CFLAGS) $(LIBEVDEV_LIBS)
ratbag_command_SOURCES = ratbag-command.c
ratbag_command_LDADD = ../src/libratbag.la libshared.la $(LIBUDEV_LIBS) $(LIBEVDEV_LIBS)
ratbag_command_CFLAGS = $(LIBUDEV_CFLAGS) $(LIBEVDEV_CFLAGS)
dist_man1_MANS = ratbag-command.man
hidpp10_dump_page_SOURCES = hidpp10-dump-page.c
hidpp10_dump_page_LDADD = ../src/libhidpp.la
hidpp10_dump_page_LDFLAGS = -no-install
hidpp10_dump_page_CFLAGS = -I$(top_srcdir)/src
hidpp20_dump_page_SOURCES = hidpp20-dump-page.c
hidpp20_dump_page_LDADD = ../src/libhidpp.la
hidpp20_dump_page_LDFLAGS = -no-install
hidpp20_dump_page_CFLAGS = -I$(top_srcdir)/src
lur_command_SOURCeS = lur-command.c
lur_command_LDADD = ../src/liblur.la
lur_command_CFLAGS = -I$(top_srcdir)/src

View File

@@ -71,7 +71,7 @@ dump_all_pages(struct hidpp10_device *dev)
return rc;
}
void
static void
usage(void)
{
printf("Usage: %s [page] [offset] /dev/hidraw0\n", program_invocation_short_name);
@@ -80,7 +80,7 @@ usage(void)
int
main(int argc, char **argv)
{
_cleanup_close_ int fd;
_cleanup_close_ int fd = 0;
const char *path;
size_t page = 0, offset = 0;
struct hidpp10_device *dev = NULL;

View File

@@ -83,7 +83,7 @@ dump_everything(struct hidpp20_device *dev)
return dump_all_pages(dev, 1);
}
void
static void
usage(void)
{
printf("Usage: %s [page] [offset] /dev/hidraw0\n", program_invocation_short_name);
@@ -92,7 +92,7 @@ usage(void)
int
main(int argc, char **argv)
{
_cleanup_close_ int fd;
_cleanup_close_ int fd = 0;
const char *path;
size_t page = 0, offset = 0;
struct hidpp20_device *dev = NULL;

View File

@@ -119,7 +119,7 @@ disconnect_device(struct lur_receiver *receiver, int index)
return;
}
if (index >= ndevices) {
if (index < 0 || index >= ndevices) {
fprintf(stderr, "Invalid index %d, only %d devices connected\n",
index, ndevices);
} else {

49
tools/lur-command.man Normal file
View File

@@ -0,0 +1,49 @@
.TH lur\-command 1 "@version@" lur\-command
.SH NAME
lur\-command \- list, pair and unpair Logitech Unifying devices
.SH SYNOPSIS
.B lur\-command find
.br
.B lur\-command list
.RI < device >
.br
.B lur\-command open
.RI < device >
.br
.B lur\-command close
.RI < device >
.br
.B lur\-command disconnect
.RI < index "> <" device >
.SH DESCRIPTION
.SS Common options
.TP
.BR \-h
displays a short help message.
.SS Listing receivers
.TP
.B find
lists all identified receivers on the system (scanning
.BI /dev/hidraw n
devices).
.SS Listing connected devices
.TP
.BR list " <" \fIdevice\fP >
lists the devices connected to the given receiver device.
.SS Pairing devices
.TP
.BR open " <" \fIdevice\fP >
opens the given receiver for pairing, for 30s.
.SS Closing a receiver
.TP
.BR close " <" \fIdevice\fP >
closes the given receiver, if it is currently open for pairing.
.SS Disconnecting a device
.TP
.BR disconnect " <" \fIindex\fP "> <" \fIdevice\fP >
disconnects the device matching the given index from the given
receiver. The index is as determined by the
.B list
command.
.SH SEE ALSO
.BR ratbag\-command (1)

View File

@@ -21,7 +21,8 @@
* DEALINGS IN THE SOFTWARE.
*/
#define _GNU_SOURCE
#include "config.h"
#include <errno.h>
#include <dirent.h>
#include <fcntl.h>
@@ -34,9 +35,11 @@
#include <sys/stat.h>
#include <linux/input.h>
#include "libratbag-version.h"
#include "shared.h"
enum options {
OPT_VERSION,
OPT_VERBOSE,
OPT_HELP,
};
@@ -90,74 +93,74 @@ usage(void)
"Query or change a device's settings:\n"
"\n"
"Options:\n"
" --verbose Print debugging output\n"
" --verbose=raw Print debugging output with protocol output.\n"
" --help Print this help.\n"
" --verbose Print debugging output\n"
" --verbose=raw Print debugging output with protocol output.\n"
" --help Print this help.\n"
"\n"
"General Commands:\n"
" list List supported devices (does not take a device argument)\n"
" list List supported devices (does not take a device argument)\n"
"\n"
"Device Commands:\n"
" info Print information about a device \n"
" info Print information about a device \n"
"\n"
"Profile Commands:\n"
" profile active get Print the currently active profile\n"
" profile active set N Set profile N as to the active profile\n"
" profile active get Print the currently active profile\n"
" profile active set N Set profile N as to the active profile\n"
" profile enable N Enable profile N\n"
" profile disable N Disable profile N\n"
" profile N {COMMAND} Use profile N for COMMAND\n"
" profile N {COMMAND} Use profile N for COMMAND\n"
"\n"
"Resolution Commands\n"
" Resolution commands work on the given profile, or on the\n"
" active profile if none is given.\n"
"\n"
" resolution active get Print the currently active resolution\n"
" resolution active set N Set resolution N as the active resolution\n"
" resolution N {COMMAND} Use resolution N for COMMAND\n"
" resolution active get Print the currently active resolution\n"
" resolution active set N Set resolution N as the active resolution\n"
" resolution N {COMMAND} Use resolution N for COMMAND\n"
"\n"
"DPI Commands:\n"
" DPI commands work on the given profile and resolution, or on the\n"
" active resolution of the active profile if none are given.\n"
"\n"
" dpi get Print the dpi value\n"
" dpi set N Set the dpi value to N\n"
" rate get Print the report rate in Hz\n"
" rate set N Set the report rate in N Hz\n"
" dpi get Print the dpi value\n"
" dpi set N Set the dpi value to N\n"
" rate get Print the report rate in Hz\n"
" rate set N Set the report rate in N Hz\n"
"\n"
"Button Commands:\n"
" Button commands work on the given profile, or on the\n"
" active profile if none is given.\n"
"\n"
" button count Print the number of buttons\n"
" button N action get Print the button action\n"
" button N action set button B Set the button action to button B\n"
" button N action set special S Set the button action to special action S\n"
" button N action set macro ... Set the button action to the given macro \n"
" button count Print the number of buttons\n"
" button N action get Print the button action\n"
" button N action set button B Set the button action to button B\n"
" button N action set special S Set the button action to special action S\n"
" button N action set macro ... Set the button action to the given macro \n"
"\n"
" Macro syntax:\n"
" A macro is a series of key events or waiting periods.\n"
" Keys must be specified in linux/input.h key names.\n"
" KEY_A Press and release 'a'\n"
" +KEY_A Press 'a'\n"
" -KEY_A Release 'a'\n"
" t300 Wait 300ms\n"
"\n"
"Special Commands:\n"
"These commands are for testing purposes and may be removed without notice\n"
"\n"
" switch-etekcity Switch the Etekcity mouse active profile\n"
" A macro is a series of key events or waiting periods.\n"
" Keys must be specified in linux/input.h key names.\n"
" KEY_A Press and release 'a'\n"
" +KEY_A Press 'a'\n"
" -KEY_A Release 'a'\n"
" t300 Wait 300ms\n"
"\n"
"LED Commands:\n"
" LED commands work on the given profile, or on the\n"
" active profile if none is given.\n"
"\n"
" led N {COMMAND}\n"
" get print the LED properties\n"
" set {COMMAND} sets LED properties\n"
" mode [on|off|cycle|breath] sets LED mode\n"
" color COLOR sets LED's color in hex format\n"
" rate N sets LED's effect rate in Hz\n"
" brightness N sets LED's effect brightness\n"
" get print the LED properties\n"
" set {COMMAND} ... sets LED properties (one or more)\n"
" mode [on|off|cycle|breathing] sets LED mode\n"
" color COLOR sets LED's color in hex format\n"
" rate N sets LED's effect rate in Hz\n"
" brightness N sets LED's effect brightness\n"
"\n"
"Special Commands:\n"
"These commands are for testing purposes and may be removed without notice\n"
"\n"
" switch-etekcity Switch the Etekcity mouse active profile\n"
"\n"
"Examples:\n"
" %s profile active get\n"
@@ -170,10 +173,10 @@ usage(void)
" %s profile 0 led 0 set rate 20\n"
"\n"
"Exit codes:\n"
" 0 Success\n"
" 1 Unsupported feature or index out of available range\n"
" 2 Commandline arguments are invalid\n"
" 3 Invalid device or a command failed on the device\n"
" 0 Success\n"
" 1 Unsupported feature or index out of available range\n"
" 2 Commandline arguments are invalid\n"
" 3 Invalid device or a command failed on the device\n"
"\n",
program_invocation_short_name,
program_invocation_short_name,
@@ -186,6 +189,12 @@ usage(void)
program_invocation_short_name);
}
static void
version(void)
{
printf("%s\n", LIBRATBAG_VERSION);
}
static inline int
ratbag_cmd_device_from_arg(struct ratbag *ratbag,
int *argc, char **argv,
@@ -216,9 +225,8 @@ static inline struct ratbag_profile *
ratbag_cmd_get_active_profile(struct ratbag_device *device)
{
struct ratbag_profile *profile = NULL;
int i;
for (i = 0; i < ratbag_device_get_num_profiles(device); i++) {
for (unsigned int i = 0; i < ratbag_device_get_num_profiles(device); i++) {
profile = ratbag_device_get_profile(device, i);
if (ratbag_profile_is_active(profile))
return profile;
@@ -237,9 +245,8 @@ static inline struct ratbag_resolution *
ratbag_cmd_get_active_resolution(struct ratbag_profile *profile)
{
struct ratbag_resolution *resolution = NULL;
int i;
for (i = 0; i < ratbag_profile_get_num_resolutions(profile); i++) {
for (unsigned int i = 0; i < ratbag_profile_get_num_resolutions(profile); i++) {
resolution = ratbag_profile_get_resolution(profile, i);
if (ratbag_resolution_is_active(resolution))
return resolution;
@@ -266,7 +273,7 @@ fill_options(struct ratbag *ratbag,
struct ratbag_button *button = options->button;
int rc;
if ((flags & (FLAG_NEED_DEVICE|FLAG_NEED_PROFILE|FLAG_NEED_RESOLUTION)) &&
if ((flags & (FLAG_NEED_DEVICE|FLAG_NEED_PROFILE|FLAG_NEED_RESOLUTION|FLAG_NEED_LED)) &&
device == NULL) {
rc = ratbag_cmd_device_from_arg(ratbag, argc, argv,
&device);
@@ -275,7 +282,7 @@ fill_options(struct ratbag *ratbag,
options->device = device;
}
if ((flags & (FLAG_NEED_PROFILE|FLAG_NEED_RESOLUTION)) &&
if ((flags & (FLAG_NEED_PROFILE|FLAG_NEED_RESOLUTION|FLAG_NEED_LED)) &&
profile == NULL) {
profile = ratbag_cmd_get_active_profile(device);
if (!profile)
@@ -329,6 +336,55 @@ run_subcommand(const char *command,
return ERR_USAGE;
}
static int
ratbag_printf_led(struct ratbag_led *led, const char *prefix_format, ...)
{
va_list arg;
enum ratbag_led_mode mode;
struct ratbag_color color;
int hz;
int brightness;
enum ratbag_led_type type;
type = ratbag_led_get_type(led);
mode = ratbag_led_get_mode(led);
color = ratbag_led_get_color(led);
hz = ratbag_led_get_effect_rate(led);
brightness = ratbag_led_get_brightness(led);
va_start(arg, prefix_format);
vprintf(prefix_format, arg);
va_end(arg);
switch (mode) {
case RATBAG_LED_OFF:
printf("type: %s, mode: %s\n",
led_type_to_str(type),
led_mode_to_str(mode));
break;
case RATBAG_LED_ON:
printf("type: %s, mode: %s, color: %02x%02x%02x\n",
led_type_to_str(type),
led_mode_to_str(mode),
color.red, color.green, color.blue);
break;
case RATBAG_LED_CYCLE:
printf("type: %s, mode: %s, rate: %d, brightness: %d\n",
led_type_to_str(type),
led_mode_to_str(mode),
hz, brightness);
break;
case RATBAG_LED_BREATHING:
printf("type: %s, mode: %s, color: %02x%02x%02x, rate: %d, brightness: %d\n",
led_type_to_str(type),
led_mode_to_str(mode),
color.red, color.green, color.blue,
hz, brightness);
break;
}
return SUCCESS;
}
static int
ratbag_cmd_info(const struct ratbag_cmd *cmd,
struct ratbag *ratbag,
@@ -341,8 +397,7 @@ ratbag_cmd_info(const struct ratbag_cmd *cmd,
struct ratbag_led *led;
char *action;
int num_profiles, num_buttons, num_leds;
int i, j, b, l;
struct ratbag_color color;
int b, l;
device = options->device;
@@ -375,7 +430,7 @@ ratbag_cmd_info(const struct ratbag_cmd *cmd,
num_profiles = ratbag_device_get_num_profiles(device);
printf("Profiles supported: %d\n", num_profiles);
for (i = 0; i < num_profiles; i++) {
for (int i = 0; i < num_profiles; i++) {
int dpi, rate;
profile = ratbag_device_get_profile(device, i);
if (!profile)
@@ -385,7 +440,7 @@ ratbag_cmd_info(const struct ratbag_cmd *cmd,
ratbag_profile_is_enabled(profile) ? "enabled" : "disabled",
ratbag_profile_is_active(profile) ? " (active)" : "");
printf(" Resolutions:\n");
for (j = 0; j < ratbag_profile_get_num_resolutions(profile); j++) {
for (unsigned int j = 0; j < ratbag_profile_get_num_resolutions(profile); j++) {
struct ratbag_resolution *res;
res = ratbag_profile_get_resolution(profile, j);
@@ -423,20 +478,11 @@ ratbag_cmd_info(const struct ratbag_cmd *cmd,
for (l = 0; l < num_leds; l++) {
led = ratbag_profile_get_led(profile, l);
color = ratbag_led_get_color(led);
printf(" LED: %d type %s mode %s color %02x%02x%02x rate %d brightness: %d\n",
l,
led_type_to_str(ratbag_led_get_type(led)),
led_mode_to_str(ratbag_led_get_mode(led)),
color.red, color.green, color.blue,
ratbag_led_get_effect_rate(led),
ratbag_led_get_brightness(led));
ratbag_printf_led(led, " LED: %d ", l);
led = ratbag_led_unref(led);
}
profile = ratbag_profile_unref(profile);
ratbag_profile_unref(profile);
}
return SUCCESS;
@@ -518,7 +564,7 @@ str_to_macro(const char *action_arg, struct macro *m)
char *str, *s;
enum ratbag_macro_event_type type;
int code;
int idx = 0;
unsigned int idx = 0;
int rc = ERR_USAGE;
/* FIXME: handle per-device maximum lengths of macros */
@@ -606,10 +652,9 @@ ratbag_cmd_change_button(const struct ratbag_cmd *cmd,
int button_index;
enum ratbag_button_action_type action_type;
int rc = ERR_DEVICE;
unsigned int btnkey;
unsigned int btnkey = 0;
enum ratbag_button_action_special special;
struct macro macro = {0};
int i;
if (argc != 3)
return ERR_USAGE;
@@ -678,7 +723,7 @@ ratbag_cmd_change_button(const struct ratbag_cmd *cmd,
break;
case RATBAG_BUTTON_ACTION_TYPE_MACRO:
m = ratbag_button_macro_new(macro.name);
for (i = 0; i < ARRAY_LENGTH(macro.events); i++) {
for (size_t i = 0; i < ARRAY_LENGTH(macro.events); i++) {
if (macro.events[i].type == RATBAG_MACRO_EVENT_NONE)
break;
@@ -757,7 +802,7 @@ ratbag_cmd_list_supported_devices(const struct ratbag_cmd *cmd,
device = ratbag_cmd_open_device(ratbag, path);
if (device) {
printf("%s:\t%s\n", path, ratbag_device_get_name(device));
device = ratbag_device_unref(device);
ratbag_device_unref(device);
supported++;
}
free(input_list[i]);
@@ -1316,13 +1361,12 @@ ratbag_cmd_button_set_macro(const struct ratbag_cmd *cmd,
struct ratbag_button_macro *m;
struct macro macro = {0};
int rc;
int i;
char macro_str[PATH_MAX] = {0};
if (argc < 1)
return ERR_USAGE;
for (i = 0; i < argc; i++) {
for (int i = 0; i < argc; i++) {
strncat(macro_str, argv[i], sizeof(macro_str) - strlen(macro_str) - 1);
strcat(macro_str, " ");
}
@@ -1339,7 +1383,7 @@ ratbag_cmd_button_set_macro(const struct ratbag_cmd *cmd,
button = options->button;
m = ratbag_button_macro_new(macro.name);
for (i = 0; i < ARRAY_LENGTH(macro.events); i++) {
for (size_t i = 0; i < ARRAY_LENGTH(macro.events); i++) {
if (macro.events[i].type == RATBAG_MACRO_EVENT_NONE)
break;
@@ -1483,10 +1527,8 @@ ratbag_cmd_led_set_brightness(const struct ratbag_cmd *cmd,
struct ratbag_cmd_options *options,
int argc, char **argv)
{
struct ratbag_device *device;
struct ratbag_led *led;
char *str, *endptr;
int brightness, b;
int brightness;
int rc;
if (argc < 1)
@@ -1495,20 +1537,27 @@ ratbag_cmd_led_set_brightness(const struct ratbag_cmd *cmd,
led = options->led;
brightness = atoi(argv[0]);
device = options->device;
rc = ratbag_led_set_brightness(led, brightness);
if (rc != 0)
return ERR_DEVICE;
return SUCCESS;
if (argc == 1)
return SUCCESS;
return run_subcommand(argv[1], cmd, ratbag, options,
argc - 1, argv + 1);
}
static const struct ratbag_cmd cmd_led_set_color;
static const struct ratbag_cmd cmd_led_set_effect_rate;
static const struct ratbag_cmd cmd_led_set_brightness = {
.name = "brightness",
.cmd = ratbag_cmd_led_set_brightness,
.flags = FLAG_NEED_DEVICE | FLAG_NEED_PROFILE | FLAG_NEED_LED,
.subcommands = {
&cmd_led_set_color,
&cmd_led_set_effect_rate,
NULL,
},
};
@@ -1520,10 +1569,9 @@ ratbag_cmd_led_set_effect_rate(const struct ratbag_cmd *cmd,
int argc, char **argv)
{
struct ratbag_device *device;
struct ratbag_led *led;
char *str, *endptr;
int hz, b;
int hz;
int rc;
if (argc < 1)
@@ -1539,7 +1587,11 @@ ratbag_cmd_led_set_effect_rate(const struct ratbag_cmd *cmd,
if (rc != 0)
return ERR_DEVICE;
return SUCCESS;
if (argc == 1)
return SUCCESS;
return run_subcommand(argv[1], cmd, ratbag, options,
argc - 1, argv + 1);
}
static const struct ratbag_cmd cmd_led_set_effect_rate = {
@@ -1547,6 +1599,8 @@ static const struct ratbag_cmd cmd_led_set_effect_rate = {
.cmd = ratbag_cmd_led_set_effect_rate,
.flags = FLAG_NEED_DEVICE | FLAG_NEED_PROFILE | FLAG_NEED_LED,
.subcommands = {
&cmd_led_set_color,
&cmd_led_set_brightness,
NULL,
},
};
@@ -1557,12 +1611,10 @@ ratbag_cmd_led_set_color(const struct ratbag_cmd *cmd,
struct ratbag_cmd_options *options,
int argc, char **argv)
{
struct ratbag_device *device;
struct ratbag_led *led;
struct ratbag_color color;
char *str, *endptr;
int rc;
char red[2], green[2], blue[2];
char red[3], green[3], blue[3];
char *p;
if (argc < 1)
@@ -1570,7 +1622,7 @@ ratbag_cmd_led_set_color(const struct ratbag_cmd *cmd,
led = options->led;
sscanf(argv[0], "%2s%2s%2s", &red, &green, &blue);
sscanf(argv[0], "%2s%2s%2s", red, green, blue);
color.red = strtoul(red, &p, 16);
color.green = strtoul(green, &p, 16);
@@ -1580,7 +1632,11 @@ ratbag_cmd_led_set_color(const struct ratbag_cmd *cmd,
if (rc != 0)
return ERR_DEVICE;
return SUCCESS;
if (argc == 1)
return SUCCESS;
return run_subcommand(argv[1], cmd, ratbag, options,
argc - 1, argv + 1);
}
static const struct ratbag_cmd cmd_led_set_color = {
@@ -1588,6 +1644,8 @@ static const struct ratbag_cmd cmd_led_set_color = {
.cmd = ratbag_cmd_led_set_color,
.flags = FLAG_NEED_DEVICE | FLAG_NEED_PROFILE | FLAG_NEED_LED,
.subcommands = {
&cmd_led_set_effect_rate,
&cmd_led_set_brightness,
NULL,
},
};
@@ -1598,10 +1656,10 @@ ratbag_cmd_led_set_mode(const struct ratbag_cmd *cmd,
struct ratbag_cmd_options *options,
int argc, char **argv)
{
struct ratbag_device *device;
struct ratbag_led *led;
struct ratbag_color color;
char *str, *endptr;
enum ratbag_led_mode mode;
char *str;
int rc;
if (argc < 1)
@@ -1610,8 +1668,6 @@ ratbag_cmd_led_set_mode(const struct ratbag_cmd *cmd,
led = options->led;
str = argv[0];
enum ratbag_led_mode mode;
if (streq(str, "off"))
mode = RATBAG_LED_OFF;
else if (streq(str, "on"))
@@ -1637,13 +1693,20 @@ ratbag_cmd_led_set_mode(const struct ratbag_cmd *cmd,
case RATBAG_LED_BREATHING:
ratbag_led_set_effect_rate(led, 20);
ratbag_led_set_brightness(led, 100);
break;
case RATBAG_LED_OFF:
break;
}
rc = ratbag_led_set_mode(led, mode);
if (rc != 0)
return ERR_DEVICE;
return SUCCESS;
if (argc == 1)
return SUCCESS;
return run_subcommand(argv[1], cmd, ratbag, options,
argc - 1, argv + 1);
}
static const struct ratbag_cmd cmd_led_set_mode = {
@@ -1651,6 +1714,9 @@ static const struct ratbag_cmd cmd_led_set_mode = {
.cmd = ratbag_cmd_led_set_mode,
.flags = FLAG_NEED_DEVICE | FLAG_NEED_PROFILE | FLAG_NEED_LED,
.subcommands = {
&cmd_led_set_color,
&cmd_led_set_effect_rate,
&cmd_led_set_brightness,
NULL,
},
};
@@ -1687,25 +1753,9 @@ ratbag_cmd_led_get(const struct ratbag_cmd *cmd,
struct ratbag_cmd_options *options,
int argc, char **argv)
{
struct ratbag_led *led;
enum ratbag_led_mode mode;
struct ratbag_color color;
int hz;
int brightness;
enum ratbag_led_type type;
struct ratbag_led *led = options->led;
led = options->led;
type = ratbag_led_get_type(led);
mode = ratbag_led_get_mode(led);
color = ratbag_led_get_color(led);
hz = ratbag_led_get_effect_rate(led);
brightness = ratbag_led_get_brightness(led);
printf("type: %s, mode: %s, color: %02x%02x%02x, rate: %d, brightness: %d\n",
led_type_to_str(type),
led_mode_to_str(mode),
color.red, color.green, color.blue,
hz, brightness);
ratbag_printf_led(led, "");
return SUCCESS;
}
@@ -2020,6 +2070,7 @@ static const struct ratbag_cmd top_level_commands = {
&cmd_profile,
&cmd_resolution_dpi,
&cmd_resolution_rate,
&cmd_led,
NULL,
},
};
@@ -2047,8 +2098,10 @@ main(int argc, char **argv)
int c;
int option_index = 0;
static struct option opts[] = {
{ "verbose", 2, 0, OPT_VERBOSE },
{ "help", 0, 0, OPT_HELP },
{ "verbose", optional_argument, 0, OPT_VERBOSE },
{ "version", no_argument, 0, OPT_VERSION },
{ "help", no_argument, 0, OPT_HELP },
{ 0, 0, 0, 0 },
};
c = getopt_long(argc, argv, "+h", opts, &option_index);
@@ -2059,6 +2112,9 @@ main(int argc, char **argv)
case OPT_HELP:
usage();
goto out;
case OPT_VERSION:
version();
goto out;
case OPT_VERBOSE:
if (optarg && streq(optarg, "raw"))
options.flags |= FLAG_VERBOSE_RAW;

View File

@@ -1,26 +1,29 @@
.TH RATBAG_COMMAND "1"
.TH RATBAG_COMMAND "1" "@version@"
.SH NAME
ratbag-command \- Query or change a device's settings
ratbag\-command \- query or change a device's settings
.SH SYNOPSIS
.B ratbag-command [OPTIONS] {COMMAND} ... /path/to/device
.B ratbag\-command [OPTIONS] {COMMAND} ... /path/to/device
.SH DESCRIPTION
.PP
The
.I ratbag-commandq
tool query or change a device's settings.
.I ratbag\-command
tool queries or changes a device's settings.
.PP
This tool usually needs to be run as root to have access to the
/dev/input/eventX nodes.
.SH OPTIONS
.TP 8
.B --verbose
Print debugging output
.B \-\-verbose
Print debugging output.
.TP 8
.B --verbose=raw
.B \-\-verbose=raw
Print debugging output with protocol output. No guarantees are given regarding
the output format when this flag is on.
.TP 8
.B --help
.B \-\-version
Print the tool's version.
.TP 8
.B \-\-help
Print the help.
.SH General Commands
.TP 8
@@ -98,7 +101,7 @@ Press and release 'a'
.B +KEY_A
Press 'a'
.TP 8
.B -KEY_A
.B \-KEY_A
Release 'a'
.TP 8
.B t300
@@ -107,19 +110,19 @@ Wait 300ms
.SH Special Commands
These commands are for testing purposes and may be removed without notice
.TP 8
.B switch-etekcity
.B switch\-etekcity
Switch the Etekcity mouse active profile
.SH Examples
.TP 8
ratbag-command profile active get
ratbag\-command profile active get
.TP 8
ratbag-command profile 0 resolution active set 4
ratbag\-command profile 0 resolution active set 4
.TP 8
ratbag-command profile 0 resolution 1 dpi get
ratbag\-command profile 0 resolution 1 dpi get
.TP 8
ratbag-command resolution 4 rate get
ratbag\-command resolution 4 rate get
.TP 8
ratbag-command dpi set 800
ratbag\-command dpi set 800
.SH Exit codes
.TP 8
.B 0
@@ -136,6 +139,6 @@ Invalid device or a command failed on the device
.SH NOTES
.PP
There is currently no guarantees that the output format of
.B ratbag-command
.B ratbag\-command
will not change in the future. There should be some stability with the commands
mentioned in this man page, but do not expect it to stay the same.

View File

@@ -83,7 +83,7 @@ led_mode_to_str(enum ratbag_led_mode mode)
str = "cycle";
break;
case RATBAG_LED_BREATHING:
str = "breath";
str = "breathing";
break;
}
@@ -129,7 +129,7 @@ button_type_to_str(enum ratbag_button_type type)
return str;
}
const static struct map {
static const struct map {
enum ratbag_button_action_special special;
const char *str;
} special_map[] = {

View File

@@ -21,6 +21,8 @@
* DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include "config.h"
#include <errno.h>