Compare commits
175 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5443083b1d | ||
|
|
cc19496699 | ||
|
|
b595691c5e | ||
|
|
7d784a1a91 | ||
|
|
a664042f64 | ||
|
|
5bc4470a8c | ||
|
|
b8ed1ea3a4 | ||
|
|
f2ad49cf20 | ||
|
|
fd6a9e73ed | ||
|
|
db57a8e7b6 | ||
|
|
2a35bf009f | ||
|
|
42d49d74ab | ||
|
|
a9f34249fc | ||
|
|
1ce59bcc1f | ||
|
|
bb35821c45 | ||
|
|
bbec42c426 | ||
|
|
cb487a6d1a | ||
|
|
7fdcf62bf2 | ||
|
|
f82c1119bf | ||
|
|
f60f8a12ab | ||
|
|
fd348d456d | ||
|
|
0f73a97bc8 | ||
|
|
7783f50110 | ||
|
|
b85fcd0cee | ||
|
|
3c879b7389 | ||
|
|
44e7bc1c23 | ||
|
|
0bcaeaeb33 | ||
|
|
da60f0748c | ||
|
|
5418392143 | ||
|
|
6c18b16a00 | ||
|
|
8e5ad717c4 | ||
|
|
1ff263f0a4 | ||
|
|
e9f0ca4385 | ||
|
|
079b67f111 | ||
|
|
a224ef6d0b | ||
|
|
0c0a6d39cb | ||
|
|
3439058a54 | ||
|
|
6414f7901f | ||
|
|
4d6390ea66 | ||
|
|
3f83d5057d | ||
|
|
67f1c00181 | ||
|
|
c4013ca4b0 | ||
|
|
25294d9a63 | ||
|
|
7d241642f9 | ||
|
|
d1e42ac56c | ||
|
|
45129b2bc8 | ||
|
|
0568b4c39d | ||
|
|
5b152a6c3f | ||
|
|
52d4e35192 | ||
|
|
a1a3750bc8 | ||
|
|
3cfda944d0 | ||
|
|
852fc2da2d | ||
|
|
adefb2921b | ||
|
|
27a141fd87 | ||
|
|
2b63ca4935 | ||
|
|
107d7e652f | ||
|
|
7e8d40b57a | ||
|
|
6c40b18229 | ||
|
|
9d51d70f70 | ||
|
|
96a9a0f6a4 | ||
|
|
31b513e6d7 | ||
|
|
d831d6e515 | ||
|
|
89de42ad8e | ||
|
|
01fcef9b9d | ||
|
|
2bcacfc1ac | ||
|
|
1e2edefd93 | ||
|
|
3aabba255d | ||
|
|
e543723856 | ||
|
|
eb8e4bbfa8 | ||
|
|
821e2798b9 | ||
|
|
3a0dc8f8a5 | ||
|
|
f75152f074 | ||
|
|
f72c96914b | ||
|
|
23036eec08 | ||
|
|
045a46aa9d | ||
|
|
01876023bb | ||
|
|
e2ae29efdc | ||
|
|
f67389c017 | ||
|
|
20a57b76a8 | ||
|
|
d54d77c395 | ||
|
|
a8897ca8ca | ||
|
|
4e62a3bdd9 | ||
|
|
d8a60eca94 | ||
|
|
9aa2120c7d | ||
|
|
f7e3f51b54 | ||
|
|
aef7b3e9bb | ||
|
|
21d0219809 | ||
|
|
3cf59af3e9 | ||
|
|
28438e638b | ||
|
|
c1bf3be48e | ||
|
|
27293a22df | ||
|
|
fc07672983 | ||
|
|
c14a0ca2a1 | ||
|
|
64037febdc | ||
|
|
fd10ebbc87 | ||
|
|
91eefb9a3f | ||
|
|
1da0180e0f | ||
|
|
22abddc9d4 | ||
|
|
e912f56c26 | ||
|
|
a715679f1f | ||
|
|
55673442f1 | ||
|
|
b6294d4f93 | ||
|
|
40112e6061 | ||
|
|
0785bf138d | ||
|
|
e18e25d685 | ||
|
|
85fdea19c2 | ||
|
|
792b6c28df | ||
|
|
5c68164d48 | ||
|
|
b1d99a744b | ||
|
|
9f544cbe1c | ||
|
|
ad06d29140 | ||
|
|
c12cb66824 | ||
|
|
c476cd0654 | ||
|
|
98315343b0 | ||
|
|
eb6787181d | ||
|
|
f7d9ca63e2 | ||
|
|
b563467164 | ||
|
|
86e9a7abcd | ||
|
|
030eaa7c1c | ||
|
|
ae129fe911 | ||
|
|
6190f0c7bf | ||
|
|
717505daef | ||
|
|
8ede0b734f | ||
|
|
090851fce1 | ||
|
|
164232bbbc | ||
|
|
4054616190 | ||
|
|
578142964d | ||
|
|
37bd43511b | ||
|
|
b53981c439 | ||
|
|
bf8442a250 | ||
|
|
198523fe8f | ||
|
|
7f7507a0dd | ||
|
|
a08c8ebc60 | ||
|
|
aa76cb5005 | ||
|
|
be008cd86c | ||
|
|
6f9aa5aa24 | ||
|
|
bfe6d446ad | ||
|
|
855a6bd831 | ||
|
|
f5ff267c54 | ||
|
|
014c4105f4 | ||
|
|
52fea6f3ce | ||
|
|
43ab3c961e | ||
|
|
f7523f000e | ||
|
|
765ee6c08c | ||
|
|
577a7c52fc | ||
|
|
85acab4642 | ||
|
|
0b5ccfeaed | ||
|
|
f108ffa9ff | ||
|
|
f233b6bf77 | ||
|
|
c95d8e05ca | ||
|
|
b3237fd001 | ||
|
|
7704c102e4 | ||
|
|
55cb7447f9 | ||
|
|
77eaa70f77 | ||
|
|
70d864af09 | ||
|
|
15968c8e39 | ||
|
|
0558bd4101 | ||
|
|
3962ec7745 | ||
|
|
2164a3b549 | ||
|
|
f0417a9535 | ||
|
|
9d9c42cc6a | ||
|
|
efd15a33fb | ||
|
|
b804e117c1 | ||
|
|
b54d28ec1a | ||
|
|
388dae76bc | ||
|
|
19f87790bb | ||
|
|
9aa8938eb8 | ||
|
|
25094daaed | ||
|
|
39069623f2 | ||
|
|
d5c74682f1 | ||
|
|
6cba2abd8e | ||
|
|
f58b91a9b2 | ||
|
|
de08323609 | ||
|
|
5fcdfab2a6 | ||
|
|
e07839bcee |
2
.gitignore
vendored
@@ -36,12 +36,12 @@ 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
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
SUBDIRS = src doc test tools hwdb data
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||
|
||||
valgrind:
|
||||
(cd test; $(MAKE) valgrind)
|
||||
33
README.md
@@ -1,5 +1,3 @@
|
||||
/*!@mainpage
|
||||
|
||||
libratbag
|
||||
=========
|
||||
|
||||
@@ -7,6 +5,13 @@ libratbag is a configuration library for gaming mice. It provides a generic
|
||||
way to access the various features exposed by these mice and abstracts away
|
||||
hardware-specific and kernel-specific quirks.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
API documentation is available here:
|
||||
|
||||
http://libratbag.github.io/libratbag/
|
||||
|
||||
Architecture
|
||||
------------
|
||||
|
||||
@@ -60,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
|
||||
----
|
||||
|
||||
@@ -93,5 +120,3 @@ libratbag is licensed under the MIT license.
|
||||
See the COPYING file for the full license information.
|
||||
|
||||
[](https://semaphoreci.com/libratbag/libratbag)
|
||||
|
||||
*/
|
||||
|
||||
161
configure.ac
@@ -1,161 +0,0 @@
|
||||
AC_PREREQ([2.64])
|
||||
|
||||
m4_define([libratbag_major_version], [0])
|
||||
m4_define([libratbag_minor_version], [2])
|
||||
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 string should be
|
||||
# modified.
|
||||
# The string is 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=1:0:0
|
||||
AC_SUBST(LIBRATBAG_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="/usr/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
|
||||
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}
|
||||
])
|
||||
@@ -1,2 +0,0 @@
|
||||
libratbagdatadir = $(datadir)/libratbag
|
||||
dist_libratbagdata_DATA = $(shell find $(top_srcdir)/data -name "*.svg" -printf "%P\n")
|
||||
26
data/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
libratbag data files
|
||||
====================
|
||||
|
||||
These SVG files should approximate the device to make it immediately
|
||||
recognizable. Detail work not required, the graphic is an illustration only.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
- Canvas size: 750x750 pixels
|
||||
- Two layers in the final SVG: a lower layer named "Device" with the device
|
||||
itself, "Leaders" with the buttons and leader-lines
|
||||
- The device should be approximately centered on the canvas and occupy a
|
||||
meaningful portion of the canvas without making it look cramped
|
||||
- Button labels must be in 12pt Sans, starting with Button0
|
||||
- Wheel buttons may be labeled separately if required (look at the Etekcity
|
||||
for an example)
|
||||
|
||||
Technique
|
||||
---------
|
||||
|
||||
The simplest approach is to find a photo of the device and import it into
|
||||
inkscape. Put it on the lowest layer, create a new layer "Device" above it
|
||||
and start tracing the outlines and edges of the device. Fill in the shapes
|
||||
and your device should resemble the underlying photo. Delete the photo
|
||||
layer, add leaders and button labels and you're done.
|
||||
@@ -10,12 +10,12 @@
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="414.6424mm"
|
||||
height="285.98199mm"
|
||||
viewBox="0 0 1469.2054 1013.322"
|
||||
width="750"
|
||||
height="750"
|
||||
viewBox="0 0 750.00005 750"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="etekcity.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@@ -46,19 +46,9 @@
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4449"
|
||||
id="linearGradient4562"
|
||||
id="linearGradient3237"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.698701,0,0,1.698701,340.78058,475.26804)"
|
||||
x1="31.968746"
|
||||
y1="18.546629"
|
||||
x2="31.968746"
|
||||
y2="29.577879" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4449"
|
||||
id="linearGradient4215"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.698701,0,0,1.698701,111.54723,131.64433)"
|
||||
gradientTransform="matrix(1.344964,0,0,1.344964,-138.13637,564.60502)"
|
||||
x1="31.968746"
|
||||
y1="18.546629"
|
||||
x2="31.968746"
|
||||
@@ -66,13 +56,43 @@
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4336"
|
||||
id="linearGradient4219"
|
||||
id="linearGradient3889"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.79176032,0,0,0.79176032,-529.7793,277.79557)"
|
||||
x1="97.085503"
|
||||
y1="74.08123"
|
||||
x2="95.471596"
|
||||
y2="200.83122"
|
||||
gradientTransform="translate(0,85.407996)" />
|
||||
y2="200.83122" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4449"
|
||||
id="linearGradient3891"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.344964,0,0,1.344964,-441.46063,314.40367)"
|
||||
x1="31.968746"
|
||||
y1="18.546629"
|
||||
x2="31.968746"
|
||||
y2="29.577879" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4336"
|
||||
id="linearGradient3921"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.79176032,0,0,0.79176032,-529.7793,277.79557)"
|
||||
x1="97.085503"
|
||||
y1="74.08123"
|
||||
x2="95.471596"
|
||||
y2="200.83122" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4449"
|
||||
id="linearGradient3923"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.344964,0,0,1.344964,-441.46063,314.40367)"
|
||||
x1="31.968746"
|
||||
y1="18.546629"
|
||||
x2="31.968746"
|
||||
y2="29.577879" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
@@ -81,11 +101,11 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.67909341"
|
||||
inkscape:cx="650.93837"
|
||||
inkscape:cy="527.80453"
|
||||
inkscape:zoom="0.96038311"
|
||||
inkscape:cx="377.27056"
|
||||
inkscape:cy="338.13614"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer6"
|
||||
inkscape:current-layer="layer4"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
@@ -94,9 +114,9 @@
|
||||
fit-margin-right="50"
|
||||
fit-margin-bottom="50"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1016"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-height="1099"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="28"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@@ -111,443 +131,352 @@
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Mouse"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(522.78594,97.359194)"
|
||||
id="layer5"
|
||||
inkscape:label="Device"
|
||||
transform="translate(647.36582,-57.672087)"
|
||||
style="display:inline">
|
||||
<g
|
||||
id="g4271"
|
||||
style="fill:#000000;fill-opacity:1;stroke:none"
|
||||
transform="translate(0,85.407996)">
|
||||
id="g3893"
|
||||
transform="translate(121.82639,-21.866275)">
|
||||
<g
|
||||
transform="matrix(0.79176032,0,0,0.79176032,-628.41671,192.05523)"
|
||||
style="fill:#000000;fill-opacity:1;stroke:none;display:inline"
|
||||
id="g4271">
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="m 421.23361,409.14757 c 4.4349,4.09496 9.16721,10.86185 32.57742,27.27412 4.08118,24.47294 2.40765,48.35999 1.01015,67.42768 -1.3975,19.06769 -9.52288,85.7367 -30.55711,85.7367 l -41.92133,-6.18719 8.9651,-171.72593 32.38801,-150.26019 27.05315,-2.27284 -2.70689,27.21098 -26.19294,53.47495 z"
|
||||
id="path4249"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cczcccccccc" />
|
||||
<use
|
||||
style="fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#path4249"
|
||||
id="use4266"
|
||||
transform="matrix(-1,0,0,1,580.95786,0)"
|
||||
width="1469.2054"
|
||||
height="1013.322" />
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="cczcccccccc"
|
||||
sodipodi:nodetypes="cccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4249"
|
||||
d="m 421.23361,409.14757 c 4.4349,4.09496 9.16721,10.86185 32.57742,27.27412 4.08118,24.47294 2.40765,48.35999 1.01015,67.42768 -1.3975,19.06769 -9.52288,85.7367 -30.55711,85.7367 l -41.92133,-6.18719 8.9651,-171.72593 32.38801,-150.26019 27.05315,-2.27284 -2.70689,27.21098 -26.19294,53.47495 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
id="path4251"
|
||||
d="m -268.43146,403.53037 c -1.07689,19.01234 -1.64984,38.40264 -3.69907,56.68573 -2.36798,4.75208 -4.96718,7.8857 -7.59809,10.79728 l -13.59657,0 5.59859,-67.18309 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4253"
|
||||
d="m -281.12826,473.7127 -0.29993,6.19844 7.09822,5.79854 -2.19945,30.1924 -8.99773,9.59758 -0.29993,28.99271 -2.3994,3.59909 -14.59632,0 0,-84.47873 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
|
||||
<use
|
||||
height="100%"
|
||||
width="100%"
|
||||
transform="matrix(-1,0,0,1,580.95786,0)"
|
||||
id="use4266"
|
||||
xlink:href="#path4249"
|
||||
height="1013.322"
|
||||
width="1469.2054"
|
||||
transform="matrix(-1,0,0,1,-698.21665,-85.740335)"
|
||||
id="use4275"
|
||||
xlink:href="#path4251"
|
||||
y="0"
|
||||
x="0"
|
||||
style="fill:#000000;fill-opacity:1;stroke:none" />
|
||||
style="display:inline" />
|
||||
<ellipse
|
||||
sodipodi:ry="36.875"
|
||||
sodipodi:rx="57.5"
|
||||
sodipodi:cy="231.07376"
|
||||
sodipodi:cx="290.47894"
|
||||
d="m 347.97894,231.07376 c 0,20.3655 -25.74362,36.875 -57.5,36.875 -31.75637,0 -57.5,-16.5095 -57.5,-36.875 0,-20.3655 25.74363,-36.875 57.5,-36.875 31.75638,0 57.5,16.5095 57.5,36.875 z"
|
||||
ry="36.875"
|
||||
rx="57.5"
|
||||
cy="231.07376"
|
||||
cx="290.47894"
|
||||
id="path4243"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#ff0000;stroke-width:1.26300848;stroke-opacity:1;display:inline"
|
||||
transform="matrix(0.79176032,0,0,0.79176032,-628.41671,124.43258)" />
|
||||
<use
|
||||
height="1013.322"
|
||||
width="1469.2054"
|
||||
transform="matrix(-1,0,0,1,-698.21665,-85.740335)"
|
||||
id="use4277"
|
||||
xlink:href="#path4253"
|
||||
y="0"
|
||||
x="0"
|
||||
style="display:inline" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccscccccccccccccccccscccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3441"
|
||||
d="m -401.08313,328.79009 0.26444,-40.70143 c -39.18883,7.37119 -44.1411,4.0242 -51.69484,0.84743 -19.57977,14.34842 -45.06471,30.13362 -73.61979,38.63234 -2.47282,19.58198 -2.71663,46.75085 -2.09075,66.56663 19.0204,10.56139 17.6053,33.92046 19.25741,48.34377 1.65211,14.4233 7.20626,94.24576 7.20626,94.24576 l -2.59797,21.72393 23.30745,43.04888 c -0.16213,7.00604 -0.46719,14.87323 -3.03251,37.40758 -7.15647,2.04323 -13.81042,1.56652 -20.02442,-1.10259 0.0912,10.91499 -0.68305,21.82736 0.56908,32.68021 11.24444,13.4205 16.39645,27.09393 56.20571,56.18715 l 6.498,11.63207 c 13.0739,7.46592 23.16933,11.65186 42.40866,14.95221 19.23933,-3.30035 29.33476,-7.48629 42.40866,-14.95221 l 6.498,-11.63207 c 39.80926,-29.09322 44.96127,-42.76665 56.2057,-56.18715 1.25213,-10.85285 0.47635,-21.76522 0.56754,-32.68021 -6.214,2.66911 -12.86641,3.14582 -20.02288,1.10259 -2.56532,-22.53435 -2.87037,-30.40154 -3.0325,-37.40758 l 23.3059,-43.04888 -2.59642,-21.72393 c 0,0 5.55415,-79.82246 7.20625,-94.24576 1.65211,-14.42331 0.23546,-37.78238 19.25586,-48.34377 0.62589,-19.81578 0.38362,-46.98465 -2.08919,-66.56663 -28.55509,-8.49872 -54.04157,-24.28392 -73.62134,-38.63234 -7.55373,3.17677 -12.50447,6.52376 -51.69329,-0.84743 l 0.26444,40.70143 z"
|
||||
style="fill:#282828;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4289"
|
||||
d="m -398.45459,328.52925 0,117.85034"
|
||||
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4247"
|
||||
d="m -390.51793,495.35976 13.14911,20.077 24.31724,0 -19.22802,-64.1898 -26.14665,-13.56354 -26.14819,13.56354 -19.22802,64.1898 24.31879,0 13.14909,-20.077 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
|
||||
<rect
|
||||
ry="3.2500002"
|
||||
rx="3.2500002"
|
||||
y="334.18024"
|
||||
x="-410.93967"
|
||||
height="59.523411"
|
||||
width="25.025282"
|
||||
id="rect4245"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#ff0000;stroke-width:1;stroke-opacity:1;display:inline" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4311"
|
||||
d="m -408.76059,297.49061 c -14.10207,2.39851 -28.95919,4.88556 -42.94836,0.51186 -20.52977,14.9081 -42.9383,27.51676 -67.08004,35.5287 -1.79569,18.70085 -2.21232,37.56904 -1.4629,56.27529 14.36611,10.46486 18.14376,29.44442 18.67596,46.17572 1.42879,19.10333 3.31403,38.21183 4.78767,57.33922 l 94.06329,0.0603 0,-99.67829 -5.64129,0 c -1.42556,0 -2.57322,-1.14766 -2.57322,-2.57323 l 0,-54.37631 c 0,-1.42556 1.14766,-2.57322 2.57322,-2.57322 l 2.21136,0 c -2.89117,-5.43908 -2.75569,-17.98166 -2.75569,-23.06002 0,-6.57742 0.14421,-9.08623 0.15,-13.63002 z"
|
||||
style="fill:url(#linearGradient3921);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
|
||||
<use
|
||||
height="1013.322"
|
||||
width="1469.2054"
|
||||
transform="matrix(-1,0,0,1,-796.64968,2.010815e-6)"
|
||||
id="use4348"
|
||||
xlink:href="#path4311"
|
||||
y="0"
|
||||
x="0"
|
||||
style="display:inline" />
|
||||
<circle
|
||||
sodipodi:ry="13.13577"
|
||||
sodipodi:rx="13.13577"
|
||||
sodipodi:cy="194.21156"
|
||||
sodipodi:cx="165.89903"
|
||||
d="m 179.0348,194.21156 c 0,7.25469 -5.88108,13.13577 -13.13577,13.13577 -7.25468,0 -13.13577,-5.88108 -13.13577,-13.13577 0,-7.25468 5.88109,-13.13577 13.13577,-13.13577 7.25469,0 13.13577,5.88109 13.13577,13.13577 z"
|
||||
r="13.13577"
|
||||
cy="194.21156"
|
||||
cx="165.89903"
|
||||
id="path4352"
|
||||
style="fill:#898989;fill-opacity:1;stroke:none;display:inline"
|
||||
transform="matrix(0.79176032,0,0,0.79176032,-529.7793,210.17291)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4357"
|
||||
d="m -420.59834,454.5406 c -5.60675,18.71514 -11.21351,37.43027 -16.82027,56.1454 5.1217,0 10.2434,0 15.3651,0 4.38485,-6.69216 8.76766,-13.38566 13.15375,-20.077 6.98254,0 13.96508,0 20.94762,0 4.38609,6.69134 8.76889,13.38484 13.15374,20.077 5.12118,0 10.24237,0 15.36355,0 -5.60676,-18.71565 -11.21352,-37.43129 -16.82027,-56.14694 -7.39028,-3.83406 -14.78056,-7.66812 -22.17083,-11.50218 -7.39079,3.83457 -14.78159,7.66915 -22.17239,11.50372 z"
|
||||
style="fill:#898989;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="use4396"
|
||||
d="m -521.43644,406.56488 c -1.77374,0.0227 -3.15566,0.4222 -3.55518,1.76754 l 0.11752,2.1727 c 1.24058,16.62081 0.75876,33.65011 3.93561,49.99997 1.98359,2.87617 3.63732,8.09685 7.96709,7.20935 1.8046,-0.22471 4.69928,1.07511 6.16243,-0.0881 -0.0876,-1.12531 -0.18047,-2.37689 -0.26598,-3.46086 -1.38363,-12.51596 -2.3414,-25.11574 -3.33096,-37.70913 -0.77697,-6.57243 -2.15369,-13.39954 -5.30263,-19.41823 -1.9185,-0.16721 -4.00601,-0.49523 -5.7279,-0.4732 z"
|
||||
style="fill:#898989;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="use4398"
|
||||
d="m -506.09917,476.83515 c -1.97837,0.009 -3.95674,0.0188 -5.93511,0.0279 0.85216,4.85149 -4.04309,7.59388 -6.85213,10.37484 -0.6345,6.02214 1.09923,12.03757 0.98197,18.13626 0.3064,4.54843 -0.35793,10.2138 4.18921,12.95425 3.89072,2.9778 6.76537,7.60716 5.65521,12.64652 0.43285,7.84497 -0.8119,15.99277 0.9062,23.38167 1.01515,0.57035 2.08809,0.77358 3.18869,0.80413 l 2.20518,-18.43626 c 0,0 -2.26899,-32.57611 -4.33922,-59.88925 z"
|
||||
style="fill:#898989;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4404"
|
||||
d="m -271.77677,406.75044 c -3.09643,0.0485 -6.19285,0.0969 -9.28928,0.14537 -3.15953,5.97283 -4.55856,12.75131 -5.34747,19.29452 l -3.45931,41.48855 c 3.94759,0.0294 9.07538,1.78551 11.24547,-2.81911 5.80456,-6.57393 3.74439,-15.87475 4.98871,-23.78837 0.76732,-11.43639 1.23856,-22.86533 1.86188,-34.32096 z"
|
||||
style="fill:#898989;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4406"
|
||||
d="m -288.21508,476.67123 c -0.84134,0.006 -1.68687,0.0599 -2.53457,0.11907 -2.07117,27.32261 -4.3423,59.9341 -4.3423,59.9341 l 2.20826,18.47337 c 1.29581,-0.023 2.52331,-0.3133 3.58612,-1.2263 1.08603,-9.86486 -0.19804,-20.31797 0.95414,-30.09153 3.59307,-4.65204 10.46727,-8.17451 9.15627,-15.08365 0.31411,-7.28513 1.50719,-14.93066 1.3129,-22.00692 -3.27092,-2.21915 -7.90201,-5.21182 -6.84904,-9.77793 -1.14795,-0.27038 -2.31544,-0.34912 -3.49178,-0.34021 z"
|
||||
style="fill:#898989;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4441"
|
||||
d="m -398.42702,334.8881 -2.54284,4.40528 -2.54281,4.40266 2.90008,0 0,9.31229 2.18557,-1.2609 2.18556,1.2609 0,-9.31229 2.90008,0 -2.54283,-4.40266 -2.54281,-4.40528 z"
|
||||
style="fill:url(#linearGradient3923);fill-opacity:1;stroke:none;display:inline" />
|
||||
<use
|
||||
height="1013.322"
|
||||
width="1469.2054"
|
||||
transform="matrix(1,0,0,-1,-9.1690072e-7,727.78645)"
|
||||
id="use4460"
|
||||
xlink:href="#path4441"
|
||||
y="0"
|
||||
x="0"
|
||||
style="display:inline" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 454.66443,352.50287 c -1.36013,24.01275 -2.08377,48.50286 -4.67196,71.59456 -2.99078,6.00192 -6.27359,9.95971 -9.59645,13.63706 l -17.17259,0 7.07107,-84.85281 z"
|
||||
id="path4251"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 438.62826,441.14375 -0.37881,7.82869 8.9651,7.3236 -2.77792,38.13326 -11.36421,12.12183 -0.37881,36.61803 -3.03046,4.54569 -18.43528,0 0,-106.69736 z"
|
||||
id="path4253"
|
||||
inkscape:connector-curvature="0" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#path4251"
|
||||
id="use4275"
|
||||
transform="matrix(-1,0,0,1,580.95786,4.8707099e-7)"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
<ellipse
|
||||
style="fill:#000000;fill-opacity:1;stroke:#ff0000;stroke-opacity:1"
|
||||
id="path4243"
|
||||
cx="290.47894"
|
||||
cy="231.07376"
|
||||
rx="57.5"
|
||||
ry="36.875" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#path4253"
|
||||
id="use4277"
|
||||
transform="matrix(-1,0,0,1,580.95786,4.8707099e-7)"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
<path
|
||||
style="fill:#282828;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 287.12424,258.10527 0.33399,-51.40625 c -49.49582,9.30987 -55.75059,5.0826 -65.29102,1.07031 -24.72942,18.12217 -56.91711,38.05902 -92.98242,48.79297 -3.12319,24.73221 -3.43113,59.04672 -2.64063,84.07422 24.02292,13.33912 22.23564,42.84183 24.32227,61.05859 2.08662,18.21675 9.10156,119.0332 9.10156,119.0332 l -3.28125,27.4375 29.4375,54.3711 c -0.20477,8.84869 -0.59006,18.78502 -3.83008,47.24609 -9.03868,2.58062 -17.44268,1.97853 -25.29101,-1.39258 0.11517,13.78573 -0.8627,27.56815 0.71875,41.27539 14.20182,16.9502 20.70885,34.21986 70.98828,70.96485 l 8.20703,14.6914 c 16.51245,9.42952 29.26306,14.71639 53.5625,18.88477 24.29944,-4.16838 37.05005,-9.45525 53.5625,-18.88477 l 8.20703,-14.6914 c 50.27943,-36.74499 56.78646,-54.01465 70.98828,-70.96485 1.58145,-13.70724 0.60163,-27.48966 0.7168,-41.27539 -7.84833,3.37111 -16.25038,3.9732 -25.28906,1.39258 -3.24002,-28.46107 -3.62531,-38.3974 -3.83008,-47.24609 l 29.43555,-54.3711 -3.2793,-27.4375 c 0,0 7.01494,-100.81645 9.10156,-119.0332 2.08663,-18.21676 0.29739,-47.71947 24.32031,-61.05859 0.7905,-25.0275 0.48452,-59.34201 -2.63867,-84.07422 -36.06531,-10.73395 -68.25495,-30.6708 -92.98437,-48.79297 -9.54043,4.01229 -15.79325,8.23956 -65.28907,-1.07031 l 0.33399,51.40625 z"
|
||||
id="path3441"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccscccccccccccccccccscccccc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 290.44411,257.77582 0,148.84598"
|
||||
id="path4289"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 300.46818,468.48417 16.60743,25.35742 30.71289,0 -24.28516,-81.07226 -33.02344,-17.13086 -33.02539,17.13086 -24.28515,81.07226 30.71484,0 16.60742,-25.35742 z"
|
||||
id="path4247"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccc" />
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1;stroke:#ff0000;stroke-opacity:1"
|
||||
id="rect4245"
|
||||
width="31.607143"
|
||||
height="75.178574"
|
||||
x="274.67535"
|
||||
y="264.91306"
|
||||
rx="3.25"
|
||||
ry="3.25" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="Actions"
|
||||
style="display:inline"
|
||||
transform="translate(647.36582,205.64997)">
|
||||
<path
|
||||
style="fill:url(#linearGradient4219);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 152.84766,110.283 c -17.81104,3.02933 -36.57571,6.1705 -54.244144,0.64648 -25.929275,18.82906 -54.231433,34.7539 -84.722657,44.87305 -2.267978,23.61933 -2.794179,47.45001 -1.847656,71.07617 18.144518,13.21721 22.915716,37.18855 23.587891,58.32032 1.804576,24.12767 4.185653,48.26187 6.046875,72.41992 l 118.802731,0.0762 0,-125.89453 -7.125,0 c -1.8005,0 -3.25,-1.4495 -3.25,-3.25 l 0,-68.67774 c 0,-1.8005 1.4495,-3.25 3.25,-3.25 l 2.79297,0 c -3.65158,-6.86961 -3.48047,-22.71099 -3.48047,-29.125 0,-8.30734 0.18214,-11.47599 0.18946,-17.21484 z"
|
||||
id="path4311"
|
||||
inkscape:connector-curvature="0" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#path4311"
|
||||
id="use4348"
|
||||
transform="matrix(-1,0,0,1,332.05619,4.8707099e-7)"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
<circle
|
||||
style="fill:#898989;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
id="path4352"
|
||||
cx="165.89903"
|
||||
cy="194.21156"
|
||||
r="13.13577" />
|
||||
<path
|
||||
style="fill:#898989;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 137.89648,308.63847 c -7.08138,23.63737 -14.16276,47.27474 -21.24414,70.91211 6.46875,0 12.9375,0 19.40625,0 5.5381,-8.45225 11.07362,-16.9062 16.61329,-25.35742 8.81901,0 17.63802,0 26.45703,0 5.53967,8.45122 11.07518,16.90517 16.61328,25.35742 6.4681,0 12.9362,0 19.40429,0 -7.08138,-23.63802 -14.16276,-47.27604 -21.24414,-70.91406 -9.33398,-4.84245 -18.66797,-9.6849 -28.00195,-14.52735 -9.33463,4.8431 -18.66927,9.6862 -28.00391,14.5293 z"
|
||||
id="path4357"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#898989;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 10.537109,248.04472 c -2.2402592,0.0287 -3.9856276,0.53324 -4.490234,2.23242 l 0.1484375,2.74414 c 1.566854,20.99222 0.9583123,42.50038 4.9707035,63.15039 2.505291,3.63263 4.593974,10.22639 10.0625,9.10547 2.27923,-0.28382 5.935234,1.35787 7.783203,-0.11133 -0.110687,-1.42127 -0.227935,-3.00203 -0.335938,-4.37109 -1.747534,-15.80777 -2.957208,-31.72139 -4.207031,-47.62695 -0.981314,-8.30104 -2.720121,-16.92373 -6.697266,-24.52539 -2.423075,-0.21119 -5.059619,-0.62548 -7.234375,-0.59766 z"
|
||||
id="use4396"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#898989;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 29.908203,336.79667 c -2.498699,0.0115 -4.997394,0.0237 -7.496094,0.0352 1.076291,6.12748 -5.106457,9.59114 -8.654297,13.10351 -0.801383,7.60601 1.388334,15.20355 1.240235,22.90625 0.386982,5.74471 -0.452066,12.90012 5.291015,16.36133 4.914007,3.76099 8.544715,9.60791 7.142579,15.97266 0.546689,9.90826 -1.025444,20.199 1.144531,29.53125 1.282147,0.72035 2.637282,0.97704 4.027344,1.01562 l 2.785156,-23.28515 c 0,0 -2.865754,-41.1439 -5.480469,-75.64063 z"
|
||||
id="use4398"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#898989;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 325.85938,248.27909 c -3.91081,0.0612 -7.82162,0.12234 -11.73243,0.1836 -3.99052,7.54373 -5.75751,16.10502 -6.7539,24.36914 l -4.36914,52.40039 c 4.98584,0.0372 11.46228,2.25512 14.20312,-3.56055 7.33121,-8.30294 4.7292,-20.04995 6.30078,-30.04492 0.96913,-14.44425 1.56431,-28.8791 2.35157,-43.34766 z"
|
||||
id="path4404"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#898989;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 305.09766,336.58964 c -1.06262,0.008 -2.13053,0.0756 -3.20118,0.15039 -2.61591,34.50868 -5.48437,75.69727 -5.48437,75.69727 l 2.78906,23.33203 c 1.63662,-0.029 3.18696,-0.39571 4.5293,-1.54883 1.37166,-12.4594 -0.25013,-25.66177 1.20508,-38.00586 4.53808,-5.87556 13.22025,-10.32447 11.56445,-19.05078 0.39672,-9.20118 1.90359,-18.85755 1.6582,-27.79492 -4.1312,-2.80281 -9.9803,-6.58258 -8.65039,-12.34961 -1.44987,-0.34149 -2.92443,-0.44095 -4.41015,-0.42969 z"
|
||||
id="path4406"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:url(#linearGradient4215);fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
d="m 165.89904,157.51634 -3.21162,5.56391 -3.21159,5.56059 3.66282,0 0,11.76151 2.76039,-1.59253 2.76039,1.59253 0,-11.76151 3.66282,0 -3.21161,-5.56059 -3.2116,-5.56391 z"
|
||||
id="path4441"
|
||||
inkscape:connector-curvature="0" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#path4441"
|
||||
id="use4460"
|
||||
transform="matrix(1,0,0,-1,-4.295044e-6,388.30011)"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer4"
|
||||
inkscape:label="Leaders"
|
||||
transform="translate(647.36582,205.64997)"
|
||||
transform="translate(647.36582,-57.672087)"
|
||||
style="display:inline">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4556"
|
||||
d="m 395.13239,501.14005 -3.21162,5.56391 -3.21159,5.56059 3.66282,0 0,11.76151 2.76039,-1.59253 2.76039,1.59253 0,-11.76151 3.66282,0 -3.21161,-5.56059 -3.2116,-5.56391 z"
|
||||
style="display:inline;fill:url(#linearGradient4562);fill-opacity:1;stroke:none;stroke-opacity:1" />
|
||||
<use
|
||||
style="display:inline"
|
||||
height="100%"
|
||||
width="100%"
|
||||
transform="matrix(1.0000001,0,0,-1.0000001,229.23333,737.5807)"
|
||||
id="use4558"
|
||||
xlink:href="#path4441"
|
||||
y="0"
|
||||
x="0" />
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
|
||||
d="M -346.88483,324.11711 -381.86206,206.36042"
|
||||
id="path4211"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 164.75586,327.92021 115.08162,-115.08161 95.36037,0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
|
||||
d="M -204.64408,314.78985 -143.68094,209.1986"
|
||||
id="path4215"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
|
||||
d="m -480.19795,353.09245 84.92794,58.46775"
|
||||
id="path4227"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
|
||||
d="m -481.9468,416.63443 92.50633,61.96547"
|
||||
id="path4229"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
|
||||
d="m -277.50576,447.94085 91.11706,-91.11705 75.50256,0"
|
||||
id="path4546"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 77.129499,171.52978 32.952959,22.802079"
|
||||
id="path4211"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 165.48259,195.09061 32.39613,0 0,-238.553341"
|
||||
id="path4213"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 256.78078,159.74937 333.77774,26.386719"
|
||||
id="path4215"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 375.15404,291.50573 -61.68003,0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
|
||||
d="m -110.92083,419.10931 -48.8358,0"
|
||||
id="path4221"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 375.28322,364.38474 -64.17738,0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
|
||||
d="m -110.81855,476.81202 -50.8131,0"
|
||||
id="path4225"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M -175.41308,446.16063 16.018609,281.97114"
|
||||
id="path4227"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M -177.6219,526.41468 23.381369,366.64285"
|
||||
id="path4229"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer5"
|
||||
inkscape:label="Controls"
|
||||
transform="translate(647.36582,205.64997)"
|
||||
style="display:inline">
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4556"
|
||||
d="m -95.10276,585.08945 -2.54284,4.40528 -2.54281,4.40265 2.90008,0 0,9.3123 2.18557,-1.2609 2.18556,1.2609 0,-9.3123 2.90008,0 -2.54283,-4.40265 -2.54281,-4.40528 z"
|
||||
style="fill:url(#linearGradient3237);fill-opacity:1;stroke:none;display:inline" />
|
||||
<use
|
||||
style="display:inline"
|
||||
height="1013.322"
|
||||
width="1469.2054"
|
||||
transform="matrix(1.0000001,0,0,-1.0000001,303.3243,982.46676)"
|
||||
id="use4558"
|
||||
xlink:href="#path4441"
|
||||
y="0"
|
||||
x="0" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="27.097548"
|
||||
y="16.66757"
|
||||
style="font-size:31.67041588px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
x="-368.79688"
|
||||
y="175.47208"
|
||||
id="text4473"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="27.097548"
|
||||
y="16.66757"
|
||||
id="tspan4217">Button0</tspan></text>
|
||||
x="-368.79688"
|
||||
y="175.47208"
|
||||
id="tspan4217"
|
||||
style="font-size:32.00000381px">Button0</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4477"
|
||||
y="21.853914"
|
||||
x="336.33337"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
y="205.6097"
|
||||
x="-141.6575"
|
||||
style="font-size:31.67041206px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
xml:space="preserve"><tspan
|
||||
y="21.853914"
|
||||
x="336.33337"
|
||||
y="205.6097"
|
||||
x="-141.6575"
|
||||
id="tspan4479"
|
||||
sodipodi:role="line">Button1</tspan></text>
|
||||
sodipodi:role="line"
|
||||
style="font-size:32.00000381px">Button1</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="196.44098"
|
||||
y="-51.004951"
|
||||
style="font-size:32.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
x="-252.41873"
|
||||
y="147.92294"
|
||||
id="text4481"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4483"
|
||||
x="196.44098"
|
||||
y="-51.004951">Button2</tspan></text>
|
||||
x="-252.41873"
|
||||
y="147.92294">Button2</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4485"
|
||||
y="446.01364"
|
||||
x="-176.11456"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
y="361.82675"
|
||||
x="-492.72778"
|
||||
style="font-size:31.67041588px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
xml:space="preserve"><tspan
|
||||
y="446.01364"
|
||||
x="-176.11456"
|
||||
y="361.82675"
|
||||
x="-492.72778"
|
||||
id="tspan4487"
|
||||
sodipodi:role="line">Button3</tspan></text>
|
||||
sodipodi:role="line"
|
||||
style="font-size:32.00000381px">Button3</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-177.07159"
|
||||
y="526.30017"
|
||||
style="font-size:31.67041588px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
x="-492.44421"
|
||||
y="414.9819"
|
||||
id="text4489"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4491"
|
||||
x="-177.07159"
|
||||
y="526.30017">Button4</tspan></text>
|
||||
x="-492.44421"
|
||||
y="414.9819"
|
||||
style="font-size:32.00000381px">Button4</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4493"
|
||||
y="212.67909"
|
||||
x="375.72412"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
y="356.69751"
|
||||
x="-110.46946"
|
||||
style="font-size:31.67041206px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
xml:space="preserve"><tspan
|
||||
y="212.67909"
|
||||
x="375.72412"
|
||||
y="356.69751"
|
||||
x="-110.46946"
|
||||
id="tspan4495"
|
||||
sodipodi:role="line">Button5</tspan></text>
|
||||
sodipodi:role="line"
|
||||
style="font-size:32.00000381px">Button5</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="375.72412"
|
||||
y="288.81161"
|
||||
style="font-size:31.67041206px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="-110.46946"
|
||||
y="416.97623"
|
||||
id="text4497"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4499"
|
||||
x="375.72412"
|
||||
y="288.81161">Button6</tspan></text>
|
||||
x="-110.46946"
|
||||
y="416.97623"
|
||||
style="font-size:32.00000381px">Button6</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4501"
|
||||
y="364.41678"
|
||||
x="375.72412"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
y="476.83734"
|
||||
x="-110.46946"
|
||||
style="font-size:31.67041206px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
xml:space="preserve"><tspan
|
||||
y="364.41678"
|
||||
x="375.72412"
|
||||
y="476.83734"
|
||||
x="-110.46946"
|
||||
id="tspan4503"
|
||||
sodipodi:role="line">Button7</tspan></text>
|
||||
sodipodi:role="line"
|
||||
style="font-size:32.00000381px">Button7</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="417.32373"
|
||||
y="526.42987"
|
||||
style="font-size:31.67041206px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="-77.532547"
|
||||
y="605.11292"
|
||||
id="text4505"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4507"
|
||||
x="417.32373"
|
||||
y="526.42987">Button8</tspan></text>
|
||||
x="-77.532547"
|
||||
y="605.11292"
|
||||
style="font-size:32.00000381px">Button8</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4509"
|
||||
y="583.15552"
|
||||
x="417.32373"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
y="650.02606"
|
||||
x="-77.532547"
|
||||
style="font-size:31.67041206px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
xml:space="preserve"><tspan
|
||||
y="583.15552"
|
||||
x="417.32373"
|
||||
y="650.02606"
|
||||
x="-77.532547"
|
||||
id="tspan4511"
|
||||
sodipodi:role="line">Button9</tspan></text>
|
||||
<g
|
||||
id="g4602"
|
||||
transform="translate(-140.12576,-153.50496)">
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4572"
|
||||
y="109.05057"
|
||||
x="-431.3205"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4576"
|
||||
y="109.05057"
|
||||
x="-431.3205"
|
||||
sodipodi:role="line">Resolution0</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-431.3205"
|
||||
y="182.02396"
|
||||
id="text4580"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="-431.3205"
|
||||
y="182.02396"
|
||||
id="tspan4582">Resolution1</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4584"
|
||||
y="254.99734"
|
||||
x="-431.3205"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4586"
|
||||
y="254.99734"
|
||||
x="-431.3205"
|
||||
sodipodi:role="line">Resolution2</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-431.3205"
|
||||
y="327.97079"
|
||||
id="text4588"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="-431.3205"
|
||||
y="327.97079"
|
||||
id="tspan4590">Resolution3</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4592"
|
||||
y="400.94421"
|
||||
x="-431.3205"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4594"
|
||||
y="400.94421"
|
||||
x="-431.3205"
|
||||
sodipodi:role="line">Resolution4</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-431.3205"
|
||||
y="473.91763"
|
||||
id="text4596"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="-431.3205"
|
||||
y="473.91763"
|
||||
id="tspan4598">Resolution5</tspan></text>
|
||||
</g>
|
||||
<rect
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="rect4600"
|
||||
width="323.85489"
|
||||
height="479.4184"
|
||||
x="-615.48309"
|
||||
y="-116.64217"
|
||||
rx="10.321068"
|
||||
ry="10.321068" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-591.40881"
|
||||
y="625.81189"
|
||||
id="text4211"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4213"
|
||||
x="-591.40881"
|
||||
y="625.81189">Current Profile</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer6"
|
||||
inkscape:label="Title">
|
||||
<text
|
||||
transform="translate(647.36582,205.64997)"
|
||||
xml:space="preserve"
|
||||
style="display:inline;font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-271.95749"
|
||||
y="-131.81583"
|
||||
id="text4223"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4225"
|
||||
x="-271.95749"
|
||||
y="-131.81583"
|
||||
style="font-size:70.00000763px">Etekcity Scroll Alpha</tspan></text>
|
||||
style="font-size:32.00000381px">Button9</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
|
||||
d="m -276.93036,342.77164 25.64997,0 0,-188.87707"
|
||||
id="path4213"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 23 KiB |
1030
data/logitech-g300.svg
Normal file
|
After Width: | Height: | Size: 46 KiB |
578
data/logitech-g303.svg
Normal file
@@ -0,0 +1,578 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="750"
|
||||
height="750"
|
||||
viewBox="0 0 198.4375 198.43751"
|
||||
version="1.1"
|
||||
id="svg124"
|
||||
inkscape:version="0.92.1 r"
|
||||
sodipodi:docname="g303_FINAL.svg">
|
||||
<defs
|
||||
id="defs118">
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker10743"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend">
|
||||
<path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path10741" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Mend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="marker8938"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path8936"
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.6) rotate(180) translate(0,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker8458"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path8456" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Mend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="marker7654"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path7652"
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.6) rotate(180) translate(0,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker7210"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Mend"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
transform="scale(0.6) rotate(180) translate(0,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
id="path7208" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Mend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Mend"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path5595"
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.6) rotate(180) translate(0,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Lend"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5589"
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " transform="scale(1.1) rotate(180) translate(1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Lend"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5571"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Lstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5568"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
transform="scale(0.8) translate(12.5,0)" />
|
||||
</marker>
|
||||
<linearGradient
|
||||
gradientTransform="matrix(1.2281683,0,0,1.2458588,-19.641241,-24.549337)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4680-3"
|
||||
id="linearGradient4831"
|
||||
x1="85.155098"
|
||||
y1="123.48504"
|
||||
x2="71.876953"
|
||||
y2="109.32611"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4680-3">
|
||||
<stop
|
||||
style="stop-color:#212121;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4676" />
|
||||
<stop
|
||||
style="stop-color:#525252;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4678" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientTransform="matrix(1.2281683,0,0,1.2458588,-19.641241,-24.549337)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4680-3"
|
||||
id="linearGradient4837"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="75.392632"
|
||||
y1="113.90072"
|
||||
x2="78.325882"
|
||||
y2="111.17885" />
|
||||
<linearGradient
|
||||
gradientTransform="matrix(1.2281683,0,0,1.2458588,-19.641241,-24.549337)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4680-3"
|
||||
id="linearGradient4820"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="58.802368"
|
||||
y1="98.166107"
|
||||
x2="67.821754"
|
||||
y2="105.06921" />
|
||||
<linearGradient
|
||||
gradientTransform="matrix(1.2281683,0,0,1.2458588,-19.641241,-24.549337)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4680-3"
|
||||
id="linearGradient4812"
|
||||
x1="65.554306"
|
||||
y1="101.39091"
|
||||
x2="57.845005"
|
||||
y2="94.387032"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
gradientTransform="matrix(1.2281683,0,0,1.2458588,-19.641241,-24.549337)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4680-3"
|
||||
id="linearGradient4801"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="93.544136"
|
||||
y1="74.89328"
|
||||
x2="97.026817"
|
||||
y2="75.489372" />
|
||||
<linearGradient
|
||||
gradientTransform="matrix(1.2281683,0,0,1.2458588,-19.641241,-24.549337)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4680-3"
|
||||
id="linearGradient4796"
|
||||
x1="100.40672"
|
||||
y1="76.753265"
|
||||
x2="102.15361"
|
||||
y2="76.166771"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
gradientTransform="matrix(1.2281683,0,0,1.2458588,-19.641241,-24.549337)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4680-3"
|
||||
id="linearGradient4682"
|
||||
x1="78.691124"
|
||||
y1="106.60219"
|
||||
x2="134.32263"
|
||||
y2="145.19518"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4680-3"
|
||||
id="linearGradient4705"
|
||||
x1="63.324043"
|
||||
y1="92.412109"
|
||||
x2="52.236984"
|
||||
y2="73.76532"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2281683,0,0,1.2458588,-20.199812,-21.797201)" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4680-3"
|
||||
id="radialGradient4695"
|
||||
cx="112.96842"
|
||||
cy="113.917"
|
||||
fx="112.96842"
|
||||
fy="113.917"
|
||||
r="41.164257"
|
||||
gradientTransform="matrix(1.2281683,0,0,1.296401,-19.641241,-30.306952)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4680-3"
|
||||
id="linearGradient4710"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="41.81852"
|
||||
y1="81.23703"
|
||||
x2="81.993874"
|
||||
y2="81.23703"
|
||||
gradientTransform="matrix(1.2281683,0,0,1.2458588,-20.199812,-21.716256)" />
|
||||
<linearGradient
|
||||
gradientTransform="matrix(1.2281683,0,0,1.2458588,-19.641241,-24.549337)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4680-3"
|
||||
id="linearGradient4763"
|
||||
x1="67.125862"
|
||||
y1="69.888031"
|
||||
x2="82.802811"
|
||||
y2="69.888031"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
gradientTransform="matrix(1.2281683,0,0,1.2458588,-19.641241,-24.549337)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4680-3"
|
||||
id="linearGradient4773"
|
||||
x1="77.743431"
|
||||
y1="69.896729"
|
||||
x2="74.04789"
|
||||
y2="65.264908"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
gradientTransform="matrix(1.2281683,0,0,1.2458588,-19.641241,-24.549337)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4680-3"
|
||||
id="linearGradient4747"
|
||||
x1="80.881615"
|
||||
y1="74.891853"
|
||||
x2="82.567528"
|
||||
y2="70.608902"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
gradientTransform="matrix(1.2281683,0,0,1.2458588,-19.641241,-24.549337)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4680-3"
|
||||
id="linearGradient4784"
|
||||
x1="89.6782"
|
||||
y1="82.01104"
|
||||
x2="124.02607"
|
||||
y2="82.01104"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
gradientTransform="matrix(1.2281683,0,0,1.2458588,-19.641241,-24.549337)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4680-3"
|
||||
id="linearGradient4735"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="81.290771"
|
||||
y1="69.214806"
|
||||
x2="58.49073"
|
||||
y2="60.248428" />
|
||||
<linearGradient
|
||||
gradientTransform="matrix(1.2281683,0,0,1.2458588,-19.641241,-24.549337)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4680-3"
|
||||
id="linearGradient4726"
|
||||
x1="58.34309"
|
||||
y1="66.386375"
|
||||
x2="116.9311"
|
||||
y2="66.386375"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.92824696"
|
||||
inkscape:cx="267.03408"
|
||||
inkscape:cy="338.19237"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer7"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:snap-page="true"
|
||||
inkscape:snap-others="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1004"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="48"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata121">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer7"
|
||||
inkscape:label="Device"
|
||||
style="display:inline">
|
||||
<path
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.32728478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 33.641311,64.982766 -1.732765,5.398727 c 0,0 -0.629464,5.678443 3.26926,11.20272 5.812872,8.815493 5.94101,9.101914 13.151365,19.243577 7.210355,10.14167 20.613506,27.64865 32.12776,42.84454 3.87757,5.11741 16.967127,10.29767 21.949299,12.68881 11.002,5.28032 27.527,13.09076 40.11549,14.1146 15.07422,1.22601 22.74792,-23.13102 22.74792,-23.13102 L 141.75352,83.564426 123.90176,65.732277 102.89006,58.202973 62.293831,52.176488 45.213712,60.714006 Z"
|
||||
id="path4839"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccczsssccccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccssccsc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4728"
|
||||
d="m 54.76863,55.588789 -2.295328,-2.726405 -0.27808,-2.350686 c 0,0 18.167671,-1.598465 22.431514,-0.940273 4.263843,0.658192 23.729205,5.171504 34.852264,9.590788 11.12306,4.419288 9.18583,4.11904 14.42276,6.57006 -8.85487,-3.133919 -23.66007,-1.760792 -33.812723,-1.477175 -0.158622,1.548423 -0.114268,2.600247 -0.114268,2.600247 C 82.7929,64.986082 54.76863,55.588789 54.76863,55.588789 Z"
|
||||
style="display:inline;fill:url(#linearGradient4726);fill-opacity:1;stroke:none;stroke-width:0.32780018;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="display:inline;fill:url(#linearGradient4735);fill-opacity:1;stroke:none;stroke-width:0.32728478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 54.856148,55.855125 -2.382846,-2.992741 -0.27808,-2.350686 c 18.481975,6.870889 20.73837,7.57628 37.893815,13.7434 -0.158622,1.548423 -0.114268,2.600247 -0.114268,2.600247 C 82.7929,64.986082 54.856148,55.855125 54.856148,55.855125 Z"
|
||||
id="path4716"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccsc" />
|
||||
<path
|
||||
style="display:inline;fill:url(#linearGradient4784);fill-opacity:1;stroke:none;stroke-width:0.32728478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 90.498682,64.587538 c 0.0014,2.415136 0.08886,3.214144 0.08886,3.214144 l 37.938998,22.41657 4.1571,0.443891 -3.58823,-15.047953 -32.119065,-9.854412 z"
|
||||
id="path4776"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;fill:url(#linearGradient4747);fill-opacity:1;stroke:none;stroke-width:0.32728478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 48.926779,56.570799 c 0,0 5.569607,-2.071605 6.497874,-2.13438 4.641336,1.255515 31.870514,10.044141 37.068811,12.052968 9.897016,3.978673 20.493146,9.162891 28.404966,13.999022 5.31807,3.262227 8.52923,5.401083 8.10688,7.972533 -0.42234,2.571452 -4.45568,5.900935 -4.45568,5.900935 0,0 -13.11951,-3.389899 -13.49083,-3.641 -0.37131,-0.251104 -18.627219,-14.438453 -18.627219,-14.438453 0,0 -13.119512,-5.335949 -13.552706,-5.587054 C 78.445686,70.444268 64.831094,63.978353 64.521671,63.915577 64.212247,63.852802 48.926779,56.570799 48.926779,56.570799 Z"
|
||||
id="path4739"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccczcccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4765"
|
||||
d="m 62.800615,61.187683 c 0.06391,-0.129654 1.75539,-2.692898 4.595099,-4.082141 1.130065,-0.55285 4.463428,-1.655606 6.038322,-1.200179 4.493777,1.299505 7.905733,3.09382 12.483497,10.149265 -3.2066,1.658274 -3.2066,1.658274 -3.2066,1.658274 l -2.49426,0.310726 z"
|
||||
style="display:inline;fill:url(#linearGradient4773);fill-opacity:1;stroke:none;stroke-width:0.32728478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
sodipodi:nodetypes="csscccc" />
|
||||
<path
|
||||
style="display:inline;fill:url(#linearGradient4763);fill-opacity:1;stroke:none;stroke-width:0.32728478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 62.800615,61.187683 c 0.08752,-0.177557 3.063124,-5.903769 8.708027,-3.639918 5.644906,2.263853 10.545906,10.120748 10.545906,10.120748 l -1.837875,0.355115 z"
|
||||
id="path4755"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:nodetypes="csscssscc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4707"
|
||||
d="m 81.061034,68.55619 c 0,0 -6.675185,12.538586 -10.603076,22.010152 -1.049126,2.529831 -2.28668,5.867231 -2.803926,7.547057 -0.660926,2.146451 -0.08433,2.769521 -0.397665,4.358811 -3.844082,-2.632003 -32.505527,-27.735224 -34.22755,-29.787815 -0.242782,-0.289387 -1.233891,-1.962381 -1.42236,-4.307299 -0.05219,-0.649308 -0.04284,-1.350134 0.06099,-2.087368 0.836918,-5.94284 11.1851,-12.607804 11.1851,-12.607804 z"
|
||||
style="display:inline;fill:url(#linearGradient4710);fill-opacity:1;stroke:none;stroke-width:0.32728478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="cscssccsscsscscc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4670"
|
||||
d="m 82.41522,69.014086 c 0,0 23.31399,10.073283 38.80002,21.370661 1.81334,1.322871 4.49209,1.676486 6.63621,-0.04062 2.14412,-1.717108 1.62492,-3.937097 -0.92121,-6.104499 -4.95885,-4.221241 -6.85739,-5.122344 -13.18638,-8.905281 -7.90195,-4.723139 -16.853771,-8.967037 -23.245174,-10.746814 9.140702,-0.572366 30.023744,-1.337857 33.403074,1.144738 8.87412,3.960851 24.30645,16.663516 31.24281,27.830947 8.63308,13.899132 12.33164,22.248122 14.23506,36.388812 2.80518,20.83995 -16.13732,43.5 -26.85791,40.5237 3.57946,-0.6342 7.33514,-2.175 6.9966,-5.15132 -0.74082,-6.51284 -8.57647,-16.59867 -48.52475,-38.11975 -18.315639,-9.86707 -32.387452,-23.46711 -32.387452,-23.46711 0,0 -0.214496,-1.83679 0.169271,-3.37698 C 71.534502,89.287367 82.41522,69.014083 82.41522,69.014083 Z"
|
||||
style="display:inline;fill:url(#radialGradient4695);fill-opacity:1;stroke:none;stroke-width:0.32728478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
style="display:inline;fill:url(#linearGradient4705);fill-opacity:1;stroke:none;stroke-width:0.32728478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 67.336162,99.153458 -0.07979,3.237812 C 63.412286,99.759262 35.095451,75.716531 33.028818,72.77516 c -1.88514,-2.683054 -1.67797,-6.628929 -0.815272,-8.362198 -0.06626,1.61221 -0.485638,3.84076 1.152105,5.623249 7.675602,8.353979 25.95005,21.003692 33.970511,29.117247 z"
|
||||
id="path178"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccscsc" />
|
||||
<path
|
||||
style="display:inline;fill:url(#linearGradient4682);fill-opacity:1;stroke:none;stroke-width:0.32728478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 142.52172,170.47574 c 3.57946,-0.6342 7.33514,-2.17499 6.9966,-5.15132 -0.74082,-6.51285 -8.57647,-16.59867 -48.52476,-38.11975 -18.315635,-9.86707 -32.387446,-23.46711 -32.387446,-23.46711 0,0 -0.214498,-1.8368 0.169271,-3.37698 3.725669,4.47916 22.509918,18.21415 41.851065,29.0174 55.62333,31.06912 43.85529,42.27142 31.89527,41.09776 z"
|
||||
id="path4672"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cssccsc" />
|
||||
<path
|
||||
style="display:inline;fill:url(#linearGradient4796);fill-opacity:1;stroke:none;stroke-width:0.32728478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 91.506481,71.019901 c 0.743609,0.908331 11.844809,6.076214 14.221649,7.257645 0.71803,0.356899 1.1815,0.799004 2.31924,0.621448 1.13772,-0.177558 2.35863,-1.316437 2.47237,-1.642404 0.12819,-0.367406 -2.52196,-5.346011 -2.73493,-5.570848 -0.15339,-0.161933 -11.5427,-4.126769 -11.902433,-4.194785 -0.229293,-0.04336 -1.679248,0.660653 -2.406747,1.242898 -0.758403,0.606982 -2.320732,1.856577 -1.969149,2.286046 z"
|
||||
id="path4788"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="sscsssss" />
|
||||
<path
|
||||
sodipodi:nodetypes="csssc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4798"
|
||||
d="m 105.24679,73.239364 c 0.34525,0.02969 2.75099,-1.328785 2.53802,-1.553622 -0.15339,-0.161933 -11.5427,-4.126769 -11.902433,-4.194785 -0.229293,-0.04336 -2.23807,0.99583 -2.472384,1.487039 -0.208466,0.437022 10.535617,4.077407 11.836797,4.261368 z"
|
||||
style="display:inline;fill:url(#linearGradient4801);fill-opacity:1;stroke:none;stroke-width:0.32728478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
style="display:inline;fill:url(#linearGradient4812);fill-opacity:1;stroke:none;stroke-width:0.32728478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 48.060396,93.734116 16.089967,15.317314 1.980305,-0.87885 1.732766,-3.76656 -17.080119,-14.81511 -1.856536,1.129967 z"
|
||||
id="path4804"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4814"
|
||||
d="m 48.060396,93.734116 16.089967,15.317314 1.608998,-3.8921 C 61.694393,101.39187 50.213564,91.368976 48.926779,90.720877 Z"
|
||||
style="display:inline;fill:url(#linearGradient4820);fill-opacity:1;stroke:none;stroke-width:0.32728478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccscssc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4833"
|
||||
d="m 68.002673,113.587 c 2.885039,3.27285 9.816521,11.87315 14.171552,17.07503 0.376971,0.45027 0.479604,0.86316 1.593523,0.36097 1.113922,-0.50223 7.5516,-4.23009 10.658617,-6.2986 0.393265,-0.26182 1.06751,-0.26234 -0.417721,-1.26676 -1.485226,-1.0044 -15.684249,-10.57631 -21.967626,-16.10646 -0.272557,-0.23987 -2.024894,0.70814 -2.197279,1.00972 -0.968716,1.69477 -1.430234,3.61135 -1.841066,5.2261 z"
|
||||
style="display:inline;fill:url(#linearGradient4837);fill-opacity:1;stroke:none;stroke-width:0.32728478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
style="display:inline;fill:url(#linearGradient4831);fill-opacity:1;stroke:none;stroke-width:0.32728478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 68.002673,113.587 c 2.885039,3.27285 9.816521,11.87315 14.171552,17.07503 0.376971,0.45027 0.479604,0.86316 1.593523,0.36097 1.113922,-0.50223 5.494927,-2.76524 8.601948,-4.83374 0.393264,-0.26183 1.067506,-0.70624 -0.417724,-1.71067 -1.485226,-1.0044 -14.896587,-10.13241 -21.179966,-15.66256 -0.272558,-0.23988 -0.755882,-0.75671 -0.928267,-0.45513 -0.968716,1.69477 -1.430234,3.61135 -1.841066,5.2261 z"
|
||||
id="path4823"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccscssc" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="Leaders"
|
||||
style="display:inline">
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 87.372004,82.225427 c 0,0 19.527816,7.279613 31.390236,17.304521 0,0 3.8591,1.194482 5.60489,-0.183766 1.74578,-1.378252 1.19448,-3.032155 -0.64318,-4.686055 -1.83767,-1.6539 -20.39812,-13.414976 -29.770225,-15.987711 7.442555,-0.459415 24.445965,-1.073843 27.197485,0.918834 7.22549,3.179214 19.79081,13.375125 25.43853,22.33877 7.02923,11.15626 10.04068,17.85767 11.59048,29.20782 2.28404,16.72738 -13.13933,34.91569 -21.86825,32.52672 2.91447,-0.50904 5.97242,-1.74578 5.69677,-4.13475 -0.60319,-5.2276 -6.98314,-13.32309 -39.50986,-30.59717 -14.912972,-7.91989 -26.370532,-18.8361 -26.370532,-18.8361 0,0 -0.174647,-1.47432 0.137824,-2.71056 2.246527,-8.888015 11.105832,-25.160553 11.105832,-25.160553 z"
|
||||
id="path4668"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csccccsscsscsc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
x="14.064545"
|
||||
y="42.284489"
|
||||
id="text4889"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4887"
|
||||
x="14.064545"
|
||||
y="42.284489"
|
||||
style="font-size:4.23333311px;stroke-width:0.26458332">Button 0</tspan></text>
|
||||
<text
|
||||
id="text4977"
|
||||
y="41.314796"
|
||||
x="99.894806"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
xml:space="preserve"><tspan
|
||||
style="stroke-width:0.26458332"
|
||||
y="41.314796"
|
||||
x="99.894806"
|
||||
sodipodi:role="line"
|
||||
id="tspan4979">Button 2</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
x="55.512764"
|
||||
y="30.319952"
|
||||
id="text4985"><tspan
|
||||
sodipodi:role="line"
|
||||
x="55.512764"
|
||||
y="30.319952"
|
||||
style="stroke-width:0.26458332"
|
||||
id="tspan4987">Button 1</tspan></text>
|
||||
<text
|
||||
id="text4993"
|
||||
y="122.63442"
|
||||
x="20.689524"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
xml:space="preserve"><tspan
|
||||
style="stroke-width:0.26458332"
|
||||
y="122.63442"
|
||||
x="20.689524"
|
||||
sodipodi:role="line"
|
||||
id="tspan4995">Button 4</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
x="55.262302"
|
||||
y="153.98589"
|
||||
id="text5001"><tspan
|
||||
sodipodi:role="line"
|
||||
x="55.262302"
|
||||
y="153.98589"
|
||||
style="stroke-width:0.26458332"
|
||||
id="tspan5003">Button 3</tspan></text>
|
||||
<text
|
||||
id="text5009"
|
||||
y="63.37672"
|
||||
x="141.62805"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
xml:space="preserve"><tspan
|
||||
style="stroke-width:0.26458332"
|
||||
y="63.37672"
|
||||
x="141.62805"
|
||||
sodipodi:role="line"
|
||||
id="tspan5011">Button 5</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3.9000001;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend)"
|
||||
d="M 65.843199,148.27125 72.399014,138.295"
|
||||
id="path5023"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path7206"
|
||||
d="m 41.615182,120.90785 13.396667,-6.27079"
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3.9000001;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker7210)" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3.9000001;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker7654)"
|
||||
d="m 22.80284,45.37344 11.401419,9.121127"
|
||||
id="path7650"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path8454"
|
||||
d="m 66.128235,34.542092 4.275532,11.686446"
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3.9000001;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker8458)" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3.9000001;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker8938)"
|
||||
d="M 98.052209,43.663228 82.660292,57.629958"
|
||||
id="path8934"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path10739"
|
||||
d="m 140.23745,65.040889 -28.50355,5.13063"
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3.9000001;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker10743)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 62 KiB |
778
data/logitech-g502.svg
Normal file
@@ -0,0 +1,778 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="750"
|
||||
height="750"
|
||||
viewBox="0 0 750.00004 749.99998"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="logitech-g502.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4372">
|
||||
<stop
|
||||
style="stop-color:#3d444c;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4374" />
|
||||
<stop
|
||||
style="stop-color:#8f9aaa;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4376" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4327">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4329" />
|
||||
<stop
|
||||
style="stop-color:#969696;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4331" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4319">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4321" />
|
||||
<stop
|
||||
style="stop-color:#969696;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4323" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4219">
|
||||
<stop
|
||||
style="stop-color:#c3c3c3;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4221" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop4223" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4197">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4199" />
|
||||
<stop
|
||||
id="stop4205"
|
||||
offset="0.23127364"
|
||||
style="stop-color:#242424;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#242424;stop-opacity:1;"
|
||||
offset="0.7880435"
|
||||
id="stop4207" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop4201" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4178">
|
||||
<stop
|
||||
id="stop4180"
|
||||
offset="0"
|
||||
style="stop-color:#000000;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#3b3b3b;stop-opacity:1;"
|
||||
offset="0.46853611"
|
||||
id="stop4182" />
|
||||
<stop
|
||||
style="stop-color:#777777;stop-opacity:1;"
|
||||
offset="0.84132797"
|
||||
id="stop4184" />
|
||||
<stop
|
||||
id="stop4186"
|
||||
offset="1"
|
||||
style="stop-color:#000000;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4168">
|
||||
<stop
|
||||
id="stop4170"
|
||||
offset="0"
|
||||
style="stop-color:#000000;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#3b3b3b;stop-opacity:1;"
|
||||
offset="0.646918"
|
||||
id="stop4172" />
|
||||
<stop
|
||||
style="stop-color:#777777;stop-opacity:1;"
|
||||
offset="0.76408035"
|
||||
id="stop4174" />
|
||||
<stop
|
||||
id="stop4176"
|
||||
offset="1"
|
||||
style="stop-color:#000000;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4150">
|
||||
<stop
|
||||
id="stop4152"
|
||||
offset="0"
|
||||
style="stop-color:#000000;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#3b3b3b;stop-opacity:1;"
|
||||
offset="0.54100561"
|
||||
id="stop4154" />
|
||||
<stop
|
||||
style="stop-color:#777777;stop-opacity:1;"
|
||||
offset="0.84132797"
|
||||
id="stop4156" />
|
||||
<stop
|
||||
id="stop4158"
|
||||
offset="1"
|
||||
style="stop-color:#000000;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4140">
|
||||
<stop
|
||||
id="stop4142"
|
||||
offset="0"
|
||||
style="stop-color:#000000;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#3b3b3b;stop-opacity:1;"
|
||||
offset="0.5890528"
|
||||
id="stop4144" />
|
||||
<stop
|
||||
style="stop-color:#777777;stop-opacity:1;"
|
||||
offset="0.69403088"
|
||||
id="stop4146" />
|
||||
<stop
|
||||
id="stop4148"
|
||||
offset="1"
|
||||
style="stop-color:#000000;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4047">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4049" />
|
||||
<stop
|
||||
id="stop4055"
|
||||
offset="0.5"
|
||||
style="stop-color:#000000;stop-opacity:0.49803922;" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop4051" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4039">
|
||||
<stop
|
||||
style="stop-color:#636363;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4041" />
|
||||
<stop
|
||||
id="stop4063"
|
||||
offset="0.19902708"
|
||||
style="stop-color:#595959;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop4061"
|
||||
offset="0.39056408"
|
||||
style="stop-color:#4f4f4f;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#a3a3a3;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop4043" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4449">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4451" />
|
||||
<stop
|
||||
id="stop4059"
|
||||
offset="0.24691147"
|
||||
style="stop-color:#3b3b3b;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop4057"
|
||||
offset="0.84132797"
|
||||
style="stop-color:#777777;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop4453" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4449"
|
||||
id="linearGradient4562"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,-1.698701,1.698701,0,-120.19569,737.44997)"
|
||||
x1="31.968746"
|
||||
y1="18.546629"
|
||||
x2="31.968746"
|
||||
y2="29.577879" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4449"
|
||||
id="linearGradient4623"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,-1.6987012,-1.6987012,0,-45.565631,793.48827)"
|
||||
x1="31.968746"
|
||||
y1="18.546629"
|
||||
x2="31.968746"
|
||||
y2="29.577879" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4319"
|
||||
id="linearGradient4325"
|
||||
x1="-258.85849"
|
||||
y1="636.73883"
|
||||
x2="-210.58292"
|
||||
y2="669.61383"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4327"
|
||||
id="linearGradient4333"
|
||||
x1="-258.85849"
|
||||
y1="636.73883"
|
||||
x2="-210.58292"
|
||||
y2="669.61383"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4372"
|
||||
id="linearGradient4378"
|
||||
x1="476.00003"
|
||||
y1="513.00006"
|
||||
x2="559.50006"
|
||||
y2="463.50003"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="359.25033"
|
||||
inkscape:cy="331.87231"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer4"
|
||||
showgrid="false"
|
||||
showguides="false"
|
||||
inkscape:guide-bbox="true"
|
||||
fit-margin-top="50"
|
||||
fit-margin-left="50"
|
||||
fit-margin-right="50"
|
||||
fit-margin-bottom="50"
|
||||
inkscape:window-width="2048"
|
||||
inkscape:window-height="1088"
|
||||
inkscape:window-x="2560"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Device"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(522.78594,-165.96284)"
|
||||
style="display:inline"
|
||||
sodipodi:insensitive="true">
|
||||
<g
|
||||
id="g4390"
|
||||
transform="translate(46.66905,-6.3639614)">
|
||||
<path
|
||||
sodipodi:nodetypes="zccccccscsscssssssssz"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4435"
|
||||
d="m -226.16095,683.58782 c -6.01535,-13.02364 -13,-16.5 -13,-16.5 l -11.25,-3.375 -116.45795,-88.57547 11.4905,-82.02437 7.62132,1.97703 6.89061,-13.15685 c -18.38478,2.65165 -27.23986,-1.01777 -28.47729,-2.60876 -1.23744,-1.59099 0.17677,-3.18198 0.17677,-3.18198 0,0 7.43505,-10.39747 47.55294,-23.33452 117.72759,-37.96429 194.75285,-32.63933 310.328127,14.65494 101.699787,41.61632 127.995243,117.50993 130.641353,159.47011 0,0 -2.38649,0.17677 -5.74524,5.03813 -3.35876,4.86136 6.0104,17.05896 3.53553,28.72622 -2.47487,11.66726 -28.637827,53.29817 -45.166448,48.70198 -16.528622,-4.5962 -39.067651,-6.98268 -55.154331,-3.00521 -16.08667977,3.97748 -95.017477,43.75224 -100.144001,46.66905 -5.126525,2.91682 -19.26866,10.42983 -25.36746,10.87177 -6.09879,0.44194 -18.29639,-4.06586 -45.25483,-14.05375 -26.95845,-9.98788 -54.09367,-22.98097 -61.25313,-32.88046 -7.15946,-9.8995 -4.95112,-20.38922 -10.96647,-33.41286 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4362"
|
||||
transform="translate(-522.78594,165.96281)"
|
||||
d="m 564.2793,394.82812 c -3.92575,-0.10626 -7.28936,3.75042 -13.08985,11.8711 -8.83883,12.37437 -39.24401,61.16451 -77.07422,75.30664 -37.83021,14.14214 -97.93406,2.12147 -130.10742,-1.41406 -32.07532,-3.52476 -80.61133,-16.61719 -80.61133,-16.61719 l -30.16601,4.00391 39.14453,29.77148 11.25,3.375 c 0,0 6.98465,3.47636 13,16.5 6.01535,13.02364 3.80734,23.51261 10.9668,33.41211 7.15946,9.89949 34.2935,22.89298 61.25195,32.88086 26.95844,9.98789 39.15707,14.49663 45.25586,14.05469 6.0988,-0.44194 20.24066,-7.95623 25.36719,-10.87305 5.12652,-2.91681 84.05785,-42.69049 100.14453,-46.66797 16.08668,-3.97747 38.62567,-1.59229 55.15429,3.00391 16.52863,4.59619 42.69115,-37.03392 45.16602,-48.70117 0.81145,-3.82542 0.34164,-7.70307 -0.52734,-11.36524 -4.70923,-11.20032 -11.76875,-25.18057 -21.7461,-38.13281 -23.82425,-30.92783 -38.18467,-40.65753 -46.3164,-47.02149 -2.79529,-2.18761 -5.00616,-3.33105 -7.0625,-3.38672 z"
|
||||
style="fill:url(#linearGradient4378);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<g
|
||||
id="g4356">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#2e2d2b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 130.91406,379.34375 c -0.46995,0.14042 -0.93877,0.27563 -1.41015,0.42187 0,10e-6 -1.6703,5.53928 -1.51758,6.25196 l 51.97265,21.91992 23.86524,-17.50195 2.72461,-3.55664 c -0.22885,-0.14243 -0.45999,-0.27609 -0.68945,-0.41602 -27.39877,-3.31358 -52.27682,-5.25289 -75.04493,-6.2793 l 0.0996,-0.83984 z"
|
||||
transform="translate(-522.78594,165.96281)"
|
||||
id="path4417" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#13130f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 128.01367,386.0293 4.48633,9.0957 66,39.375 -18.53906,-26.56445 -0.002,0.002 -51.94531,-21.9082 z"
|
||||
transform="translate(-522.78594,165.96281)"
|
||||
id="path4422" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#7c7a79;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 203.82422,390.61328 c 0,0 -0.57509,0.25215 -0.60156,0.26367 l -23.26172,17.0586 18.38281,26.33984 -1.14844,-4.50586 0.79492,-17.32422 5.83399,-21.83203 z"
|
||||
transform="translate(-522.78594,165.96281)"
|
||||
id="path4427" />
|
||||
</g>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4216"
|
||||
transform="translate(-522.78594,165.96281)"
|
||||
d="M 411.19922,269.32812 C 389.02158,276.55183 382.23256,283.7763 371.75,291 l 25.375,6.25 c 18.2282,-19.41084 23.88453,-20.47312 31.20117,-23.95898 -5.76229,-1.45746 -11.46778,-2.78139 -17.12695,-3.9629 z"
|
||||
style="fill:#3d4144;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4220"
|
||||
d="m -170.91095,464.08782 -8.5,16.125 35.75,3.25 1.625,-16.25 z"
|
||||
style="fill:#3c4247;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="cssccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4226"
|
||||
transform="translate(-522.78594,165.96281)"
|
||||
d="m 411.17969,269.33398 c -24.50302,-5.11518 -48.18402,-7.65405 -72.22657,-7.57031 -42.56105,0.14824 -86.27544,8.47266 -137.78124,25.08203 -40.11789,12.93705 -47.55274,23.33399 -47.55274,23.33399 0,0 -0.48629,0.56241 -0.63476,1.3457 l 0.10351,0.0684 c 65.05383,-30.40559 116.42376,-36.77027 218.33008,-20.63869 11.09267,-7.17661 17.60011,-14.39959 39.76172,-21.62112 z"
|
||||
style="fill:#363c41;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4263"
|
||||
transform="translate(-522.78594,165.96281)"
|
||||
d="m 296.87305,518.20312 c 5.68645,12.75421 3.66653,23.08278 10.71875,32.83399 7.15946,9.89949 34.2935,22.89298 61.25195,32.88086 26.95844,9.98789 39.15707,14.49663 45.25586,14.05469 5.82656,-0.42222 18.90685,-7.25764 24.54101,-10.41407 -0.55038,-0.0177 -1.10725,-0.03 -1.64062,-0.0586 -7,-0.375 -17.75,-3.625 -26.375,-6.5 -8.625,-2.875 -67.14947,-20.67049 -76.375,-33.125 -7.10507,-9.59187 -5.33684,-16.54135 -8.83008,-19.27148 -2.49111,-1.94692 -8.34261,-3.73063 -12.5039,-5.15625 -3.08671,-1.05747 -11.18273,-3.67568 -16.04297,-5.24415 z"
|
||||
style="fill:#10f5fa;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<g
|
||||
id="g4348">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#a6a09b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 244.0293,281.64062 c -11.87933,0.21005 -21.28719,4.70945 -25.45899,14.41407 l -7.76367,15.2207 c 4.63005,-8.00151 13.38623,-11.7657 24.20703,-11.95703 13.84985,-0.24489 31.05521,5.35529 47.24414,15.31641 4.24517,-2.44738 6.87171,-7.03619 7.65625,-8.34375 0.83684,-1.39473 3.09281,-4.54246 4.70703,-7.20118 -17.13681,-11.29215 -35.78244,-17.71107 -50.59179,-17.44922 z m -33.22266,29.63477 c -0.45292,0.78273 -0.88022,1.59229 -1.25195,2.45703 l 1.25195,-2.45703 z"
|
||||
transform="translate(-522.78594,165.96281)"
|
||||
id="path4228" />
|
||||
<path
|
||||
style="fill:#0c0d08;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 210.77539,311.25976 -1.12305,2.28126 c -0.45554,2.37144 2.75076,4.2831 5.21875,3.9746 2.82843,-0.35354 20.06602,-2.56346 32.97071,-2.74023 12.9047,-0.17678 22.09591,1.76761 29.34375,1.41406 1.88682,-0.092 3.57816,-0.69332 5.07226,-1.55468 -16.18893,-9.96112 -33.39429,-15.5613 -47.24414,-15.31641 -10.8208,0.19133 -19.60823,3.93989 -24.23828,11.9414 z"
|
||||
id="path4247"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccssscsc"
|
||||
transform="translate(-522.78594,165.96281)" />
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4258"
|
||||
d="m -179.35432,480.17165 -2.95971,5.51668 39.24443,5.56847 -0.88388,-7.86656 z"
|
||||
style="fill:#111419;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4260"
|
||||
d="m -143.07496,491.2041 -1.00352,-7.90761 2.03293,-16.10721 1.45082,6.56663 z"
|
||||
style="fill:#282d32;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<g
|
||||
id="g4352">
|
||||
<path
|
||||
style="fill:#2f333a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -313.91094,553.83781 -2.375,3.5 -3.875,14.125 93.375,-1.625 c -21.95804,-4.72268 -46.10785,-9.6343 -87.125,-16 z"
|
||||
id="path4262"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccc"
|
||||
style="fill:#585958;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -320.16094,571.44718 -3.125,23.01563 3.25,7.125 99.5,-15.375 -6.29687,-16.40625 z"
|
||||
id="path4264"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g4335">
|
||||
<path
|
||||
style="fill:url(#linearGradient4333);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4325);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -295.16094,608.46281 6.625,27.125 27.125,5.875 c 0,0 38.75,14.5 45.75,29.125 l 5.5,0.875 2.375,-4.625 c 0,0 -13.875,-23.75 -49.625,-33.375 l -1,-1.25 2.25,-11.25 z"
|
||||
id="path4288"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccc" />
|
||||
<path
|
||||
style="fill:#1f2021;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 235.18359,469.82617 272.125,497.75 l 35,6.875 C 300.125,490 261.375,475.5 261.375,475.5 Z"
|
||||
transform="translate(-522.78594,165.96281)"
|
||||
id="path4290"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
</g>
|
||||
<g
|
||||
id="g4297">
|
||||
<path
|
||||
style="fill:#5e5d5c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -271.28594,618.46281 4,7 85.38128,13.44194 9.61872,-8.44194 z"
|
||||
id="path4266"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
style="fill:#242422;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -181.07659,638.77695 c 0,0 22.18548,12.55115 -5.48008,8.04334 -27.66555,-4.5078 -67.97064,-12.55114 -67.97064,-12.55114 l -12.72792,-8.75045 z"
|
||||
id="path4268"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#5e6570;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -172.41453,630.38006 -9.45755,8.3085 9.28077,8.3969 9.54594,-5.3033 z"
|
||||
id="path4270"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
style="fill:#181719;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -271.48416,618.56636 2.19822,-8.60355 103.25,9.875 6,18.125 -2.625,3.875 -9.60983,-10.91789 z"
|
||||
id="path4280"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
</g>
|
||||
<g
|
||||
id="g4305">
|
||||
<path
|
||||
style="fill:#676763;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -164.98991,632.50138 6.18718,9.72272 75.041708,8.22011 8.131734,-6.54073 1.155328,-4.55469 4.153795,-8.23574 -93.255535,-9.12988 z"
|
||||
id="path4272"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<path
|
||||
style="fill:#2f343b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -70.32599,631.08717 5.48008,5.39169 -5.74524,12.90469 -5.204655,-5.54257 c 0.08832,-4.98178 3.353501,-8.62593 5.469815,-12.75381 z"
|
||||
id="path4274"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
style="fill:#202328;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -83.58424,650.17905 3.8007,4.06586 -77.87014,-6.89429 -1.15104,-5.14215 z"
|
||||
id="path4276"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4278"
|
||||
d="m -70.59115,649.38355 -9.1397,4.91406 -3.894905,-4.1034 7.819685,-6.37912 z"
|
||||
style="fill:#97a6b5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4292"
|
||||
d="m -153.03036,495.18342 44.96255,6.76837 1.76776,125.51145 -32.51219,-3.18198 z"
|
||||
style="fill:#676769;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:#181719;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -164.98991,632.50138 89.360622,11.4021 1.155328,-4.55469 4.153795,-8.23574 -93.255535,-9.12988 z"
|
||||
id="path4303"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
<g
|
||||
id="g4282">
|
||||
<path
|
||||
style="fill:#9b9994;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -283.96063,605.18939 1.59099,4.06586 144.42656,16.26346 -6.01041,-45.07806 z"
|
||||
id="path4244"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#2cbfff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 312.64258,435.04297 -5.01172,0.64453 8.00195,8.8418 5.88281,0.41015 -8.87304,-9.89648 z"
|
||||
transform="translate(-522.78594,165.96281)"
|
||||
id="path4246" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#2cbfff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 331.68945,432.58984 -4.78515,0.61524 11.86718,12.93945 6.72461,0.4707 -13.80664,-14.02539 z"
|
||||
transform="translate(-522.78594,165.96281)"
|
||||
id="path4248" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#2cbfff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 351.97266,429.97852 -6.13282,0.78906 16.58594,17.0293 7.58399,0.52929 -18.03711,-18.34765 z"
|
||||
transform="translate(-522.78594,165.96281)"
|
||||
id="path4250" />
|
||||
</g>
|
||||
<g
|
||||
id="g4339">
|
||||
<path
|
||||
style="fill:#4c5053;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -386.31433,498.06271 -5.65686,48.08326 c 45.99186,2.07336 100.55399,7.85718 167.23075,21.21321 l 1.06066,3.0052 c 23.24045,-1.15617 46.44002,-2.32824 77.95852,-0.26516 l 3.35876,3.62392 -10.6066,-78.48885 c -119.63944,-15.8417 -179.55343,-5.16228 -233.34523,2.82842 z"
|
||||
id="path3608"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#413d44;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 344.67578,403.00977 c -16.50546,-0.0586 -30.99426,0.6673 -45.49414,1.38867 l 6.64258,15.02929 74.77539,-10.96093 -0.94727,-1.53907 -2.58789,-2.79101 c -11.81943,-0.77366 -22.46808,-1.09174 -32.38867,-1.12695 z"
|
||||
transform="translate(-522.78594,165.96281)"
|
||||
id="path4412" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -296.22345,497.71282 4.375,6.6875 6.875,-6.8125 z"
|
||||
id="path4242"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
style="stroke:none"
|
||||
id="g4344">
|
||||
<path
|
||||
style="fill:#6d747e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 428.32422,273.29297 c -7.29616,3.47575 -12.94858,4.55152 -31.06055,23.8125 0.0479,0.0864 0.0803,0.17102 0.13086,0.25781 6.62912,19.7106 10.60547,165.375 10.60547,165.375 0,0 41.19295,7.2655 67.125,1.38672 22.33947,-5.06434 38.625,-29.625 51.125,-42.625 12.5,-13 24.89365,-35.29164 33.5,-37.875 6.89763,-2.07046 15.8234,4.4109 29.125,12.375 33.4418,20.02269 42.89394,39.55603 52.79297,65.09375 0.30214,-0.10531 0.47265,-0.12305 0.47265,-0.12305 C 639.49453,419.01054 613.19977,343.11632 511.5,301.5 481.65769,289.2883 454.39027,279.88532 428.32422,273.29297 Z"
|
||||
transform="translate(-522.78594,165.96281)"
|
||||
id="path4234"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccssssccsc" />
|
||||
<ellipse
|
||||
style="opacity:1;fill:#2cbfff;fill-opacity:1;stroke:none;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4261"
|
||||
cx="-58.535938"
|
||||
cy="561.08783"
|
||||
rx="32.25"
|
||||
ry="29.875" />
|
||||
</g>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4218"
|
||||
d="m -205.53595,454.96282 -11.375,19 21.5,-0.875 10.875,-18.875 z"
|
||||
style="fill:#202124;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4254"
|
||||
d="m -222.88428,483.39024 6.01577,-9.47808 21.47301,-0.86336 1.23744,11.49049 z"
|
||||
style="fill:#121518;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4256"
|
||||
d="m -195.50442,473.05324 10.88157,-18.79455 2.39721,10.39322 -12.00029,19.91863 z"
|
||||
style="fill:#1a1e22;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer4"
|
||||
inkscape:label="Leaders"
|
||||
transform="translate(647.36582,-57.672066)"
|
||||
style="display:inline">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4556"
|
||||
d="m -94.323676,683.09816 5.56391,3.21163 5.56059,3.21159 0,-3.66282 11.76151,0 -1.59253,-2.7604 1.59253,-2.76039 -11.76151,0 0,-3.66282 -5.56059,3.21162 -5.56391,3.21159 z"
|
||||
style="display:inline;fill:url(#linearGradient4562);fill-opacity:1;stroke:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="use4558"
|
||||
d="m -71.437651,739.13645 -5.56391,3.21162 -5.56059,3.21159 0,-3.66282 -11.76152,0 1.59254,-2.76039 -1.59254,-2.76039 11.76152,0 0,-3.66282 5.56059,3.21161 5.56391,3.2116 z"
|
||||
style="fill:url(#linearGradient4623);fill-opacity:1;stroke:none" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="-507.44232"
|
||||
y="412.75952"
|
||||
id="text4489"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4491"
|
||||
x="-507.44232"
|
||||
y="412.75952"
|
||||
style="font-size:32px">Button0</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="-60.689339"
|
||||
y="696.94501"
|
||||
id="text4505"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4507"
|
||||
x="-60.689339"
|
||||
y="696.94501"
|
||||
style="font-size:32px">Button10</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4509"
|
||||
y="753.67065"
|
||||
x="-60.689339"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
xml:space="preserve"><tspan
|
||||
y="753.67065"
|
||||
x="-60.689339"
|
||||
id="tspan4511"
|
||||
sodipodi:role="line"
|
||||
style="font-size:32px">Button9</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4440"
|
||||
y="467.91382"
|
||||
x="-507.44232"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:32px"
|
||||
y="467.91382"
|
||||
x="-507.44232"
|
||||
id="tspan4442"
|
||||
sodipodi:role="line">Button7</tspan></text>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4448"
|
||||
d="m -501.44135,408.77695 79.19595,0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -290.72353,319.68149 38.18376,-118.08684"
|
||||
id="path4450"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4452"
|
||||
y="209.51634"
|
||||
x="-419.71732"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:32px;font-family:Sans;-inkscape-font-specification:Sans"
|
||||
y="209.51634"
|
||||
x="-419.71732"
|
||||
id="tspan4454"
|
||||
sodipodi:role="line">Button2</tspan></text>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4456"
|
||||
d="M -355.77735,340.18759 -422.9525,219.97943"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4466"
|
||||
d="m -302.74434,651.31459 94.0452,-113.8442"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="-507.44232"
|
||||
y="516.70416"
|
||||
id="text4468"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4470"
|
||||
x="-507.44232"
|
||||
y="516.70416"
|
||||
style="font-size:32px">Button6</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4472"
|
||||
y="566.90875"
|
||||
x="-455.11642"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:32px"
|
||||
y="566.90875"
|
||||
x="-455.11642"
|
||||
id="tspan4474"
|
||||
sodipodi:role="line">Button4</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="-456.53064"
|
||||
y="616.40625"
|
||||
id="text4476"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4478"
|
||||
x="-456.53064"
|
||||
y="616.40625"
|
||||
style="font-size:32px">Button5</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4480"
|
||||
y="662.36816"
|
||||
x="-310.86664"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:32px"
|
||||
y="662.36816"
|
||||
x="-310.86664"
|
||||
id="tspan4482"
|
||||
sodipodi:role="line">Button3</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:left;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="-252.13301"
|
||||
y="200.32396"
|
||||
id="text4484"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4486"
|
||||
x="-252.13301"
|
||||
y="200.32396"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:32px;font-family:Sans;-inkscape-font-specification:Sans">Button1</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4488"
|
||||
y="247.93217"
|
||||
x="-103.82285"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:32px"
|
||||
y="247.93217"
|
||||
x="-103.82285"
|
||||
id="tspan4490"
|
||||
sodipodi:role="line">Button8</tspan></text>
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -502.14846,464.63839 60.10407,-12.72792"
|
||||
id="path4492"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4494"
|
||||
d="m -496.4916,512.72165 126.57211,-43.84061"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -445.57991,562.92624 140.71425,-43.84062"
|
||||
id="path4496"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4498"
|
||||
d="m -439.21595,608.88818 100.40916,-61.51829"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M -232.03365,357.15816 -108.28996,250.38503"
|
||||
id="path4500"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 38 KiB |
708
data/logitech-g700.svg
Normal file
|
After Width: | Height: | Size: 36 KiB |
1630
data/logitech-g900.svg
Normal file
|
After Width: | Height: | Size: 65 KiB |
@@ -10,12 +10,12 @@
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="414.6424mm"
|
||||
height="285.98199mm"
|
||||
viewBox="0 0 1469.2054 1013.322"
|
||||
width="750"
|
||||
height="750"
|
||||
viewBox="0 0 750.00004 749.99998"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="logitech-mx_master.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@@ -46,22 +46,22 @@
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5128"
|
||||
id="linearGradient5134"
|
||||
id="linearGradient3078"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
spreadMethod="reflect"
|
||||
x1="230.63638"
|
||||
y1="432.30179"
|
||||
x2="238.061"
|
||||
y2="447.85815"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
spreadMethod="reflect" />
|
||||
y2="447.85815" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5204"
|
||||
id="linearGradient5210"
|
||||
id="linearGradient3080"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="196.63423"
|
||||
y1="468.17209"
|
||||
x2="170.13423"
|
||||
y2="402.67206"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
y2="402.67206" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
@@ -70,11 +70,11 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.70710678"
|
||||
inkscape:cx="672.09896"
|
||||
inkscape:cy="504.57351"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="417.6511"
|
||||
inkscape:cy="345.62267"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer2"
|
||||
inkscape:current-layer="layer4"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
@@ -83,9 +83,9 @@
|
||||
fit-margin-right="50"
|
||||
fit-margin-bottom="50"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1016"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-height="1099"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="28"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@@ -100,290 +100,253 @@
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Mouse"
|
||||
inkscape:label="Device"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(522.78594,97.359194)"
|
||||
style="display:inline"
|
||||
sodipodi:insensitive="true">
|
||||
<path
|
||||
style="fill:#433737;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 921.14258,351.92188 c -10.71472,0.3561 17.48242,40.65039 17.48242,40.65039 l -0.99805,38.58007 c -0.0632,-0.10181 -0.1163,-0.2052 -0.18164,-0.30664 -0.41273,0.4635 -0.8827,0.9276 -1.47656,1.39063 C 883.92622,472.81347 836.5,478.32226 756.5,516.32227 c -80,37.99997 -316.69239,159.29807 -343.5,147.5 -0.19217,-0.0846 -0.3462,-0.18445 -0.50195,-0.28321 -0.14711,0.0864 -0.35538,0.19871 -0.49805,0.28321 -0.0138,-0.0118 -0.0272,-0.0234 -0.041,-0.0352 l -0.0273,0.0156 c 20.65212,21.99316 41.34778,28.42752 134.68945,6.01954 l 67.87891,0 c 0,0 31.685,6.41255 73,41.25 56.21397,47.40048 70.15272,37.94645 213.83008,7.3789 120.72766,-25.68496 98.22343,-76.56575 107.07816,-168.1289 5.6329,-58.24749 15.6725,-114.94915 -35.90824,-161 -31.61176,-28.22275 -46.12465,-37.57431 -51.35742,-37.40039 z"
|
||||
transform="translate(-522.78594,-97.359255)"
|
||||
id="path5084"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#3d3d3d;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 766.6582,304.5 c -179.15881,0.002 -367.84961,155.86523 -367.84961,155.86523 -21.93235,32.98189 -41.23548,69.54864 -57.98242,109.60157 7.5036,28.04106 30.67382,59.21512 71.17383,93.85547 59.9519,-35.50497 512.63903,-236.02476 512.5,-244 95.7156,51.99999 -269.006,189 -269,189 -12.27104,5.04673 -14.55606,11.0677 -7.5,18 l 2.06445,1.76953 0.002,0 11.89062,10.1875 c -0.62249,0.15805 -1.26128,0.30706 -1.87305,0.48242 -47.26127,13.54738 -84.55325,23.64795 -114.41015,30.79101 L 615,669.82227 l 63.40625,-16.95508 38.59961,33.06445 c 38.18376,34.64823 37.84255,32.06806 141.42187,14.14258 C 964.16532,681.77523 962.3307,680.80807 974.39258,545.2168 984.45817,432.06647 1011.3318,377.81074 858.42773,320.35742 828.82733,309.23515 797.88772,304.49969 766.6582,304.5 Z"
|
||||
transform="translate(-522.78594,-97.359255)"
|
||||
id="path5077"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="scccccccccsccccssss" />
|
||||
<path
|
||||
style="fill:#826c5e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 924.5,419.82227 c 0.13868,7.95534 -450.25292,207.4789 -512.00586,243.71484 0.15695,0.0995 0.31224,0.19994 0.50586,0.28516 26.80761,11.79809 263.5,-109.50001 343.5,-147.5 80,-38.00001 127.42622,-43.50878 179.46875,-84.08594 0.5964,-0.46501 1.06842,-0.93101 1.48242,-1.39649 -2.56726,-3.98332 -6.80221,-7.67699 -12.95117,-11.01757 z"
|
||||
transform="translate(-522.78594,-97.359255)"
|
||||
id="path5079"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 633.2832,328.9668 c -128.50884,43.87332 -234.47461,131.39843 -234.47461,131.39843 -21.86064,32.87406 -41.10756,69.31169 -57.8164,109.21094 l 0.008,-0.004 61.25,-46.25 c -0.31467,-30.27892 8.67871,-33.61166 108.5,-91 105.67745,-60.75512 109.87649,-54.6167 115.74609,-80.49805 1.83541,-8.09301 4.52898,-16.4514 6.78711,-22.85742 z"
|
||||
transform="translate(-522.78594,-97.359255)"
|
||||
id="path5101"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 640.70703,428.57422 c -3.04651,0.0756 -6.31444,0.73835 -9.96875,2.0918 -19.09188,7.07104 -141.89935,74.20682 -175.71484,98.99414 -48.59449,35.62053 -48.4375,14.14257 -48.4375,14.14257 l -4.24219,-20.85937 c 0,0 -0.0901,0.0489 -0.0937,0.0508 9.1e-4,0.11168 -10e-4,0.2157 0,0.32813 l -61.25,46.25 -0.008,0.004 c -0.0548,0.13093 -0.11124,0.25961 -0.16602,0.39063 7.5036,28.04104 30.67382,59.21512 71.17383,93.85547 0.14966,-0.0886 0.33959,-0.19447 0.49414,-0.28516 0.0169,-0.01 0.0397,-0.0213 0.0566,-0.0312 1.02546,-0.60112 2.16407,-1.25057 3.39844,-1.93945 0.2066,-0.11531 0.43415,-0.23971 0.64648,-0.35743 1.08032,-0.59888 2.2254,-1.22479 3.45118,-1.88476 0.32998,-0.17769 0.67334,-0.36095 1.01367,-0.54297 1.22538,-0.65535 2.51457,-1.33647 3.87109,-2.04687 0.32591,-0.17069 0.65104,-0.34183 0.98438,-0.51563 0.98003,-0.51099 2.03888,-1.05627 3.08203,-1.59375 1.50441,-0.77516 3.19823,-1.63034 4.83007,-2.45898 2.6812,-1.36148 5.48308,-2.77245 8.49219,-4.27149 1.45002,-0.72234 2.95192,-1.46789 4.47461,-2.2207 3.14575,-1.55527 6.43566,-3.16851 9.87696,-4.84766 1.7505,-0.85415 3.50304,-1.70917 5.32617,-2.59375 3.69907,-1.79476 7.57491,-3.665 11.55664,-5.57812 1.62203,-0.77935 3.19102,-1.53607 4.85742,-2.33399 4.85137,-2.32297 9.91021,-4.73306 15.11328,-7.20312 1.05862,-0.50256 2.06054,-0.98002 3.13281,-1.48828 6.27234,-2.97314 12.74159,-6.02841 19.44532,-9.18164 0.19493,-0.0917 0.37504,-0.1777 0.57031,-0.26954 0.88374,-0.4156 1.84183,-0.86083 2.73242,-1.27929 8.89106,-4.17765 18.33343,-8.58591 27.83008,-13.01563 9.48674,-4.42512 19.20352,-8.94432 29.15625,-13.5625 5.63004,-2.6124 11.17539,-5.18811 16.91992,-7.84765 11.03955,-5.11098 22.24511,-10.28776 33.57227,-15.51563 4.59686,-2.12162 9.06381,-4.18813 13.6875,-6.32031 31.79772,-14.66333 64.04275,-29.4992 94.89648,-43.72656 0.64347,-0.29672 1.23671,-0.57103 1.87891,-0.86719 -0.0661,-2.523 -0.5325,-5.27289 -1.4043,-8.3125 -2.95973,-10.3194 -36.14133,-35.93502 -56.06055,-50.55859 C 663.08118,438.83704 654.18972,428.94451 642,428.57812 c -0.42664,-0.0128 -0.85775,-0.0147 -1.29297,-0.004 z"
|
||||
transform="translate(-522.78594,-97.359255)"
|
||||
id="path5107"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:1.00065422;stroke-opacity:1"
|
||||
id="rect5118"
|
||||
width="42.955582"
|
||||
height="22.140448"
|
||||
x="-63.730179"
|
||||
y="299.94894"
|
||||
rx="3.3438475"
|
||||
ry="3.162921"
|
||||
transform="matrix(0.89707316,-0.44188205,0.39545007,0.91848747,0,0)" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 275.08906,417.33778 4.375,22.875 80.75,-60.625 z"
|
||||
id="path5120"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 281.58906,443.33778 91.75,-68.625 c 10.87423,-8.13345 34.03844,-10.26653 -9.25,21.375 -37.38734,27.32814 -82.5,47.25 -82.5,47.25 z"
|
||||
id="path5122"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cssc" />
|
||||
<path
|
||||
style="fill:url(#linearGradient5134);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 197.58906,448.96278 c 6.125,13 10.625,29.125 10.625,29.125 0,0 57.34269,-25.16319 68.25,-30.75 -0.13843,-9.48681 -3.52264,-22.72856 -8.375,-27.875 -27.125,3.75 -70.5,29.5 -70.5,29.5 z"
|
||||
id="path5124"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
style="fill:#797979;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 3.47828,341.26173 c 0,0 6.886406,9.46214 7.95495,30.22881 -9.7125082,0.38797 -22.45064,-1.59098 -48.96714,10.78339 -26.5165,12.37437 -35.70889,37.29989 -35.70889,37.29989 l -6.84404,-0.46967 -8.1731,-22.75242 c 0,0 5.196794,-22.7334 30.485095,-40.41753 C -32.486544,338.25007 3.47828,341.26173 3.47828,341.26173 Z"
|
||||
id="path5138"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccsccczc" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 527.89648,441.94336 c -11.21543,-6.8e-4 -35.91089,1.15173 -54.02148,10.37891 -20.66776,10.53002 -34.76604,36.66892 -38.41016,44.00195 l 7.17383,19.9707 c 2.6388,-7.65898 11.92913,-28.82418 37.36133,-42.34765 27.46537,-14.60461 48.83613,-10.8705 53.86328,-9.67383 -1.11415,-11.22385 -3.86953,-18.48609 -5.74414,-22.32617 -0.0929,-1.7e-4 -0.12786,-0.004 -0.22266,-0.004 z"
|
||||
transform="translate(-522.78594,-97.359255)"
|
||||
id="path5140"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 485.25195,479.63281 c -26.5165,12.37437 -35.70886,37.34486 -35.70886,37.34486 9.75656,-6.29912 84.5483,-48.37571 84.5483,-48.37571 -6.04962,0.7682 -22.32294,-1.34352 -48.83944,11.03085 z"
|
||||
transform="translate(-522.78594,-97.359255)"
|
||||
id="path5145"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="sccs" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="Actions"
|
||||
style="display:inline"
|
||||
transform="translate(647.36582,205.64997)"
|
||||
sodipodi:insensitive="true">
|
||||
<path
|
||||
style="display:inline;fill:#868686;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -6.1035156,230.91992 c -19.3024674,3.60682 -35.0488854,16.31894 -52.6556354,24.21599 -51.094769,27.0536 -101.437299,55.94388 -149.051399,88.65901 -9.95415,5.51243 -22.54214,11.99271 -33.83984,6.61914 -6.38959,-3.90926 -7.96324,-11.94005 -8.66992,-18.82617 -15.28799,12.40039 -32.51253,23.07504 -46.6875,36.30469 11.43671,32.54466 37.53518,57.07166 61.90234,80.5625 1.79409,1.58773 4.14015,-3.28155 6.15485,-2.80815 C -144.1825,402.09598 -56.798635,363.92186 29.448769,323.50255 46.66114,315.61589 63.86767,307.71041 80.912109,299.46484 75.326356,287.31278 62.865961,280.7519 53.502952,271.87742 35.5688,257.98999 18.22755,242.94827 -1.484375,231.63672 c -1.4916064,-0.46547 -3.0527704,-0.75113 -4.6191406,-0.7168 z"
|
||||
id="path5151"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;fill:#868686;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -28.414062,137.02148 c -76.907488,29.50803 -148.819988,71.80459 -213.308758,122.89206 -13.55128,17.43946 -23.11685,37.54603 -33.88323,56.82187 -3.7754,7.32186 -7.34192,14.58222 -10.84707,22.04584 11.21464,-8.37958 22.86793,-16.47415 33.20898,-25.8125 -0.25698,-17.631 11.68533,-33.06792 26.42383,-41.59375 31.52229,-22.08766 66.11652,-39.23093 99.04413,-59.05073 30.395219,-17.37588 61.961588,-32.92482 91.295711,-52.0313 6.692064,-6.28955 7.910236,-15.49613 9.814453,-23.93359 l -0.935164,0.35421 -0.812882,0.30789 z"
|
||||
id="path5162"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;fill:#868686;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 152.77364,310.2307 c 1.1582,6.05599 2.3164,12.11198 3.4746,18.16797 21.37631,-16.04948 42.75261,-32.09896 64.12891,-48.14843 -22.5345,9.99349 -45.06901,19.98697 -67.60351,29.98046 z"
|
||||
id="path5173"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;fill:#868686;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 261.2834,263.28539 c -12.21657,2.16029 -20.42211,12.86093 -30.56476,19.12846 -18.40968,13.8199 -38.36778,28.59535 -55.81414,41.82076 29.28272,-15.22709 58.48771,-31.62916 82.88671,-54.0625 1.70896,-1.96865 4.73868,-4.48833 4.69532,-6.85547 -0.39767,-0.0641 -0.80252,-0.0596 -1.20313,-0.0312 z"
|
||||
id="path5187"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;fill:url(#linearGradient5210);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 42.546875,449.04102 c 19.339052,15.73498 36.723013,34.10436 57.603515,47.67578 20.60808,9.36671 43.55773,2.08926 64.83959,-0.49809 35.57938,-6.15258 71.49952,-11.18454 106.39931,-20.59787 15.04923,-4.60526 29.72058,-14.93837 34.46618,-30.81811 9.43121,-25.52623 9.54274,-53.05503 12.87313,-79.81517 -0.62149,-4.24546 3.55982,-14.72991 -0.52003,-14.51534 -91.88723,32.85626 -183.77446,65.71253 -275.661695,98.5688 z"
|
||||
id="path5192"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;fill:#868686;fill-opacity:1;stroke:none;stroke-width:1.00065422;stroke-opacity:1"
|
||||
d="m -27.103516,182.32422 c -10.397754,4.71799 -21.409505,9.91406 -30.929687,15.4375 2.508683,3.97971 3.88786,8.5168 5.707031,12.72266 10.007293,-5.84796 21.032198,-9.89858 31.039063,-15.81641 -1.598593,-4.02995 -3.118058,-9.77197 -5.816407,-12.34375 z"
|
||||
id="rect5212"
|
||||
inkscape:connector-curvature="0" />
|
||||
transform="translate(522.78594,-165.96284)"
|
||||
style="display:inline">
|
||||
<g
|
||||
id="g3058"
|
||||
transform="matrix(0.70142923,0,0,0.70142923,-172.43767,286.8878)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5084"
|
||||
transform="translate(-522.78594,-97.359255)"
|
||||
d="m 921.14258,351.92188 c -10.71472,0.3561 17.48242,40.65039 17.48242,40.65039 l -0.99805,38.58007 c -0.0632,-0.10181 -0.1163,-0.2052 -0.18164,-0.30664 -0.41273,0.4635 -0.8827,0.9276 -1.47656,1.39063 C 883.92622,472.81347 836.5,478.32226 756.5,516.32227 c -80,37.99997 -316.69239,159.29807 -343.5,147.5 -0.19217,-0.0846 -0.3462,-0.18445 -0.50195,-0.28321 -0.14711,0.0864 -0.35538,0.19871 -0.49805,0.28321 -0.0138,-0.0118 -0.0272,-0.0234 -0.041,-0.0352 l -0.0273,0.0156 c 20.65212,21.99316 41.34778,28.42752 134.68945,6.01954 l 67.87891,0 c 0,0 31.685,6.41255 73,41.25 56.21397,47.40048 70.15272,37.94645 213.83008,7.3789 120.72766,-25.68496 98.22343,-76.56575 107.07816,-168.1289 5.6329,-58.24749 15.6725,-114.94915 -35.90824,-161 -31.61176,-28.22275 -46.12465,-37.57431 -51.35742,-37.40039 z"
|
||||
style="fill:#433737;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.42566061px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="scccccccccsccccssss"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5077"
|
||||
transform="translate(-522.78594,-97.359255)"
|
||||
d="m 766.6582,304.5 c -179.15881,0.002 -367.84961,155.86523 -367.84961,155.86523 -21.93235,32.98189 -41.23548,69.54864 -57.98242,109.60157 7.5036,28.04106 30.67382,59.21512 71.17383,93.85547 59.9519,-35.50497 512.63903,-236.02476 512.5,-244 95.7156,51.99999 -269.006,189 -269,189 -12.27104,5.04673 -14.55606,11.0677 -7.5,18 l 2.06445,1.76953 0.002,0 11.89062,10.1875 c -0.62249,0.15805 -1.26128,0.30706 -1.87305,0.48242 -47.26127,13.54738 -84.55325,23.64795 -114.41015,30.79101 L 615,669.82227 l 63.40625,-16.95508 38.59961,33.06445 c 38.18376,34.64823 37.84255,32.06806 141.42187,14.14258 C 964.16532,681.77523 962.3307,680.80807 974.39258,545.2168 984.45817,432.06647 1011.3318,377.81074 858.42773,320.35742 828.82733,309.23515 797.88772,304.49969 766.6582,304.5 z"
|
||||
style="fill:#3d3d3d;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.42566061px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5079"
|
||||
transform="translate(-522.78594,-97.359255)"
|
||||
d="m 924.5,419.82227 c 0.13868,7.95534 -450.25292,207.4789 -512.00586,243.71484 0.15695,0.0995 0.31224,0.19994 0.50586,0.28516 26.80761,11.79809 263.5,-109.50001 343.5,-147.5 80,-38.00001 127.42622,-43.50878 179.46875,-84.08594 0.5964,-0.46501 1.06842,-0.93101 1.48242,-1.39649 -2.56726,-3.98332 -6.80221,-7.67699 -12.95117,-11.01757 z"
|
||||
style="fill:#826c5e;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5101"
|
||||
transform="translate(-522.78594,-97.359255)"
|
||||
d="m 633.2832,328.9668 c -128.50884,43.87332 -234.47461,131.39843 -234.47461,131.39843 -21.86064,32.87406 -41.10756,69.31169 -57.8164,109.21094 l 0.008,-0.004 61.25,-46.25 c -0.31467,-30.27892 8.67871,-33.61166 108.5,-91 105.67745,-60.75512 109.87649,-54.6167 115.74609,-80.49805 1.83541,-8.09301 4.52898,-16.4514 6.78711,-22.85742 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.42566061px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5107"
|
||||
transform="translate(-522.78594,-97.359255)"
|
||||
d="m 640.70703,428.57422 c -3.04651,0.0756 -6.31444,0.73835 -9.96875,2.0918 -19.09188,7.07104 -141.89935,74.20682 -175.71484,98.99414 -48.59449,35.62053 -48.4375,14.14257 -48.4375,14.14257 l -4.24219,-20.85937 c 0,0 -0.0901,0.0489 -0.0937,0.0508 9.1e-4,0.11168 -10e-4,0.2157 0,0.32813 l -61.25,46.25 -0.008,0.004 c -0.0548,0.13093 -0.11124,0.25961 -0.16602,0.39063 7.5036,28.04104 30.67382,59.21512 71.17383,93.85547 0.14966,-0.0886 0.33959,-0.19447 0.49414,-0.28516 0.0169,-0.01 0.0397,-0.0213 0.0566,-0.0312 1.02546,-0.60112 2.16407,-1.25057 3.39844,-1.93945 0.2066,-0.11531 0.43415,-0.23971 0.64648,-0.35743 1.08032,-0.59888 2.2254,-1.22479 3.45118,-1.88476 0.32998,-0.17769 0.67334,-0.36095 1.01367,-0.54297 1.22538,-0.65535 2.51457,-1.33647 3.87109,-2.04687 0.32591,-0.17069 0.65104,-0.34183 0.98438,-0.51563 0.98003,-0.51099 2.03888,-1.05627 3.08203,-1.59375 1.50441,-0.77516 3.19823,-1.63034 4.83007,-2.45898 2.6812,-1.36148 5.48308,-2.77245 8.49219,-4.27149 1.45002,-0.72234 2.95192,-1.46789 4.47461,-2.2207 3.14575,-1.55527 6.43566,-3.16851 9.87696,-4.84766 1.7505,-0.85415 3.50304,-1.70917 5.32617,-2.59375 3.69907,-1.79476 7.57491,-3.665 11.55664,-5.57812 1.62203,-0.77935 3.19102,-1.53607 4.85742,-2.33399 4.85137,-2.32297 9.91021,-4.73306 15.11328,-7.20312 1.05862,-0.50256 2.06054,-0.98002 3.13281,-1.48828 6.27234,-2.97314 12.74159,-6.02841 19.44532,-9.18164 0.19493,-0.0917 0.37504,-0.1777 0.57031,-0.26954 0.88374,-0.4156 1.84183,-0.86083 2.73242,-1.27929 8.89106,-4.17765 18.33343,-8.58591 27.83008,-13.01563 9.48674,-4.42512 19.20352,-8.94432 29.15625,-13.5625 5.63004,-2.6124 11.17539,-5.18811 16.91992,-7.84765 11.03955,-5.11098 22.24511,-10.28776 33.57227,-15.51563 4.59686,-2.12162 9.06381,-4.18813 13.6875,-6.32031 31.79772,-14.66333 64.04275,-29.4992 94.89648,-43.72656 0.64347,-0.29672 1.23671,-0.57103 1.87891,-0.86719 -0.0661,-2.523 -0.5325,-5.27289 -1.4043,-8.3125 -2.95973,-10.3194 -36.14133,-35.93502 -56.06055,-50.55859 C 663.08118,438.83704 654.18972,428.94451 642,428.57812 c -0.42664,-0.0128 -0.85775,-0.0147 -1.29297,-0.004 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.42566061px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<rect
|
||||
transform="matrix(0.89707316,-0.44188205,0.39545007,0.91848747,0,0)"
|
||||
ry="4.5092516"
|
||||
rx="4.7671914"
|
||||
y="299.94894"
|
||||
x="-63.730179"
|
||||
height="22.140448"
|
||||
width="42.955582"
|
||||
id="rect5118"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:1.4265933;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5120"
|
||||
d="m 275.08906,417.33778 4.375,22.875 80.75,-60.625 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.42566061px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="cssc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5122"
|
||||
d="m 281.58906,443.33778 91.75,-68.625 c 10.87423,-8.13345 34.03844,-10.26653 -9.25,21.375 -37.38734,27.32814 -82.5,47.25 -82.5,47.25 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.42566061px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5124"
|
||||
d="m 197.58906,448.96278 c 6.125,13 10.625,29.125 10.625,29.125 0,0 57.34269,-25.16319 68.25,-30.75 -0.13843,-9.48681 -3.52264,-22.72856 -8.375,-27.875 -27.125,3.75 -70.5,29.5 -70.5,29.5 z"
|
||||
style="fill:url(#linearGradient3078);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.42566073;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccsccczc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5138"
|
||||
d="m 3.47828,341.26173 c 0,0 6.886406,9.46214 7.95495,30.22881 -9.7125082,0.38797 -22.45064,-1.59098 -48.96714,10.78339 -26.5165,12.37437 -35.70889,37.29989 -35.70889,37.29989 l -6.84404,-0.46967 -8.1731,-22.75242 c 0,0 5.196794,-22.7334 30.485095,-40.41753 C -32.486544,338.25007 3.47828,341.26173 3.47828,341.26173 z"
|
||||
style="fill:#797979;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.42566061px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5140"
|
||||
transform="translate(-522.78594,-97.359255)"
|
||||
d="m 527.89648,441.94336 c -11.21543,-6.8e-4 -35.91089,1.15173 -54.02148,10.37891 -20.66776,10.53002 -34.76604,36.66892 -38.41016,44.00195 l 7.17383,19.9707 c 2.6388,-7.65898 11.92913,-28.82418 37.36133,-42.34765 27.46537,-14.60461 48.83613,-10.8705 53.86328,-9.67383 -1.11415,-11.22385 -3.86953,-18.48609 -5.74414,-22.32617 -0.0929,-1.7e-4 -0.12786,-0.004 -0.22266,-0.004 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="sccs"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5145"
|
||||
transform="translate(-522.78594,-97.359255)"
|
||||
d="m 485.25195,479.63281 c -26.5165,12.37437 -35.70886,37.34486 -35.70886,37.34486 9.75656,-6.29912 84.5483,-48.37571 84.5483,-48.37571 -6.04962,0.7682 -22.32294,-1.34352 -48.83944,11.03085 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5151"
|
||||
d="m -6.1035156,230.91992 c -19.3024674,3.60682 -35.0488854,16.31894 -52.6556354,24.21599 -51.094769,27.0536 -101.437299,55.94388 -149.051399,88.65901 -9.95415,5.51243 -22.54214,11.99271 -33.83984,6.61914 -6.38959,-3.90926 -7.96324,-11.94005 -8.66992,-18.82617 -15.28799,12.40039 -32.51253,23.07504 -46.6875,36.30469 11.43671,32.54466 37.53518,57.07166 61.90234,80.5625 1.79409,1.58773 4.14015,-3.28155 6.15485,-2.80815 C -144.1825,402.09598 -56.798635,363.92186 29.448769,323.50255 46.66114,315.61589 63.86767,307.71041 80.912109,299.46484 75.326356,287.31278 62.865961,280.7519 53.502952,271.87742 35.5688,257.98999 18.22755,242.94827 -1.484375,231.63672 c -1.4916064,-0.46547 -3.0527704,-0.75113 -4.6191406,-0.7168 z"
|
||||
style="fill:#868686;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
|
||||
transform="translate(124.57988,108.29077)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5162"
|
||||
d="m -28.414062,137.02148 c -76.907488,29.50803 -148.819988,71.80459 -213.308758,122.89206 -13.55128,17.43946 -23.11685,37.54603 -33.88323,56.82187 -3.7754,7.32186 -7.34192,14.58222 -10.84707,22.04584 11.21464,-8.37958 22.86793,-16.47415 33.20898,-25.8125 -0.25698,-17.631 11.68533,-33.06792 26.42383,-41.59375 31.52229,-22.08766 66.11652,-39.23093 99.04413,-59.05073 30.395219,-17.37588 61.961588,-32.92482 91.295711,-52.0313 6.692064,-6.28955 7.910236,-15.49613 9.814453,-23.93359 l -0.935164,0.35421 -0.812882,0.30789 z"
|
||||
style="fill:#868686;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
|
||||
transform="translate(124.57988,108.29077)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5173"
|
||||
d="m 152.77364,310.2307 c 1.1582,6.05599 2.3164,12.11198 3.4746,18.16797 21.37631,-16.04948 42.75261,-32.09896 64.12891,-48.14843 -22.5345,9.99349 -45.06901,19.98697 -67.60351,29.98046 z"
|
||||
style="fill:#868686;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
|
||||
transform="translate(124.57988,108.29077)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5187"
|
||||
d="m 261.2834,263.28539 c -12.21657,2.16029 -20.42211,12.86093 -30.56476,19.12846 -18.40968,13.8199 -38.36778,28.59535 -55.81414,41.82076 29.28272,-15.22709 58.48771,-31.62916 82.88671,-54.0625 1.70896,-1.96865 4.73868,-4.48833 4.69532,-6.85547 -0.39767,-0.0641 -0.80252,-0.0596 -1.20313,-0.0312 z"
|
||||
style="fill:#868686;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
|
||||
transform="translate(124.57988,108.29077)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5192"
|
||||
d="m 42.546875,449.04102 c 19.339052,15.73498 36.723013,34.10436 57.603515,47.67578 20.60808,9.36671 43.55773,2.08926 64.83959,-0.49809 35.57938,-6.15258 71.49952,-11.18454 106.39931,-20.59787 15.04923,-4.60526 29.72058,-14.93837 34.46618,-30.81811 9.43121,-25.52623 9.54274,-53.05503 12.87313,-79.81517 -0.62149,-4.24546 3.55982,-14.72991 -0.52003,-14.51534 -91.88723,32.85626 -183.77446,65.71253 -275.661695,98.5688 z"
|
||||
style="fill:url(#linearGradient3080);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
|
||||
transform="translate(124.57988,108.29077)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect5212"
|
||||
d="m -27.103516,182.32422 c -10.397754,4.71799 -21.409505,9.91406 -30.929687,15.4375 2.508683,3.97971 3.88786,8.5168 5.707031,12.72266 10.007293,-5.84796 21.032198,-9.89858 31.039063,-15.81641 -1.598593,-4.02995 -3.118058,-9.77197 -5.816407,-12.34375 z"
|
||||
style="fill:#868686;fill-opacity:1;stroke:none;display:inline"
|
||||
transform="translate(124.57988,108.29077)" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer4"
|
||||
inkscape:label="Leaders"
|
||||
transform="translate(647.36582,205.64997)"
|
||||
style="display:inline">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -345.36582,473.672 139,-91"
|
||||
id="path5269"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -367.36582,346.672 192,-87"
|
||||
id="path5271"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -336.36582,223.672 152,5"
|
||||
id="path5273"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 22.63418,39.672 -60,152"
|
||||
id="path5275"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 296.63418,105.672 -132,205"
|
||||
id="path5277"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 431.63418,222.672 -187,54"
|
||||
id="path5279"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 398.63418,512.672 -163,-63"
|
||||
id="path5281"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer5"
|
||||
inkscape:label="Controls"
|
||||
transform="translate(647.36582,205.64997)"
|
||||
transform="translate(647.36582,-57.672066)"
|
||||
style="display:inline">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-352.13092"
|
||||
y="486.22949"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
x="-502.6427"
|
||||
y="633.16559"
|
||||
id="text4473"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4475"
|
||||
x="-352.13092"
|
||||
y="486.22949">Button0</tspan></text>
|
||||
x="-502.6427"
|
||||
y="633.16559"
|
||||
style="font-size:32px">Button0</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4477"
|
||||
y="225.95509"
|
||||
x="-348.13092"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
y="337.89117"
|
||||
x="-491.6427"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
xml:space="preserve"><tspan
|
||||
y="225.95509"
|
||||
x="-348.13092"
|
||||
y="337.89117"
|
||||
x="-491.6427"
|
||||
id="tspan4479"
|
||||
sodipodi:role="line">Button1</tspan></text>
|
||||
sodipodi:role="line"
|
||||
style="font-size:32px">Button1</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-376.13092"
|
||||
y="351.68076"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
x="-484.6427"
|
||||
y="453.61685"
|
||||
id="text4481"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4483"
|
||||
x="-376.13092"
|
||||
y="351.68076">Button2</tspan></text>
|
||||
x="-484.6427"
|
||||
y="453.61685"
|
||||
style="font-size:32px">Button2</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4485"
|
||||
y="218.54855"
|
||||
x="442.71985"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
y="235.48463"
|
||||
x="-59.791931"
|
||||
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
xml:space="preserve"><tspan
|
||||
y="218.54855"
|
||||
x="442.71985"
|
||||
y="235.48463"
|
||||
x="-59.791931"
|
||||
id="tspan4487"
|
||||
sodipodi:role="line">Button3</tspan></text>
|
||||
sodipodi:role="line"
|
||||
style="font-size:32px">Button3</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="296.71985"
|
||||
y="96.274208"
|
||||
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="-265.79193"
|
||||
y="177.2103"
|
||||
id="text4489"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4491"
|
||||
x="296.71985"
|
||||
y="96.274208">Button4</tspan></text>
|
||||
x="-265.79193"
|
||||
y="177.2103"
|
||||
style="font-size:32px">Button4</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4493"
|
||||
y="524.99994"
|
||||
x="402.71985"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
y="713.93604"
|
||||
x="-229.79195"
|
||||
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
xml:space="preserve"><tspan
|
||||
y="524.99994"
|
||||
x="402.71985"
|
||||
y="713.93604"
|
||||
x="-229.79195"
|
||||
id="tspan4495"
|
||||
sodipodi:role="line">Button5</tspan></text>
|
||||
sodipodi:role="line"
|
||||
style="font-size:32px">Button5</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-29.28018"
|
||||
y="29.72551"
|
||||
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="-499.79196"
|
||||
y="209.66159"
|
||||
id="text4497"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4499"
|
||||
x="-29.28018"
|
||||
y="29.72551">Button6</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-425.66364"
|
||||
y="83.6576"
|
||||
id="text4572"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="-425.66364"
|
||||
y="83.6576"
|
||||
id="tspan4576">Resolution0</tspan></text>
|
||||
<rect
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="rect4600"
|
||||
width="323.85489"
|
||||
height="120.2081"
|
||||
x="-469.70047"
|
||||
y="11.469827"
|
||||
rx="10.321068"
|
||||
ry="10.321068" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Title">
|
||||
<text
|
||||
transform="translate(647.36582,205.64997)"
|
||||
xml:space="preserve"
|
||||
style="display:inline;font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-261.24213"
|
||||
y="-97.912132"
|
||||
id="text4223"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4225"
|
||||
x="-261.24213"
|
||||
y="-97.912132"
|
||||
style="font-size:70.00000763px">Logitech MX Master</tspan></text>
|
||||
x="-499.79196"
|
||||
y="209.66159"
|
||||
style="font-size:32px">Button6</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -484.36582,336.67204 121,88"
|
||||
id="path3082"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -480.36582,448.67204 148,-7"
|
||||
id="path3084"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -492.36582,626.67204 130,-108"
|
||||
id="path3086"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -375.36582,214.67204 133,180"
|
||||
id="path3088"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -167.36582,192.67204 81,275"
|
||||
id="path3092"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 34.63418,254.67204 -67,189"
|
||||
id="path3094"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -152.36582,675.67204 85,-87"
|
||||
id="path3096"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 21 KiB |
@@ -9,12 +9,12 @@
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="414.6424mm"
|
||||
height="285.98199mm"
|
||||
viewBox="0 0 1469.2054 1013.322"
|
||||
width="750"
|
||||
height="750"
|
||||
viewBox="0 0 750.00004 749.99998"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="roccat-kone-xtd.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
@@ -26,10 +26,10 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.3581868"
|
||||
inkscape:cx="554.68333"
|
||||
inkscape:cy="461.59649"
|
||||
inkscape:cx="337.88759"
|
||||
inkscape:cy="511.56243"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer5"
|
||||
inkscape:current-layer="layer4"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
@@ -37,10 +37,10 @@
|
||||
fit-margin-left="50"
|
||||
fit-margin-right="50"
|
||||
fit-margin-bottom="50"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1571"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="55"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1099"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="28"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@@ -55,307 +55,173 @@
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Mouse"
|
||||
inkscape:label="Device"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(522.78594,97.359194)"
|
||||
transform="translate(522.78594,-165.96284)"
|
||||
style="display:inline">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:20.31594276;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m -6.8766439,519.77381 c -32.5046101,10.85914 -64.2932331,9.07935 -55.9542041,-23.77308 18.883288,-74.39257 -57.845532,2.41084 -29.233145,-133.3763"
|
||||
id="path4770"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csc" />
|
||||
<path
|
||||
style="fill:#293843;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m -33.934887,422.04568 10.14038,-25.10953 C 52.122953,323.19727 160.74504,269.07207 269.83981,256.48052 c 114.24665,-13.18617 232.89306,-1.04277 284.3675,72.85307 67.68352,97.16539 16.07476,170.11753 -8.69176,195.56454 -20.05502,20.60604 -39.26023,38.76732 -57.46217,50.70193 -38.08063,24.96863 -99.02413,29.12078 -118.30443,27.5239 -56.28478,-4.66179 -227.65266,41.307 -235.6432,46.83891 L 32.219046,607.9527 C 4.8894737,559.61921 -21.751345,509.50644 -33.934887,422.04568 Z"
|
||||
id="path3661"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccsssssccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 520.63342,372.91486 c -22.02158,0.11026 -45.15654,9.22867 -63.99943,19.07328 -68.64532,35.8642 -269.2094,153.12888 -338.02986,180.28255 l -87.122352,34.37512 c 0.245863,0.43536 0.49112,0.87206 0.737105,1.30711 l 39.216027,16.16965 c 44.83999,-15.41316 98.86516,-40.41176 154.72423,-67.21674 90.48008,-43.41854 177.45369,-92.45774 236.96271,-121.89569 60.39622,-29.87684 105.87888,-24.18751 112.83284,44.85426 6.15884,-13.91293 10.75607,-30.17964 11.63778,-48.45529 -13.44827,-44.58801 -39.32739,-58.63259 -66.95905,-58.49425 z"
|
||||
id="path4463" />
|
||||
<path
|
||||
style="fill:#00ff3a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 460.17444,405.06363 c -25.33816,12.5814 -164.20311,89.16529 -247.36725,132.94909 -31.24494,16.55348 -62.91668,32.44366 -95.5461,46.08015 l 3.13236,9.65662 c 54.85379,-22.99389 108.07344,-49.78006 161.39646,-76.09146 64.31558,-32.64428 127.12882,-68.2385 192.32459,-99.13545 18.32983,-7.64259 38.30614,-12.8303 58.27155,-10.58417 14.47996,1.85097 28.06901,9.59531 37.24885,20.96153 6.66994,-53.74538 -76.10417,-40.33748 -109.46046,-23.83631 z"
|
||||
id="path4468"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
<path
|
||||
style="fill:#202427;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 270.88842,559.80819 26.12051,4.09732 62.14289,-30.90074 c 11.97455,-20.17142 5.93562,-23.53024 5.29239,-31.92505 l -91.50713,47.4608 c -3.16993,2.58552 -6.42443,5.13123 -2.04866,11.26767 z"
|
||||
id="path4545"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
<path
|
||||
style="fill:#202427;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 392.10122,486.05615 c 1.23298,4.69552 4.04803,7.598 -1.19506,19.63307 l -9.73117,17.58438 80.75159,-31.4129 c 5.77716,-10.78358 11.4074,-21.61616 11.4384,-34.31516 -2.7867,-11.40006 -8.20083,-9.22506 -13.65779,-6.82888 z"
|
||||
id="path4547"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
<path
|
||||
style="fill:#202427;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 20.837165,461.33753 26.414193,480.9345 62.94875,466.25238 55.307676,431.63187 Z"
|
||||
id="path4549"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
style="fill:#202427;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 178.69842,365.35554 12.29201,31.24217 56.50906,-25.09617 -12.46274,-27.48628 z"
|
||||
id="path4551"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#202427;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 261.4987,335.64987 11.95056,26.63267 49.85089,-20.31594 12.80416,-3.41445 -6.82888,-14.16994 -12.97489,-3.41445 z"
|
||||
id="path4553"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-style:normal;font-weight:normal;font-size:medium;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;writing-mode:tb-rl;fill:#838d96;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4560"
|
||||
d="m 204.43745,364.0435 2.09895,5.60714 5.81901,-2.56255 0.64062,1.71134 -5.81901,2.56254 2.09895,5.60714 -1.75511,0.77292 -2.09894,-5.60715 -5.81902,2.56255 -0.64059,-1.71135 5.81898,-2.56254 -2.09892,-5.60714 1.75508,-0.7729 z" />
|
||||
<path
|
||||
d="m 305.42303,329.94388 4.03768,8.95391 -2.72436,1.22853 -4.03769,-8.95391 2.72437,-1.22853 z"
|
||||
id="path4567"
|
||||
inkscape:connector-curvature="0"
|
||||
style="font-style:normal;font-weight:normal;font-size:medium;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#838d96;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
style="font-style:normal;font-weight:normal;font-size:medium;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#838d96;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4569"
|
||||
d="m 46.989112,448.7916 2.557622,11.39542 -2.682847,1.56354 -2.557622,-11.39545 2.682847,-1.56351 z" />
|
||||
<path
|
||||
d="m 42.643233,451.50777 2.557622,11.39545 -2.682847,1.56351 -2.557622,-11.39545 2.682847,-1.56351 z"
|
||||
id="path4577"
|
||||
inkscape:connector-curvature="0"
|
||||
style="font-style:normal;font-weight:normal;font-size:medium;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#838d96;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
style="font-style:normal;font-weight:normal;font-size:medium;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#838d96;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4579"
|
||||
d="m 38.478433,454.34466 2.557622,11.39543 -2.682847,1.56354 -2.557622,-11.39545 2.682847,-1.56352 z" />
|
||||
<path
|
||||
style="fill:#838d96;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 119.43841,465.4441 5.37199,3.74229 1.87114,-8.26926 z"
|
||||
id="path4581"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#838d96;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 99.218,376.23286 -2.29366,6.51884 6.33774,-3.25942 z"
|
||||
id="path4583"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 370.13999,299.12951 c -0.43414,-0.004 -0.88599,0.004 -1.35658,0.0243 -114.61991,18.29248 -262.7613,57.8235 -362.6396132,162.97056 l -0.2413441,18.34924 -23.0804397,18.75305 c 0.295394,0.96107 0.592605,1.91666 0.892085,2.8672 L 6.8682998,485.78508 11.938416,498.5815 c 3.022522,1.91455 4.542353,4.99753 13.03731,2.65575 0,0 35.049508,-13.87527 66.878294,-31.62836 25.86269,-14.4254 169.13513,-92.29377 297.45122,-135.68783 3.53168,-1.85807 6.92052,-3.82383 2.89753,-11.3479 l -11.34789,-17.38339 c -1.68431,-3.27833 -4.20267,-6.0005 -10.71489,-6.06024 z m 0.85055,7.18994 c 0.76127,-0.0183 1.49621,0.14715 2.1413,0.68389 2.28062,2.60105 3.95393,5.73706 5.90572,8.6044 2.36789,3.85426 5.13602,7.51375 7.31692,11.43239 -2.00889,0.76437 -4.02217,1.5172 -6.0383,2.2622 -74.38121,26.47497 -146.51346,58.91354 -216.93155,94.53357 -23.7859,11.80119 -47.13201,24.45131 -70.49007,37.07193 -21.87976,12.03816 -44.368571,22.99172 -67.494965,32.39674 -2.178032,0.79387 -4.91012,2.49014 -7.139522,0.97798 -2.462342,-3.62775 -3.065109,-8.18739 -5.10326,-12.05744 -0.191754,-5.72806 0.125694,-11.45575 0.125574,-17.18406 19.24401,-19.99827 40.662677,-37.85032 63.501803,-53.60899 56.88977,-39.14613 121.81546,-65.28367 188.25625,-83.14833 34.45174,-9.02055 69.30996,-16.66573 104.56505,-21.77335 0.46215,-0.10291 0.9283,-0.17995 1.38505,-0.19093 z"
|
||||
id="path4585" />
|
||||
<path
|
||||
style="fill:#202427;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 69.56866,436.43193 c 2.34022,-18.39325 11.0874,-31.41629 35.56456,-46.25604 24.47717,-14.83973 51.02774,-12.17822 62.53237,-11.10613 4.19739,0.39116 6.14741,2.1271 9.65751,8.20888 l 9.65751,18.10785 c -9.72905,-3.24303 -45.31306,0.55135 -63.36379,8.82104 -23.93977,10.96767 -32.63451,13.417 -49.78556,44.90031 z"
|
||||
id="path4590"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="czsccscc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:19.26995659px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#838d96;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="541.47949"
|
||||
y="544.12469"
|
||||
id="text4751"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="matrix(0.81792144,-0.30782972,0,1.2226113,0,0)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4753"
|
||||
<g
|
||||
id="g3136"
|
||||
transform="matrix(0.68876596,0,0,0.68876596,-231.95789,223.11559)">
|
||||
<path
|
||||
sodipodi:nodetypes="csc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4770"
|
||||
d="m -6.8766439,519.77381 c -32.5046101,10.85914 -64.2932331,9.07935 -55.9542041,-23.77308 18.883288,-74.39257 -57.845532,2.41084 -29.233145,-133.3763"
|
||||
style="fill:none;stroke:#000000;stroke-width:29.49614906;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccsssssccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3661"
|
||||
d="m -33.934887,422.04568 10.14038,-25.10953 C 52.122953,323.19727 160.74504,269.07207 269.83981,256.48052 c 114.24665,-13.18617 232.89306,-1.04277 284.3675,72.85307 67.68352,97.16539 16.07476,170.11753 -8.69176,195.56454 -20.05502,20.60604 -39.26023,38.76732 -57.46217,50.70193 -38.08063,24.96863 -99.02413,29.12078 -118.30443,27.5239 -56.28478,-4.66179 -227.65266,41.307 -235.6432,46.83891 L 32.219046,607.9527 C 4.8894737,559.61921 -21.751345,509.50644 -33.934887,422.04568 z"
|
||||
style="fill:#293843;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
id="path4463"
|
||||
d="m 520.63342,372.91486 c -22.02158,0.11026 -45.15654,9.22867 -63.99943,19.07328 -68.64532,35.8642 -269.2094,153.12888 -338.02986,180.28255 l -87.122352,34.37512 c 0.245863,0.43536 0.49112,0.87206 0.737105,1.30711 l 39.216027,16.16965 c 44.83999,-15.41316 98.86516,-40.41176 154.72423,-67.21674 90.48008,-43.41854 177.45369,-92.45774 236.96271,-121.89569 60.39622,-29.87684 105.87888,-24.18751 112.83284,44.85426 6.15884,-13.91293 10.75607,-30.17964 11.63778,-48.45529 -13.44827,-44.58801 -39.32739,-58.63259 -66.95905,-58.49425 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4468"
|
||||
d="m 460.17444,405.06363 c -25.33816,12.5814 -164.20311,89.16529 -247.36725,132.94909 -31.24494,16.55348 -62.91668,32.44366 -95.5461,46.08015 l 3.13236,9.65662 c 54.85379,-22.99389 108.07344,-49.78006 161.39646,-76.09146 64.31558,-32.64428 127.12882,-68.2385 192.32459,-99.13545 18.32983,-7.64259 38.30614,-12.8303 58.27155,-10.58417 14.47996,1.85097 28.06901,9.59531 37.24885,20.96153 6.66994,-53.74538 -76.10417,-40.33748 -109.46046,-23.83631 z"
|
||||
style="fill:#00ff3a;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4545"
|
||||
d="m 270.88842,559.80819 26.12051,4.09732 62.14289,-30.90074 c 11.97455,-20.17142 5.93562,-23.53024 5.29239,-31.92505 l -91.50713,47.4608 c -3.16993,2.58552 -6.42443,5.13123 -2.04866,11.26767 z"
|
||||
style="fill:#202427;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4547"
|
||||
d="m 392.10122,486.05615 c 1.23298,4.69552 4.04803,7.598 -1.19506,19.63307 l -9.73117,17.58438 80.75159,-31.4129 c 5.77716,-10.78358 11.4074,-21.61616 11.4384,-34.31516 -2.7867,-11.40006 -8.20083,-9.22506 -13.65779,-6.82888 z"
|
||||
style="fill:#202427;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4549"
|
||||
d="M 20.837165,461.33753 26.414193,480.9345 62.94875,466.25238 55.307676,431.63187 z"
|
||||
style="fill:#202427;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4551"
|
||||
d="m 178.69842,365.35554 12.29201,31.24217 56.50906,-25.09617 -12.46274,-27.48628 z"
|
||||
style="fill:#202427;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4553"
|
||||
d="m 261.4987,335.64987 11.95056,26.63267 49.85089,-20.31594 12.80416,-3.41445 -6.82888,-14.16994 -12.97489,-3.41445 z"
|
||||
style="fill:#202427;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
d="m 204.43745,364.0435 2.09895,5.60714 5.81901,-2.56255 0.64062,1.71134 -5.81901,2.56254 2.09895,5.60714 -1.75511,0.77292 -2.09894,-5.60715 -5.81902,2.56255 -0.64059,-1.71135 5.81898,-2.56254 -2.09892,-5.60714 1.75508,-0.7729 z"
|
||||
id="path4560"
|
||||
inkscape:connector-curvature="0"
|
||||
style="font-size:medium;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:tb-rl;fill:#838d96;fill-opacity:1;stroke:none;font-family:sans-serif" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#838d96;fill-opacity:1;stroke:none;font-family:sans-serif"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4567"
|
||||
d="m 305.42303,329.94388 4.03768,8.95391 -2.72436,1.22853 -4.03769,-8.95391 2.72437,-1.22853 z" />
|
||||
<path
|
||||
d="m 46.989112,448.7916 2.557622,11.39542 -2.682847,1.56354 -2.557622,-11.39545 2.682847,-1.56351 z"
|
||||
id="path4569"
|
||||
inkscape:connector-curvature="0"
|
||||
style="font-size:medium;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#838d96;fill-opacity:1;stroke:none;font-family:sans-serif" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#838d96;fill-opacity:1;stroke:none;font-family:sans-serif"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4577"
|
||||
d="m 42.643233,451.50777 2.557622,11.39545 -2.682847,1.56351 -2.557622,-11.39545 2.682847,-1.56351 z" />
|
||||
<path
|
||||
d="m 38.478433,454.34466 2.557622,11.39543 -2.682847,1.56354 -2.557622,-11.39545 2.682847,-1.56352 z"
|
||||
id="path4579"
|
||||
inkscape:connector-curvature="0"
|
||||
style="font-size:medium;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#838d96;fill-opacity:1;stroke:none;font-family:sans-serif" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4581"
|
||||
d="m 119.43841,465.4441 5.37199,3.74229 1.87114,-8.26926 z"
|
||||
style="fill:#838d96;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4583"
|
||||
d="m 99.218,376.23286 -2.29366,6.51884 6.33774,-3.25942 z"
|
||||
style="fill:#838d96;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
id="path4585"
|
||||
d="m 370.13999,299.12951 c -0.43414,-0.004 -0.88599,0.004 -1.35658,0.0243 -114.61991,18.29248 -262.7613,57.8235 -362.6396132,162.97056 l -0.2413441,18.34924 -23.0804397,18.75305 c 0.295394,0.96107 0.592605,1.91666 0.892085,2.8672 L 6.8682998,485.78508 11.938416,498.5815 c 3.022522,1.91455 4.542353,4.99753 13.03731,2.65575 0,0 35.049508,-13.87527 66.878294,-31.62836 25.86269,-14.4254 169.13513,-92.29377 297.45122,-135.68783 3.53168,-1.85807 6.92052,-3.82383 2.89753,-11.3479 l -11.34789,-17.38339 c -1.68431,-3.27833 -4.20267,-6.0005 -10.71489,-6.06024 z m 0.85055,7.18994 c 0.76127,-0.0183 1.49621,0.14715 2.1413,0.68389 2.28062,2.60105 3.95393,5.73706 5.90572,8.6044 2.36789,3.85426 5.13602,7.51375 7.31692,11.43239 -2.00889,0.76437 -4.02217,1.5172 -6.0383,2.2622 -74.38121,26.47497 -146.51346,58.91354 -216.93155,94.53357 -23.7859,11.80119 -47.13201,24.45131 -70.49007,37.07193 -21.87976,12.03816 -44.368571,22.99172 -67.494965,32.39674 -2.178032,0.79387 -4.91012,2.49014 -7.139522,0.97798 -2.462342,-3.62775 -3.065109,-8.18739 -5.10326,-12.05744 -0.191754,-5.72806 0.125694,-11.45575 0.125574,-17.18406 19.24401,-19.99827 40.662677,-37.85032 63.501803,-53.60899 56.88977,-39.14613 121.81546,-65.28367 188.25625,-83.14833 34.45174,-9.02055 69.30996,-16.66573 104.56505,-21.77335 0.46215,-0.10291 0.9283,-0.17995 1.38505,-0.19093 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:nodetypes="czsccscc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4590"
|
||||
d="m 69.56866,436.43193 c 2.34022,-18.39325 11.0874,-31.41629 35.56456,-46.25604 24.47717,-14.83973 51.02774,-12.17822 62.53237,-11.10613 4.19739,0.39116 6.14741,2.1271 9.65751,8.20888 l 9.65751,18.10785 c -9.72905,-3.24303 -45.31306,0.55135 -63.36379,8.82104 -23.93977,10.96767 -32.63451,13.417 -49.78556,44.90031 z"
|
||||
style="fill:#202427;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<text
|
||||
transform="matrix(0.81792144,-0.30782972,0,1.2226113,0,0)"
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4751"
|
||||
y="544.12469"
|
||||
x="541.47949"
|
||||
y="544.12469">></tspan></text>
|
||||
<path
|
||||
style="fill:#838d96;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 300.25264,556.5858 10.24335,-10.8622 0.29876,2.6035 -4.75887,5.05767 6.35939,-0.96032 0.72556,2.19804 z"
|
||||
id="path4759"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#151d23;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 175.51398,404.23374 c -14.95857,0.0867 -38.3591,3.7713 -51.89715,9.97357 -23.8618,10.93194 -32.57995,13.40905 -49.62048,44.60172 l 112.98222,-53.41898 -0.0122,-0.008 c -2.4337,-0.80767 -6.47543,-1.17722 -11.45245,-1.14838 z"
|
||||
id="path4761" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="Actions"
|
||||
style="display:inline"
|
||||
transform="translate(647.36582,205.64997)">
|
||||
<ellipse
|
||||
style="display:inline;fill:#898989;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
id="path4352"
|
||||
cx="-12.758862"
|
||||
cy="294.12094"
|
||||
rx="11.98534"
|
||||
ry="11.985341" />
|
||||
style="font-size:19.26995659px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#838d96;fill-opacity:1;stroke:none;font-family:sans-serif;-inkscape-font-specification:sans-serif Bold"
|
||||
xml:space="preserve"><tspan
|
||||
y="544.12469"
|
||||
x="541.47949"
|
||||
id="tspan4753"
|
||||
sodipodi:role="line">></tspan></text>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4759"
|
||||
d="m 300.25264,556.5858 10.24335,-10.8622 0.29876,2.6035 -4.75887,5.05767 6.35939,-0.96032 0.72556,2.19804 z"
|
||||
style="fill:#838d96;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
id="path4761"
|
||||
d="m 175.51398,404.23374 c -14.95857,0.0867 -38.3591,3.7713 -51.89715,9.97357 -23.8618,10.93194 -32.57995,13.40905 -49.62048,44.60172 l 112.98222,-53.41898 -0.0122,-0.008 c -2.4337,-0.80767 -6.47543,-1.17722 -11.45245,-1.14838 z"
|
||||
style="fill:#151d23;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
inkscape:connector-curvature="0" />
|
||||
<ellipse
|
||||
sodipodi:ry="11.985341"
|
||||
sodipodi:rx="11.98534"
|
||||
sodipodi:cy="294.12094"
|
||||
sodipodi:cx="-12.758862"
|
||||
d="m -0.77352142,294.12094 c 0,6.61932 -5.36601958,11.98534 -11.98534058,11.98534 -6.61932,0 -11.98534,-5.36602 -11.98534,-11.98534 0,-6.61932 5.36602,-11.98534 11.98534,-11.98534 6.619321,0 11.98534058,5.36602 11.98534058,11.98534 z"
|
||||
ry="11.985341"
|
||||
rx="11.98534"
|
||||
cy="294.12094"
|
||||
cx="-12.758862"
|
||||
id="path4352"
|
||||
style="fill:#898989;fill-opacity:1;stroke:none;display:inline"
|
||||
transform="translate(124.57988,108.29077)" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer4"
|
||||
inkscape:label="Leaders"
|
||||
transform="translate(647.36582,205.64997)"
|
||||
style="display:inline">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M -216.45721,492.54598 -83.92758,424.07234"
|
||||
id="path4368"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M -148.71984,592.67948 0.00785948,357.80752"
|
||||
id="path4370"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M -231.919,376.21442 -92.76289,355.5987"
|
||||
id="path4372"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -237.07293,234.84948 113.38646,72.89129"
|
||||
id="path4374"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M -177.52663,109.77463 -12.600865,294.57984"
|
||||
id="path4376"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -30.915721,22.80206 6.62648,247.38865"
|
||||
id="path4378"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 107.50411,-32.41862 96.45998,252.52009"
|
||||
id="path4380"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 258.44064,52.98937 162.7248,230.43182"
|
||||
id="path4382"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 130.32866,662.62568 199.53858,430.69882"
|
||||
id="path4384"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 192.9121,662.62567 295.9907,385.786"
|
||||
id="path4386"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer5"
|
||||
inkscape:label="Controls"
|
||||
transform="translate(647.36582,205.64997)"
|
||||
transform="translate(647.36582,-57.672066)"
|
||||
style="display:inline">
|
||||
<g
|
||||
id="g4200"
|
||||
transform="translate(1110.0988,277.2489)">
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4572"
|
||||
y="-44.454391"
|
||||
x="-571.44623"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4576"
|
||||
y="-44.454391"
|
||||
x="-571.44623"
|
||||
sodipodi:role="line">Resolution0</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-571.44623"
|
||||
y="28.518997"
|
||||
id="text4580"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="-571.44623"
|
||||
y="28.518997"
|
||||
id="tspan4582">Resolution1</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4584"
|
||||
y="101.49239"
|
||||
x="-571.44623"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4586"
|
||||
y="101.49239"
|
||||
x="-571.44623"
|
||||
sodipodi:role="line">Resolution2</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-571.44623"
|
||||
y="174.46584"
|
||||
id="text4588"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="-571.44623"
|
||||
y="174.46584"
|
||||
id="tspan4590">Resolution3</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4592"
|
||||
y="247.43925"
|
||||
x="-571.44623"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4594"
|
||||
y="247.43925"
|
||||
x="-571.44623"
|
||||
sodipodi:role="line">Resolution4</tspan></text>
|
||||
</g>
|
||||
<rect
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="rect4600"
|
||||
width="323.85489"
|
||||
height="410.20847"
|
||||
x="494.82077"
|
||||
y="158.72498"
|
||||
rx="10.321068"
|
||||
ry="10.321068" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-629.95673"
|
||||
y="789.13135"
|
||||
id="text4211"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4213"
|
||||
x="-629.95673"
|
||||
y="789.13135">Current Profile</tspan></text>
|
||||
<g
|
||||
style="display:inline"
|
||||
id="g4230"
|
||||
transform="translate(-73.440271,-63.319721)">
|
||||
transform="translate(-312.22243,78.703789)">
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4473"
|
||||
y="547.70569"
|
||||
x="-157.20392"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4217"
|
||||
y="547.70569"
|
||||
x="-157.20392"
|
||||
sodipodi:role="line">Button0</tspan></text>
|
||||
sodipodi:role="line"
|
||||
style="font-size:32px">Button0</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
x="-157.20392"
|
||||
y="591.14594"
|
||||
id="text4212"
|
||||
@@ -363,14 +229,16 @@
|
||||
sodipodi:role="line"
|
||||
x="-157.20392"
|
||||
y="591.14594"
|
||||
id="tspan4214">Button12</tspan></text>
|
||||
id="tspan4214"
|
||||
style="font-size:32px">Button12</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
style="display:inline"
|
||||
id="g4224"
|
||||
transform="translate(112.10123,30.187304)">
|
||||
transform="translate(-177.72019,47.152301)">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
x="6.9855804"
|
||||
y="647.10291"
|
||||
id="text4216"
|
||||
@@ -378,51 +246,69 @@
|
||||
sodipodi:role="line"
|
||||
x="6.9855804"
|
||||
y="647.10291"
|
||||
id="tspan4218">Button3</tspan></text>
|
||||
id="tspan4218"
|
||||
style="font-size:32px">Button3</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4220"
|
||||
y="690.54315"
|
||||
x="6.9855804"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4222"
|
||||
y="690.54315"
|
||||
x="6.9855781"
|
||||
sodipodi:role="line">Button15</tspan></text>
|
||||
x="6.9855804"
|
||||
sodipodi:role="line"
|
||||
style="font-size:32px">Button15</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
style="display:inline"
|
||||
id="g4250"
|
||||
transform="translate(14.912823,34.604968)">
|
||||
transform="translate(-353.6901,52.306237)">
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4238"
|
||||
y="642.68524"
|
||||
x="195.12758"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
y="645.63037"
|
||||
x="270.96399"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4240"
|
||||
y="642.68524"
|
||||
x="195.12758"
|
||||
sodipodi:role="line">Button4</tspan></text>
|
||||
y="645.63037"
|
||||
x="270.96399"
|
||||
sodipodi:role="line"
|
||||
style="font-size:32px">Button4</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="195.12758"
|
||||
y="686.12549"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
x="270.96399"
|
||||
y="689.07062"
|
||||
id="text4242"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="195.12758"
|
||||
y="686.12549"
|
||||
id="tspan4244">Button16</tspan></text>
|
||||
x="270.96399"
|
||||
y="689.07062"
|
||||
id="tspan4244"
|
||||
style="font-size:32px">Button16</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 426.30366,602.00857 72.8913,-163.45321"
|
||||
id="path3163"
|
||||
inkscape:connector-curvature="0"
|
||||
transform="translate(-293.67572,5.365799)" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 629.51576,602.74485 586.81177,393.64254"
|
||||
id="path3165"
|
||||
inkscape:connector-curvature="0"
|
||||
transform="translate(-293.67572,5.365799)" />
|
||||
</g>
|
||||
<g
|
||||
style="display:inline"
|
||||
id="g4256"
|
||||
transform="translate(86.33157,-599.32852)">
|
||||
transform="translate(-311.42639,-501.45091)">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
x="195.12758"
|
||||
y="642.68524"
|
||||
id="text4258"
|
||||
@@ -430,36 +316,40 @@
|
||||
sodipodi:role="line"
|
||||
x="195.12758"
|
||||
y="642.68524"
|
||||
id="tspan4260">Button10</tspan></text>
|
||||
id="tspan4260"
|
||||
style="font-size:32.00000171px">Button10</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4262"
|
||||
y="686.12549"
|
||||
x="195.12758"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4264"
|
||||
y="686.12549"
|
||||
x="195.12758"
|
||||
sodipodi:role="line">Button22</tspan></text>
|
||||
sodipodi:role="line"
|
||||
style="font-size:32.00000171px">Button22</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
transform="translate(-76.385377,-689.15417)"
|
||||
style="display:inline"
|
||||
transform="translate(-539.74217,-541.2965)"
|
||||
id="g4266">
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4268"
|
||||
y="642.68524"
|
||||
x="195.12758"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4270"
|
||||
y="642.68524"
|
||||
x="195.12758"
|
||||
sodipodi:role="line">Button9</tspan></text>
|
||||
sodipodi:role="line"
|
||||
style="font-size:32px">Button9</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
x="195.12758"
|
||||
y="686.12549"
|
||||
id="text4272"
|
||||
@@ -467,14 +357,16 @@
|
||||
sodipodi:role="line"
|
||||
x="195.12758"
|
||||
y="686.12549"
|
||||
id="tspan4274">Button21</tspan></text>
|
||||
id="tspan4274"
|
||||
style="font-size:32px">Button21</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
transform="translate(0.18730648,35.341239)"
|
||||
style="display:inline"
|
||||
transform="translate(-209.20512,184.48383)"
|
||||
id="g4276">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
x="-157.20392"
|
||||
y="547.70569"
|
||||
id="text4278"
|
||||
@@ -482,36 +374,40 @@
|
||||
sodipodi:role="line"
|
||||
x="-157.20392"
|
||||
y="547.70569"
|
||||
id="tspan4280">Button5</tspan></text>
|
||||
id="tspan4280"
|
||||
style="font-size:32px">Button5</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4282"
|
||||
y="591.14594"
|
||||
x="-157.20392"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4284"
|
||||
y="591.14594"
|
||||
x="-157.20392"
|
||||
sodipodi:role="line">Button17</tspan></text>
|
||||
sodipodi:role="line"
|
||||
style="font-size:32px">Button17</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
style="display:inline"
|
||||
id="g4286"
|
||||
transform="translate(-73.440271,-166.39834)">
|
||||
transform="translate(-330.93429,-54.814789)">
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4288"
|
||||
y="547.70569"
|
||||
x="-157.20392"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4290"
|
||||
y="547.70569"
|
||||
x="-157.20392"
|
||||
sodipodi:role="line">Button11</tspan></text>
|
||||
sodipodi:role="line"
|
||||
style="font-size:32px">Button11</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
x="-157.20392"
|
||||
y="591.14594"
|
||||
id="text4292"
|
||||
@@ -519,14 +415,16 @@
|
||||
sodipodi:role="line"
|
||||
x="-157.20392"
|
||||
y="591.14594"
|
||||
id="tspan4294">Button23</tspan></text>
|
||||
id="tspan4294"
|
||||
style="font-size:32px">Button23</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
transform="translate(-86.693235,-300.40054)"
|
||||
style="display:inline"
|
||||
transform="translate(-333.46977,-188.98667)"
|
||||
id="g4338">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
x="-157.20392"
|
||||
y="547.70569"
|
||||
id="text4340"
|
||||
@@ -534,36 +432,40 @@
|
||||
sodipodi:role="line"
|
||||
x="-157.20392"
|
||||
y="547.70569"
|
||||
id="tspan4342">Button1</tspan></text>
|
||||
id="tspan4342"
|
||||
style="font-size:32px">Button1</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4344"
|
||||
y="591.14594"
|
||||
x="-157.20392"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4346"
|
||||
y="591.14594"
|
||||
x="-157.20392"
|
||||
sodipodi:role="line">Button13</tspan></text>
|
||||
sodipodi:role="line"
|
||||
style="font-size:32px">Button13</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
style="display:inline"
|
||||
id="g4348"
|
||||
transform="translate(-31.472552,-438.82039)">
|
||||
transform="translate(-264.96175,-314.68951)">
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4350"
|
||||
y="547.70569"
|
||||
x="-157.20392"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4352"
|
||||
y="547.70569"
|
||||
x="-157.20392"
|
||||
sodipodi:role="line">Button2</tspan></text>
|
||||
sodipodi:role="line"
|
||||
style="font-size:32px">Button2</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
x="-157.20392"
|
||||
y="591.14594"
|
||||
id="text4354"
|
||||
@@ -571,14 +473,16 @@
|
||||
sodipodi:role="line"
|
||||
x="-157.20392"
|
||||
y="591.14594"
|
||||
id="tspan4356">Button14</tspan></text>
|
||||
id="tspan4356"
|
||||
style="font-size:32px">Button14</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
transform="translate(115.04633,-541.16273)"
|
||||
style="display:inline"
|
||||
transform="translate(-220.77251,-418.68304)"
|
||||
id="g4358">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
x="-157.20392"
|
||||
y="547.70569"
|
||||
id="text4360"
|
||||
@@ -586,36 +490,68 @@
|
||||
sodipodi:role="line"
|
||||
x="-157.20392"
|
||||
y="547.70569"
|
||||
id="tspan4362">Button6</tspan></text>
|
||||
id="tspan4362"
|
||||
style="font-size:32px">Button6</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4364"
|
||||
y="591.14594"
|
||||
x="-157.20392"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40.00000381px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-size:40.00000381px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:'Sans, Normal'"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4366"
|
||||
y="591.14594"
|
||||
x="-157.20392"
|
||||
sodipodi:role="line">Button18</tspan></text>
|
||||
sodipodi:role="line"
|
||||
style="font-size:32px">Button18</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer6"
|
||||
inkscape:label="Title"
|
||||
sodipodi:insensitive="true">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="733.21844"
|
||||
y="73.834145"
|
||||
id="text4223"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4225"
|
||||
x="733.21844"
|
||||
y="73.834145"
|
||||
style="font-size:70.00000763px;text-align:center;text-anchor:middle">Roccat Kone XTD</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 250.33375,638.82236 373.2918,377.44447"
|
||||
id="path3167"
|
||||
inkscape:connector-curvature="0"
|
||||
transform="translate(-647.36582,57.672036)" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 187.75032,550.46927 313.65347,442.97301"
|
||||
id="path3171"
|
||||
inkscape:connector-curvature="0"
|
||||
transform="translate(-647.36582,57.672036)" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 170.0797,442.23674 318.07112,378.91702"
|
||||
id="path3173"
|
||||
inkscape:connector-curvature="0"
|
||||
transform="translate(-647.36582,57.672036)" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 590.49315,144.78134 502.14006,287.61883"
|
||||
id="path3175"
|
||||
inkscape:connector-curvature="0"
|
||||
transform="translate(-647.36582,57.672036)" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 403.47911,102.07734 437.34779,309.7071"
|
||||
id="path3177"
|
||||
inkscape:connector-curvature="0"
|
||||
transform="translate(-647.36582,57.672036)" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 257.69651,135.20975 98.66095,183.33266"
|
||||
id="path3179"
|
||||
inkscape:connector-curvature="0"
|
||||
transform="translate(-647.36582,57.672036)" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 207.62976,229.45305 365.19277,333.26793"
|
||||
id="path3181"
|
||||
inkscape:connector-curvature="0"
|
||||
transform="translate(-647.36582,57.672036)" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 162.71694,318.54241 133.26591,29.45103"
|
||||
id="path3183"
|
||||
inkscape:connector-curvature="0"
|
||||
transform="translate(-647.36582,57.672036)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 29 KiB |
@@ -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 )
|
||||
@@ -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
|
||||
|
||||
@@ -95,6 +95,11 @@ mouse:usb:v046dpc249:name:*:
|
||||
RATBAG_HIDPP10_DPI=0:5700@23.53
|
||||
RATBAG_HIDPP10_PROFILE=G500
|
||||
|
||||
# G300
|
||||
mouse:usb:v046dpc246:name:*:
|
||||
RATBAG_DRIVER=logitech_g300
|
||||
RATBAG_SVG=logitech-g300.svg
|
||||
|
||||
# G500
|
||||
mouse:usb:v046dpc068:name:*:
|
||||
RATBAG_DRIVER=hidpp10
|
||||
@@ -108,13 +113,20 @@ mouse:usb:v046dpc24e:name:*:
|
||||
RATBAG_HIDPP10_DPI=0:8200@50
|
||||
RATBAG_HIDPP10_PROFILE=G500
|
||||
|
||||
# G502 over USB
|
||||
# G502 Proteus Core over USB
|
||||
mouse:usb:v046dpc07d:name:*:
|
||||
RATBAG_DRIVER=hidpp20
|
||||
RATBAG_SVG=logitech-g502.svg
|
||||
|
||||
# G502 Proteus Spectrum over USB
|
||||
mouse:usb:v046dpc332:name:*:
|
||||
RATBAG_DRIVER=hidpp20
|
||||
RATBAG_SVG=logitech-g502.svg
|
||||
|
||||
# G700 over USB
|
||||
mouse:usb:v046dpc06b:name:*:
|
||||
RATBAG_DRIVER=hidpp10
|
||||
RATBAG_SVG=logitech-g700.svg
|
||||
RATBAG_HIDPP10_DPI=0:5700@23.53
|
||||
RATBAG_HIDPP10_PROFILE=G700
|
||||
|
||||
@@ -125,6 +137,21 @@ mouse:usb:v046dpc531:name:*:
|
||||
RATBAG_HIDPP10_PROFILE=G700
|
||||
RATBAG_HIDPP10_INDEX=1
|
||||
|
||||
# G700s over USB
|
||||
mouse:usb:v046dpc07c:name:*:
|
||||
RATBAG_DRIVER=hidpp10
|
||||
RATBAG_SVG=logitech-g700.svg
|
||||
RATBAG_HIDPP10_DPI=0:8200@50
|
||||
RATBAG_HIDPP10_PROFILE=G700
|
||||
|
||||
# G700s over wireless USB
|
||||
mouse:usb:v046dpc531:name:*:
|
||||
RATBAG_DRIVER=hidpp10
|
||||
RATBAG_SVG=logitech-g700.svg
|
||||
RATBAG_HIDPP10_DPI=0:8200@50
|
||||
RATBAG_HIDPP10_PROFILE=G700
|
||||
RATBAG_HIDPP10_INDEX=1
|
||||
|
||||
# MX Master over unifying
|
||||
mouse:usb:v046dp4041:name:*:
|
||||
# MX Master over bluetooth
|
||||
@@ -143,6 +170,26 @@ mouse:usb:v046dp400a:name:*:
|
||||
# G303 over USB
|
||||
mouse:usb:v046dpc080:name:*:
|
||||
RATBAG_DRIVER=hidpp20
|
||||
RATBAG_SVG=logitech-g303.svg
|
||||
|
||||
# Wireless Touchpad (Unifying)
|
||||
mouse:usb:v046dp4011:name:*:
|
||||
RATBAG_DRIVER=hidpp20
|
||||
|
||||
# G602 over wireless USB
|
||||
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
|
||||
RATBAG_SVG=logitech-g900.svg
|
||||
RATBAG_HIDPP20_INDEX=1
|
||||
|
||||
|
||||
##########################################
|
||||
# Roccat
|
||||
@@ -151,3 +198,12 @@ mouse:usb:v046dpc080:name:*:
|
||||
mouse:usb:v1e7dp2e22:name:*:
|
||||
RATBAG_DRIVER=roccat
|
||||
RATBAG_SVG=roccat-kone-xtd.svg
|
||||
|
||||
|
||||
##########################################
|
||||
# G.Skill
|
||||
##########################################
|
||||
|
||||
# MX-780
|
||||
mouse:usb:v28dap3101:name:*:
|
||||
RATBAG_DRIVER=gskill
|
||||
|
||||
@@ -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)
|
||||
390
meson.build
Normal file
@@ -0,0 +1,390 @@
|
||||
project('libratbag', 'c', 'cpp',
|
||||
version : '0.7.0',
|
||||
license : 'MIT/Expat',
|
||||
default_options : [ 'c_std=gnu99' ])
|
||||
|
||||
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=1
|
||||
libratbag_so_a=0
|
||||
liblur_so_c=3
|
||||
liblur_so_r=1
|
||||
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 = ['-Wall', '-Wextra', '-Wno-unused-parameter', '-g', '-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('LIBRATBAG_VERSION', meson.project_version())
|
||||
|
||||
libratbag_version_h = configure_file(
|
||||
ratbag : 'src/libratbag-version.h.in',
|
||||
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
|
||||
)
|
||||
|
||||
pkgconfig.generate(
|
||||
filebase: 'libratbag',
|
||||
name: 'Libratbag',
|
||||
description: 'Mouse configuration library',
|
||||
version: meson.project_version(),
|
||||
libraries: lib_libratbag
|
||||
)
|
||||
|
||||
#### libshared.a ####
|
||||
src_libshared = [
|
||||
'tools/shared.c',
|
||||
'tools/shared.h'
|
||||
]
|
||||
|
||||
deps_libshared = [
|
||||
dep_udev,
|
||||
dep_libevdev,
|
||||
]
|
||||
lib_libshared = static_library('shared',
|
||||
src_libshared,
|
||||
dependencies : deps_libshared,
|
||||
include_directories : include_directories('src')
|
||||
)
|
||||
dep_libshared = declare_dependency(link_with: lib_libshared)
|
||||
|
||||
#### 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,
|
||||
)
|
||||
|
||||
#### 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
@@ -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)')
|
||||
574
release.sh
Executable file
@@ -0,0 +1,574 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Generate the announce template
|
||||
#
|
||||
# Completely copy/paste of Xorg/util/modular/release.sh:
|
||||
#
|
||||
# Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
export LC_ALL=C
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Function: check_local_changes
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
check_local_changes() {
|
||||
git diff --quiet HEAD > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo ""
|
||||
echo "Uncommitted changes found. Did you forget to commit? Aborting."
|
||||
echo ""
|
||||
echo "You can perform a 'git stash' to save your local changes and"
|
||||
echo "a 'git stash apply' to recover them after the tarball release."
|
||||
echo "Make sure to rebuild and run 'make distcheck' again."
|
||||
echo ""
|
||||
echo "Alternatively, you can clone the module in another directory"
|
||||
echo "and run ./configure. No need to build if testing was finished."
|
||||
echo ""
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Function: check_option_args
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# perform sanity checks on cmdline args which require arguments
|
||||
# arguments:
|
||||
# $1 - the option being examined
|
||||
# $2 - the argument to the option
|
||||
# returns:
|
||||
# if it returns, everything is good
|
||||
# otherwise it exit's
|
||||
check_option_args() {
|
||||
option=$1
|
||||
arg=$2
|
||||
|
||||
# check for an argument
|
||||
if [ x"$arg" = x ]; then
|
||||
echo ""
|
||||
echo "Error: the '$option' option is missing its required argument."
|
||||
echo ""
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# does the argument look like an option?
|
||||
echo $arg | $GREP "^-" > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo ""
|
||||
echo "Error: the argument '$arg' of option '$option' looks like an option itself."
|
||||
echo ""
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Function: check_modules_specification
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
check_modules_specification() {
|
||||
|
||||
if [ x"$MODFILE" = x ]; then
|
||||
if [ x"${INPUT_MODULES}" = x ]; then
|
||||
echo ""
|
||||
echo "Error: no modules specified (blank command line)."
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Function: generate_announce
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
generate_announce()
|
||||
{
|
||||
cat <<RELEASE
|
||||
Subject: [ANNOUNCE] $pkg_name $pkg_version
|
||||
To: $list_to
|
||||
Cc: $list_cc
|
||||
|
||||
libratbag $tag_name is out.
|
||||
|
||||
The list of interesting changes are:
|
||||
|
||||
See the full log at the end if you are interested in the details.
|
||||
|
||||
`git log --no-merges "$tag_range" | git shortlog`
|
||||
|
||||
git tag: $tag_name
|
||||
|
||||
RELEASE
|
||||
|
||||
for tarball in $tarbz2 $targz $tarxz; do
|
||||
cat <<RELEASE
|
||||
The libratbag project does not generate tarballs for releases, you can
|
||||
grab one directly from github:
|
||||
|
||||
https://github.com/libratbag/libratbag/archive/$tag_name/$tarball
|
||||
|
||||
RELEASE
|
||||
done
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Function: read_modfile
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Read the module names from the file and set a variable to hold them
|
||||
# This will be the same interface as cmd line supplied modules
|
||||
#
|
||||
read_modfile() {
|
||||
|
||||
if [ x"$MODFILE" != x ]; then
|
||||
# Make sure the file is sane
|
||||
if [ ! -r "$MODFILE" ]; then
|
||||
echo "Error: module file '$MODFILE' is not readable or does not exist."
|
||||
exit 1
|
||||
fi
|
||||
# read from input file, skipping blank and comment lines
|
||||
while read line; do
|
||||
# skip blank lines
|
||||
if [ x"$line" = x ]; then
|
||||
continue
|
||||
fi
|
||||
# skip comment lines
|
||||
if echo "$line" | $GREP -q "^#" ; then
|
||||
continue;
|
||||
fi
|
||||
INPUT_MODULES="$INPUT_MODULES $line"
|
||||
done <"$MODFILE"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Function: print_epilog
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
print_epilog() {
|
||||
|
||||
epilog="======== Successful Completion"
|
||||
if [ x"$NO_QUIT" != x ]; then
|
||||
if [ x"$failed_modules" != x ]; then
|
||||
epilog="======== Partial Completion"
|
||||
fi
|
||||
elif [ x"$failed_modules" != x ]; then
|
||||
epilog="======== Stopped on Error"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "$epilog `date`"
|
||||
|
||||
# Report about modules that failed for one reason or another
|
||||
if [ x"$failed_modules" != x ]; then
|
||||
echo " List of failed modules:"
|
||||
for mod in $failed_modules; do
|
||||
echo " $mod"
|
||||
done
|
||||
echo "========"
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Function: process_modules
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Loop through each module to release
|
||||
# Exit on error if --no-quit was not specified
|
||||
#
|
||||
process_modules() {
|
||||
for MODULE_RPATH in ${INPUT_MODULES}; do
|
||||
if ! process_module ; then
|
||||
echo "Error: processing module \"$MODULE_RPATH\" failed."
|
||||
failed_modules="$failed_modules $MODULE_RPATH"
|
||||
if [ x"$NO_QUIT" = x ]; then
|
||||
print_epilog
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Function: get_section
|
||||
#------------------------------------------------------------------------------
|
||||
# Code 'return 0' on success
|
||||
# Code 'return 1' on error
|
||||
# Sets global variable $section
|
||||
get_section() {
|
||||
local module_url
|
||||
local full_module_url
|
||||
|
||||
# Obtain the git url in order to find the section to which this module belongs
|
||||
full_module_url=`git config --get remote.$remote_name.url | sed 's:\.git$::'`
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: unable to obtain git url for remote \"$remote_name\"."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# The last part of the git url will tell us the section. Look for xorg first
|
||||
echo "$full_module_url"
|
||||
module_url=`echo "$full_module_url" | $GREP -o "libratbag/.*"`
|
||||
if [ $? -eq 0 ]; then
|
||||
module_url=`echo $module_url | cut -d'/' -f2,3`
|
||||
else
|
||||
echo "Error: unable to locate a valid project url from \"$full_module_url\"."
|
||||
echo "Cannot establish url as one of libratbag"
|
||||
cd $top_src
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Find the section (subdirs) where the tarballs are to be uploaded
|
||||
# The module relative path can be app/xfs, xserver, or mesa/drm for example
|
||||
section=`echo $module_url | cut -d'/' -f1`
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: unable to extract section from $module_url first field."
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Function: process_module
|
||||
#------------------------------------------------------------------------------
|
||||
# Code 'return 0' on success to process the next module
|
||||
# Code 'return 1' on error to process next module if invoked with --no-quit
|
||||
#
|
||||
process_module() {
|
||||
|
||||
top_src=`pwd`
|
||||
echo ""
|
||||
echo "======== Processing \"$top_src/$MODULE_RPATH\""
|
||||
|
||||
# This is the location where the script has been invoked
|
||||
if [ ! -d $MODULE_RPATH ] ; then
|
||||
echo "Error: $MODULE_RPATH cannot be found under $top_src."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Change directory to be in the git module
|
||||
cd $MODULE_RPATH
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: failed to cd to $MODULE_RPATH."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# ----- Now in the git module *root* directory ----- #
|
||||
|
||||
# Check that this is indeed a git module
|
||||
if [ ! -d .git ]; then
|
||||
echo "Error: there is no git module here: `pwd`"
|
||||
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
|
||||
cd $top_src
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Determine what is the current branch and the remote name
|
||||
current_branch=`git branch | $GREP "\*" | sed -e "s/\* //"`
|
||||
remote_name=`git config --get branch.$current_branch.remote`
|
||||
remote_branch=`git config --get branch.$current_branch.merge | cut -d'/' -f3,4`
|
||||
remote_url_root="https://github.com/libratbag/libratbag/archive"
|
||||
echo "Info: working off the \"$current_branch\" branch tracking the remote \"$remote_name/$remote_branch\"."
|
||||
|
||||
# Obtain the section
|
||||
get_section
|
||||
if [ $? -ne 0 ]; then
|
||||
cd $top_src
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Find out the tarname from meson.build
|
||||
pkg_name=$($GREP '^project(' meson.build | sed 's|project(\([^\s,]*\).*|\1|' | sed "s/'//g")
|
||||
pkg_version=$($GREP -m 1 '^ version : ' meson.build | sed 's| version : \([^\s,]*\).*|\1|' | sed "s/'//g")
|
||||
tar_name="$pkg_name-$pkg_version"
|
||||
targz=$tar_name.tar.gz
|
||||
tag_name=$(echo "v$pkg_version" | sed 's|.0$||')
|
||||
|
||||
# Now get the tarballs from github directly to compute their checksum
|
||||
remote_targz_url=$remote_url_root/$tag_name/$targz
|
||||
echo "downloading the tarbal from $remote_targz_url"
|
||||
curl $remote_targz_url > $targz
|
||||
|
||||
# Obtain the top commit SHA which should be the version bump
|
||||
# It should not have been tagged yet (the script will do it later)
|
||||
local_top_commit_sha=`git rev-list --max-count=1 HEAD`
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: unable to obtain the local top commit id."
|
||||
cd $top_src
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check that the top commit looks like a version bump
|
||||
git diff --unified=0 HEAD^ | $GREP -F $pkg_version >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
# Wayland repos use m4_define([wayland_major_version], [0])
|
||||
git diff --unified=0 HEAD^ | $GREP -E "(major|minor|micro)_version" >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: the local top commit does not look like a version bump."
|
||||
echo " the diff does not contain the string \"$pkg_version\"."
|
||||
local_top_commit_descr=`git log --oneline --max-count=1 $local_top_commit_sha`
|
||||
echo " the local top commit is: \"$local_top_commit_descr\""
|
||||
cd $top_src
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check that the top commit has been pushed to remote
|
||||
remote_top_commit_sha=`git rev-list --max-count=1 $remote_name/$remote_branch`
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: unable to obtain top commit from the remote repository."
|
||||
cd $top_src
|
||||
return 1
|
||||
fi
|
||||
if [ x"$remote_top_commit_sha" != x"$local_top_commit_sha" ]; then
|
||||
echo "Error: the local top commit has not been pushed to the remote."
|
||||
local_top_commit_descr=`git log --oneline --max-count=1 $local_top_commit_sha`
|
||||
echo " the local top commit is: \"$local_top_commit_descr\""
|
||||
cd $top_src
|
||||
return 1
|
||||
fi
|
||||
|
||||
# If a tag exists with the the tar name, ensure it is tagging the top commit
|
||||
# It may happen if the version set in configure.ac has been previously released
|
||||
tagged_commit_sha=`git rev-list --max-count=1 $tag_name 2>/dev/null`
|
||||
if [ $? -eq 0 ]; then
|
||||
# Check if the tag is pointing to the top commit
|
||||
if [ x"$tagged_commit_sha" != x"$remote_top_commit_sha" ]; then
|
||||
echo "Error: the \"$tag_name\" already exists."
|
||||
echo " this tag is not tagging the top commit."
|
||||
remote_top_commit_descr=`git log --oneline --max-count=1 $remote_top_commit_sha`
|
||||
echo " the top commit is: \"$remote_top_commit_descr\""
|
||||
local_tag_commit_descr=`git log --oneline --max-count=1 $tagged_commit_sha`
|
||||
echo " tag \"$tag_name\" is tagging some other commit: \"$local_tag_commit_descr\""
|
||||
cd $top_src
|
||||
return 1
|
||||
else
|
||||
echo "Info: module already tagged with \"$tag_name\"."
|
||||
fi
|
||||
else
|
||||
# Tag the top commit with the tar name
|
||||
if [ x"$DRY_RUN" = x ]; then
|
||||
git tag -s -m $tag_name $tag_name
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: unable to tag module with \"$tag_name\"."
|
||||
cd $top_src
|
||||
return 1
|
||||
else
|
||||
echo "Info: module tagged with \"$tag_name\"."
|
||||
fi
|
||||
else
|
||||
echo "Info: skipping the commit tagging in dry-run mode."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Mailing lists where to post the all [Announce] e-mails
|
||||
list_to="input-tools@lists.freedesktop.org"
|
||||
|
||||
# Pushing the top commit tag to the remote repository
|
||||
if [ x$DRY_RUN = x ]; then
|
||||
echo "Info: pushing tag \"$tag_name\" to remote \"$remote_name\":"
|
||||
git push $remote_name $tag_name
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: unable to push tag \"$tag_name\" to the remote repository."
|
||||
echo " it is recommended you fix this manually and not run the script again"
|
||||
cd $top_src
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
echo "Info: skipped pushing tag \"$tag_name\" to the remote repository in dry-run mode."
|
||||
fi
|
||||
|
||||
# --------- Generate the announce e-mail ------------------
|
||||
# Failing to generate the announce is not considered a fatal error
|
||||
|
||||
# Git-describe returns only "the most recent tag", it may not be the expected one
|
||||
# However, we only use it for the commit history which will be the same anyway.
|
||||
tag_previous=`git describe --abbrev=0 HEAD^ 2>/dev/null`
|
||||
# Git fails with rc=128 if no tags can be found prior to HEAD^
|
||||
if [ $? -ne 0 ]; then
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Warning: unable to find a previous tag."
|
||||
echo " perhaps a first release on this branch."
|
||||
echo " Please check the commit history in the announce."
|
||||
fi
|
||||
fi
|
||||
if [ x"$tag_previous" != x ]; then
|
||||
# The top commit may not have been tagged in dry-run mode. Use commit.
|
||||
tag_range=$tag_previous..$local_top_commit_sha
|
||||
else
|
||||
tag_range=$tag_name
|
||||
fi
|
||||
generate_announce > "$tar_name.announce"
|
||||
echo "Info: [ANNOUNCE] template generated in \"$tar_name.announce\" file."
|
||||
echo " Please pgp sign and send it."
|
||||
|
||||
# --------- Successful completion --------------------------
|
||||
cd $top_src
|
||||
return 0
|
||||
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Function: usage
|
||||
#------------------------------------------------------------------------------
|
||||
# Displays the script usage and exits successfully
|
||||
#
|
||||
usage() {
|
||||
basename="`expr "//$0" : '.*/\([^/]*\)'`"
|
||||
cat <<HELP
|
||||
|
||||
Usage: $basename [options] path...
|
||||
|
||||
Where "path" is a relative path to a git module, including '.'.
|
||||
|
||||
Options:
|
||||
--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
|
||||
|
||||
HELP
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Script main line
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
|
||||
# Choose which grep program to use (on Solaris, must be gnu grep)
|
||||
if [ "x$GREP" = "x" ] ; then
|
||||
if [ -x /usr/gnu/bin/grep ] ; then
|
||||
GREP=/usr/gnu/bin/grep
|
||||
else
|
||||
GREP=grep
|
||||
fi
|
||||
fi
|
||||
|
||||
# Process command line args
|
||||
while [ $# != 0 ]
|
||||
do
|
||||
case $1 in
|
||||
# Does everything except uploading tarball
|
||||
--dry-run)
|
||||
DRY_RUN=yes
|
||||
;;
|
||||
# Force overwriting an existing release
|
||||
# Use only if nothing changed in the git repo
|
||||
--force)
|
||||
FORCE=yes
|
||||
;;
|
||||
# Display this help and exit successfully
|
||||
--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
# Do not quit after error; just print error message
|
||||
--no-quit)
|
||||
NO_QUIT=yes
|
||||
;;
|
||||
--*)
|
||||
echo ""
|
||||
echo "Error: unknown option: $1"
|
||||
echo ""
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
-*)
|
||||
echo ""
|
||||
echo "Error: unknown option: $1"
|
||||
echo ""
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
if [ x"${MODFILE}" != x ]; then
|
||||
echo ""
|
||||
echo "Error: specifying both modules and --modfile is not permitted"
|
||||
echo ""
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
INPUT_MODULES="${INPUT_MODULES} $1"
|
||||
;;
|
||||
esac
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
# If no modules specified (blank cmd line) display help
|
||||
check_modules_specification
|
||||
|
||||
# Read the module file and normalize input in INPUT_MODULES
|
||||
read_modfile
|
||||
|
||||
# Loop through each module to release
|
||||
# Exit on error if --no-quit no specified
|
||||
process_modules
|
||||
|
||||
# Print the epilog with final status
|
||||
print_epilog
|
||||
@@ -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
|
||||
|
||||
@@ -1,70 +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-roccat.c \
|
||||
driver-test.c \
|
||||
libratbag.c \
|
||||
libratbag.h \
|
||||
libratbag-hidraw.c \
|
||||
libratbag-hidraw.h \
|
||||
libratbag-private.h \
|
||||
libratbag-test.c \
|
||||
libratbag-test.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)
|
||||
liblur_la_LDFLAGS = -shared
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libratbag.pc
|
||||
|
||||
AM_CFLAGS = $(GCC_CFLAGS)
|
||||
|
||||
DISTCLEANFILES = libratbag-version.h
|
||||
EXTRA_DIST = libratbag-version.h.in libratbag.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
|
||||
libhidpp_la_LDFLAGS = -lm
|
||||
libutil_la_SOURCES = \
|
||||
libratbag-util.c \
|
||||
libratbag-util.h
|
||||
libutil_la_LIBADD = $(LIBUDEV_LIBS)
|
||||
@@ -36,6 +36,7 @@
|
||||
#define ETEKCITY_PROFILE_MAX 4
|
||||
#define ETEKCITY_BUTTON_MAX 10
|
||||
#define ETEKCITY_NUM_DPI 6
|
||||
#define ETEKCITY_LED 0
|
||||
|
||||
#define ETEKCITY_REPORT_ID_CONFIGURE_PROFILE 4
|
||||
#define ETEKCITY_REPORT_ID_PROFILE 5
|
||||
@@ -430,6 +431,7 @@ etekcity_read_button(struct ratbag_button *button)
|
||||
{
|
||||
const struct ratbag_button_action *action;
|
||||
struct ratbag_device *device;
|
||||
struct ratbag_button_macro *m;
|
||||
struct etekcity_macro *macro;
|
||||
struct etekcity_data *drv_data;
|
||||
uint8_t *buf;
|
||||
@@ -464,7 +466,7 @@ etekcity_read_button(struct ratbag_button *button)
|
||||
button->index, button->profile->index,
|
||||
rc < 0 ? strerror(-rc) : "not read enough", rc);
|
||||
} else {
|
||||
ratbag_button_set_macro(button, macro->name);
|
||||
m = ratbag_button_macro_new(macro->name);
|
||||
log_raw(device->ratbag,
|
||||
"macro on button %d of profile %d is named '%s', and contains %d events:\n",
|
||||
button->index, button->profile->index,
|
||||
@@ -472,7 +474,7 @@ etekcity_read_button(struct ratbag_button *button)
|
||||
for (j = 0; j < macro->length; j++) {
|
||||
unsigned int keycode = ratbag_hidraw_get_keycode_from_keyboard_usage(device,
|
||||
macro->keys[j].keycode);
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
j,
|
||||
macro->keys[j].flag & 0x80 ? RATBAG_MACRO_EVENT_KEY_RELEASED : RATBAG_MACRO_EVENT_KEY_PRESSED,
|
||||
keycode);
|
||||
@@ -481,6 +483,8 @@ etekcity_read_button(struct ratbag_button *button)
|
||||
libevdev_event_code_get_name(EV_KEY, keycode),
|
||||
macro->keys[j].flag & 0x80 ? "released" : "pressed");
|
||||
}
|
||||
ratbag_button_copy_macro(button, m);
|
||||
ratbag_button_macro_unref(m);
|
||||
}
|
||||
msleep(10);
|
||||
}
|
||||
@@ -633,13 +637,8 @@ etekcity_probe(struct ratbag_device *device)
|
||||
int active_idx;
|
||||
|
||||
rc = ratbag_open_hidraw(device);
|
||||
if (rc) {
|
||||
log_error(device->ratbag,
|
||||
"Can't open corresponding hidraw node: '%s' (%d)\n",
|
||||
strerror(-rc),
|
||||
rc);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (!ratbag_hidraw_has_report(device, ETEKCITY_REPORT_ID_KEY_MAPPING)) {
|
||||
ratbag_close_hidraw(device);
|
||||
@@ -659,7 +658,8 @@ etekcity_probe(struct ratbag_device *device)
|
||||
ratbag_device_init_profiles(device,
|
||||
ETEKCITY_PROFILE_MAX + 1,
|
||||
ETEKCITY_NUM_DPI,
|
||||
ETEKCITY_BUTTON_MAX + 1);
|
||||
ETEKCITY_BUTTON_MAX + 1,
|
||||
ETEKCITY_LED);
|
||||
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS);
|
||||
|
||||
@@ -667,8 +667,8 @@ etekcity_probe(struct ratbag_device *device)
|
||||
if (active_idx < 0) {
|
||||
log_error(device->ratbag,
|
||||
"Can't talk to the mouse: '%s' (%d)\n",
|
||||
strerror(-rc),
|
||||
rc);
|
||||
strerror(-active_idx),
|
||||
active_idx);
|
||||
rc = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
1510
src/driver-gskill.c
Normal file
@@ -35,8 +35,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define USB_VENDOR_ID_LOGITECH 0x046d
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
@@ -45,6 +43,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "hidpp10.h"
|
||||
#include "usb-ids.h"
|
||||
|
||||
#include "libratbag-private.h"
|
||||
#include "libratbag-hidraw.h"
|
||||
@@ -76,6 +75,7 @@ hidpp10drv_read_macro(struct ratbag_button *button,
|
||||
union hidpp10_button *binding)
|
||||
{
|
||||
struct ratbag_device *device = button->profile->device;
|
||||
struct ratbag_button_macro *m;
|
||||
const char *name;
|
||||
union hidpp10_macro_data *macro;
|
||||
unsigned int i, keycode;
|
||||
@@ -84,13 +84,13 @@ hidpp10drv_read_macro(struct ratbag_button *button,
|
||||
macro = profile->macros[binding->macro.address];
|
||||
|
||||
name = binding->macro.address > 1 ? (const char *)profile->macro_names[binding->macro.address - 2] : "";
|
||||
ratbag_button_set_macro(button, name);
|
||||
i = 0;
|
||||
m = ratbag_button_macro_new(name);
|
||||
|
||||
while (macro && macro->any.type != HIDPP10_MACRO_END && i < MAX_MACRO_EVENTS) {
|
||||
switch (macro->any.type) {
|
||||
case HIDPP10_MACRO_DELAY:
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
i++,
|
||||
RATBAG_MACRO_EVENT_WAIT,
|
||||
macro->delay.time);
|
||||
@@ -99,11 +99,11 @@ hidpp10drv_read_macro(struct ratbag_button *button,
|
||||
case HIDPP10_MACRO_KEY_PRESS:
|
||||
keycode = ratbag_hidraw_get_keycode_from_keyboard_usage(device, macro->key.key);
|
||||
if (!delay)
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
i++,
|
||||
RATBAG_MACRO_EVENT_WAIT,
|
||||
1);
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
i++,
|
||||
RATBAG_MACRO_EVENT_KEY_PRESSED,
|
||||
keycode);
|
||||
@@ -112,11 +112,11 @@ hidpp10drv_read_macro(struct ratbag_button *button,
|
||||
case HIDPP10_MACRO_KEY_RELEASE:
|
||||
keycode = ratbag_hidraw_get_keycode_from_keyboard_usage(device, macro->key.key);
|
||||
if (!delay)
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
i++,
|
||||
RATBAG_MACRO_EVENT_WAIT,
|
||||
1);
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
i++,
|
||||
RATBAG_MACRO_EVENT_KEY_RELEASED,
|
||||
keycode);
|
||||
@@ -125,11 +125,11 @@ hidpp10drv_read_macro(struct ratbag_button *button,
|
||||
case HIDPP10_MACRO_MOD_PRESS:
|
||||
keycode = hidpp10drv_read_macro_modifier(device, macro);
|
||||
if (!delay)
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
i++,
|
||||
RATBAG_MACRO_EVENT_WAIT,
|
||||
1);
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
i++,
|
||||
RATBAG_MACRO_EVENT_KEY_PRESSED,
|
||||
keycode);
|
||||
@@ -138,11 +138,11 @@ hidpp10drv_read_macro(struct ratbag_button *button,
|
||||
case HIDPP10_MACRO_MOD_RELEASE:
|
||||
keycode = hidpp10drv_read_macro_modifier(device, macro);
|
||||
if (!delay)
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
i++,
|
||||
RATBAG_MACRO_EVENT_WAIT,
|
||||
1);
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
i++,
|
||||
RATBAG_MACRO_EVENT_KEY_RELEASED,
|
||||
keycode);
|
||||
@@ -151,6 +151,9 @@ hidpp10drv_read_macro(struct ratbag_button *button,
|
||||
}
|
||||
macro++;
|
||||
}
|
||||
|
||||
ratbag_button_copy_macro(button, m);
|
||||
ratbag_button_macro_unref(m);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -248,6 +251,27 @@ hidpp10drv_read_button(struct ratbag_button *button)
|
||||
}
|
||||
hidpp10drv_map_button(device, hidpp10, button);
|
||||
break;
|
||||
case HIDPP10_PROFILE_G9:
|
||||
switch (button->index) {
|
||||
case 0: type = RATBAG_BUTTON_TYPE_LEFT; break;
|
||||
case 1: type = RATBAG_BUTTON_TYPE_RIGHT; break;
|
||||
case 2: type = RATBAG_BUTTON_TYPE_MIDDLE; break;
|
||||
case 3: type = RATBAG_BUTTON_TYPE_THUMB; break;
|
||||
case 4: type = RATBAG_BUTTON_TYPE_THUMB2; break;
|
||||
case 5: type = RATBAG_BUTTON_TYPE_UNKNOWN; break;
|
||||
case 6: type = RATBAG_BUTTON_TYPE_WHEEL_LEFT; break;
|
||||
case 7: type = RATBAG_BUTTON_TYPE_WHEEL_RIGHT; break;
|
||||
case 8: type = RATBAG_BUTTON_TYPE_RESOLUTION_UP; break;
|
||||
case 9: type = RATBAG_BUTTON_TYPE_RESOLUTION_DOWN; break;
|
||||
case 10:
|
||||
case 11:
|
||||
case 12: /* these don't actually exist on the device */
|
||||
type = RATBAG_BUTTON_TYPE_UNKNOWN; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
hidpp10drv_map_button(device, hidpp10, button);
|
||||
break;
|
||||
default:
|
||||
switch (button->index) {
|
||||
case 0: type = RATBAG_BUTTON_TYPE_LEFT; break;
|
||||
@@ -441,7 +465,8 @@ hidpp10drv_fill_from_profile(struct ratbag_device *device, struct hidpp10_device
|
||||
ratbag_device_init_profiles(device,
|
||||
count,
|
||||
profile.num_dpi_modes,
|
||||
profile.num_buttons);
|
||||
profile.num_buttons,
|
||||
profile.num_leds);
|
||||
|
||||
if (dev->profile_type != HIDPP10_PROFILE_UNKNOWN) {
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_PROFILE);
|
||||
@@ -479,16 +504,8 @@ hidpp10drv_probe(struct ratbag_device *device)
|
||||
int nread = 0;
|
||||
|
||||
rc = ratbag_find_hidraw(device, hidpp10drv_test_hidraw);
|
||||
if (rc == -ENODEV) {
|
||||
return rc;
|
||||
} else if (rc) {
|
||||
log_error(device->ratbag,
|
||||
"Can't open corresponding hidraw node: '%s' (%d)\n",
|
||||
strerror(-rc),
|
||||
rc);
|
||||
rc = -ENODEV;
|
||||
if (rc)
|
||||
goto err;
|
||||
}
|
||||
|
||||
drv_data = zalloc(sizeof(*drv_data));
|
||||
hidpp_device_init(&base, device->hidraw.fd);
|
||||
@@ -568,7 +585,7 @@ hidpp10drv_probe(struct ratbag_device *device)
|
||||
/* Fall back to something that every mouse has */
|
||||
struct ratbag_profile *profile;
|
||||
|
||||
ratbag_device_init_profiles(device, 1, 1, 3);
|
||||
ratbag_device_init_profiles(device, 1, 1, 3, 0);
|
||||
profile = ratbag_device_get_profile(device, 0);
|
||||
profile->is_active = true;
|
||||
ratbag_profile_unref(profile);
|
||||
|
||||
@@ -51,7 +51,8 @@
|
||||
#define HIDPP_CAP_BUTTON_KEY_1b04 (1 << 2)
|
||||
#define HIDPP_CAP_BATTERY_LEVEL_1000 (1 << 3)
|
||||
#define HIDPP_CAP_KBD_REPROGRAMMABLE_KEYS_1b00 (1 << 4)
|
||||
#define HIDPP_CAP_ONBOARD_PROFILES_8100 (1 << 5)
|
||||
#define HIDPP_CAP_COLOR_LED_EFFECTS_8070 (1 << 5)
|
||||
#define HIDPP_CAP_ONBOARD_PROFILES_8100 (1 << 6)
|
||||
|
||||
struct hidpp20drv_data {
|
||||
struct hidpp20_device *dev;
|
||||
@@ -61,10 +62,12 @@ struct hidpp20drv_data {
|
||||
unsigned num_controls;
|
||||
struct hidpp20_control_id *controls;
|
||||
struct hidpp20_profiles *profiles;
|
||||
struct hidpp20_color_led_zone_info *led_infos;
|
||||
|
||||
unsigned int num_profiles;
|
||||
unsigned int num_resolutions;
|
||||
unsigned int num_buttons;
|
||||
unsigned int num_leds;
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -117,38 +120,43 @@ hidpp20drv_read_macro_key_8100(struct ratbag_device *device, union hidpp20_macro
|
||||
return ratbag_hidraw_get_keycode_from_keyboard_usage(device, macro->key.key);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
hidpp20drv_read_macro_8100(struct ratbag_button *button,
|
||||
struct hidpp20_profile *profile,
|
||||
union hidpp20_button_binding *binding)
|
||||
{
|
||||
struct ratbag_device *device = button->profile->device;
|
||||
struct ratbag_button_macro *m;
|
||||
union hidpp20_macro_data *macro;
|
||||
unsigned int i, keycode;
|
||||
bool delay = true;
|
||||
|
||||
macro = profile->macros[binding->macro.page];
|
||||
|
||||
ratbag_button_set_macro(button, "macro");
|
||||
if (!macro)
|
||||
return -EINVAL;
|
||||
|
||||
i = 0;
|
||||
|
||||
m = ratbag_button_macro_new("macro");
|
||||
|
||||
while (macro && macro->any.type != HIDPP20_MACRO_END && i < MAX_MACRO_EVENTS) {
|
||||
switch (macro->any.type) {
|
||||
case HIDPP20_MACRO_DELAY:
|
||||
ratbag_button_set_macro_event(button,
|
||||
i++,
|
||||
RATBAG_MACRO_EVENT_WAIT,
|
||||
macro->delay.time);
|
||||
ratbag_button_macro_set_event(m,
|
||||
i++,
|
||||
RATBAG_MACRO_EVENT_WAIT,
|
||||
macro->delay.time);
|
||||
delay = true;
|
||||
break;
|
||||
case HIDPP20_MACRO_KEY_PRESS:
|
||||
keycode = hidpp20drv_read_macro_key_8100(device, macro);
|
||||
if (!delay)
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
i++,
|
||||
RATBAG_MACRO_EVENT_WAIT,
|
||||
1);
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
i++,
|
||||
RATBAG_MACRO_EVENT_KEY_PRESSED,
|
||||
keycode);
|
||||
@@ -157,11 +165,11 @@ hidpp20drv_read_macro_8100(struct ratbag_button *button,
|
||||
case HIDPP20_MACRO_KEY_RELEASE:
|
||||
keycode = hidpp20drv_read_macro_key_8100(device, macro);
|
||||
if (!delay)
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
i++,
|
||||
RATBAG_MACRO_EVENT_WAIT,
|
||||
1);
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
i++,
|
||||
RATBAG_MACRO_EVENT_KEY_RELEASED,
|
||||
keycode);
|
||||
@@ -170,6 +178,11 @@ hidpp20drv_read_macro_8100(struct ratbag_button *button,
|
||||
}
|
||||
macro++;
|
||||
}
|
||||
|
||||
ratbag_button_copy_macro(button, m);
|
||||
ratbag_button_macro_unref(m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -178,6 +191,7 @@ hidpp20drv_read_button_8100(struct ratbag_button *button)
|
||||
struct ratbag_device *device = button->profile->device;
|
||||
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
|
||||
struct hidpp20_profile *profile;
|
||||
int rc;
|
||||
|
||||
if (!(drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100))
|
||||
return;
|
||||
@@ -208,10 +222,13 @@ hidpp20drv_read_button_8100(struct ratbag_button *button)
|
||||
button->action.action.special = hidpp20_onboard_profiles_get_special(profile->buttons[button->index].special.special);
|
||||
break;
|
||||
case HIDPP20_BUTTON_MACRO:
|
||||
hidpp20drv_read_macro_8100(button, profile, &profile->buttons[button->index]);
|
||||
rc = hidpp20drv_read_macro_8100(button, profile, &profile->buttons[button->index]);
|
||||
if (rc)
|
||||
button->action.type = RATBAG_BUTTON_ACTION_TYPE_NONE;
|
||||
break;
|
||||
default:
|
||||
button->action.type = RATBAG_BUTTON_ACTION_TYPE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_BUTTON);
|
||||
@@ -227,6 +244,44 @@ hidpp20drv_read_button(struct ratbag_button *button)
|
||||
hidpp20drv_read_button_8100(button);
|
||||
}
|
||||
|
||||
static void
|
||||
hidpp20drv_read_led(struct ratbag_led *led)
|
||||
{
|
||||
struct ratbag_device *device = led->profile->device;
|
||||
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
|
||||
struct hidpp20_profile *profile;
|
||||
struct hidpp20_color_led_zone_info *led_info;
|
||||
struct hidpp20_led *h_led;
|
||||
|
||||
if (!(drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100))
|
||||
return;
|
||||
|
||||
led_info = &drv_data->led_infos[led->index];
|
||||
profile = &drv_data->profiles->profiles[led->profile->index];
|
||||
h_led = &profile->leds[led->index];
|
||||
|
||||
switch (h_led->mode) {
|
||||
case HIDPP20_LED_ON:
|
||||
led->mode = RATBAG_LED_ON;
|
||||
break;
|
||||
case HIDPP20_LED_CYCLE:
|
||||
led->mode = RATBAG_LED_CYCLE;
|
||||
break;
|
||||
case HIDPP20_LED_BREATHING:
|
||||
led->mode = RATBAG_LED_BREATHING;
|
||||
break;
|
||||
default:
|
||||
led->mode = RATBAG_LED_OFF;
|
||||
break;
|
||||
}
|
||||
led->type = hidpp20_8070_get_location_mapping(led_info->location);
|
||||
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;
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp20drv_write_button_1b04(struct ratbag_button *button,
|
||||
const struct ratbag_button_action *action)
|
||||
@@ -330,6 +385,52 @@ hidpp20drv_write_button(struct ratbag_button *button,
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp20drv_write_led(struct ratbag_led *led,
|
||||
enum ratbag_led_mode mode,
|
||||
struct ratbag_color color, unsigned int hz,
|
||||
unsigned int brightness)
|
||||
{
|
||||
struct ratbag_profile *profile = led->profile;
|
||||
struct ratbag_device *device = profile->device;
|
||||
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
|
||||
struct hidpp20_profile *h_profile;
|
||||
struct hidpp20_led *h_led;
|
||||
|
||||
if (!(drv_data->capabilities & HIDPP_CAP_COLOR_LED_EFFECTS_8070))
|
||||
return -ENOTSUP;
|
||||
|
||||
h_profile = &drv_data->profiles->profiles[profile->index];
|
||||
|
||||
h_led = &(h_profile->leds[led->index]);
|
||||
|
||||
if (!h_led)
|
||||
return -EINVAL;
|
||||
|
||||
switch (mode) {
|
||||
case RATBAG_LED_ON:
|
||||
h_led->mode = HIDPP20_LED_ON;
|
||||
break;
|
||||
case RATBAG_LED_CYCLE:
|
||||
h_led->mode = HIDPP20_LED_CYCLE;
|
||||
break;
|
||||
case RATBAG_LED_BREATHING:
|
||||
h_led->mode = HIDPP20_LED_BREATHING;
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
|
||||
return hidpp20_onboard_profiles_write(drv_data->dev, profile->index,
|
||||
drv_data->profiles);
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp20drv_current_profile(struct ratbag_device *device)
|
||||
{
|
||||
@@ -556,6 +657,29 @@ hidpp20drv_read_kbd_reprogrammable_key(struct ratbag_device *device)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp20drv_read_color_leds(struct ratbag_device *device)
|
||||
{
|
||||
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
|
||||
int rc;
|
||||
|
||||
if (!(drv_data->capabilities & HIDPP_CAP_COLOR_LED_EFFECTS_8070))
|
||||
return 0;
|
||||
|
||||
free(drv_data->led_infos);
|
||||
drv_data->led_infos = NULL;
|
||||
drv_data->num_leds = 0;
|
||||
|
||||
rc = hidpp20_color_led_effects_get_zone_infos(drv_data->dev, &drv_data->led_infos);
|
||||
|
||||
if (rc > 0) {
|
||||
drv_data->num_leds = rc;
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp20drv_read_onboard_profile(struct ratbag_device *device, unsigned index)
|
||||
{
|
||||
@@ -579,7 +703,7 @@ hidpp20drv_read_profile_8100(struct ratbag_profile *profile, unsigned int index)
|
||||
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
|
||||
struct ratbag_resolution *res;
|
||||
struct hidpp20_profile *p;
|
||||
unsigned i, dpi;
|
||||
unsigned i, dpi = 0;
|
||||
|
||||
hidpp20drv_read_onboard_profile(device, profile->index);
|
||||
|
||||
@@ -587,6 +711,10 @@ hidpp20drv_read_profile_8100(struct ratbag_profile *profile, unsigned int index)
|
||||
if ((int)index == hidpp20drv_current_profile(device))
|
||||
profile->is_active = true;
|
||||
|
||||
/* retrieve the resolution through 220X as the profile doesn't has it */
|
||||
if (profile->is_active)
|
||||
hidpp20drv_read_resolution_dpi(profile);
|
||||
|
||||
dpi = ratbag_resolution_get_dpi(profile->resolution.modes);
|
||||
|
||||
p = &drv_data->profiles->profiles[index];
|
||||
@@ -651,13 +779,13 @@ hidpp20drv_init_feature(struct ratbag_device *device, uint16_t feature)
|
||||
}
|
||||
case HIDPP_PAGE_ADJUSTABLE_DPI: {
|
||||
log_debug(ratbag, "device has adjustable dpi\n");
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION);
|
||||
drv_data->capabilities |= HIDPP_CAP_SWITCHABLE_RESOLUTION_2201;
|
||||
/* we read the profile once to get the correct number of
|
||||
* supported resolutions. */
|
||||
rc = hidpp20drv_read_resolution_dpi_2201(device);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
return 0; /* this is not a hard failure */
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION);
|
||||
drv_data->capabilities |= HIDPP_CAP_SWITCHABLE_RESOLUTION_2201;
|
||||
break;
|
||||
}
|
||||
case HIDPP_PAGE_SPECIAL_KEYS_BUTTONS: {
|
||||
@@ -701,6 +829,15 @@ hidpp20drv_init_feature(struct ratbag_device *device, uint16_t feature)
|
||||
}
|
||||
case HIDPP_PAGE_COLOR_LED_EFFECTS: {
|
||||
log_debug(ratbag, "device has color effects\n");
|
||||
drv_data->capabilities |= HIDPP_CAP_COLOR_LED_EFFECTS_8070;
|
||||
|
||||
/* we read the profile once to get the correct number of
|
||||
* supported leds. */
|
||||
if (hidpp20drv_read_color_leds(device))
|
||||
return 0;
|
||||
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_LED);
|
||||
device->num_leds = drv_data->num_leds;
|
||||
break;
|
||||
}
|
||||
case HIDPP_PAGE_ONBOARD_PROFILES: {
|
||||
@@ -714,6 +851,7 @@ hidpp20drv_init_feature(struct ratbag_device *device, uint16_t feature)
|
||||
drv_data->num_profiles = drv_data->profiles->num_profiles;
|
||||
drv_data->num_resolutions = drv_data->profiles->num_modes;
|
||||
drv_data->num_buttons = drv_data->profiles->num_buttons;
|
||||
drv_data->num_leds = drv_data->profiles->num_leds;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -734,6 +872,7 @@ hidpp20drv_20_probe(struct ratbag_device *device)
|
||||
struct hidpp20_device *dev = drv_data->dev;
|
||||
struct hidpp20_feature *feature_list = dev->feature_list;
|
||||
unsigned int i;
|
||||
int rc;
|
||||
|
||||
log_raw(device->ratbag,
|
||||
"'%s' has %d features\n",
|
||||
@@ -744,7 +883,9 @@ hidpp20drv_20_probe(struct ratbag_device *device)
|
||||
log_raw(device->ratbag, "Init feature %s (0x%04x) \n",
|
||||
hidpp20_feature_get_name(feature_list[i].feature),
|
||||
feature_list[i].feature);
|
||||
hidpp20drv_init_feature(device, feature_list[i].feature);
|
||||
rc = hidpp20drv_init_feature(device, feature_list[i].feature);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -765,6 +906,26 @@ hidpp20_log(void *userdata, enum hidpp_log_priority priority, const char *format
|
||||
log_msg_va(device->ratbag, priority, format, args);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
ratbag_close_hidraw(device);
|
||||
|
||||
if (drv_data->profiles)
|
||||
hidpp20_onboard_profiles_destroy(dev, drv_data->profiles);
|
||||
free(drv_data->controls);
|
||||
free(drv_data->sensors);
|
||||
if (drv_data->dev)
|
||||
hidpp20_device_destroy(drv_data->dev);
|
||||
free(drv_data);
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp20drv_probe(struct ratbag_device *device)
|
||||
{
|
||||
@@ -772,28 +933,42 @@ hidpp20drv_probe(struct ratbag_device *device)
|
||||
struct hidpp20drv_data *drv_data;
|
||||
struct hidpp_device base;
|
||||
struct hidpp20_device *dev;
|
||||
const char *prop;
|
||||
int device_idx = HIDPP_RECEIVER_IDX;
|
||||
int nread = 0;
|
||||
|
||||
rc = ratbag_find_hidraw(device, hidpp20drv_test_hidraw);
|
||||
if (rc == -ENODEV) {
|
||||
if (rc)
|
||||
return rc;
|
||||
} else if (rc) {
|
||||
log_error(device->ratbag,
|
||||
"Can't open corresponding hidraw node: '%s' (%d)\n",
|
||||
strerror(-rc),
|
||||
rc);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
drv_data = zalloc(sizeof(*drv_data));
|
||||
ratbag_set_drv_data(device, drv_data);
|
||||
hidpp_device_init(&base, device->hidraw.fd);
|
||||
hidpp_device_set_log_handler(&base, hidpp20_log, HIDPP_LOG_PRIORITY_RAW, device);
|
||||
|
||||
dev = hidpp20_device_new(&base, HIDPP_RECEIVER_IDX);
|
||||
prop = ratbag_device_get_udev_property(device, "RATBAG_HIDPP20_INDEX");
|
||||
if (prop) {
|
||||
sscanf(prop, "%d%n", &device_idx, &nread);
|
||||
if (!nread || (prop[nread]) != '\0' || device_idx < 0) {
|
||||
log_error(device->ratbag,
|
||||
"Error parsing RATBAG_HIDPP20_INDEX: '%s' for %s\n",
|
||||
prop,
|
||||
device->name);
|
||||
device_idx = HIDPP_RECEIVER_IDX;
|
||||
}
|
||||
}
|
||||
|
||||
/* In the general case, we can treat all devices as wired devices
|
||||
* here. If we talk to the correct hidraw device the kernel adjusts
|
||||
* the device index for us, so even for unifying receiver devices
|
||||
* we can just use 0xff as device index.
|
||||
*
|
||||
* If there is a special need like for G900, we can pass a
|
||||
* udev prop RATBAG_HIDPP20_INDEX.
|
||||
*/
|
||||
dev = hidpp20_device_new(&base, device_idx);
|
||||
if (!dev) {
|
||||
log_error(device->ratbag,
|
||||
"Failed to get HID++2.0 device for %s\n",
|
||||
device->name);
|
||||
rc = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -805,41 +980,24 @@ hidpp20drv_probe(struct ratbag_device *device)
|
||||
drv_data->num_profiles = 1;
|
||||
drv_data->num_resolutions = 1;
|
||||
drv_data->num_buttons = 8;
|
||||
drv_data->num_leds = 2;
|
||||
|
||||
if (dev->proto_major >= 2) {
|
||||
rc = hidpp20drv_20_probe(device);
|
||||
if (rc)
|
||||
goto err;
|
||||
}
|
||||
rc = hidpp20drv_20_probe(device);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
ratbag_device_init_profiles(device,
|
||||
drv_data->num_profiles,
|
||||
drv_data->num_resolutions,
|
||||
drv_data->num_buttons);
|
||||
drv_data->num_buttons,
|
||||
drv_data->num_leds);
|
||||
|
||||
return rc;
|
||||
err:
|
||||
free(drv_data);
|
||||
ratbag_set_drv_data(device, NULL);
|
||||
hidpp20drv_remove(device);
|
||||
return rc;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ratbag_close_hidraw(device);
|
||||
|
||||
if (drv_data->profiles)
|
||||
hidpp20_onboard_profiles_destroy(dev, drv_data->profiles);
|
||||
free(drv_data->controls);
|
||||
free(drv_data->sensors);
|
||||
hidpp20_device_destroy(drv_data->dev);
|
||||
free(drv_data);
|
||||
}
|
||||
|
||||
struct ratbag_driver hidpp20_driver = {
|
||||
.name = "Logitech HID++2.0",
|
||||
.id = "hidpp20",
|
||||
@@ -849,6 +1007,8 @@ struct ratbag_driver hidpp20_driver = {
|
||||
.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,
|
||||
};
|
||||
|
||||
500
src/driver-logitech-g300.c
Normal file
@@ -0,0 +1,500 @@
|
||||
/*
|
||||
* Copyright © 2016 Thomas Hindoe Paaboel Andersen.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <libevdev/libevdev.h>
|
||||
#include <linux/input.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libratbag-private.h"
|
||||
#include "libratbag-hidraw.h"
|
||||
|
||||
#define LOGITECH_G300_PROFILE_MAX 2
|
||||
#define LOGITECH_G300_BUTTON_MAX 8
|
||||
#define LOGITECH_G300_NUM_DPI 4
|
||||
#define LOGITECH_G300_NUM_LED 0
|
||||
|
||||
#define LOGITECH_G300_REPORT_ID_SET_ACTIVE_PROFILE 0xF0
|
||||
#define LOGITECH_G300_REPORT_ID_GET_ACTIVE_PROFILE 0xF1
|
||||
#define LOGITECH_G300_REPORT_ID_SET_ACTIVE_RESOLUTION 0xF0
|
||||
#define LOGITECH_G300_REPORT_ID_PROFILE_0 0xF3
|
||||
#define LOGITECH_G300_REPORT_ID_PROFILE_1 0xF4
|
||||
#define LOGITECH_G300_REPORT_ID_PROFILE_2 0xF5
|
||||
|
||||
#define LOGITECH_G300_REPORT_SIZE_ACTIVE_PROFILE 2
|
||||
#define LOGITECH_G300_REPORT_SIZE_PROFILE 35
|
||||
|
||||
struct logitech_g300_resolution {
|
||||
uint8_t dpi :7; /* Range 1-10. dpi = 250*value */
|
||||
uint8_t is_default :1;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct logitech_g300_button {
|
||||
uint8_t code;
|
||||
uint8_t modifier;
|
||||
uint8_t key;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct logitech_g300_profile_report {
|
||||
uint8_t id; /* F3, F4, F5 */
|
||||
uint8_t led; /* 00=off, 01=red, 02=green, 03=yellow, 04=blue, 05=pink, 06=turquoise, 07=white */
|
||||
uint8_t frequency; /* 00=1000, 01=125, 02=250, 03=500 */
|
||||
struct logitech_g300_resolution dpi_levels[LOGITECH_G300_NUM_DPI];
|
||||
uint8_t unknown; /* dpi index for shift, but something else too */
|
||||
struct logitech_g300_button buttons[LOGITECH_G300_BUTTON_MAX + 1];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct logitech_g300_profile_data {
|
||||
struct logitech_g300_profile_report report;
|
||||
};
|
||||
|
||||
struct logitech_g300_data {
|
||||
struct logitech_g300_profile_data profile_data[LOGITECH_G300_PROFILE_MAX + 1];
|
||||
};
|
||||
|
||||
_Static_assert(sizeof(struct logitech_g300_profile_report) == LOGITECH_G300_REPORT_SIZE_PROFILE,
|
||||
"Size of logitech_g300_profile_report is wrong");
|
||||
|
||||
struct logitech_g300_button_type_mapping {
|
||||
uint8_t raw;
|
||||
enum ratbag_button_type type;
|
||||
};
|
||||
|
||||
static const struct logitech_g300_button_type_mapping logitech_g300_button_type_mapping[] = {
|
||||
{ 0, RATBAG_BUTTON_TYPE_LEFT },
|
||||
{ 1, RATBAG_BUTTON_TYPE_RIGHT },
|
||||
{ 2, RATBAG_BUTTON_TYPE_MIDDLE },
|
||||
{ 3, RATBAG_BUTTON_TYPE_THUMB },
|
||||
{ 4, RATBAG_BUTTON_TYPE_THUMB2 },
|
||||
{ 5, RATBAG_BUTTON_TYPE_PINKIE },
|
||||
{ 6, RATBAG_BUTTON_TYPE_PINKIE2 },
|
||||
{ 7, RATBAG_BUTTON_TYPE_PROFILE_CYCLE_UP },
|
||||
{ 8, RATBAG_BUTTON_TYPE_RESOLUTION_CYCLE_UP },
|
||||
};
|
||||
|
||||
static enum ratbag_button_type
|
||||
logitech_g300_raw_to_button_type(uint8_t data)
|
||||
{
|
||||
const struct logitech_g300_button_type_mapping *mapping;
|
||||
|
||||
ARRAY_FOR_EACH(logitech_g300_button_type_mapping, mapping) {
|
||||
if (mapping->raw == data)
|
||||
return mapping->type;
|
||||
}
|
||||
|
||||
return RATBAG_BUTTON_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
struct logitech_g300_button_mapping {
|
||||
uint8_t raw;
|
||||
struct ratbag_button_action action;
|
||||
};
|
||||
|
||||
static struct logitech_g300_button_mapping logitech_g300_button_mapping[] = {
|
||||
/* 0x00 is either key or unassigned. Must be handled separatly */
|
||||
{ 0x01, BUTTON_ACTION_BUTTON(1) },
|
||||
{ 0x02, BUTTON_ACTION_BUTTON(2) },
|
||||
{ 0x03, BUTTON_ACTION_BUTTON(3) },
|
||||
{ 0x04, BUTTON_ACTION_BUTTON(4) },
|
||||
{ 0x05, BUTTON_ACTION_BUTTON(5) },
|
||||
{ 0x06, BUTTON_ACTION_BUTTON(6) },
|
||||
{ 0x07, BUTTON_ACTION_BUTTON(7) },
|
||||
{ 0x08, BUTTON_ACTION_BUTTON(8) },
|
||||
{ 0x09, BUTTON_ACTION_BUTTON(9) },
|
||||
{ 0x0A, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_UP) },
|
||||
{ 0x0B, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_DOWN) },
|
||||
{ 0x0C, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_UP) },
|
||||
{ 0x0D, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_CYCLE_UP) },
|
||||
{ 0x0E, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_ALTERNATE) },
|
||||
{ 0x0F, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_DEFAULT) },
|
||||
};
|
||||
|
||||
static const struct ratbag_button_action*
|
||||
logitech_g300_raw_to_button_action(uint8_t data)
|
||||
{
|
||||
struct logitech_g300_button_mapping *mapping;
|
||||
|
||||
ARRAY_FOR_EACH(logitech_g300_button_mapping, mapping) {
|
||||
if (mapping->raw == data)
|
||||
return &mapping->action;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
logitech_g300_button_action_to_raw(const struct ratbag_button_action *action)
|
||||
{
|
||||
struct logitech_g300_button_mapping *mapping;
|
||||
|
||||
ARRAY_FOR_EACH(logitech_g300_button_mapping, mapping) {
|
||||
if (ratbag_button_action_match(&mapping->action, action))
|
||||
return mapping->raw;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct logitech_g300_frequency_mapping {
|
||||
uint8_t raw;
|
||||
unsigned int frequency;
|
||||
};
|
||||
|
||||
static struct logitech_g300_frequency_mapping logitech_g300_frequency_mapping[] = {
|
||||
{ 0, 1000 },
|
||||
{ 1, 125 },
|
||||
{ 2, 250 },
|
||||
{ 3, 500 },
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
logitech_g300_raw_to_frequency(uint8_t data)
|
||||
{
|
||||
struct logitech_g300_frequency_mapping *mapping;
|
||||
|
||||
ARRAY_FOR_EACH(logitech_g300_frequency_mapping, mapping) {
|
||||
if (mapping->raw == data)
|
||||
return mapping->frequency;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
logitech_g300_frequency_to_raw(unsigned int frequency)
|
||||
{
|
||||
struct logitech_g300_frequency_mapping *mapping;
|
||||
|
||||
ARRAY_FOR_EACH(logitech_g300_frequency_mapping, mapping) {
|
||||
if (mapping->frequency == frequency)
|
||||
return mapping->raw;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
logitech_g300_current_profile(struct ratbag_device *device)
|
||||
{
|
||||
struct logitech_g300_data *drv_data = device->drv_data;
|
||||
uint8_t buf[LOGITECH_G300_REPORT_SIZE_ACTIVE_PROFILE];
|
||||
int i, ret;
|
||||
|
||||
ret = ratbag_hidraw_raw_request(device, LOGITECH_G300_REPORT_ID_GET_ACTIVE_PROFILE, buf,
|
||||
sizeof(buf), HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (ret != sizeof(buf))
|
||||
return -EIO;
|
||||
|
||||
/* The current profile is identifed by its LED color code. */
|
||||
for (i = 0; i <= LOGITECH_G300_PROFILE_MAX; i++) {
|
||||
struct logitech_g300_profile_report report;
|
||||
|
||||
report = drv_data->profile_data[i].report;
|
||||
if (report.led == buf[1])
|
||||
return i;
|
||||
}
|
||||
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
static int
|
||||
logitech_g300_set_current_profile(struct ratbag_device *device, unsigned int index)
|
||||
{
|
||||
uint8_t buf[] = {LOGITECH_G300_REPORT_ID_SET_ACTIVE_PROFILE, 0x80 + index, 0x00, 0x00};
|
||||
int ret;
|
||||
|
||||
if (index > LOGITECH_G300_PROFILE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
ret = ratbag_hidraw_raw_request(device, buf[0], buf, sizeof(buf),
|
||||
HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
|
||||
|
||||
return ret == sizeof(buf) ? 0 : ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int
|
||||
logitech_g300_set_current_resolution(struct ratbag_device *device, unsigned int index)
|
||||
{
|
||||
uint8_t buf[] = {LOGITECH_G300_REPORT_ID_SET_ACTIVE_PROFILE, 0x40 + index*2, 0x00, 0x00};
|
||||
int ret;
|
||||
|
||||
if (index >= LOGITECH_G300_NUM_DPI)
|
||||
return -EINVAL;
|
||||
|
||||
ret = ratbag_hidraw_raw_request(device, buf[0], buf, sizeof(buf),
|
||||
HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
|
||||
|
||||
return ret == sizeof(buf) ? 0 : ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
logitech_g300_read_profile(struct ratbag_profile *profile, unsigned int index)
|
||||
{
|
||||
struct ratbag_device *device = profile->device;
|
||||
struct logitech_g300_data *drv_data = device->drv_data;
|
||||
struct logitech_g300_profile_data *pdata;
|
||||
struct logitech_g300_profile_report *report;
|
||||
struct ratbag_resolution *resolution;
|
||||
unsigned int i, hz;
|
||||
uint8_t report_id;
|
||||
int rc;
|
||||
|
||||
assert(index <= LOGITECH_G300_PROFILE_MAX);
|
||||
|
||||
pdata = &drv_data->profile_data[index];
|
||||
report = &pdata->report;
|
||||
|
||||
switch (index) {
|
||||
case 0: report_id = LOGITECH_G300_REPORT_ID_PROFILE_0; break;
|
||||
case 1: report_id = LOGITECH_G300_REPORT_ID_PROFILE_1; break;
|
||||
case 2: report_id = LOGITECH_G300_REPORT_ID_PROFILE_2; break;
|
||||
}
|
||||
|
||||
rc = ratbag_hidraw_raw_request(device, report_id,
|
||||
(uint8_t*)report,
|
||||
sizeof(*report),
|
||||
HID_FEATURE_REPORT,
|
||||
HID_REQ_GET_REPORT);
|
||||
|
||||
if (rc < (signed)sizeof(*report)) {
|
||||
log_error(device->ratbag,
|
||||
"Error while requesting profile: %d\n", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
hz = logitech_g300_raw_to_frequency(report->frequency);
|
||||
|
||||
for (i = 0; i < profile->resolution.num_modes; i++) {
|
||||
struct logitech_g300_resolution *res =
|
||||
&report->dpi_levels[i];
|
||||
|
||||
resolution = &profile->resolution.modes[i];
|
||||
resolution->dpi_x = res->dpi * 250;
|
||||
resolution->dpi_y = res->dpi * 250;
|
||||
resolution->hz = hz;
|
||||
resolution->is_default = res->is_default;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
logitech_g300_read_button(struct ratbag_button *button)
|
||||
{
|
||||
const struct ratbag_button_action *action;
|
||||
struct ratbag_profile *profile = button->profile;
|
||||
struct ratbag_device *device = profile->device;
|
||||
struct logitech_g300_data *drv_data = device->drv_data;
|
||||
struct logitech_g300_profile_data *pdata;
|
||||
struct logitech_g300_profile_report *profile_report;
|
||||
struct logitech_g300_button *button_report;
|
||||
|
||||
pdata = &drv_data->profile_data[profile->index];
|
||||
profile_report = &pdata->report;
|
||||
button_report = &profile_report->buttons[button->index];
|
||||
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_BUTTON);
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_SPECIAL);
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_KEY);
|
||||
|
||||
button->type = logitech_g300_raw_to_button_type(button->index);
|
||||
|
||||
action = logitech_g300_raw_to_button_action(button_report->code);
|
||||
if (action) {
|
||||
button->action = *action;
|
||||
}
|
||||
else if (button_report->code == 0x00 && (button_report->modifier > 0x00 || button_report->key > 0x00))
|
||||
{
|
||||
struct ratbag_button_action *key_action = &button->action;
|
||||
|
||||
key_action->type = RATBAG_BUTTON_ACTION_TYPE_KEY;
|
||||
key_action->action.key.key = ratbag_hidraw_get_keycode_from_keyboard_usage(
|
||||
device, button_report->key);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
logitech_g300_test_hidraw(struct ratbag_device *device)
|
||||
{
|
||||
return ratbag_hidraw_has_report(device, LOGITECH_G300_REPORT_ID_GET_ACTIVE_PROFILE);
|
||||
}
|
||||
|
||||
static int
|
||||
logitech_g300_probe(struct ratbag_device *device)
|
||||
{
|
||||
int rc;
|
||||
struct ratbag_profile *profile;
|
||||
struct logitech_g300_data *drv_data = NULL;
|
||||
int active_idx;
|
||||
|
||||
rc = ratbag_find_hidraw(device, logitech_g300_test_hidraw);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
drv_data = zalloc(sizeof(*drv_data));
|
||||
ratbag_set_drv_data(device, drv_data);
|
||||
|
||||
/* profiles are 0-indexed */
|
||||
ratbag_device_init_profiles(device,
|
||||
LOGITECH_G300_PROFILE_MAX + 1,
|
||||
LOGITECH_G300_NUM_DPI,
|
||||
LOGITECH_G300_BUTTON_MAX + 1,
|
||||
LOGITECH_G300_NUM_LED);
|
||||
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION);
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_PROFILE);
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_KEY);
|
||||
|
||||
active_idx = logitech_g300_current_profile(device);
|
||||
|
||||
if (active_idx < 0) {
|
||||
log_error(device->ratbag,
|
||||
"Can't talk to the mouse: '%s' (%d)\n",
|
||||
strerror(-active_idx),
|
||||
active_idx);
|
||||
rc = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
list_for_each(profile, &device->profiles, link) {
|
||||
if (profile->index == (unsigned int)active_idx) {
|
||||
profile->is_active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
log_raw(device->ratbag,
|
||||
"'%s' is in profile %d\n",
|
||||
ratbag_device_get_name(device),
|
||||
profile->index);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
free(drv_data);
|
||||
ratbag_set_drv_data(device, NULL);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
logitech_g300_write_profile(struct ratbag_profile *profile)
|
||||
{
|
||||
struct ratbag_device *device = profile->device;
|
||||
struct logitech_g300_data *drv_data = device->drv_data;
|
||||
struct logitech_g300_profile_data *pdata;
|
||||
struct logitech_g300_profile_report *report;
|
||||
struct ratbag_button *button;
|
||||
uint8_t *buf;
|
||||
unsigned int hz, i;
|
||||
int rc;
|
||||
|
||||
pdata = &drv_data->profile_data[profile->index];
|
||||
report = &pdata->report;
|
||||
|
||||
/* The same hz is used for all resolutions */
|
||||
hz = profile->resolution.modes[0].hz;
|
||||
report->frequency = logitech_g300_frequency_to_raw(hz);
|
||||
|
||||
for (i = 0; i < profile->resolution.num_modes; i++) {
|
||||
struct ratbag_resolution *resolution = &profile->resolution.modes[i];
|
||||
struct logitech_g300_resolution *res = &report->dpi_levels[i];
|
||||
|
||||
res->dpi = resolution->dpi_x / 250;
|
||||
res->is_default = resolution->is_default;
|
||||
}
|
||||
|
||||
list_for_each(button, &profile->buttons, link) {
|
||||
struct ratbag_button_action *action = &button->action;
|
||||
struct logitech_g300_button *raw_button;
|
||||
|
||||
if (!button->dirty)
|
||||
continue;
|
||||
|
||||
raw_button = &report->buttons[button->index];
|
||||
|
||||
raw_button->code = logitech_g300_button_action_to_raw(action);
|
||||
raw_button->modifier = 0x00;
|
||||
raw_button->key = 0x00;
|
||||
if (action->type == RATBAG_BUTTON_ACTION_TYPE_KEY) {
|
||||
raw_button->key = ratbag_hidraw_get_keyboard_usage_from_keycode(
|
||||
device, action->action.key.key);
|
||||
}
|
||||
}
|
||||
|
||||
buf = (uint8_t*)report;
|
||||
|
||||
rc = ratbag_hidraw_raw_request(device, report->id,
|
||||
buf,
|
||||
sizeof(*report),
|
||||
HID_FEATURE_REPORT,
|
||||
HID_REQ_SET_REPORT);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
logitech_g300_commit(struct ratbag_device *device)
|
||||
{
|
||||
struct ratbag_profile *profile;
|
||||
int rc = 0;
|
||||
|
||||
list_for_each(profile, &device->profiles, link) {
|
||||
if (!profile->dirty)
|
||||
continue;
|
||||
|
||||
log_debug(device->ratbag,
|
||||
"Profile %d changed, rewriting\n", profile->index);
|
||||
|
||||
rc = logitech_g300_write_profile(profile);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
logitech_g300_remove(struct ratbag_device *device)
|
||||
{
|
||||
ratbag_close_hidraw(device);
|
||||
free(ratbag_get_drv_data(device));
|
||||
}
|
||||
|
||||
struct ratbag_driver logitech_g300_driver = {
|
||||
.name = "Logitech G300",
|
||||
.id = "logitech_g300",
|
||||
.probe = logitech_g300_probe,
|
||||
.remove = logitech_g300_remove,
|
||||
.read_profile = logitech_g300_read_profile,
|
||||
.commit = logitech_g300_commit,
|
||||
.set_active_profile = logitech_g300_set_current_profile,
|
||||
.read_button = logitech_g300_read_button,
|
||||
};
|
||||
@@ -36,6 +36,7 @@
|
||||
#define ROCCAT_PROFILE_MAX 4
|
||||
#define ROCCAT_BUTTON_MAX 23
|
||||
#define ROCCAT_NUM_DPI 5
|
||||
#define ROCCAT_LED_MAX 0
|
||||
|
||||
#define ROCCAT_MAX_RETRY_READY 10
|
||||
|
||||
@@ -532,6 +533,7 @@ roccat_read_button(struct ratbag_button *button)
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_MACRO);
|
||||
|
||||
if (action && action->type == RATBAG_BUTTON_ACTION_TYPE_MACRO) {
|
||||
struct ratbag_button_macro *m = NULL;
|
||||
|
||||
roccat_set_config_profile(device,
|
||||
button->profile->index,
|
||||
@@ -566,7 +568,7 @@ roccat_read_button(struct ratbag_button *button)
|
||||
goto out_macro;
|
||||
}
|
||||
|
||||
ratbag_button_set_macro(button, macro->name);
|
||||
m = ratbag_button_macro_new(macro->name);
|
||||
log_raw(device->ratbag,
|
||||
"macro on button %d of profile %d is named '%s', and contains %d events:\n",
|
||||
button->index, button->profile->index,
|
||||
@@ -574,7 +576,7 @@ roccat_read_button(struct ratbag_button *button)
|
||||
for (j = 0; j < macro->length; j++) {
|
||||
unsigned int keycode = ratbag_hidraw_get_keycode_from_keyboard_usage(device,
|
||||
macro->keys[j].keycode);
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
j * 2,
|
||||
macro->keys[j].flag & 0x01 ? RATBAG_MACRO_EVENT_KEY_PRESSED : RATBAG_MACRO_EVENT_KEY_RELEASED,
|
||||
keycode);
|
||||
@@ -582,7 +584,7 @@ roccat_read_button(struct ratbag_button *button)
|
||||
time = macro->keys[j].time;
|
||||
else
|
||||
time = macro->keys[j].flag & 0x01 ? 10 : 50;
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
j * 2 + 1,
|
||||
RATBAG_MACRO_EVENT_WAIT,
|
||||
time);
|
||||
@@ -592,9 +594,11 @@ roccat_read_button(struct ratbag_button *button)
|
||||
libevdev_event_code_get_name(EV_KEY, keycode),
|
||||
macro->keys[j].flag & 0x80 ? "released" : "pressed");
|
||||
}
|
||||
ratbag_button_copy_macro(button, m);
|
||||
}
|
||||
out_macro:
|
||||
msleep(10);
|
||||
ratbag_button_macro_unref(m);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -777,13 +781,8 @@ roccat_probe(struct ratbag_device *device)
|
||||
int active_idx;
|
||||
|
||||
rc = ratbag_open_hidraw(device);
|
||||
if (rc) {
|
||||
log_error(device->ratbag,
|
||||
"Can't open corresponding hidraw node: '%s' (%d)\n",
|
||||
strerror(-rc),
|
||||
rc);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (!ratbag_hidraw_has_report(device, ROCCAT_REPORT_ID_KEY_MAPPING)) {
|
||||
ratbag_close_hidraw(device);
|
||||
@@ -797,7 +796,8 @@ roccat_probe(struct ratbag_device *device)
|
||||
ratbag_device_init_profiles(device,
|
||||
ROCCAT_PROFILE_MAX + 1,
|
||||
ROCCAT_NUM_DPI,
|
||||
ROCCAT_BUTTON_MAX + 1);
|
||||
ROCCAT_BUTTON_MAX + 1,
|
||||
ROCCAT_LED_MAX);
|
||||
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS);
|
||||
|
||||
@@ -805,8 +805,8 @@ roccat_probe(struct ratbag_device *device)
|
||||
if (active_idx < 0) {
|
||||
log_error(device->ratbag,
|
||||
"Can't talk to the mouse: '%s' (%d)\n",
|
||||
strerror(-rc),
|
||||
rc);
|
||||
strerror(-active_idx),
|
||||
active_idx);
|
||||
rc = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <libevdev/libevdev.h>
|
||||
|
||||
#include "libratbag-private.h"
|
||||
#include "libratbag-test.h"
|
||||
@@ -73,6 +74,102 @@ test_set_active_profile(struct ratbag_device *device, unsigned int index)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
test_read_button(struct ratbag_button *button)
|
||||
{
|
||||
struct ratbag_device *device = button->profile->device;
|
||||
struct ratbag_test_device *d = ratbag_get_drv_data(device);
|
||||
struct ratbag_test_profile *p = &d->profiles[button->profile->index];
|
||||
struct ratbag_button_macro *m;
|
||||
const char data[] = "TEST";
|
||||
const char *c;
|
||||
|
||||
switch (p->buttons[button->index].type) {
|
||||
case RATBAG_BUTTON_ACTION_TYPE_BUTTON:
|
||||
button->action.type = RATBAG_BUTTON_ACTION_TYPE_BUTTON;
|
||||
button->action.action.button = p->buttons[button->index].button;
|
||||
break;
|
||||
case RATBAG_BUTTON_ACTION_TYPE_KEY:
|
||||
button->action.type = RATBAG_BUTTON_ACTION_TYPE_KEY;
|
||||
button->action.action.key.key = p->buttons[button->index].key;
|
||||
break;
|
||||
case RATBAG_BUTTON_ACTION_TYPE_MACRO:
|
||||
button->action.type = RATBAG_BUTTON_ACTION_TYPE_MACRO;
|
||||
m = ratbag_button_macro_new("test macro");
|
||||
|
||||
ARRAY_FOR_EACH(data, c) {
|
||||
char str[6];
|
||||
snprintf_safe(str, 6, "KEY_%c", *c);
|
||||
ratbag_button_macro_set_event(m,
|
||||
0,
|
||||
RATBAG_MACRO_EVENT_KEY_PRESSED,
|
||||
libevdev_event_code_from_name(EV_KEY, str));
|
||||
ratbag_button_macro_set_event(m,
|
||||
0,
|
||||
RATBAG_MACRO_EVENT_KEY_RELEASED,
|
||||
libevdev_event_code_from_name(EV_KEY, str));
|
||||
}
|
||||
ratbag_button_copy_macro(button, m);
|
||||
ratbag_button_macro_unref(m);
|
||||
break;
|
||||
default:
|
||||
button->action.type = RATBAG_BUTTON_ACTION_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_BUTTON);
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_KEY);
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_SPECIAL);
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_MACRO);
|
||||
}
|
||||
|
||||
static void
|
||||
test_read_led(struct ratbag_led *led)
|
||||
{
|
||||
struct ratbag_device *device = led->profile->device;
|
||||
struct ratbag_test_device *d = ratbag_get_drv_data(device);
|
||||
struct ratbag_test_profile *p = &d->profiles[led->profile->index];
|
||||
struct ratbag_test_led t_led = p->leds[led->index];
|
||||
|
||||
switch (t_led.mode) {
|
||||
case RATBAG_LED_ON:
|
||||
led->mode = RATBAG_LED_ON;
|
||||
break;
|
||||
case RATBAG_LED_CYCLE:
|
||||
led->mode = RATBAG_LED_CYCLE;
|
||||
break;
|
||||
case RATBAG_LED_BREATHING:
|
||||
led->mode = RATBAG_LED_BREATHING;
|
||||
break;
|
||||
default:
|
||||
led->mode = RATBAG_LED_OFF;
|
||||
}
|
||||
led->color.red = t_led.color.red;
|
||||
led->color.green = t_led.color.green;
|
||||
led->color.blue = t_led.color.blue;
|
||||
led->hz = t_led.hz;
|
||||
led->brightness = t_led.brightness;
|
||||
}
|
||||
|
||||
static int
|
||||
test_write_button(struct ratbag_button *button,
|
||||
const struct ratbag_button_action *action)
|
||||
{
|
||||
/* check if the device is still valid */
|
||||
assert(ratbag_get_drv_data(button->profile->device) != NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_write_led(struct ratbag_led *led,
|
||||
enum ratbag_led_mode mode,
|
||||
struct ratbag_color color, unsigned int hz,
|
||||
unsigned int brightness)
|
||||
{
|
||||
/* check if the device is still valid */
|
||||
assert(ratbag_get_drv_data(led->profile->device) != NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_fake_probe(struct ratbag_device *device)
|
||||
{
|
||||
@@ -88,7 +185,8 @@ test_probe(struct ratbag_device *device, void *data)
|
||||
ratbag_device_init_profiles(device,
|
||||
test_device->num_profiles,
|
||||
test_device->num_resolutions,
|
||||
test_device->num_buttons);
|
||||
test_device->num_buttons,
|
||||
test_device->num_leds);
|
||||
if (test_device->num_profiles > 1)
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS);
|
||||
|
||||
@@ -116,7 +214,9 @@ struct ratbag_driver test_driver = {
|
||||
.read_profile = test_read_profile,
|
||||
.write_profile = test_write_profile,
|
||||
.set_active_profile = test_set_active_profile,
|
||||
.read_button = NULL,
|
||||
.write_button = NULL,
|
||||
.read_button = test_read_button,
|
||||
.read_led = test_read_led,
|
||||
.write_button = test_write_button,
|
||||
.write_resolution_dpi = NULL,
|
||||
.write_led = test_write_led,
|
||||
};
|
||||
|
||||
@@ -138,6 +138,21 @@ static const struct hidpp20_1b04_physical_mapping hidpp20_1b04_physical_mapping[
|
||||
BUTTON_PHYS_MAPPING(221, "LedToggle" , RATBAG_BUTTON_TYPE_UNKNOWN),
|
||||
};
|
||||
|
||||
struct hidpp20_8070_location_mapping {
|
||||
uint16_t value;
|
||||
const char *name;
|
||||
enum ratbag_led_type type;
|
||||
};
|
||||
|
||||
#define LED_LOC_MAPPING(v_, n_, t_) \
|
||||
{ v_, n_, t_ }
|
||||
|
||||
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),
|
||||
};
|
||||
|
||||
const struct ratbag_button_action *
|
||||
hidpp20_1b04_get_logical_mapping(uint16_t value)
|
||||
{
|
||||
@@ -203,6 +218,32 @@ hidpp20_1b04_get_physical_mapping_name(uint16_t value)
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
enum ratbag_led_type
|
||||
hidpp20_8070_get_location_mapping(uint16_t value)
|
||||
{
|
||||
const struct hidpp20_8070_location_mapping *map;
|
||||
|
||||
ARRAY_FOR_EACH(hidpp20_8070_location_mapping, map) {
|
||||
if (map->value == value)
|
||||
return map->type;
|
||||
}
|
||||
|
||||
return RATBAG_LED_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
const char *
|
||||
hidpp20_8070_get_location_mapping_name(uint16_t value)
|
||||
{
|
||||
const struct hidpp20_8070_location_mapping *map;
|
||||
|
||||
ARRAY_FOR_EACH(hidpp20_8070_location_mapping, map) {
|
||||
if (map->value == value)
|
||||
return map->name;
|
||||
}
|
||||
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
int
|
||||
hidpp_write_command(struct hidpp_device *dev, uint8_t *cmd, int size)
|
||||
{
|
||||
|
||||
@@ -106,6 +106,12 @@ hidpp20_1b04_get_physical_mapping_name(uint16_t value);
|
||||
enum ratbag_button_type
|
||||
hidpp20_1b04_get_physical_mapping(uint16_t value);
|
||||
|
||||
enum ratbag_led_type
|
||||
hidpp20_8070_get_location_mapping(uint16_t value);
|
||||
|
||||
const char *
|
||||
hidpp20_8070_get_location_mapping_name(uint16_t value);
|
||||
|
||||
const char *
|
||||
hidpp20_1b04_get_logical_mapping_name(uint16_t value);
|
||||
|
||||
@@ -200,4 +206,10 @@ hidpp_cpu_to_le_u16(uint16_t data)
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
hidpp_get_unaligned_be_u32(uint8_t *buf)
|
||||
{
|
||||
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
||||
}
|
||||
|
||||
#endif /* HIDPP_GENERIC_H */
|
||||
|
||||
146
src/hidpp10.c
@@ -305,7 +305,7 @@ hidpp10_get_hidpp_notifications(struct hidpp10_device *dev,
|
||||
return res;
|
||||
|
||||
*reporting_flags = notifications.msg.parameters[0];
|
||||
*reporting_flags |= (notifications.msg.parameters[0] & 0x1F) << 8;
|
||||
*reporting_flags |= (notifications.msg.parameters[1] & 0x1F) << 8;
|
||||
*reporting_flags |= (notifications.msg.parameters[2] & 0x7 ) << 16;
|
||||
|
||||
return res;
|
||||
@@ -520,16 +520,16 @@ hidpp10_get_battery_mileage(struct hidpp10_device *dev,
|
||||
} \
|
||||
}
|
||||
|
||||
struct _hidpp10_dpi_mode_8_sym {
|
||||
struct _hidpp10_dpi_mode_8 {
|
||||
uint8_t res;
|
||||
uint8_t led1:4;
|
||||
uint8_t led2:4;
|
||||
uint8_t led3:4;
|
||||
uint8_t led4:4;
|
||||
} __attribute__((packed));
|
||||
_Static_assert(sizeof(struct _hidpp10_dpi_mode_8_sym) == 3, "Invalid size");
|
||||
_Static_assert(sizeof(struct _hidpp10_dpi_mode_8) == 3, "Invalid size");
|
||||
|
||||
struct _hidpp10_dpi_mode_8 {
|
||||
struct _hidpp10_dpi_mode_8_dual {
|
||||
uint8_t xres;
|
||||
uint8_t yres;
|
||||
uint8_t led1:4;
|
||||
@@ -537,7 +537,7 @@ struct _hidpp10_dpi_mode_8 {
|
||||
uint8_t led3:4;
|
||||
uint8_t led4:4;
|
||||
} __attribute__((packed));
|
||||
_Static_assert(sizeof(struct _hidpp10_dpi_mode_8) == 4, "Invalid size");
|
||||
_Static_assert(sizeof(struct _hidpp10_dpi_mode_8_dual) == 4, "Invalid size");
|
||||
|
||||
struct _hidpp10_dpi_mode_16 {
|
||||
uint16_t xres;
|
||||
@@ -616,7 +616,7 @@ static const uint8_t _hidpp10_profile_700_unknown1[3] = { 0x80, 0x01, 0x10 };
|
||||
static const uint8_t _hidpp10_profile_700_unknown2[10] = { 0x01, 0x2c, 0x02, 0x58, 0x64, 0xff, 0xbc, 0x00, 0x09, 0x31 };
|
||||
|
||||
struct _hidpp10_profile_700 {
|
||||
struct _hidpp10_dpi_mode_8 dpi_modes[PROFILE_NUM_DPI_MODES];
|
||||
struct _hidpp10_dpi_mode_8_dual dpi_modes[PROFILE_NUM_DPI_MODES];
|
||||
uint8_t default_dpi_mode;
|
||||
uint8_t unknown1[3];
|
||||
uint8_t usb_refresh_rate;
|
||||
@@ -631,11 +631,11 @@ struct _hidpp10_profile_9 {
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
uint8_t unknown1;
|
||||
struct _hidpp10_dpi_mode_8_sym dpi_modes[PROFILE_NUM_DPI_MODES];
|
||||
struct _hidpp10_dpi_mode_8 dpi_modes[PROFILE_NUM_DPI_MODES];
|
||||
uint8_t default_dpi_mode;
|
||||
uint8_t unknown2[2];
|
||||
uint8_t usb_refresh_rate;
|
||||
union _hidpp10_button_binding buttons[10];
|
||||
union _hidpp10_button_binding buttons[PROFILE_NUM_BUTTONS_G9];
|
||||
uint8_t unknown3[3];
|
||||
union _hidpp10_profile_metadata metadata;
|
||||
} __attribute__((packed));
|
||||
@@ -858,28 +858,6 @@ hidpp10_set_current_profile(struct hidpp10_device *dev, int16_t current_profile)
|
||||
PROFILE_TYPE_INDEX);
|
||||
}
|
||||
|
||||
static void
|
||||
hidpp10_fill_dpi_modes_8_sym(struct hidpp10_device *dev,
|
||||
struct hidpp10_profile *profile,
|
||||
struct _hidpp10_dpi_mode_8_sym *dpi_list,
|
||||
unsigned int count)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
profile->num_dpi_modes = count;
|
||||
for (i = 0; i < count; i++) {
|
||||
struct _hidpp10_dpi_mode_8_sym *dpi = &dpi_list[i];
|
||||
|
||||
profile->dpi_modes[i].xres = hidpp10_get_dpi_value(dev, dpi->res);
|
||||
profile->dpi_modes[i].yres = hidpp10_get_dpi_value(dev, dpi->res);
|
||||
|
||||
profile->dpi_modes[i].led[0] = dpi->led1 == 0x2;
|
||||
profile->dpi_modes[i].led[1] = dpi->led2 == 0x2;
|
||||
profile->dpi_modes[i].led[2] = dpi->led3 == 0x2;
|
||||
profile->dpi_modes[i].led[3] = dpi->led4 == 0x2;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hidpp10_fill_dpi_modes_8(struct hidpp10_device *dev,
|
||||
struct hidpp10_profile *profile,
|
||||
@@ -892,8 +870,8 @@ hidpp10_fill_dpi_modes_8(struct hidpp10_device *dev,
|
||||
for (i = 0; i < count; i++) {
|
||||
struct _hidpp10_dpi_mode_8 *dpi = &dpi_list[i];
|
||||
|
||||
profile->dpi_modes[i].xres = hidpp10_get_dpi_value(dev, dpi->xres);
|
||||
profile->dpi_modes[i].yres = hidpp10_get_dpi_value(dev, dpi->yres);
|
||||
profile->dpi_modes[i].xres = hidpp10_get_dpi_value(dev, dpi->res);
|
||||
profile->dpi_modes[i].yres = hidpp10_get_dpi_value(dev, dpi->res);
|
||||
|
||||
profile->dpi_modes[i].led[0] = dpi->led1 == 0x2;
|
||||
profile->dpi_modes[i].led[1] = dpi->led2 == 0x2;
|
||||
@@ -913,6 +891,48 @@ hidpp10_write_dpi_modes_8(struct hidpp10_device *dev,
|
||||
for (i = 0; i < count; i++) {
|
||||
struct _hidpp10_dpi_mode_8 *dpi = &dpi_list[i];
|
||||
|
||||
dpi->res = hidpp10_get_dpi_mapping(dev, profile->dpi_modes[i].xres);
|
||||
|
||||
dpi->led1 = profile->dpi_modes[i].led[0] ? 0x02 : 0x01;
|
||||
dpi->led2 = profile->dpi_modes[i].led[1] ? 0x02 : 0x01;
|
||||
dpi->led3 = profile->dpi_modes[i].led[2] ? 0x02 : 0x01;
|
||||
dpi->led4 = profile->dpi_modes[i].led[3] ? 0x02 : 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hidpp10_fill_dpi_modes_8_dual(struct hidpp10_device *dev,
|
||||
struct hidpp10_profile *profile,
|
||||
struct _hidpp10_dpi_mode_8_dual *dpi_list,
|
||||
unsigned int count)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
profile->num_dpi_modes = count;
|
||||
for (i = 0; i < count; i++) {
|
||||
struct _hidpp10_dpi_mode_8_dual *dpi = &dpi_list[i];
|
||||
|
||||
profile->dpi_modes[i].xres = hidpp10_get_dpi_value(dev, dpi->xres);
|
||||
profile->dpi_modes[i].yres = hidpp10_get_dpi_value(dev, dpi->yres);
|
||||
|
||||
profile->dpi_modes[i].led[0] = dpi->led1 == 0x2;
|
||||
profile->dpi_modes[i].led[1] = dpi->led2 == 0x2;
|
||||
profile->dpi_modes[i].led[2] = dpi->led3 == 0x2;
|
||||
profile->dpi_modes[i].led[3] = dpi->led4 == 0x2;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hidpp10_write_dpi_modes_8_dual(struct hidpp10_device *dev,
|
||||
struct hidpp10_profile *profile,
|
||||
struct _hidpp10_dpi_mode_8_dual *dpi_list,
|
||||
unsigned int count)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
struct _hidpp10_dpi_mode_8_dual *dpi = &dpi_list[i];
|
||||
|
||||
dpi->xres = hidpp10_get_dpi_mapping(dev, profile->dpi_modes[i].xres);
|
||||
dpi->yres = hidpp10_get_dpi_mapping(dev, profile->dpi_modes[i].yres);
|
||||
|
||||
@@ -1437,6 +1457,7 @@ hidpp10_get_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr
|
||||
break;
|
||||
default:
|
||||
hidpp_log_error(&dev->base, "This should never happen, complain to your maintainer.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
profile = &dev->profiles[number];
|
||||
@@ -1474,7 +1495,7 @@ hidpp10_get_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr
|
||||
profile->default_dpi_mode = p700->default_dpi_mode;
|
||||
profile->refresh_rate = p700->usb_refresh_rate ? 1000/p700->usb_refresh_rate : 0;
|
||||
|
||||
hidpp10_fill_dpi_modes_8(dev, profile, p700->dpi_modes, PROFILE_NUM_DPI_MODES);
|
||||
hidpp10_fill_dpi_modes_8_dual(dev, profile, p700->dpi_modes, PROFILE_NUM_DPI_MODES);
|
||||
hidpp10_profile_parse_names(dev, profile, number, &p700->metadata);
|
||||
hidpp10_fill_buttons(dev, profile, buttons, PROFILE_NUM_BUTTONS);
|
||||
break;
|
||||
@@ -1482,9 +1503,9 @@ hidpp10_get_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr
|
||||
profile->default_dpi_mode = p9->default_dpi_mode;
|
||||
profile->refresh_rate = p9->usb_refresh_rate ? 1000/p9->usb_refresh_rate : 0;
|
||||
|
||||
hidpp10_fill_dpi_modes_8_sym(dev, profile, p9->dpi_modes, PROFILE_NUM_DPI_MODES);
|
||||
hidpp10_fill_dpi_modes_8(dev, profile, p9->dpi_modes, PROFILE_NUM_DPI_MODES);
|
||||
hidpp10_profile_parse_names(dev, profile, number, &p9->metadata);
|
||||
hidpp10_fill_buttons(dev, profile, buttons, 10);
|
||||
hidpp10_fill_buttons(dev, profile, buttons, PROFILE_NUM_BUTTONS_G9);
|
||||
break;
|
||||
default:
|
||||
hidpp_log_error(&dev->base, "This should never happen, complain to your maintainer.\n");
|
||||
@@ -1561,11 +1582,12 @@ static const enum ratbag_button_action_special hidpp10_profiles_specials[] = {
|
||||
[0x02] = RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_RIGHT,
|
||||
[0x03] = RATBAG_BUTTON_ACTION_SPECIAL_BATTERY_LEVEL,
|
||||
[0x04] = RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_UP,
|
||||
[0x05] = RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_UP,
|
||||
|
||||
[0x05 ... 0x07] = RATBAG_BUTTON_ACTION_SPECIAL_INVALID,
|
||||
[0x06 ... 0x07] = RATBAG_BUTTON_ACTION_SPECIAL_INVALID,
|
||||
|
||||
[0x08] = RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_DOWN,
|
||||
[0x09] = RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_UP,
|
||||
[0x09] = RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_DOWN,
|
||||
|
||||
[0x0a ... 0x0f] = RATBAG_BUTTON_ACTION_SPECIAL_INVALID,
|
||||
|
||||
@@ -1575,8 +1597,9 @@ static const enum ratbag_button_action_special hidpp10_profiles_specials[] = {
|
||||
[0x12 ... 0x1f] = RATBAG_BUTTON_ACTION_SPECIAL_INVALID,
|
||||
|
||||
[0x20] = RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_DOWN,
|
||||
[0x21] = RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_CYCLE_DOWN,
|
||||
|
||||
[0x21 ... 0xff] = RATBAG_BUTTON_ACTION_SPECIAL_INVALID,
|
||||
[0x22 ... 0xff] = RATBAG_BUTTON_ACTION_SPECIAL_INVALID,
|
||||
};
|
||||
|
||||
enum ratbag_button_action_special
|
||||
@@ -1605,6 +1628,7 @@ hidpp10_set_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr
|
||||
union _hidpp10_profile_data *data = (union _hidpp10_profile_data *)page_data;
|
||||
struct _hidpp10_profile_500 *p500 = &data->profile_500;
|
||||
struct _hidpp10_profile_700 *p700 = &data->profile_700;
|
||||
struct _hidpp10_profile_9 *p9 = &data->profile_9;
|
||||
int res;
|
||||
struct hidpp10_directory directory[16]; /* completely random profile count */
|
||||
union _hidpp10_button_binding *buttons;
|
||||
@@ -1636,6 +1660,9 @@ hidpp10_set_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr
|
||||
case HIDPP10_PROFILE_G700:
|
||||
buttons = p700->buttons;
|
||||
break;
|
||||
case HIDPP10_PROFILE_G9:
|
||||
buttons = p9->buttons;
|
||||
break;
|
||||
default:
|
||||
hidpp_log_error(&dev->base, "This should never happen, complain to your maintainer.\n");
|
||||
}
|
||||
@@ -1645,6 +1672,7 @@ hidpp10_set_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr
|
||||
* values when we are not sure. */
|
||||
switch (dev->profile_type) {
|
||||
case HIDPP10_PROFILE_G500:
|
||||
case HIDPP10_PROFILE_G9:
|
||||
/* we do not know the actual values of the remaining field right now
|
||||
* so pre-fill with the current data */
|
||||
res = hidpp10_read_page(dev, directory[number].page, page_data);
|
||||
@@ -1676,10 +1704,21 @@ hidpp10_set_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr
|
||||
p700->default_dpi_mode = profile->default_dpi_mode;
|
||||
p700->usb_refresh_rate = 1000 / profile->refresh_rate;
|
||||
|
||||
hidpp10_write_dpi_modes_8(dev, profile, p700->dpi_modes, PROFILE_NUM_DPI_MODES);
|
||||
hidpp10_write_dpi_modes_8_dual(dev, profile, p700->dpi_modes, PROFILE_NUM_DPI_MODES);
|
||||
hidpp10_write_buttons(dev, profile, buttons, PROFILE_NUM_BUTTONS);
|
||||
hidpp10_profile_set_names(dev, profile, number, &p700->metadata);
|
||||
break;
|
||||
case HIDPP10_PROFILE_G9:
|
||||
p9->red = profile->red;
|
||||
p9->green = profile->green;
|
||||
p9->blue = profile->blue;
|
||||
p9->default_dpi_mode = profile->default_dpi_mode;
|
||||
p9->usb_refresh_rate = 1000 / profile->refresh_rate;
|
||||
|
||||
hidpp10_write_dpi_modes_8(dev, profile, p9->dpi_modes, PROFILE_NUM_DPI_MODES);
|
||||
hidpp10_write_buttons(dev, profile, buttons, PROFILE_NUM_BUTTONS);
|
||||
hidpp10_profile_set_names(dev, profile, number, &p9->metadata);
|
||||
break;
|
||||
default:
|
||||
hidpp_log_error(&dev->base, "This should never happen, complain to your maintainer.\n");
|
||||
}
|
||||
@@ -2002,18 +2041,28 @@ hidpp10_get_current_resolution(struct hidpp10_device *dev,
|
||||
uint16_t *yres)
|
||||
{
|
||||
unsigned idx = dev->index;
|
||||
union hidpp10_message resolution = CMD_CURRENT_RESOLUTION(REPORT_ID_SHORT, idx, GET_LONG_REGISTER_REQ);
|
||||
union hidpp10_message resolution = CMD_CURRENT_RESOLUTION(REPORT_ID_SHORT, idx, GET_REGISTER_REQ);
|
||||
union hidpp10_message resolution_long = CMD_CURRENT_RESOLUTION(REPORT_ID_SHORT, idx, GET_LONG_REGISTER_REQ);
|
||||
int res;
|
||||
|
||||
hidpp_log_raw(&dev->base, "Fetching current resolution\n");
|
||||
|
||||
res = hidpp10_request_command(dev, &resolution);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
/* resolution is in 50dpi multiples */
|
||||
*xres = hidpp10_get_dpi_value(dev, hidpp_get_unaligned_le_u16(&resolution.data[4]));
|
||||
*yres = hidpp10_get_dpi_value(dev, hidpp_get_unaligned_le_u16(&resolution.data[6]));
|
||||
switch (dev->profile_type) {
|
||||
case HIDPP10_PROFILE_G9:
|
||||
res = hidpp10_request_command(dev, &resolution);
|
||||
if (res)
|
||||
return res;
|
||||
/* resolution is in 50dpi multiples */
|
||||
*xres = *yres = hidpp10_get_dpi_value(dev, hidpp_get_unaligned_le_u16(&resolution.data[4]));
|
||||
break;
|
||||
default:
|
||||
res = hidpp10_request_command(dev, &resolution_long);
|
||||
if (res)
|
||||
return res;
|
||||
/* resolution is in 50dpi multiples */
|
||||
*xres = hidpp10_get_dpi_value(dev, hidpp_get_unaligned_le_u16(&resolution_long.data[4]));
|
||||
*yres = hidpp10_get_dpi_value(dev, hidpp_get_unaligned_le_u16(&resolution_long.data[6]));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2508,8 +2557,7 @@ hidpp10_get_extended_pairing_information(struct hidpp10_device *dev,
|
||||
if (res)
|
||||
return -1;
|
||||
|
||||
*serial = hidpp_get_unaligned_be_u16(&info.msg.string[2]) << 16;
|
||||
*serial |= hidpp_get_unaligned_be_u16(&info.msg.string[4]);
|
||||
*serial = hidpp_get_unaligned_be_u32(&info.msg.string[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -365,6 +365,7 @@ hidpp10_get_battery_mileage(struct hidpp10_device *dev,
|
||||
/* 0x0F: Profile queries */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
#define PROFILE_NUM_BUTTONS 13
|
||||
#define PROFILE_NUM_BUTTONS_G9 10
|
||||
#define PROFILE_NUM_DPI_MODES 5
|
||||
#define PROFILE_BUTTON_TYPE_BUTTON 0x81
|
||||
#define PROFILE_BUTTON_TYPE_KEYS 0x82
|
||||
@@ -493,6 +494,7 @@ struct hidpp10_profile {
|
||||
} buttons[PROFILE_NUM_BUTTONS];
|
||||
union hidpp10_macro_data *macros[PROFILE_NUM_BUTTONS];
|
||||
size_t num_buttons;
|
||||
size_t num_leds;
|
||||
|
||||
unsigned int initialized;
|
||||
};
|
||||
|
||||
437
src/hidpp20.c
@@ -500,6 +500,118 @@ err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0x8070 - Color LED effects */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#define CMD_COLOR_LED_EFFECTS_GET_INFO 0x00
|
||||
#define CMD_COLOR_LED_EFFECTS_GET_ZONE_INFO 0x10
|
||||
|
||||
static int
|
||||
hidpp20_color_led_zones_get_count(struct hidpp20_device *device, uint8_t reg)
|
||||
{
|
||||
int rc;
|
||||
union hidpp20_message msg = {
|
||||
.msg.report_id = REPORT_ID_SHORT,
|
||||
.msg.device_idx = device->index,
|
||||
.msg.address = CMD_COLOR_LED_EFFECTS_GET_INFO,
|
||||
};
|
||||
struct hidpp20_color_led_info *info;
|
||||
uint8_t feature_index;
|
||||
|
||||
feature_index = hidpp_root_get_feature_idx(device,
|
||||
HIDPP_PAGE_COLOR_LED_EFFECTS);
|
||||
if (feature_index == 0)
|
||||
return -ENOTSUP;
|
||||
|
||||
msg.msg.sub_id = feature_index;
|
||||
|
||||
rc = hidpp20_request_command(device, &msg);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
info = (struct hidpp20_color_led_info *)msg.msg.parameters;
|
||||
|
||||
return info->zone_count;
|
||||
}
|
||||
|
||||
int
|
||||
hidpp20_color_led_effects_get_zone_info(struct hidpp20_device *device,
|
||||
uint8_t reg,
|
||||
struct hidpp20_color_led_zone_info *info)
|
||||
{
|
||||
int rc;
|
||||
struct hidpp20_color_led_zone_info *msg_info;
|
||||
union hidpp20_message msg = {
|
||||
.msg.report_id = REPORT_ID_LONG,
|
||||
.msg.device_idx = device->index,
|
||||
.msg.sub_id = reg,
|
||||
.msg.address = CMD_COLOR_LED_EFFECTS_GET_ZONE_INFO,
|
||||
.msg.parameters[0] = info->index,
|
||||
};
|
||||
|
||||
rc = hidpp20_request_command(device, &msg);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
msg_info = (struct hidpp20_color_led_zone_info *)msg.msg.parameters;
|
||||
info->location = msg_info->location;
|
||||
info->num_effects = msg_info->num_effects;
|
||||
info->persistency_caps = msg_info->persistency_caps;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hidpp20_color_led_effects_get_zone_infos(struct hidpp20_device *device,
|
||||
struct hidpp20_color_led_zone_info **infos_list)
|
||||
{
|
||||
uint8_t feature_index;
|
||||
struct hidpp20_color_led_zone_info *i_list, *info;
|
||||
uint8_t num_infos;
|
||||
unsigned i;
|
||||
int rc;
|
||||
|
||||
feature_index = hidpp_root_get_feature_idx(device,
|
||||
HIDPP_PAGE_COLOR_LED_EFFECTS);
|
||||
if (feature_index == 0)
|
||||
return -ENOTSUP;
|
||||
|
||||
rc = hidpp20_color_led_zones_get_count(device, feature_index);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
num_infos = rc;
|
||||
if (num_infos == 0) {
|
||||
*infos_list = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
i_list = zalloc(num_infos * sizeof(struct hidpp20_color_led_zone_info));
|
||||
|
||||
for (i = 0; i < num_infos; i++) {
|
||||
info = &i_list[i];
|
||||
info->index = i;
|
||||
rc = hidpp20_color_led_effects_get_zone_info(device, feature_index, info);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
hidpp_log_raw(&device->base,
|
||||
"led_info %d: location: %d type %s num_effects: %d persistency_caps: 0x%02x\n",
|
||||
info->index,
|
||||
info->location,
|
||||
hidpp20_8070_get_location_mapping_name(info->location),
|
||||
info->num_effects,
|
||||
info->persistency_caps);
|
||||
}
|
||||
|
||||
*infos_list = i_list;
|
||||
return num_infos;
|
||||
err:
|
||||
free(i_list);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0x1b04: Special keys and mouse buttons */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@@ -863,8 +975,9 @@ int hidpp20_adjustable_dpi_get_sensors(struct hidpp20_device *device,
|
||||
*sensors_list = s_list;
|
||||
return num_sensors;
|
||||
err:
|
||||
num_sensors = 0;
|
||||
free(s_list);
|
||||
return rc;
|
||||
return rc > 0 ? -EPROTO : rc;
|
||||
}
|
||||
|
||||
int hidpp20_adjustable_dpi_set_sensor_dpi(struct hidpp20_device *device,
|
||||
@@ -907,6 +1020,8 @@ int hidpp20_adjustable_dpi_set_sensor_dpi(struct hidpp20_device *device,
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#define CMD_ONBOARD_PROFILES_GET_PROFILES_DESCR 0x00
|
||||
#define CMD_ONBOARD_PROFILES_SET_ONBOARD_MODE 0x10
|
||||
#define CMD_ONBOARD_PROFILES_GET_ONBOARD_MODE 0x20
|
||||
#define CMD_ONBOARD_PROFILES_SET_CURRENT_PROFILE 0x30
|
||||
#define CMD_ONBOARD_PROFILES_GET_CURRENT_PROFILE 0x40
|
||||
#define CMD_ONBOARD_PROFILES_MEMORY_READ 0x50
|
||||
@@ -920,6 +1035,31 @@ int hidpp20_adjustable_dpi_set_sensor_dpi(struct hidpp20_device *device,
|
||||
#define HIDPP20_PROFILE_SIZE HIDPP20_PAGE_SIZE
|
||||
#define HIDPP20_BUTTON_HID 0x80
|
||||
|
||||
#define HIDPP20_MODE_NO_CHANGE 0x00
|
||||
#define HIDPP20_ONBOARD_MODE 0x01
|
||||
#define HIDPP20_HOST_MODE 0x02
|
||||
|
||||
#define HIDPP20_ONBOARD_PROFILES_MEMORY_TYPE_G402 0x01
|
||||
#define HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G402 0x01
|
||||
#define HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G303 0x02
|
||||
#define HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G900 0x03
|
||||
#define HIDPP20_ONBOARD_PROFILES_MACRO_TYPE_G402 0x01
|
||||
|
||||
struct hidpp20_onboard_profiles_info {
|
||||
uint8_t memory_model_id;
|
||||
uint8_t profile_format_id;
|
||||
uint8_t macro_format_id;
|
||||
uint8_t profile_count;
|
||||
uint8_t profile_count_oob;
|
||||
uint8_t button_count;
|
||||
uint8_t sector_count;
|
||||
uint16_t sector_size;
|
||||
uint8_t mechanical_layout;
|
||||
uint8_t various_info;
|
||||
uint8_t reserved[5];
|
||||
} __attribute__((packed));
|
||||
_Static_assert(sizeof(struct hidpp20_onboard_profiles_info) == 16, "Invalid size");
|
||||
|
||||
int
|
||||
hidpp20_onboard_profiles_read_memory(struct hidpp20_device *device,
|
||||
uint8_t read_rom,
|
||||
@@ -1076,6 +1216,58 @@ hidpp20_onboard_profiles_write_page(struct hidpp20_device *device,
|
||||
return hidpp20_onboard_profiles_write_data(device, page, 0x00, data, HIDPP20_PAGE_SIZE);
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp20_onboard_profiles_get_onboard_mode(struct hidpp20_device *device)
|
||||
{
|
||||
uint8_t feature_index;
|
||||
int rc;
|
||||
union hidpp20_message msg = {
|
||||
.msg.report_id = REPORT_ID_SHORT,
|
||||
.msg.device_idx = device->index,
|
||||
.msg.address = CMD_ONBOARD_PROFILES_GET_ONBOARD_MODE,
|
||||
};
|
||||
|
||||
feature_index = hidpp_root_get_feature_idx(device,
|
||||
HIDPP_PAGE_ONBOARD_PROFILES);
|
||||
if (feature_index == 0)
|
||||
return -ENOTSUP;
|
||||
|
||||
msg.msg.sub_id = feature_index;
|
||||
|
||||
rc = hidpp20_request_command(device, &msg);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return msg.msg.parameters[0];
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp20_onboard_profiles_set_onboard_mode(struct hidpp20_device *device,
|
||||
uint8_t onboard_mode)
|
||||
{
|
||||
uint8_t feature_index;
|
||||
int rc;
|
||||
union hidpp20_message msg = {
|
||||
.msg.report_id = REPORT_ID_SHORT,
|
||||
.msg.device_idx = device->index,
|
||||
.msg.address = CMD_ONBOARD_PROFILES_SET_ONBOARD_MODE,
|
||||
.msg.parameters[1] = onboard_mode,
|
||||
};
|
||||
|
||||
feature_index = hidpp_root_get_feature_idx(device,
|
||||
HIDPP_PAGE_ONBOARD_PROFILES);
|
||||
if (feature_index == 0)
|
||||
return -ENOTSUP;
|
||||
|
||||
msg.msg.sub_id = feature_index;
|
||||
|
||||
rc = hidpp20_request_command(device, &msg);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hidpp20_onboard_profiles_get_current_profile(struct hidpp20_device *device)
|
||||
{
|
||||
@@ -1130,16 +1322,18 @@ hidpp20_onboard_profiles_set_current_profile(struct hidpp20_device *device,
|
||||
|
||||
static int
|
||||
hidpp20_onboard_profiles_initialize(struct hidpp20_device *device,
|
||||
unsigned profile_count,
|
||||
struct hidpp20_profiles *profiles_list)
|
||||
struct hidpp20_profiles **profiles_list)
|
||||
{
|
||||
uint8_t feature_index;
|
||||
int rc;
|
||||
struct hidpp20_profiles *profiles;
|
||||
union hidpp20_message msg = {
|
||||
.msg.report_id = REPORT_ID_SHORT,
|
||||
.msg.device_idx = device->index,
|
||||
.msg.address = CMD_ONBOARD_PROFILES_GET_PROFILES_DESCR,
|
||||
};
|
||||
struct hidpp20_onboard_profiles_info *info;
|
||||
int onboard_mode;
|
||||
|
||||
feature_index = hidpp_root_get_feature_idx(device,
|
||||
HIDPP_PAGE_ONBOARD_PROFILES);
|
||||
@@ -1152,10 +1346,78 @@ hidpp20_onboard_profiles_initialize(struct hidpp20_device *device,
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
profiles_list->num_buttons = msg.msg.parameters[5] <= 16 ? msg.msg.parameters[5] : 16;
|
||||
profiles_list->num_profiles = profile_count;
|
||||
/* FIXME: actually retrieve the correct values */
|
||||
profiles_list->num_modes = 5;
|
||||
info = (struct hidpp20_onboard_profiles_info *)msg.msg.parameters;
|
||||
|
||||
if (info->memory_model_id != HIDPP20_ONBOARD_PROFILES_MEMORY_TYPE_G402) {
|
||||
hidpp_log_error(&device->base,
|
||||
"Memory layout not supported: 0x%02x.\n",
|
||||
info->memory_model_id);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if ((info->profile_format_id != HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G402) &&
|
||||
(info->profile_format_id != HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G303) &&
|
||||
(info->profile_format_id != HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G900)) {
|
||||
hidpp_log_error(&device->base,
|
||||
"Profile layout not supported: 0x%02x.\n",
|
||||
info->profile_format_id);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (info->macro_format_id != HIDPP20_ONBOARD_PROFILES_MACRO_TYPE_G402) {
|
||||
hidpp_log_error(&device->base,
|
||||
"Macro format not supported: 0x%02x.\n",
|
||||
info->macro_format_id);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
info->sector_size = hidpp_be_u16_to_cpu(info->sector_size);
|
||||
if (info->sector_size != HIDPP20_PAGE_SIZE) {
|
||||
hidpp_log_error(&device->base,
|
||||
"Unsupported sector size: %d.\n",
|
||||
info->sector_size);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
rc = hidpp20_onboard_profiles_get_onboard_mode(device);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
onboard_mode = rc;
|
||||
if (onboard_mode != HIDPP20_ONBOARD_MODE) {
|
||||
hidpp_log_raw(&device->base,
|
||||
"not on the correct mode: %d.\n",
|
||||
onboard_mode);
|
||||
rc = hidpp20_onboard_profiles_set_onboard_mode(device,
|
||||
HIDPP20_ONBOARD_MODE);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
profiles = zalloc(sizeof(struct hidpp20_profiles) +
|
||||
info->profile_count * sizeof(struct hidpp20_profile));
|
||||
|
||||
profiles->num_profiles = info->profile_count;
|
||||
profiles->num_rom_profiles = info->profile_count_oob;
|
||||
profiles->num_buttons = msg.msg.parameters[5] <= 16 ? msg.msg.parameters[5] : 16;
|
||||
profiles->num_modes = HIDPP20_DPI_COUNT;
|
||||
profiles->num_leds = HIDPP20_LED_COUNT;
|
||||
profiles->has_g_shift = (info->mechanical_layout & 0x03) == 2;
|
||||
profiles->has_dpi_shift = ((info->mechanical_layout & 0x0c) >> 2) == 2;
|
||||
switch(info->various_info & 0x07) {
|
||||
case 1:
|
||||
profiles->corded = 1;
|
||||
break;
|
||||
case 2:
|
||||
profiles->wireless = 1;
|
||||
break;
|
||||
case 4:
|
||||
profiles->corded = 1;
|
||||
profiles->wireless = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
*profiles_list = profiles;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1320,44 +1582,64 @@ hidpp20_onboard_profiles_parse_macro(struct hidpp20_device *device,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
hidpp20_onboard_profiles_compute_dict_size(struct hidpp20_device *device,
|
||||
struct hidpp20_profiles *profiles)
|
||||
{
|
||||
unsigned p, num_offset;
|
||||
|
||||
num_offset = 0;
|
||||
p = profiles->num_profiles;
|
||||
while (p) {
|
||||
p >>= 2;
|
||||
num_offset += 16;
|
||||
}
|
||||
|
||||
return num_offset;
|
||||
}
|
||||
|
||||
int
|
||||
hidpp20_onboard_profiles_allocate(struct hidpp20_device *device,
|
||||
struct hidpp20_profiles **profiles_list)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned i, offset, num_offset;
|
||||
int rc;
|
||||
uint8_t data[16] = {0};
|
||||
struct hidpp20_profiles *profiles;
|
||||
unsigned profile_count = 0;
|
||||
uint8_t data[HIDPP20_PAGE_SIZE] = {0};
|
||||
struct hidpp20_profiles *profiles = NULL;
|
||||
|
||||
rc = hidpp20_onboard_profiles_read_memory(device,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
data);
|
||||
rc = hidpp20_onboard_profiles_initialize(device,
|
||||
&profiles);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
profiles = zalloc(sizeof(struct hidpp20_profiles));
|
||||
assert(profiles);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
uint8_t *d = data + 4 * i;
|
||||
num_offset = hidpp20_onboard_profiles_compute_dict_size(device,
|
||||
profiles);
|
||||
|
||||
for (offset = 0; offset < num_offset; offset += 16) {
|
||||
rc = hidpp20_onboard_profiles_read_memory(device,
|
||||
0x00,
|
||||
0x00,
|
||||
offset,
|
||||
data + offset);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = 0; i < profiles->num_profiles; i++) {
|
||||
uint8_t *d = data + offset + 4 * i;
|
||||
|
||||
if (d[0] == 0xFF && d[1] == 0xFF)
|
||||
break;
|
||||
|
||||
profile_count++;
|
||||
profiles->profiles[i].index = d[1];
|
||||
profiles->profiles[i].enabled = d[2];
|
||||
}
|
||||
|
||||
hidpp20_onboard_profiles_initialize(device,
|
||||
profile_count,
|
||||
profiles);
|
||||
|
||||
*profiles_list = profiles;
|
||||
|
||||
return profile_count;
|
||||
return profiles->num_profiles;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1386,7 +1668,8 @@ hidpp20_onboard_profiles_destroy(struct hidpp20_device *device,
|
||||
static int
|
||||
hidpp20_onboard_profiles_find_and_read_profile(struct hidpp20_device *device,
|
||||
unsigned int index,
|
||||
uint8_t *data)
|
||||
uint8_t *data,
|
||||
unsigned int num_rom_profiles)
|
||||
{
|
||||
int rc;
|
||||
unsigned i;
|
||||
@@ -1419,13 +1702,19 @@ hidpp20_onboard_profiles_find_and_read_profile(struct hidpp20_device *device,
|
||||
}
|
||||
|
||||
/* something went wrong, the mouse is using the factory profile in ROM */
|
||||
if (num_rom_profiles == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (index >= num_rom_profiles)
|
||||
index = num_rom_profiles - 1;
|
||||
|
||||
for (i = 0; i < HIDPP20_PROFILE_SIZE / 0x10; i++) {
|
||||
rc = hidpp20_onboard_profiles_read_memory(device,
|
||||
1,
|
||||
index + 1,
|
||||
i * 0x10,
|
||||
data + i * 0x10);
|
||||
if (rc < 0)
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1446,7 +1735,7 @@ hidpp20_onboard_profiles_enable_profile(struct hidpp20_device *device,
|
||||
profiles_list->profiles[index].index = index + 1;
|
||||
profiles_list->profiles[index].enabled = 0x01;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (i = 0; i < profiles_list->num_profiles; i++) {
|
||||
data[buffer_index++] = 0x00;
|
||||
data[buffer_index++] = i + 1;
|
||||
data[buffer_index++] = profiles_list->profiles[i].enabled;
|
||||
@@ -1461,7 +1750,11 @@ hidpp20_onboard_profiles_enable_profile(struct hidpp20_device *device,
|
||||
|
||||
memset(data + buffer_index, 0xff, sizeof(data) - buffer_index);
|
||||
|
||||
hidpp_log_buf_error(&device->base, "dictionary: ", data, 16);
|
||||
hidpp_log_buf_debug(&device->base,
|
||||
"dictionary: ",
|
||||
data,
|
||||
hidpp20_onboard_profiles_compute_dict_size(device,
|
||||
profiles_list));
|
||||
|
||||
return hidpp20_onboard_profiles_write_page(device, 0x00, data);
|
||||
}
|
||||
@@ -1472,16 +1765,19 @@ union hidpp20_internal_profile {
|
||||
uint8_t report_rate;
|
||||
uint8_t default_dpi;
|
||||
uint8_t switched_dpi;
|
||||
uint16_t dpi[7];
|
||||
uint8_t zero;
|
||||
uint8_t padding[14];
|
||||
uint16_t dpi[5];
|
||||
struct hidpp20_color profile_color;
|
||||
uint8_t power_mode;
|
||||
uint8_t angle_snapping;
|
||||
uint8_t reserved[14];
|
||||
union hidpp20_button_binding buttons[16];
|
||||
union hidpp20_button_binding alternate_buttons[16];
|
||||
union {
|
||||
char txt[16 * 3];
|
||||
uint8_t raw[16 * 3];
|
||||
} name;
|
||||
uint8_t padding1[46];
|
||||
struct hidpp20_internal_led leds[2]; /* G303, g502, g900 only */
|
||||
uint8_t free[24];
|
||||
uint16_t crc;
|
||||
} __attribute__((packed)) profile;
|
||||
};
|
||||
@@ -1593,6 +1889,30 @@ 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)
|
||||
{
|
||||
uint16_t rate = 0;
|
||||
uint8_t brightness = 0;
|
||||
|
||||
switch (internal_led.mode) {
|
||||
case HIDPP20_LED_CYCLE:
|
||||
rate = internal_led.effect.cycle.rate;
|
||||
brightness = internal_led.effect.cycle.brightness;
|
||||
break;
|
||||
case HIDPP20_LED_BREATHING:
|
||||
rate = internal_led.effect.breath.rate;
|
||||
brightness = internal_led.effect.breath.brightness;
|
||||
break;
|
||||
}
|
||||
|
||||
led->mode = (enum hidpp20_led_mode)internal_led.mode;
|
||||
led->color = internal_led.color;
|
||||
led->rate = rate;
|
||||
led->brightness = brightness;
|
||||
}
|
||||
|
||||
int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
|
||||
unsigned int index,
|
||||
struct hidpp20_profiles *profiles_list)
|
||||
@@ -1606,8 +1926,11 @@ int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
|
||||
if (index >= profiles_list->num_profiles)
|
||||
return -EINVAL;
|
||||
|
||||
rc = hidpp20_onboard_profiles_find_and_read_profile(device, index, data);
|
||||
if (rc < 0)
|
||||
rc = hidpp20_onboard_profiles_find_and_read_profile(device,
|
||||
index,
|
||||
data,
|
||||
profiles_list->num_rom_profiles);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
profile->report_rate = 1000 / max(1, pdata.profile.report_rate);
|
||||
@@ -1618,6 +1941,9 @@ int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
|
||||
profile->dpi[i] = hidpp_get_unaligned_le_u16(&data[2 * i + 3]);
|
||||
}
|
||||
|
||||
for (i = 0; i < profiles_list->num_leds; i++)
|
||||
hidpp20_onboard_profile_read_led(&profile->leds[i], pdata.profile.leds[i]);
|
||||
|
||||
hidpp20_buttons_to_cpu(device, profile, pdata.profile.buttons, profiles_list->num_buttons);
|
||||
|
||||
memcpy(profile->name, pdata.profile.name.txt, sizeof(profile->name));
|
||||
@@ -1635,6 +1961,33 @@ int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
hidpp20_onboard_write_profile_led(struct hidpp20_internal_led *internal_led,
|
||||
struct hidpp20_led *led)
|
||||
{
|
||||
uint16_t rate = led->rate;
|
||||
uint8_t brightness = led->brightness;
|
||||
|
||||
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;
|
||||
break;
|
||||
case HIDPP20_LED_BREATHING:
|
||||
internal_led->effect.breath.rate = rate;
|
||||
internal_led->effect.breath.brightness = brightness;
|
||||
break;
|
||||
case HIDPP20_LED_ON:
|
||||
case HIDPP20_LED_OFF:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int hidpp20_onboard_profiles_write(struct hidpp20_device *device,
|
||||
unsigned int index,
|
||||
struct hidpp20_profiles *profiles_list)
|
||||
@@ -1648,7 +2001,10 @@ int hidpp20_onboard_profiles_write(struct hidpp20_device *device,
|
||||
if (index >= profiles_list->num_profiles)
|
||||
return -EINVAL;
|
||||
|
||||
rc = hidpp20_onboard_profiles_find_and_read_profile(device, index, data);
|
||||
rc = hidpp20_onboard_profiles_find_and_read_profile(device,
|
||||
index,
|
||||
data,
|
||||
profiles_list->num_rom_profiles);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
@@ -1664,6 +2020,9 @@ int hidpp20_onboard_profiles_write(struct hidpp20_device *device,
|
||||
pdata.profile.dpi[i] = hidpp_cpu_to_le_u16(profile->dpi[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < profiles_list->num_leds; i++)
|
||||
hidpp20_onboard_write_profile_led(&pdata.profile.leds[i], &profile->leds[i]);
|
||||
|
||||
hidpp20_buttons_from_cpu(profile, pdata.profile.buttons, profiles_list->num_buttons);
|
||||
|
||||
memcpy(pdata.profile.name.txt, profile->name, sizeof(profile->name));
|
||||
@@ -1691,8 +2050,9 @@ static const enum ratbag_button_action_special hidpp20_profiles_specials[] = {
|
||||
[0x09] = RATBAG_BUTTON_ACTION_SPECIAL_INVALID,
|
||||
[0x0a] = RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_CYCLE_UP,
|
||||
[0x0b] = RATBAG_BUTTON_ACTION_SPECIAL_SECOND_MODE,
|
||||
[0x0c] = RATBAG_BUTTON_ACTION_SPECIAL_BATTERY_LEVEL,
|
||||
|
||||
[0x0c ... 0xff] = RATBAG_BUTTON_ACTION_SPECIAL_INVALID,
|
||||
[0x0d ... 0xff] = RATBAG_BUTTON_ACTION_SPECIAL_INVALID,
|
||||
};
|
||||
|
||||
enum ratbag_button_action_special
|
||||
@@ -1738,6 +2098,9 @@ hidpp20_device_new(const struct hidpp_device *base, unsigned int idx)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (dev->proto_major < 2)
|
||||
goto err;
|
||||
|
||||
rc = hidpp20_feature_set_get(dev);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
|
||||
118
src/hidpp20.h
@@ -117,6 +117,13 @@ 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.
|
||||
*
|
||||
@@ -258,6 +265,41 @@ int hidpp20_adjustable_dpi_set_sensor_dpi(struct hidpp20_device *device,
|
||||
|
||||
#define HIDPP_PAGE_COLOR_LED_EFFECTS 0x8070
|
||||
|
||||
|
||||
struct hidpp20_color_led_info;
|
||||
|
||||
struct hidpp20_color_led_zone_info;
|
||||
|
||||
int
|
||||
hidpp20_color_led_effects_get_zone_info(struct hidpp20_device *device,
|
||||
uint8_t reg, struct hidpp20_color_led_zone_info *info);
|
||||
|
||||
int
|
||||
hidpp20_color_led_effects_get_zone_infos(struct hidpp20_device *device,
|
||||
struct hidpp20_color_led_zone_info **infos_list);
|
||||
|
||||
enum hidpp20_color_led_location {
|
||||
HIDPP20_COLOR_LED_LOCATION_UNDEFINED = 0,
|
||||
HIDPP20_COLOR_LED_LOCATION_PRIMARY,
|
||||
HIDPP20_COLOR_LED_LOCATION_LOGO,
|
||||
HIDPP20_COLOR_LED_LOCATION_LEFT,
|
||||
HIDPP20_COLOR_LED_LOCATION_RIGHT,
|
||||
HIDPP20_COLOR_LED_LOCATION_COMBINED,
|
||||
HIDPP20_COLOR_LED_LOCATION_PRIMARY_1,
|
||||
HIDPP20_COLOR_LED_LOCATION_PRIMARY_2,
|
||||
HIDPP20_COLOR_LED_LOCATION_PRIMARY_3,
|
||||
HIDPP20_COLOR_LED_LOCATION_PRIMARY_4,
|
||||
HIDPP20_COLOR_LED_LOCATION_PRIMARY_5,
|
||||
HIDPP20_COLOR_LED_LOCATION_PRIMARY_6,
|
||||
};
|
||||
|
||||
enum hidpp20_color_led_persistency {
|
||||
HIDPP20_COLOR_LED_PERSISTENCY_UNSUPPORTED,
|
||||
HIDPP20_COLOR_LED_PERSISTENCY_ON,
|
||||
HIDPP20_COLOR_LED_PERSISTENCY_OFF,
|
||||
HIDPP20_COLOR_LED_PERSISTENCY_ON_OFF,
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0x8100 - Onboard Profiles */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@@ -275,6 +317,9 @@ int hidpp20_adjustable_dpi_set_sensor_dpi(struct hidpp20_device *device,
|
||||
#define HIDPP20_MODIFIER_KEY_CTRL 0x01
|
||||
#define HIDPP20_MODIFIER_KEY_SHIFT 0x02
|
||||
|
||||
#define HIDPP20_DPI_COUNT 5
|
||||
#define HIDPP20_LED_COUNT 2
|
||||
|
||||
union hidpp20_button_binding {
|
||||
struct {
|
||||
uint8_t type;
|
||||
@@ -315,6 +360,68 @@ union hidpp20_button_binding {
|
||||
} __attribute__((packed));
|
||||
_Static_assert(sizeof(union hidpp20_button_binding) == 4, "Invalid size");
|
||||
|
||||
struct hidpp20_color_led_info {
|
||||
uint8_t zone_count;
|
||||
/* we don't care about NV capabilities for libratbag, they just
|
||||
* indicate sale demo effects */
|
||||
uint16_t nv_caps;
|
||||
uint16_t ext_caps;
|
||||
} __attribute__((packed));
|
||||
_Static_assert(sizeof(struct hidpp20_color_led_info) == 5, "Invalid size");
|
||||
|
||||
struct hidpp20_color_led_zone_info {
|
||||
uint8_t index;
|
||||
uint16_t location;
|
||||
uint8_t num_effects;
|
||||
uint8_t persistency_caps;
|
||||
} __attribute__((packed));
|
||||
_Static_assert(sizeof(struct hidpp20_color_led_zone_info) == 5, "Invalid size");
|
||||
|
||||
struct hidpp20_color {
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
} __attribute__((packed));
|
||||
_Static_assert(sizeof(struct hidpp20_color) == 3, "Invalid size");
|
||||
|
||||
enum hidpp20_led_type {
|
||||
HIDPP20_LED_UNKNOWN = -1,
|
||||
HIDPP20_LED_LOGO = 0,
|
||||
HIDPP20_LED_SIDE,
|
||||
};
|
||||
|
||||
struct hidpp20_internal_led {
|
||||
uint8_t mode; /* 00 - off; 01 - on; 03 - cycle; 0a - breath */
|
||||
struct hidpp20_color color;
|
||||
union {
|
||||
struct hidpp20_led_cycle {
|
||||
uint16_t pad_1;
|
||||
uint16_t rate; /* 16000 - 20000Hz */
|
||||
uint8_t brightness; /* 0 - 100 percent */
|
||||
uint16_t pad_2;
|
||||
} __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;
|
||||
} __attribute__((packed)) breath;
|
||||
} __attribute__((packed)) effect;
|
||||
};
|
||||
_Static_assert(sizeof(struct hidpp20_led_cycle) == 7, "Invalid size");
|
||||
_Static_assert(sizeof(struct hidpp20_led_breath) == 7, "Invalid size");
|
||||
_Static_assert(sizeof(struct hidpp20_internal_led) == 11, "Invalid size");
|
||||
|
||||
typedef uint8_t percent_t;
|
||||
|
||||
struct hidpp20_led {
|
||||
enum hidpp20_led_mode mode;
|
||||
struct hidpp20_color color;
|
||||
uint16_t rate;
|
||||
percent_t brightness;
|
||||
};
|
||||
|
||||
#define HIDPP20_MACRO_NOOP 0x01
|
||||
#define HIDPP20_MACRO_DELAY 0x40
|
||||
#define HIDPP20_MACRO_KEY_PRESS 0x43
|
||||
@@ -353,16 +460,23 @@ struct hidpp20_profile {
|
||||
unsigned report_rate;
|
||||
unsigned default_dpi;
|
||||
unsigned switched_dpi;
|
||||
uint16_t dpi[5];
|
||||
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_profiles {
|
||||
uint8_t num_profiles;
|
||||
uint8_t num_rom_profiles;
|
||||
uint8_t num_buttons;
|
||||
uint8_t num_modes;
|
||||
struct hidpp20_profile profiles[5];
|
||||
uint8_t num_leds;
|
||||
uint8_t has_g_shift;
|
||||
uint8_t has_dpi_shift;
|
||||
uint8_t corded;
|
||||
uint8_t wireless;
|
||||
struct hidpp20_profile profiles[0];
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
31
src/liblur.c
@@ -24,18 +24,19 @@
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/hidraw.h>
|
||||
|
||||
#include "usb-ids.h"
|
||||
#include "hidpp10.h"
|
||||
#include "libratbag-util.h"
|
||||
#include "liblur.h"
|
||||
|
||||
#define _EXPORT_ __attribute__ ((visibility("default")))
|
||||
#define MAX_DEVICES 6
|
||||
#define VENDOR_ID_LOGITECH 0x046d
|
||||
|
||||
struct lur_receiver {
|
||||
int refcount;
|
||||
@@ -50,6 +51,7 @@ struct lur_receiver {
|
||||
struct lur_device {
|
||||
struct lur_receiver *receiver;
|
||||
int refcount;
|
||||
void *userdata;
|
||||
|
||||
char *name;
|
||||
uint16_t vid, pid;
|
||||
@@ -111,7 +113,7 @@ lur_device_disconnect(struct lur_device *dev)
|
||||
_EXPORT_ int
|
||||
lur_is_receiver(uint16_t vid, uint16_t pid)
|
||||
{
|
||||
return (vid == VENDOR_ID_LOGITECH && (pid == 0xc52b || pid == 0xc532));
|
||||
return (vid == USB_VENDOR_ID_LOGITECH && (pid == 0xc52b || pid == 0xc532));
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -140,13 +142,13 @@ hidpp10_init(int fd)
|
||||
HIDPP10_PROFILE_UNKNOWN);
|
||||
}
|
||||
|
||||
_EXPORT_ struct lur_receiver*
|
||||
lur_receiver_new_from_hidraw(int fd, void *userdata)
|
||||
_EXPORT_ int
|
||||
lur_receiver_new_from_hidraw(int fd, void *userdata, struct lur_receiver **out)
|
||||
{
|
||||
struct lur_receiver *receiver;
|
||||
|
||||
if (!hidraw_is_receiver(fd))
|
||||
return NULL;
|
||||
return -EINVAL;
|
||||
|
||||
receiver = zalloc(sizeof(*receiver));
|
||||
receiver->refcount = 1;
|
||||
@@ -158,11 +160,12 @@ lur_receiver_new_from_hidraw(int fd, void *userdata)
|
||||
if (!receiver->hidppdev)
|
||||
goto error;
|
||||
|
||||
return receiver;
|
||||
*out = receiver;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free(receiver);
|
||||
return NULL;
|
||||
return -errno;
|
||||
|
||||
}
|
||||
|
||||
@@ -229,7 +232,7 @@ lur_receiver_enumerate(struct lur_receiver *lur,
|
||||
lur_receiver_ref(lur);
|
||||
dev->refcount = 1;
|
||||
dev->name = strdup_safe(name);
|
||||
dev->vid = VENDOR_ID_LOGITECH;
|
||||
dev->vid = USB_VENDOR_ID_LOGITECH;
|
||||
dev->pid = wpid;
|
||||
dev->type = type;
|
||||
dev->serial = serial;
|
||||
@@ -347,3 +350,15 @@ lur_device_unref(struct lur_device *dev)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_EXPORT_ void
|
||||
lur_device_set_user_data(struct lur_device *dev, void *userdata)
|
||||
{
|
||||
dev->userdata = userdata;
|
||||
}
|
||||
|
||||
_EXPORT_ void*
|
||||
lur_device_get_user_data(const struct lur_device *dev)
|
||||
{
|
||||
return dev->userdata;
|
||||
}
|
||||
|
||||
36
src/liblur.h
@@ -85,8 +85,8 @@ int
|
||||
lur_device_disconnect(struct lur_device *dev);
|
||||
|
||||
/**
|
||||
* Returns non-zero if a device with the given vid/pid is a logitech
|
||||
* unifying receiver device.
|
||||
* Returns non-zero if a device with the given vid/pid is a Logitech
|
||||
* Unifying Receiver device.
|
||||
*
|
||||
* @param vid The vendor ID
|
||||
* @param pid The product ID
|
||||
@@ -107,11 +107,16 @@ lur_is_receiver(uint16_t vid, uint16_t pid);
|
||||
*
|
||||
* @param fd An O_RDWR file descriptor pointing to a /dev/hidraw node
|
||||
* @param userdata Caller-specific data
|
||||
* @param lur Set to the lur object on success, otherwise unmodified
|
||||
*
|
||||
* @return A lur object, or NULL on error.
|
||||
* @return 0 on success or a negative errno on error
|
||||
* @retval -EINVAL The fd does not point to a lur receiver
|
||||
*
|
||||
* @note liblur does not have OOM handling. If an allocation fails, liblur
|
||||
* will simply abort()
|
||||
*/
|
||||
struct lur_receiver*
|
||||
lur_receiver_new_from_hidraw(int fd, void *userdata);
|
||||
int
|
||||
lur_receiver_new_from_hidraw(int fd, void *userdata, struct lur_receiver **lur);
|
||||
|
||||
/**
|
||||
* Enumerate devices currently paired with the given receiver.
|
||||
@@ -239,6 +244,27 @@ lur_device_ref(struct lur_device *dev);
|
||||
struct lur_device *
|
||||
lur_device_unref(struct lur_device *dev);
|
||||
|
||||
/**
|
||||
* Set caller-specific data associated with this object. liblur does
|
||||
* not manage, look at, or modify this data. The caller must ensure the
|
||||
* data is valid.
|
||||
*
|
||||
* @param dev A valid device object
|
||||
* @param userdata Caller-specific data
|
||||
*/
|
||||
void
|
||||
lur_device_set_user_data(struct lur_device *dev, void *userdata);
|
||||
|
||||
/**
|
||||
* Get the caller-specific data associated with this object, if any.
|
||||
*
|
||||
* @param dev A valid device object
|
||||
* @return The caller-specific data previously assigned in
|
||||
* lur_device_set_user_data().
|
||||
*/
|
||||
void*
|
||||
lur_device_get_user_data(const struct lur_device *dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
13
src/liblur.pc.in
Normal file
@@ -0,0 +1,13 @@
|
||||
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
|
||||
28
src/liblur.sym
Normal file
@@ -0,0 +1,28 @@
|
||||
/* in alphabetical order! */
|
||||
|
||||
LIBLUR_0.4.0 {
|
||||
global:
|
||||
lur_device_disconnect;
|
||||
lur_device_get_name;
|
||||
lur_device_get_product_id;
|
||||
lur_device_get_serial;
|
||||
lur_device_get_type;
|
||||
lur_device_get_user_data;
|
||||
lur_device_get_vendor_id;
|
||||
lur_device_ref;
|
||||
lur_device_set_user_data;
|
||||
lur_device_unref;
|
||||
lur_is_receiver;
|
||||
lur_receiver_close;
|
||||
lur_receiver_enumerate;
|
||||
lur_receiver_get_fd;
|
||||
lur_receiver_get_user_data;
|
||||
lur_receiver_new_from_hidraw;
|
||||
lur_receiver_open;
|
||||
lur_receiver_ref;
|
||||
lur_receiver_set_user_data;
|
||||
lur_receiver_unref;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
@@ -1417,14 +1417,12 @@ ratbag_find_hidraw_node(struct ratbag_device *device,
|
||||
goto skip;
|
||||
|
||||
matched = match(device);
|
||||
if (matched == 1) {
|
||||
rc = 0;
|
||||
rc = matched ? 0 : -ENODEV;
|
||||
if (matched == 1)
|
||||
goto out;
|
||||
}
|
||||
|
||||
skip:
|
||||
ratbag_close_hidraw(device);
|
||||
rc = -ENODEV;
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
@@ -95,6 +95,7 @@ struct ratbag_device {
|
||||
struct list profiles;
|
||||
|
||||
unsigned num_buttons;
|
||||
unsigned num_leds;
|
||||
|
||||
void *drv_data;
|
||||
|
||||
@@ -130,6 +131,18 @@ struct ratbag_driver {
|
||||
*/
|
||||
void (*remove)(struct ratbag_device *device);
|
||||
|
||||
/**
|
||||
* Callback called when the driver should write any profiles that
|
||||
* were modified back to the device.
|
||||
*
|
||||
* Both profile and button structs have a dirty variable that can
|
||||
* be used to tell whether or not they've actually changed since
|
||||
* the last commit. In order to reduce the amount of time
|
||||
* committing takes, drivers should use this information to avoid
|
||||
* writing back profiles and buttons that haven't actually changed.
|
||||
*/
|
||||
int (*commit)(struct ratbag_device *device);
|
||||
|
||||
/**
|
||||
* Callback called when a read profile is requested by the
|
||||
* caller of the library.
|
||||
@@ -141,9 +154,10 @@ struct ratbag_driver {
|
||||
*/
|
||||
void (*read_profile)(struct ratbag_profile *profile, unsigned int index);
|
||||
|
||||
/**
|
||||
* Here, the driver should actually write the profile to the
|
||||
* device.
|
||||
/*
|
||||
* FIXME: This function is deprecated and should not be removed. Once
|
||||
* we've updated all the device drivers to stop using it we'll remove
|
||||
* it. Look at commit() instead.
|
||||
*/
|
||||
int (*write_profile)(struct ratbag_profile *profile);
|
||||
|
||||
@@ -168,29 +182,44 @@ struct ratbag_driver {
|
||||
*/
|
||||
void (*read_button)(struct ratbag_button *button);
|
||||
|
||||
/**
|
||||
* For the given button, store in the profile and in the device
|
||||
* the given struct ratbag_button.
|
||||
/*
|
||||
* FIXME: This function is deprecated and should not be removed. Once
|
||||
* we've updated all the device drivers to stop using it we'll remove
|
||||
* it. Look at commit() instead.
|
||||
*/
|
||||
int (*write_button)(struct ratbag_button *button,
|
||||
const struct ratbag_button_action *action);
|
||||
|
||||
/**
|
||||
* For the given profile, overwrite the current resolution
|
||||
* of the sensor expressed in DPI, and commit it to the hardware.
|
||||
*
|
||||
* Mandatory if the driver exports RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION.
|
||||
/*
|
||||
* FIXME: This function is deprecated and should not be removed. Once
|
||||
* we've updated all the device drivers to stop using it we'll remove
|
||||
* it. Look at commit() instead.
|
||||
*/
|
||||
int (*write_resolution_dpi)(struct ratbag_resolution *resolution,
|
||||
int dpi_x, int dpi_y);
|
||||
|
||||
/**
|
||||
* For the given led, fill in the struct ratbag_led
|
||||
* with the available information.
|
||||
*/
|
||||
void (*read_led)(struct ratbag_led *led);
|
||||
|
||||
/*
|
||||
* FIXME: This function is deprecated and should be removed. Once
|
||||
* we've updated all the device drivers to stop using it we'll remove
|
||||
* it. Look at commit() instead.
|
||||
*/
|
||||
int (*write_led)(struct ratbag_led *led, enum ratbag_led_mode mode,
|
||||
struct ratbag_color color, unsigned int hz,
|
||||
unsigned int brightness);
|
||||
|
||||
/* private */
|
||||
int (*test_probe)(struct ratbag_device *device, void *data);
|
||||
|
||||
struct list link;
|
||||
};
|
||||
|
||||
struct ratbag_resolution{
|
||||
struct ratbag_resolution {
|
||||
struct ratbag_profile *profile;
|
||||
int refcount;
|
||||
void *userdata;
|
||||
@@ -202,6 +231,20 @@ struct ratbag_resolution{
|
||||
uint32_t capabilities;
|
||||
};
|
||||
|
||||
struct ratbag_led {
|
||||
int refcount;
|
||||
void *userdata;
|
||||
struct list link;
|
||||
struct ratbag_profile *profile;
|
||||
unsigned index;
|
||||
enum ratbag_led_type type;
|
||||
enum ratbag_led_mode mode;
|
||||
struct ratbag_color color;
|
||||
unsigned int hz; /**< rate of action in hz */
|
||||
unsigned int brightness; /**< brightness of the LED */
|
||||
bool dirty;
|
||||
};
|
||||
|
||||
struct ratbag_profile {
|
||||
int refcount;
|
||||
void *userdata;
|
||||
@@ -216,8 +259,11 @@ struct ratbag_profile {
|
||||
struct ratbag_resolution *modes;
|
||||
unsigned int num_modes;
|
||||
} resolution;
|
||||
struct list leds;
|
||||
|
||||
bool is_active; /**< profile is the currently active one */
|
||||
bool is_enabled;
|
||||
bool dirty; /**< profile changed since last commit */
|
||||
};
|
||||
|
||||
#define BUTTON_ACTION_NONE \
|
||||
@@ -250,6 +296,11 @@ struct ratbag_macro {
|
||||
struct ratbag_macro_event events[MAX_MACRO_EVENTS];
|
||||
};
|
||||
|
||||
struct ratbag_button_macro {
|
||||
int refcount;
|
||||
struct ratbag_macro macro;
|
||||
};
|
||||
|
||||
struct ratbag_button_action {
|
||||
enum ratbag_button_action_type type;
|
||||
union ratbag_btn_action {
|
||||
@@ -272,6 +323,7 @@ struct ratbag_button {
|
||||
enum ratbag_button_type type;
|
||||
struct ratbag_button_action action;
|
||||
uint32_t action_caps;
|
||||
bool dirty; /* changed since last commit to device */
|
||||
};
|
||||
|
||||
static inline void
|
||||
@@ -313,7 +365,8 @@ int
|
||||
ratbag_device_init_profiles(struct ratbag_device *device,
|
||||
unsigned int num_profiles,
|
||||
unsigned int num_resolutions,
|
||||
unsigned int num_buttons);
|
||||
unsigned int num_buttons,
|
||||
unsigned int num_leds);
|
||||
|
||||
void
|
||||
ratbag_device_set_capability(struct ratbag_device *device,
|
||||
@@ -412,7 +465,9 @@ log_buffer(struct ratbag *ratbag,
|
||||
struct ratbag_driver etekcity_driver;
|
||||
struct ratbag_driver hidpp20_driver;
|
||||
struct ratbag_driver hidpp10_driver;
|
||||
struct ratbag_driver logitech_g300_driver;
|
||||
struct ratbag_driver roccat_driver;
|
||||
struct ratbag_driver gskill_driver;
|
||||
|
||||
struct ratbag_device*
|
||||
ratbag_device_new(struct ratbag *ratbag, struct udev_device *udev_device,
|
||||
@@ -424,13 +479,17 @@ const char *
|
||||
ratbag_device_get_udev_property(const struct ratbag_device* device,
|
||||
const char *name);
|
||||
|
||||
struct ratbag_driver *
|
||||
ratbag_find_driver(struct ratbag_device *device,
|
||||
const struct input_id *dev_id,
|
||||
struct ratbag_test_device *test_device);
|
||||
bool
|
||||
ratbag_assign_driver(struct ratbag_device *device,
|
||||
const struct input_id *dev_id,
|
||||
struct ratbag_test_device *test_device);
|
||||
|
||||
void
|
||||
ratbag_register_driver(struct ratbag *ratbag, struct ratbag_driver *driver);
|
||||
|
||||
void
|
||||
ratbag_button_copy_macro(struct ratbag_button *button,
|
||||
const struct ratbag_button_macro *macro);
|
||||
|
||||
#endif /* LIBRATBAG_PRIVATE_H */
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ ratbag_device_new_test_device(struct ratbag *ratbag,
|
||||
|
||||
device = ratbag_device_new(ratbag, NULL, "Test device", &id);
|
||||
|
||||
if (!ratbag_find_driver(device, &device->ids, test_device)) {
|
||||
if (!ratbag_assign_driver(device, &device->ids, test_device)) {
|
||||
ratbag_device_destroy(device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -30,8 +30,15 @@
|
||||
#define RATBAG_TEST_MAX_PROFILES 12
|
||||
#define RATBAG_TEST_MAX_BUTTONS 25
|
||||
#define RATBAG_TEST_MAX_RESOLUTIONS 8
|
||||
#define RATBAG_TEST_MAX_LEDS 8
|
||||
|
||||
struct ratbag_test_button {
|
||||
enum ratbag_button_action_type type;
|
||||
union {
|
||||
int button;
|
||||
int key;
|
||||
enum ratbag_button_action_special special;
|
||||
};
|
||||
};
|
||||
|
||||
struct ratbag_test_resolution {
|
||||
@@ -42,9 +49,24 @@ struct ratbag_test_resolution {
|
||||
uint32_t caps;
|
||||
};
|
||||
|
||||
struct ratbag_test_color {
|
||||
unsigned short red;
|
||||
unsigned short green;
|
||||
unsigned short blue;
|
||||
};
|
||||
|
||||
struct ratbag_test_led {
|
||||
enum ratbag_led_type type;
|
||||
enum ratbag_led_mode mode;
|
||||
struct ratbag_test_color color;
|
||||
unsigned int hz;
|
||||
unsigned int brightness;
|
||||
};
|
||||
|
||||
struct ratbag_test_profile {
|
||||
struct ratbag_test_button buttons[RATBAG_TEST_MAX_BUTTONS];
|
||||
struct ratbag_test_resolution resolutions[RATBAG_TEST_MAX_RESOLUTIONS];
|
||||
struct ratbag_test_led leds[RATBAG_TEST_MAX_LEDS];
|
||||
bool active;
|
||||
bool dflt;
|
||||
};
|
||||
@@ -53,6 +75,7 @@ struct ratbag_test_device {
|
||||
unsigned int num_profiles;
|
||||
unsigned int num_resolutions;
|
||||
unsigned int num_buttons;
|
||||
unsigned int num_leds;
|
||||
struct ratbag_test_profile profiles[RATBAG_TEST_MAX_PROFILES];
|
||||
void (*destroyed)(struct ratbag_device *device, void *data);
|
||||
void *destroyed_data;
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <iconv.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "libratbag-util.h"
|
||||
#include "libratbag-private.h"
|
||||
@@ -85,3 +87,95 @@ udev_prop_value(struct udev_device *device,
|
||||
|
||||
return prop_value;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ratbag_utf8_to_enc(char *buf, size_t buf_len, const char *to_enc,
|
||||
const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
iconv_t converter;
|
||||
char str[buf_len];
|
||||
char *in_buf = str, *out_buf = (char*)buf;
|
||||
size_t in_bytes_left, out_bytes_left = buf_len;
|
||||
int ret;
|
||||
|
||||
memset(buf, 0, buf_len);
|
||||
|
||||
va_start(args, format);
|
||||
ret = vsnprintf(str, buf_len, format, args);
|
||||
va_end(args);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
in_bytes_left = ret;
|
||||
|
||||
converter = iconv_open(to_enc, "UTF-8");
|
||||
if (converter == (iconv_t)-1)
|
||||
return -errno;
|
||||
|
||||
ret = iconv(converter, &in_buf, &in_bytes_left, &out_buf,
|
||||
&out_bytes_left);
|
||||
if (ret)
|
||||
ret = -errno;
|
||||
else
|
||||
ret = buf_len - out_bytes_left;
|
||||
|
||||
iconv_close(converter);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ratbag_utf8_from_enc(char *in_buf, size_t in_len, const char *from_enc,
|
||||
char **out)
|
||||
{
|
||||
iconv_t converter;
|
||||
size_t len = in_len * 6,
|
||||
in_bytes_left = in_len,
|
||||
out_bytes_left = len;
|
||||
char *pos;
|
||||
ssize_t ret;
|
||||
|
||||
converter = iconv_open("UTF-8", from_enc);
|
||||
if (converter == (iconv_t)-1)
|
||||
return -errno;
|
||||
|
||||
/*
|
||||
* 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
|
||||
* needs to be for a mouse with blinking lights.
|
||||
*
|
||||
* So, since there's no encoding that takes more then 6 bytes per
|
||||
* character, allocate for that and just fail if that's not enough.
|
||||
*/
|
||||
*out = zalloc(len);
|
||||
pos = *out;
|
||||
if (!*out) {
|
||||
ret = -errno;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = iconv(converter, &in_buf, &in_bytes_left, &pos, &out_bytes_left);
|
||||
if (ret) {
|
||||
ret = -errno;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Now get rid of any space in the buffer we don't need */
|
||||
*out = realloc(*out, (len - out_bytes_left) + 1);
|
||||
if (!*out)
|
||||
ret = -errno;
|
||||
else
|
||||
ret = (len - out_bytes_left) + 1;
|
||||
|
||||
err:
|
||||
if (ret < 0 && *out) {
|
||||
free(*out);
|
||||
*out = NULL;
|
||||
}
|
||||
|
||||
iconv_close(converter);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -200,4 +200,21 @@ long_set_bit_state(unsigned long *array, int bit, int state)
|
||||
const char *
|
||||
udev_prop_value(struct udev_device *device,
|
||||
const char *property_name);
|
||||
|
||||
/**
|
||||
* Converts a string from UTF-8 to the encoding specified. Returns the number
|
||||
* of bytes written to buf on success, or negative errno value on failure.
|
||||
*/
|
||||
ssize_t
|
||||
ratbag_utf8_to_enc(char *buf, size_t buf_len, const char *to_enc,
|
||||
const char *format, ...) __attribute__((format(printf, 4, 5)));
|
||||
/**
|
||||
* Converts a string from the given encoding into UTF-8. The memory for the
|
||||
* result is allocated and a pointer to the result is placed in *out. Returns
|
||||
* the number of bytes in the UTF-8 version of the string on success, negative
|
||||
* errno value on failure.
|
||||
*/
|
||||
ssize_t
|
||||
ratbag_utf8_from_enc(char *in_buf, size_t in_len, const char *from_enc,
|
||||
char **out);
|
||||
#endif /* LIBRATBAG_UTIL_H */
|
||||
|
||||
836
src/libratbag.c
601
src/libratbag.h
@@ -30,6 +30,7 @@ extern "C" {
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <libudev.h>
|
||||
|
||||
#define LIBRATBAG_ATTRIBUTE_PRINTF(_format, _args) \
|
||||
@@ -54,6 +55,8 @@ extern "C" {
|
||||
*
|
||||
* @defgroup button Button configuration
|
||||
*
|
||||
* @defgroup led LED configuration
|
||||
*
|
||||
* @defgroup resolution Resolution and frequency mappings
|
||||
*
|
||||
* A device's sensor resolution and report rate can be configured per
|
||||
@@ -125,6 +128,81 @@ struct ratbag_button;
|
||||
*/
|
||||
struct ratbag_resolution;
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
* @struct ratbag_color
|
||||
*
|
||||
* Represents LED color in RGB format.
|
||||
* each color component is integer 0 - 255
|
||||
*/
|
||||
|
||||
struct ratbag_color {
|
||||
unsigned int red;
|
||||
unsigned int green;
|
||||
unsigned int blue;
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
* @struct ratbag_led
|
||||
*
|
||||
* Represents a led on the device.
|
||||
*/
|
||||
struct ratbag_led;
|
||||
|
||||
/**
|
||||
* @ingroup button
|
||||
* @struct ratbag_macro
|
||||
*
|
||||
* Represents a macro that can be assigned to a button.
|
||||
*
|
||||
* This struct is refcounted, use ratbag_button_macro_ref() and
|
||||
* ratbag_button_macro_unref().
|
||||
*/
|
||||
struct ratbag_button_macro;
|
||||
|
||||
/**
|
||||
* @ingroup base
|
||||
*
|
||||
* Error codes used by libratbag.
|
||||
*/
|
||||
enum ratbag_error_code {
|
||||
RATBAG_SUCCESS = 0,
|
||||
|
||||
/**
|
||||
* An error occured on the device. Either the device is not a
|
||||
* libratbag device or communication with the device failed.
|
||||
*/
|
||||
RATBAG_ERROR_DEVICE = -1000,
|
||||
|
||||
/**
|
||||
* Insufficient capabilities. This error occurs when a requested change is
|
||||
* beyond the device's capabilities.
|
||||
*/
|
||||
RATBAG_ERROR_CAPABILITY = -1001,
|
||||
|
||||
/**
|
||||
* Invalid value or value range. The provided value or value range
|
||||
* is outside of the legal or supported range.
|
||||
*/
|
||||
RATBAG_ERROR_VALUE = -1002,
|
||||
|
||||
/**
|
||||
* A low-level system error has occured, e.g. a failure to access
|
||||
* files that should be there. This error is usually unrecoverable
|
||||
* and libratbag will print a log message with details about the
|
||||
* error.
|
||||
*/
|
||||
RATBAG_ERROR_SYSTEM = -1003,
|
||||
|
||||
/**
|
||||
* Implementation bug, either in libratbag or in the caller. This
|
||||
* error is usually unrecoverable and libratbag will print a log
|
||||
* message with details about the
|
||||
* error.
|
||||
*/
|
||||
RATBAG_ERROR_IMPLEMENTATION = -1004,
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup base
|
||||
@@ -325,12 +403,18 @@ ratbag_unref(struct ratbag *ratbag);
|
||||
* The device is refcounted with an initial value of at least 1.
|
||||
* Use ratbag_device_unref() to release the device.
|
||||
*
|
||||
* @return A new device based on the udev device, or NULL in case of
|
||||
* failure.
|
||||
* @param ratbag A previously initialized ratbag context
|
||||
* @param udev_device The udev device that points at the device
|
||||
* @param device Set to a new device based on the udev device.
|
||||
*
|
||||
* @return 0 on success or the error.
|
||||
* @retval RATBAG_ERROR_DEVICE The given device does not exist or is not
|
||||
* supported by libratbag.
|
||||
*/
|
||||
struct ratbag_device*
|
||||
enum ratbag_error_code
|
||||
ratbag_device_new_from_udev_device(struct ratbag *ratbag,
|
||||
struct udev_device *device);
|
||||
struct udev_device *udev_device,
|
||||
struct ratbag_device **device);
|
||||
|
||||
/**
|
||||
* @ingroup device
|
||||
@@ -431,6 +515,11 @@ enum ratbag_device_capability {
|
||||
*/
|
||||
RATBAG_DEVICE_CAP_BUTTON_KEY,
|
||||
|
||||
/**
|
||||
* The device supports assigning LED colors and effects
|
||||
*/
|
||||
RATBAG_DEVICE_CAP_LED,
|
||||
|
||||
/**
|
||||
* The device supports user-defined key or button sequences.
|
||||
*/
|
||||
@@ -443,6 +532,32 @@ enum ratbag_device_capability {
|
||||
* last-used profile or a specific profile (usually the first).
|
||||
*/
|
||||
RATBAG_DEVICE_CAP_DEFAULT_PROFILE,
|
||||
|
||||
/**
|
||||
* The device has the capability to query the current hardware
|
||||
* configuration. If this capability is missing, libratbag cannot
|
||||
* query the device for its current configuration and the
|
||||
* configured resolutions and button mappings are unknown.
|
||||
* libratbag will still provide information about the structure of
|
||||
* the device such as the number of buttons and resolutions.
|
||||
* Clients that encounter a device without this resolution are
|
||||
* encouraged to upload a configuration stored on-disk to the
|
||||
* device to reset the device to a known state.
|
||||
*
|
||||
* Any changes uploaded to the device will be cached in libratbag,
|
||||
* once a client has sent a full configuration to the device
|
||||
* libratbag can be used to query the device as normal.
|
||||
*/
|
||||
RATBAG_DEVICE_CAP_QUERY_CONFIGURATION,
|
||||
|
||||
/**
|
||||
* The device has the capability to disable and enable profiles. While
|
||||
* profiles are not immediately deleted after being disabled, it is not
|
||||
* guaranteed that the device will remember any disabled profiles the
|
||||
* next time ratbag runs. Furthermore, the order of profiles may get
|
||||
* changed the next time ratbag runs if profiles are disabled.
|
||||
*/
|
||||
RATBAG_DEVICE_CAP_DISABLE_PROFILE,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -461,6 +576,18 @@ int
|
||||
ratbag_device_has_capability(const struct ratbag_device *device,
|
||||
enum ratbag_device_capability cap);
|
||||
|
||||
/**
|
||||
* @ingroup device
|
||||
*
|
||||
* Write any changes to the device. Depending on the device, this may take
|
||||
* a couple of seconds.
|
||||
*
|
||||
* @param device A previously initialized ratbag device
|
||||
* @return 0 on success or an error code otherwise
|
||||
*/
|
||||
enum ratbag_error_code
|
||||
ratbag_device_commit(struct ratbag_device *device);
|
||||
|
||||
/**
|
||||
* @ingroup device
|
||||
*
|
||||
@@ -490,6 +617,17 @@ ratbag_device_get_num_profiles(struct ratbag_device *device);
|
||||
unsigned int
|
||||
ratbag_device_get_num_buttons(struct ratbag_device *device);
|
||||
|
||||
/**
|
||||
* @ingroup device
|
||||
*
|
||||
* Return the number of LEDs available on this device.
|
||||
*
|
||||
* @param device A previously initialized ratbag device
|
||||
* @return The number of LEDs available on this device.
|
||||
*/
|
||||
unsigned int
|
||||
ratbag_device_get_num_leds(struct ratbag_device *device);
|
||||
|
||||
/**
|
||||
* @ingroup profile
|
||||
*
|
||||
@@ -515,6 +653,34 @@ ratbag_profile_ref(struct ratbag_profile *profile);
|
||||
struct ratbag_profile *
|
||||
ratbag_profile_unref(struct ratbag_profile *profile);
|
||||
|
||||
/**
|
||||
* @ingroup profile
|
||||
*
|
||||
* Enable/disable the ratbag profile. For this to work, the device must support
|
||||
* @ref RATBAG_DEVICE_CAP_DISABLE_PROFILE.
|
||||
*
|
||||
* @param profile A previously initialized ratbag profile
|
||||
* @param enabled Whether to enable or disable the profile
|
||||
*
|
||||
* @return 0 on success or an error code otherwise
|
||||
*/
|
||||
enum ratbag_error_code
|
||||
ratbag_profile_set_enabled(struct ratbag_profile *profile, bool enabled);
|
||||
|
||||
/**
|
||||
* @ingroup profile
|
||||
*
|
||||
* Check whether the ratbag profile is enabled or not. For devices that don't
|
||||
* support @ref RATBAG_DEVICE_CAP_DISABLE_PROFILE the profile will always be
|
||||
* set to enabled.
|
||||
*
|
||||
* @param profile A previously initialized ratbag profile
|
||||
*
|
||||
* @return Whether the profile is enabled or not.
|
||||
*/
|
||||
bool
|
||||
ratbag_profile_is_enabled(const struct ratbag_profile *profile);
|
||||
|
||||
/**
|
||||
* @ingroup profile
|
||||
*
|
||||
@@ -583,9 +749,9 @@ ratbag_profile_is_active(struct ratbag_profile *profile);
|
||||
*
|
||||
* @param profile The profile to make the active profile.
|
||||
*
|
||||
* @return 0 on success or nonzero otherwise.
|
||||
* @return 0 on success or an error code otherwise
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_profile_set_active(struct ratbag_profile *profile);
|
||||
|
||||
/**
|
||||
@@ -601,9 +767,9 @@ ratbag_profile_set_active(struct ratbag_profile *profile);
|
||||
*
|
||||
* @param profile A previously initialized ratbag profile
|
||||
*
|
||||
* @return The number of profiles available.
|
||||
* @return The number of resolutions available.
|
||||
*/
|
||||
int
|
||||
unsigned int
|
||||
ratbag_profile_get_num_resolutions(struct ratbag_profile *profile);
|
||||
|
||||
/**
|
||||
@@ -723,9 +889,9 @@ ratbag_resolution_has_capability(struct ratbag_resolution *resolution,
|
||||
* @param resolution A previously initialized ratbag resolution
|
||||
* @param dpi Set to the resolution in dpi, 0 to disable
|
||||
*
|
||||
* @return zero on success, non-zero otherwise
|
||||
* @return zero on success or an error code on failure
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_resolution_set_dpi(struct ratbag_resolution *resolution,
|
||||
unsigned int dpi);
|
||||
|
||||
@@ -749,9 +915,9 @@ ratbag_resolution_set_dpi(struct ratbag_resolution *resolution,
|
||||
* @param x The x resolution in dpi
|
||||
* @param y The y resolution in dpi
|
||||
*
|
||||
* @return zero on success, non-zero otherwise
|
||||
* @return zero on success or an error code on failure
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_resolution_set_dpi_xy(struct ratbag_resolution *resolution,
|
||||
unsigned int x, unsigned int y);
|
||||
|
||||
@@ -809,37 +975,37 @@ ratbag_resolution_get_dpi_y(struct ratbag_resolution *resolution);
|
||||
/**
|
||||
* @ingroup resolution
|
||||
*
|
||||
* Set the the report rate in Hz for the resolution mode.
|
||||
* Set the report rate in Hz for the resolution mode.
|
||||
*
|
||||
* A value of 0 hz disables the mode.
|
||||
*
|
||||
* If the resolution mode is the currently active mode and the profile is
|
||||
* the currently active profile, the change takes effect immediately.
|
||||
*
|
||||
* @param resolution A previously initialized ratbag resolution
|
||||
* @param hz Set to the report rate in Hz, may be 0
|
||||
*
|
||||
* @return zero on success, non-zero otherwise
|
||||
*/
|
||||
int
|
||||
ratbag_resolution_set_report_rate(struct ratbag_resolution *resolution,
|
||||
unsigned int hz);
|
||||
|
||||
/**
|
||||
* @ingroup resolution
|
||||
*
|
||||
* Get the the report rate in Hz for the resolution mode.
|
||||
*
|
||||
* A value of 0 hz indicates the mode is disabled.
|
||||
*
|
||||
* If the resolution does not have the @ref
|
||||
* RATBAG_RESOLUTION_CAP_INDIVIDUAL_REPORT_RATE capability, changing the
|
||||
* report rate on one resolution changes the report rate for all resolutions
|
||||
* in this profile.
|
||||
*
|
||||
* @param resolution A previously initialized ratbag resolution
|
||||
* @param hz Set to the report rate in Hz, may be 0
|
||||
*
|
||||
* @return zero on success, non-zero otherwise
|
||||
* @return zero on success or an error code on failure
|
||||
*/
|
||||
enum ratbag_error_code
|
||||
ratbag_resolution_set_report_rate(struct ratbag_resolution *resolution,
|
||||
unsigned int hz);
|
||||
|
||||
/**
|
||||
* @ingroup resolution
|
||||
*
|
||||
* Get the report rate in Hz for the resolution mode.
|
||||
*
|
||||
* A value of 0 hz indicates the mode is disabled.
|
||||
*
|
||||
* @param resolution A previously initialized ratbag resolution
|
||||
*
|
||||
* @return The report rate for this resolution in Hz
|
||||
*/
|
||||
int
|
||||
ratbag_resolution_get_report_rate(struct ratbag_resolution *resolution);
|
||||
@@ -855,9 +1021,9 @@ ratbag_resolution_get_report_rate(struct ratbag_resolution *resolution);
|
||||
*
|
||||
* @param resolution A previously initialized ratbag resolution
|
||||
*
|
||||
* @return zero on success, non-zero otherwise
|
||||
* @return zero on success or an error code on failure
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_resolution_set_active(struct ratbag_resolution *resolution);
|
||||
|
||||
/**
|
||||
@@ -889,9 +1055,9 @@ ratbag_resolution_is_active(const struct ratbag_resolution *resolution);
|
||||
*
|
||||
* @param resolution A previously initialized ratbag resolution
|
||||
*
|
||||
* @return zero on success, non-zero otherwise
|
||||
* @return zero on success or an error code on failure
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_resolution_set_default(struct ratbag_resolution *resolution);
|
||||
|
||||
/**
|
||||
@@ -927,7 +1093,7 @@ ratbag_resolution_is_default(const struct ratbag_resolution *resolution);
|
||||
*
|
||||
* @return A button context, or NULL if the button does not exist.
|
||||
*
|
||||
* @see ratbag_get_num_buttons
|
||||
* @see ratbag_device_get_num_buttons
|
||||
*/
|
||||
struct ratbag_button*
|
||||
ratbag_profile_get_button(struct ratbag_profile *profile, unsigned int index);
|
||||
@@ -1101,6 +1267,7 @@ enum ratbag_button_action_special {
|
||||
|
||||
/* DPI switch */
|
||||
RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_UP,
|
||||
RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_DOWN,
|
||||
RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_UP,
|
||||
RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_DOWN,
|
||||
RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_ALTERNATE,
|
||||
@@ -1108,6 +1275,7 @@ enum ratbag_button_action_special {
|
||||
|
||||
/* Profile */
|
||||
RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_CYCLE_UP,
|
||||
RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_CYCLE_DOWN,
|
||||
RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_UP,
|
||||
RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_DOWN,
|
||||
|
||||
@@ -1148,12 +1316,12 @@ ratbag_button_get_button(struct ratbag_button *button);
|
||||
*
|
||||
* @param button A previously initialized ratbag button
|
||||
* @param btn The logical button number to assign to this button.
|
||||
* @return 0 on success or nonzero otherwise. On success, the button's
|
||||
* @return 0 on success or an error code otherwise. On success, the button's
|
||||
* action is set to @ref RATBAG_BUTTON_ACTION_TYPE_BUTTON.
|
||||
*
|
||||
* @see ratbag_button_get_button
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_button_set_button(struct ratbag_button *button,
|
||||
unsigned int btn);
|
||||
|
||||
@@ -1173,6 +1341,172 @@ ratbag_button_set_button(struct ratbag_button *button,
|
||||
enum ratbag_button_action_special
|
||||
ratbag_button_get_special(struct ratbag_button *button);
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* RATBAG_LED_OFF - led is now off,
|
||||
* RATBAG_LED_ON - led is on with static color,
|
||||
* RATBAG_LED_CYCLE - led is cycling between all colors.
|
||||
* RATBAG_LED_BREATHING - led is pulsating with static color
|
||||
*
|
||||
* Each LED mode has different properties, e.g. the brightness and rate are only
|
||||
* available in modes @ref RATBAG_LED_CYCLE and @ref RATBAG_LED_BREATHING modes
|
||||
*/
|
||||
enum ratbag_led_mode {
|
||||
RATBAG_LED_OFF = 0,
|
||||
RATBAG_LED_ON,
|
||||
RATBAG_LED_CYCLE,
|
||||
RATBAG_LED_BREATHING,
|
||||
};
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* LED types, usually based on their physical location
|
||||
*/
|
||||
enum ratbag_led_type {
|
||||
RATBAG_LED_TYPE_UNKNOWN = -1,
|
||||
RATBAG_LED_TYPE_LOGO = 0,
|
||||
RATBAG_LED_TYPE_SIDE
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* Return a reference to the LED given by the index. The order of the
|
||||
* LEDs is device-specific though.
|
||||
*
|
||||
* The LED is refcounted with an initial value of at least 1.
|
||||
* Use ratbag_led_unref() to release the LED.
|
||||
*
|
||||
* @param profile A previously initialized ratbag profile
|
||||
* @param index The index of the LED
|
||||
*
|
||||
* @return A LED context, or NULL if the LED does not exist.
|
||||
*
|
||||
* @see ratbag_device_get_profile
|
||||
*/
|
||||
struct ratbag_led *
|
||||
ratbag_profile_get_led(struct ratbag_profile *profile, unsigned int index);
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* This function returns the type for ratbag_led.
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @return The LED type @ref ratbag_led_type
|
||||
*
|
||||
* @see ratbag_led_set_mode
|
||||
*/
|
||||
enum ratbag_led_type
|
||||
ratbag_led_get_type(struct ratbag_led *led);
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* This function returns the mode for ratbag_led.
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @return The LED mod @ref ratbag_led_mode
|
||||
*
|
||||
* @see ratbag_led_set_mode
|
||||
*/
|
||||
enum ratbag_led_mode
|
||||
ratbag_led_get_mode(struct ratbag_led *led);
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* This function returns the led color.
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @return The LED color in @ref ratbag_led_mode
|
||||
*
|
||||
* @see ratbag_led_set_color
|
||||
*/
|
||||
struct ratbag_color
|
||||
ratbag_led_get_color(struct ratbag_led *led);
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* This function returns the LED effect rate.
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @return The LED rate in Hz, can be 100 - 20000
|
||||
*
|
||||
* @see ratbag_led_set_effect_rate
|
||||
*/
|
||||
int
|
||||
ratbag_led_get_effect_rate(struct ratbag_led *led);
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* This function returns the LED brightness.
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @return The LED brightness 0 - 255
|
||||
*
|
||||
* @see ratbag_led_get_brightness
|
||||
*/
|
||||
unsigned int
|
||||
ratbag_led_get_brightness(struct ratbag_led *led);
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* this function sets the LED mode.
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @param mode LED mode @ref ratbag_led_mode.
|
||||
* @return 0 on success or an error code otherwise.
|
||||
*
|
||||
* @see ratbag_led_get_mode
|
||||
*/
|
||||
enum ratbag_error_code
|
||||
ratbag_led_set_mode(struct ratbag_led *led, enum ratbag_led_mode mode);
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* If the LED's mode is @ref RATBAG_LED_ON or @ref RATBAG_LED_BREATHING
|
||||
* then this function sets the LED color, otherwise it has no effect.
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @param color A LED color.
|
||||
* @return 0 on success or an error code otherwise.
|
||||
*
|
||||
* @see ratbag_led_get_color
|
||||
*/
|
||||
enum ratbag_error_code
|
||||
ratbag_led_set_color(struct ratbag_led *led, struct ratbag_color color);
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* If the LED's mode is @ref RATBAG_LED_CYCLE or @ref RATBAG_LED_BREATHING
|
||||
* then this function sets the LED rate in Hz
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @param rate Effect rate in hz, 100 - 20000
|
||||
* @return 0 on success or an error code otherwise.
|
||||
*
|
||||
* @see ratbag_led_get_effect_rate
|
||||
*/
|
||||
enum ratbag_error_code
|
||||
ratbag_led_set_effect_rate(struct ratbag_led *led, unsigned int rate);
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* If the LED's mode is @ref RATBAG_LED_CYCLE or @ref RATBAG_LED_BREATHING
|
||||
* then this function sets the LED brightness, otherwise it has no effect.
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @param brightness Effect brightness 0 - 255
|
||||
* @return 0 on success or an error code otherwise.
|
||||
*
|
||||
* @see ratbag_led_get_brightness
|
||||
*/
|
||||
enum ratbag_error_code
|
||||
ratbag_led_set_brightness(struct ratbag_led *led, unsigned int brightness);
|
||||
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
@@ -1180,12 +1514,12 @@ ratbag_button_get_special(struct ratbag_button *button);
|
||||
*
|
||||
* @param button A previously initialized ratbag button
|
||||
* @param action The special action to assign to this button.
|
||||
* @return 0 on success or nonzero otherwise. On success, the button's
|
||||
* @return 0 on success or an error code otherwise. On success, the button's
|
||||
* action is set to @ref RATBAG_BUTTON_ACTION_TYPE_SPECIAL.
|
||||
*
|
||||
* @see ratbag_button_get_button
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_button_set_special(struct ratbag_button *button,
|
||||
enum ratbag_button_action_special action);
|
||||
|
||||
@@ -1226,10 +1560,10 @@ ratbag_button_get_key(struct ratbag_button *button,
|
||||
* @param sz The size of the modifiers array. sz may be 0 if no modifiers
|
||||
* are required.
|
||||
*
|
||||
* @return 0 on success or nonzero otherwise. On success, the button's
|
||||
* @return 0 on success or an error code otherwise. On success, the button's
|
||||
* action is set to @ref RATBAG_BUTTON_ACTION_TYPE_KEY.
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_button_set_key(struct ratbag_button *button,
|
||||
unsigned int key,
|
||||
unsigned int *modifiers,
|
||||
@@ -1240,10 +1574,10 @@ ratbag_button_set_key(struct ratbag_button *button,
|
||||
*
|
||||
* @param button A previously initialized ratbag button
|
||||
*
|
||||
* @return 0 on success or nonzero otherwise. On success, the button's
|
||||
* @return 0 on success or an error code otherwise. On success, the button's
|
||||
* action is set to @ref RATBAG_BUTTON_ACTION_TYPE_NONE.
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_button_disable(struct ratbag_button *button);
|
||||
|
||||
/**
|
||||
@@ -1262,101 +1596,175 @@ enum ratbag_macro_event_type {
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
* If a button's action is @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
|
||||
* this function returns the macro name.
|
||||
* @param macro A previously initialized ratbag button macro
|
||||
*
|
||||
* If the button's action type is not @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
|
||||
* this function returns NULL.
|
||||
*
|
||||
* @param button A previously initialized ratbag button
|
||||
*
|
||||
* @return The name of the macro associated to the button.
|
||||
* @return The name of the macro
|
||||
*/
|
||||
const char *
|
||||
ratbag_button_get_macro_name(struct ratbag_button *button);
|
||||
ratbag_button_macro_get_name(struct ratbag_button_macro *macro);
|
||||
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
* If a button's action is @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
|
||||
* this function returns the macro event type configured for the event at the
|
||||
* @param macro A previously initialized ratbag button macro
|
||||
*
|
||||
* @return The maximum number of events that can be assigned to this macro
|
||||
*/
|
||||
unsigned int
|
||||
ratbag_button_macro_get_num_events(struct ratbag_button_macro *macro);
|
||||
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
* Returns the macro event type configured for the event at the
|
||||
* given index.
|
||||
*
|
||||
* If the button's action type is not @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
|
||||
* this function returns @ref RATBAG_MACRO_EVENT_INVALID.
|
||||
* The behavior of this function for an index equal to or greater than the
|
||||
* return value of ratbag_button_macro_get_num_events() is undefined.
|
||||
*
|
||||
* @param button A previously initialized ratbag button
|
||||
* @param macro A previously initialized ratbag button macro
|
||||
* @param index An index of the event within the macro we are interested in.
|
||||
*
|
||||
* @return The type of the event at the given index
|
||||
*/
|
||||
enum ratbag_macro_event_type
|
||||
ratbag_button_get_macro_event_type(struct ratbag_button *button, unsigned int index);
|
||||
ratbag_button_macro_get_event_type(struct ratbag_button_macro *macro,
|
||||
unsigned int index);
|
||||
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
* If a button's action is @ref RATBAG_BUTTON_ACTION_TYPE_MACRO, and if the
|
||||
* event stored at the given index is @ref RATBAG_MACRO_EVENT_KEY_PRESSED or
|
||||
* @ref RATBAG_MACRO_EVENT_KEY_RELEASED, this function returns the key code
|
||||
* configured for the event at the given index.
|
||||
* If the event stored at the given index is @ref
|
||||
* RATBAG_MACRO_EVENT_KEY_PRESSED or @ref RATBAG_MACRO_EVENT_KEY_RELEASED,
|
||||
* this function returns the key code configured for the event at the given
|
||||
* index.
|
||||
*
|
||||
* If the button's action type is not @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
|
||||
* or if the event stored at the given index is not
|
||||
* @ref RATBAG_MACRO_EVENT_KEY_PRESSED or @ref RATBAG_MACRO_EVENT_KEY_RELEASED,
|
||||
* this function returns -EINVAL.
|
||||
* The behavior of this function for an index equal to or greater than the
|
||||
* return value of ratbag_button_macro_get_num_events() is undefined.
|
||||
*
|
||||
* @param button A previously initialized ratbag button
|
||||
* @param macro A previously initialized ratbag button macro
|
||||
* @param index An index of the event within the macro we are interested in.
|
||||
*
|
||||
* @return The key of the event at the given index
|
||||
*/
|
||||
int
|
||||
ratbag_button_get_macro_event_key(struct ratbag_button *button, unsigned int index);
|
||||
ratbag_button_macro_get_event_key(struct ratbag_button_macro*macro,
|
||||
unsigned int index);
|
||||
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
* If a button's action is @ref RATBAG_BUTTON_ACTION_TYPE_MACRO, and if the
|
||||
* event stored at the given index is @ref RATBAG_MACRO_EVENT_WAIT, this
|
||||
* function returns the timeout configured for the event at the given index.
|
||||
* If the event stored at the given index is @ref RATBAG_MACRO_EVENT_WAIT,
|
||||
* this function returns the timeout configured for the event at the given
|
||||
* index.
|
||||
*
|
||||
* If the button's action type is not @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
|
||||
* or if the event stored at the given index is not
|
||||
* @ref RATBAG_MACRO_EVENT_WAIT, this function returns -EINVAL.
|
||||
* The behavior of this function for an index equal to or greater than the
|
||||
* return value of ratbag_button_macro_get_num_events() is undefined.
|
||||
*
|
||||
* @param button A previously initialized ratbag button
|
||||
* @param macro A previously initialized ratbag button macro
|
||||
* @param index An index of the event within the macro we are interested in.
|
||||
*
|
||||
* @return The tiemout of the event at the given index
|
||||
* @return The timeout of the event at the given index
|
||||
*/
|
||||
int
|
||||
ratbag_button_get_macro_event_timeout(struct ratbag_button *button, unsigned int index);
|
||||
ratbag_button_macro_get_event_timeout(struct ratbag_button_macro *macro,
|
||||
unsigned int index);
|
||||
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
* Sets the button's action to @ref RATBAG_BUTTON_ACTION_TYPE_MACRO and
|
||||
* allocates the required memory to store the macro.
|
||||
* assigns the given macro to this button.
|
||||
*
|
||||
* libratbag does not use the macro struct passed in, it extracts the
|
||||
* required information from the struct. Changes to the macro after a call
|
||||
* to ratbag_button_set_macro() are not reflected in the device until a
|
||||
* subsequent call to ratbag_button_set_macro().
|
||||
*
|
||||
* @param button A previously intialized ratbag button
|
||||
* @param macro A fully initialized macro
|
||||
*
|
||||
* @return 0 on success or nonzero otherwise
|
||||
*/
|
||||
int
|
||||
ratbag_button_set_macro(struct ratbag_button *button, const char *name);
|
||||
enum ratbag_error_code
|
||||
ratbag_button_set_macro(struct ratbag_button *button,
|
||||
const struct ratbag_button_macro *macro);
|
||||
|
||||
int
|
||||
ratbag_button_write_macro(struct ratbag_button *button);
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
* Initialize a new button macro.
|
||||
*
|
||||
* The macro is refcounted with an initial value of at least 1.
|
||||
* Use ratbag_button_macro_unref() to release the macro.
|
||||
*
|
||||
* Note that some devices have limited storage for the macro names.
|
||||
* libratbag silently shortens macro names to the longest string the device
|
||||
* is capable of storing.
|
||||
*
|
||||
* @param name The name to assign to this macro.
|
||||
*
|
||||
* @return An "empty" button macro
|
||||
*/
|
||||
struct ratbag_button_macro *
|
||||
ratbag_button_macro_new(const char *name);
|
||||
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
* If a button's action is @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
|
||||
* this function returns the current button macro. The macro is a copy of
|
||||
* the one used on the device, changes to the macro are not reflected on the
|
||||
* device until a subsequent call to ratbag_button_set_macro().
|
||||
*
|
||||
* If a button's action is not @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
|
||||
* this function returns NULL.
|
||||
*
|
||||
* @param button A previously initialized ratbag button
|
||||
*/
|
||||
struct ratbag_button_macro *
|
||||
ratbag_button_get_macro(struct ratbag_button *button);
|
||||
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
* Sets the macro's event at the given index to the given type with the
|
||||
* key code or timeout given.
|
||||
*
|
||||
* The behavior of this function for an index equal to or greater than the
|
||||
* return value of ratbag_button_macro_get_num_events() is undefined.
|
||||
*/
|
||||
int
|
||||
ratbag_button_set_macro_event(struct ratbag_button *button,
|
||||
enum ratbag_error_code
|
||||
ratbag_button_macro_set_event(struct ratbag_button_macro *macro,
|
||||
unsigned int index,
|
||||
enum ratbag_macro_event_type type,
|
||||
unsigned int data);
|
||||
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
* Add a reference to the macro. A macro is destroyed whenever the
|
||||
* reference count reaches 0. See @ref ratbag_button_macro_unref.
|
||||
*
|
||||
* @param macro A previously initialized valid ratbag button macro
|
||||
* @return The passed ratbag macro
|
||||
*/
|
||||
struct ratbag_button_macro *
|
||||
ratbag_button_macro_ref(struct ratbag_button_macro *macro);
|
||||
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
* Dereference the ratbag button macro. When the internal refcount reaches
|
||||
* zero, all resources associated with this object are released. The object
|
||||
* must be considered invalid once unref is called.
|
||||
*
|
||||
* @param macro A previously initialized ratbag button macro
|
||||
* @return Always NULL
|
||||
*/
|
||||
struct ratbag_button_macro *
|
||||
ratbag_button_macro_unref(struct ratbag_button_macro *macro);
|
||||
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
@@ -1382,6 +1790,31 @@ ratbag_button_ref(struct ratbag_button *button);
|
||||
struct ratbag_button *
|
||||
ratbag_button_unref(struct ratbag_button *button);
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* Add a reference to the led. A led is destroyed whenever the
|
||||
* reference count reaches 0. See @ref ratbag_led_unref.
|
||||
*
|
||||
* @param led A previously initialized valid ratbag led
|
||||
* @return The passed ratbag led
|
||||
*/
|
||||
struct ratbag_led *
|
||||
ratbag_led_ref(struct ratbag_led *led);
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* Dereference the ratbag led. When the internal refcount reaches
|
||||
* zero, all resources associated with this object are released. The object
|
||||
* must be considered invalid once unref is called.
|
||||
*
|
||||
* @param led A previously initialized ratbag led
|
||||
* @return Always NULL
|
||||
*/
|
||||
struct ratbag_led *
|
||||
ratbag_led_unref(struct ratbag_led *led);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* in alphabetical order! */
|
||||
|
||||
LIBRATBAG_0.1.0 {
|
||||
LIBRATBAG_0.5.0 {
|
||||
global:
|
||||
ratbag_create_context;
|
||||
ratbag_button_disable;
|
||||
@@ -8,22 +8,27 @@ global:
|
||||
ratbag_button_get_type;
|
||||
ratbag_button_get_button;
|
||||
ratbag_button_get_key;
|
||||
ratbag_button_get_macro_event_type;
|
||||
ratbag_button_get_macro_event_key;
|
||||
ratbag_button_get_macro_event_timeout;
|
||||
ratbag_button_get_macro_name;
|
||||
ratbag_button_get_macro;
|
||||
ratbag_button_get_special;
|
||||
ratbag_button_get_user_data;
|
||||
ratbag_button_has_action_type;
|
||||
ratbag_button_macro_get_event_key;
|
||||
ratbag_button_macro_get_event_timeout;
|
||||
ratbag_button_macro_get_event_type;
|
||||
ratbag_button_macro_get_name;
|
||||
ratbag_button_macro_get_num_events;
|
||||
ratbag_button_macro_new;
|
||||
ratbag_button_macro_ref;
|
||||
ratbag_button_macro_set_event;
|
||||
ratbag_button_macro_unref;
|
||||
ratbag_button_ref;
|
||||
ratbag_button_set_button;
|
||||
ratbag_button_set_key;
|
||||
ratbag_button_set_macro;
|
||||
ratbag_button_set_macro_event;
|
||||
ratbag_button_set_special;
|
||||
ratbag_button_set_user_data;
|
||||
ratbag_button_unref;
|
||||
ratbag_button_write_macro;
|
||||
ratbag_device_commit;
|
||||
ratbag_device_get_name;
|
||||
ratbag_device_get_num_buttons;
|
||||
ratbag_device_get_num_profiles;
|
||||
@@ -40,14 +45,29 @@ global:
|
||||
ratbag_log_get_priority;
|
||||
ratbag_log_set_handler;
|
||||
ratbag_log_set_priority;
|
||||
ratbag_profile_get_led;
|
||||
ratbag_led_get_mode;
|
||||
ratbag_led_get_type;
|
||||
ratbag_led_get_color;
|
||||
ratbag_led_get_effect_rate;
|
||||
ratbag_led_get_brightness;
|
||||
ratbag_led_ref;
|
||||
ratbag_led_set_mode;
|
||||
ratbag_led_set_color;
|
||||
ratbag_led_set_effect_rate;
|
||||
ratbag_led_set_brightness;
|
||||
ratbag_led_unref;
|
||||
ratbag_device_get_num_leds;
|
||||
ratbag_profile_get_button;
|
||||
ratbag_profile_get_num_resolutions;
|
||||
ratbag_profile_get_resolution;
|
||||
ratbag_profile_get_user_data;
|
||||
ratbag_profile_is_active;
|
||||
ratbag_profile_is_enabled;
|
||||
ratbag_profile_ref;
|
||||
ratbag_profile_set_user_data;
|
||||
ratbag_profile_set_active;
|
||||
ratbag_profile_set_enabled;
|
||||
ratbag_profile_unref;
|
||||
ratbag_resolution_get_dpi;
|
||||
ratbag_resolution_get_dpi_x;
|
||||
|
||||
29
src/usb-ids.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright © 2016 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef USB_IDS_H
|
||||
#define USB_IDS_H
|
||||
|
||||
#define USB_VENDOR_ID_LOGITECH 0x046d
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,65 +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
|
||||
|
||||
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
|
||||
|
||||
# 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
@@ -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)
|
||||
@@ -26,12 +26,16 @@
|
||||
#include <check.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "libratbag.h"
|
||||
|
||||
#define _unused_ __attribute__ ((unused))
|
||||
|
||||
static int
|
||||
open_restricted(const char *path, int flags, void *user_data)
|
||||
{
|
||||
@@ -65,23 +69,40 @@ END_TEST
|
||||
|
||||
START_TEST(context_init_bad_iface)
|
||||
{
|
||||
struct ratbag *lr;
|
||||
struct ratbag *lr _unused_;
|
||||
struct ratbag_interface iface = {
|
||||
.open_restricted = NULL,
|
||||
.close_restricted = NULL,
|
||||
};
|
||||
|
||||
lr = ratbag_create_context(&iface, NULL);
|
||||
ck_assert(lr == NULL);
|
||||
/* abort */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
iface.open_restricted = open_restricted;
|
||||
lr = ratbag_create_context(&iface, NULL);
|
||||
ck_assert(lr == NULL);
|
||||
START_TEST(context_init_bad_iface_open)
|
||||
{
|
||||
struct ratbag *lr _unused_;
|
||||
struct ratbag_interface iface = {
|
||||
.open_restricted = open_restricted,
|
||||
.close_restricted = NULL,
|
||||
};
|
||||
|
||||
iface.open_restricted = NULL;
|
||||
iface.close_restricted = close_restricted;
|
||||
lr = ratbag_create_context(&iface, NULL);
|
||||
ck_assert(lr == NULL);
|
||||
/* abort */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(context_init_bad_iface_close)
|
||||
{
|
||||
struct ratbag *lr _unused_;
|
||||
struct ratbag_interface iface = {
|
||||
.open_restricted = NULL,
|
||||
.close_restricted = close_restricted,
|
||||
};
|
||||
|
||||
lr = ratbag_create_context(&iface, NULL);
|
||||
/* abort */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
@@ -115,15 +136,19 @@ START_TEST(context_ref)
|
||||
END_TEST
|
||||
|
||||
static Suite *
|
||||
test_context_suite(void)
|
||||
test_context_suite(bool using_valgrind)
|
||||
{
|
||||
TCase *tc;
|
||||
Suite *s;
|
||||
|
||||
s = suite_create("context");
|
||||
tc = tcase_create("init");
|
||||
tcase_add_test(tc, context_init_NULL);
|
||||
tcase_add_test(tc, context_init_bad_iface);
|
||||
if (!using_valgrind) {
|
||||
tcase_add_test_raise_signal(tc, context_init_NULL, SIGABRT);
|
||||
tcase_add_test_raise_signal(tc, context_init_bad_iface, SIGABRT);
|
||||
tcase_add_test_raise_signal(tc, context_init_bad_iface_open, SIGABRT);
|
||||
tcase_add_test_raise_signal(tc, context_init_bad_iface_close, SIGABRT);
|
||||
}
|
||||
tcase_add_test(tc, context_init);
|
||||
tcase_add_test(tc, context_ref);
|
||||
suite_add_tcase(s, tc);
|
||||
@@ -136,9 +161,14 @@ int main(void)
|
||||
int nfailed;
|
||||
Suite *s;
|
||||
SRunner *sr;
|
||||
bool using_valgrind;
|
||||
|
||||
s = test_context_suite();
|
||||
sr = srunner_create(s);
|
||||
/* when running under valgrind we're using nofork mode, so a
|
||||
* signal raised by a test will fail in valgrind */
|
||||
using_valgrind = !!getenv("USING_VALGRIND");
|
||||
|
||||
s = test_context_suite(using_valgrind);
|
||||
sr = srunner_create(s);
|
||||
|
||||
srunner_run_all(sr, CK_ENV);
|
||||
nfailed = srunner_ntests_failed(sr);
|
||||
|
||||
@@ -53,6 +53,7 @@ const struct ratbag_test_device sane_device = {
|
||||
.num_profiles = 3,
|
||||
.num_resolutions = 3,
|
||||
.num_buttons = 1,
|
||||
.num_leds = 2,
|
||||
.profiles = {
|
||||
{
|
||||
.resolutions = {
|
||||
@@ -78,6 +79,20 @@ const struct ratbag_test_device sane_device = {
|
||||
{ .xres = 2200, .yres = 2300, .hz = 3000 },
|
||||
{ .xres = 2300, .yres = 2400, .hz = 3000 },
|
||||
},
|
||||
.leds = {
|
||||
{
|
||||
.mode = RATBAG_LED_ON,
|
||||
.color = { .red = 255, .green = 0, .blue = 0 },
|
||||
.hz = 1,
|
||||
.brightness = 20
|
||||
},
|
||||
{
|
||||
.mode = RATBAG_LED_CYCLE,
|
||||
.color = { .red = 255, .green = 255, .blue = 0 },
|
||||
.hz = 3,
|
||||
.brightness = 40
|
||||
}
|
||||
},
|
||||
.active = false,
|
||||
.dflt = false,
|
||||
},
|
||||
@@ -110,7 +125,7 @@ START_TEST(device_init)
|
||||
{
|
||||
struct ratbag *r;
|
||||
struct ratbag_device *d;
|
||||
int nprofiles, nbuttons;
|
||||
int nprofiles, nbuttons, nleds;
|
||||
struct ratbag_test_device td = sane_device;
|
||||
int device_freed_count = 0;
|
||||
|
||||
@@ -124,6 +139,8 @@ START_TEST(device_init)
|
||||
ck_assert_int_eq(nprofiles, 3);
|
||||
nbuttons = ratbag_device_get_num_buttons(d);
|
||||
ck_assert_int_eq(nbuttons, 1);
|
||||
nleds = ratbag_device_get_num_leds(d);
|
||||
ck_assert_int_eq(nleds, 2);
|
||||
|
||||
ratbag_device_unref(d);
|
||||
ratbag_unref(r);
|
||||
@@ -649,6 +666,221 @@ START_TEST(device_and_profile_and_resolution_freed_before_button)
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_buttons)
|
||||
{
|
||||
struct ratbag *r;
|
||||
struct ratbag_device *d;
|
||||
struct ratbag_profile *p;
|
||||
struct ratbag_button *b;
|
||||
struct ratbag_button_macro *m;
|
||||
int nprofiles, nbuttons;
|
||||
int i, j;
|
||||
int device_freed_count = 0;
|
||||
|
||||
struct ratbag_test_device td = sane_device;
|
||||
td.num_buttons = 10;
|
||||
|
||||
td.profiles[0].buttons[8].type = RATBAG_BUTTON_ACTION_TYPE_MACRO;
|
||||
|
||||
td.destroyed_data = &device_freed_count;
|
||||
|
||||
r = ratbag_create_context(&abort_iface, NULL);
|
||||
d = ratbag_device_new_test_device(r, &td);
|
||||
|
||||
nprofiles = ratbag_device_get_num_profiles(d);
|
||||
ck_assert_int_eq(nprofiles, 3);
|
||||
|
||||
nbuttons = ratbag_device_get_num_buttons(d);
|
||||
ck_assert_int_eq(nbuttons, 10);
|
||||
|
||||
for (i = 0; i < nprofiles; i++) {
|
||||
p = ratbag_device_get_profile(d, i);
|
||||
ck_assert(p != NULL);
|
||||
|
||||
for (j = 0; j < nbuttons; j++) {
|
||||
b = ratbag_profile_get_button(p, j);
|
||||
ck_assert(b != NULL);
|
||||
|
||||
if (ratbag_button_get_action_type(b) ==
|
||||
RATBAG_BUTTON_ACTION_TYPE_MACRO) {
|
||||
m = ratbag_button_get_macro(b);
|
||||
ck_assert(m != NULL);
|
||||
|
||||
ratbag_button_macro_unref(m);
|
||||
}
|
||||
|
||||
ratbag_button_unref(b);
|
||||
}
|
||||
ratbag_profile_unref(p);
|
||||
}
|
||||
ratbag_device_unref(d);
|
||||
ratbag_unref(r);
|
||||
ck_assert_int_eq(device_freed_count, 1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_buttons_ref_unref)
|
||||
{
|
||||
struct ratbag *r;
|
||||
struct ratbag_device *d;
|
||||
struct ratbag_profile *p;
|
||||
struct ratbag_button *b;
|
||||
|
||||
struct ratbag_test_device td = sane_device;
|
||||
td.num_buttons = 10;
|
||||
|
||||
r = ratbag_create_context(&abort_iface, NULL);
|
||||
d = ratbag_device_new_test_device(r, &td);
|
||||
p = ratbag_device_get_profile(d, 1);
|
||||
b = ratbag_profile_get_button(p, 0);
|
||||
|
||||
ratbag_unref(r);
|
||||
ratbag_device_unref(d);
|
||||
ratbag_profile_unref(p);
|
||||
|
||||
ref_unref_test(ratbag_button, b);
|
||||
|
||||
ratbag_button_unref(b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_buttons_set)
|
||||
{
|
||||
struct ratbag *r;
|
||||
struct ratbag_device *d;
|
||||
struct ratbag_profile *p;
|
||||
struct ratbag_button *b;
|
||||
|
||||
struct ratbag_test_device td = sane_device;
|
||||
td.num_buttons = 10;
|
||||
|
||||
r = ratbag_create_context(&abort_iface, NULL);
|
||||
d = ratbag_device_new_test_device(r, &td);
|
||||
p = ratbag_device_get_profile(d, 1);
|
||||
b = ratbag_profile_get_button(p, 0);
|
||||
|
||||
ratbag_button_set_button(b, 3);
|
||||
|
||||
ratbag_button_unref(b);
|
||||
ratbag_profile_unref(p);
|
||||
ratbag_device_unref(d);
|
||||
ratbag_unref(r);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static void
|
||||
assert_led_equals(struct ratbag_led *l, struct ratbag_test_led e_l)
|
||||
{
|
||||
enum ratbag_led_mode mode;
|
||||
struct ratbag_color color;
|
||||
int brightness, hz;
|
||||
|
||||
ck_assert(l != NULL);
|
||||
mode = ratbag_led_get_mode(l);
|
||||
color = ratbag_led_get_color(l);
|
||||
hz = ratbag_led_get_effect_rate(l);
|
||||
brightness = ratbag_led_get_brightness(l);
|
||||
ck_assert_int_eq(mode, e_l.mode);
|
||||
ck_assert_int_eq(color.red, e_l.color.red);
|
||||
ck_assert_int_eq(color.green, e_l.color.green);
|
||||
ck_assert_int_eq(color.blue, e_l.color.blue);
|
||||
ck_assert_int_eq(hz, e_l.hz);
|
||||
ck_assert_int_eq(brightness, e_l.brightness);
|
||||
}
|
||||
|
||||
START_TEST(device_leds)
|
||||
{
|
||||
struct ratbag *r;
|
||||
struct ratbag_device *d;
|
||||
struct ratbag_profile *p;
|
||||
struct ratbag_led *led_logo, *led_side;
|
||||
int nprofiles;
|
||||
int device_freed_count = 0;
|
||||
|
||||
struct ratbag_test_device td = sane_device;
|
||||
|
||||
td.destroyed_data = &device_freed_count;
|
||||
|
||||
r = ratbag_create_context(&abort_iface, NULL);
|
||||
d = ratbag_device_new_test_device(r, &td);
|
||||
|
||||
nprofiles = ratbag_device_get_num_profiles(d);
|
||||
ck_assert_int_eq(nprofiles, 3);
|
||||
|
||||
p = ratbag_device_get_profile(d, 2);
|
||||
ck_assert(p != NULL);
|
||||
|
||||
led_logo = ratbag_profile_get_led(p, RATBAG_LED_TYPE_LOGO);
|
||||
assert_led_equals(led_logo, td.profiles[2].leds[RATBAG_LED_TYPE_LOGO]);
|
||||
led_side = ratbag_profile_get_led(p, RATBAG_LED_TYPE_SIDE);
|
||||
assert_led_equals(led_side, td.profiles[2].leds[RATBAG_LED_TYPE_SIDE]);
|
||||
|
||||
ratbag_led_unref(led_logo);
|
||||
ratbag_led_unref(led_side);
|
||||
ratbag_profile_unref(p);
|
||||
ratbag_device_unref(d);
|
||||
ratbag_unref(r);
|
||||
ck_assert_int_eq(device_freed_count, 1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_leds_set)
|
||||
{
|
||||
struct ratbag *r;
|
||||
struct ratbag_device *d;
|
||||
struct ratbag_profile *p;
|
||||
struct ratbag_led *l;
|
||||
int nprofiles;
|
||||
int device_freed_count = 0;
|
||||
|
||||
struct ratbag_test_device td = sane_device;
|
||||
|
||||
struct ratbag_color c = {
|
||||
.red = 0,
|
||||
.green = 111,
|
||||
.blue = 222
|
||||
};
|
||||
|
||||
td.destroyed_data = &device_freed_count;
|
||||
|
||||
r = ratbag_create_context(&abort_iface, NULL);
|
||||
d = ratbag_device_new_test_device(r, &td);
|
||||
|
||||
nprofiles = ratbag_device_get_num_profiles(d);
|
||||
ck_assert_int_eq(nprofiles, 3);
|
||||
|
||||
p = ratbag_device_get_profile(d, 0);
|
||||
ck_assert(p != NULL);
|
||||
|
||||
l = ratbag_profile_get_led(p, RATBAG_LED_TYPE_LOGO);
|
||||
|
||||
ratbag_led_set_mode(l, RATBAG_LED_BREATHING);
|
||||
ratbag_led_set_color(l, c);
|
||||
ratbag_led_set_effect_rate(l, 11);
|
||||
ratbag_led_set_brightness(l, 22);
|
||||
|
||||
l = ratbag_profile_get_led(p, RATBAG_LED_TYPE_LOGO);
|
||||
struct ratbag_test_led e_l = {
|
||||
.mode = RATBAG_LED_BREATHING,
|
||||
.color = {
|
||||
.red = c.red,
|
||||
.green = c.green,
|
||||
.blue = c.blue
|
||||
},
|
||||
.hz = 11,
|
||||
.brightness = 22
|
||||
};
|
||||
assert_led_equals(l, e_l);
|
||||
|
||||
ratbag_led_unref(l);
|
||||
ratbag_led_unref(l);
|
||||
ratbag_profile_unref(p);
|
||||
ratbag_device_unref(d);
|
||||
ratbag_unref(r);
|
||||
ck_assert_int_eq(device_freed_count, 1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static Suite *
|
||||
test_context_suite(void)
|
||||
{
|
||||
@@ -681,6 +913,17 @@ test_context_suite(void)
|
||||
tcase_add_test(tc, device_resolutions_num_0);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("buttons");
|
||||
tcase_add_test(tc, device_buttons);
|
||||
tcase_add_test(tc, device_buttons_ref_unref);
|
||||
tcase_add_test(tc, device_buttons_set);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("led");
|
||||
tcase_add_test(tc, device_leds);
|
||||
tcase_add_test(tc, device_leds_set);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
178
test/test-iconv-helper.c
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright © 2016 Red Hat, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <check.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "libratbag-util.h"
|
||||
|
||||
static const char sample_utf16le[] = { 'F', '\0', 'o', '\0', 'o', '\0' };
|
||||
static const char sample_single_char_utf16le[] = { 'A', '\0' };
|
||||
|
||||
/* Sample UTF-8 string used: 🐺🖖🗺🗹💯👏 */
|
||||
static const char sample_emoji_utf8[] = {
|
||||
0xf0, 0x9f, 0x90, 0xba, 0xf0, 0x9f, 0x96, 0x96, 0xf0, 0x9f, 0x97, 0xba,
|
||||
0xf0, 0x9f, 0x97, 0xb9, 0xf0, 0x9f, 0x92, 0xaf, 0xf0, 0x9f, 0x91, 0x8f,
|
||||
0x0a, 0x00
|
||||
};
|
||||
|
||||
static const char sample_emoji_utf16le[] = {
|
||||
0x3d, 0xd8, 0x3a, 0xdc, 0x3d, 0xd8, 0x96, 0xdd, 0x3d, 0xd8, 0xfa, 0xdd,
|
||||
0x3d, 0xd8, 0xf9, 0xdd, 0x3d, 0xd8, 0xaf, 0xdc, 0x3d, 0xd8, 0x4f, 0xdc,
|
||||
0x0a, 0x00
|
||||
};
|
||||
|
||||
START_TEST(iconv_convert_to_utf16le)
|
||||
{
|
||||
char output[4096];
|
||||
ssize_t rc;
|
||||
|
||||
rc = ratbag_utf8_to_enc(output, sizeof(sample_utf16le),
|
||||
"UTF-16LE", "%s", "Foo");
|
||||
|
||||
ck_assert_int_eq(rc, sizeof(sample_utf16le));
|
||||
ck_assert(memcmp(output, sample_utf16le, sizeof(sample_utf16le)) == 0);
|
||||
|
||||
rc = ratbag_utf8_to_enc(output, sizeof(sample_emoji_utf16le),
|
||||
"UTF-16LE", "%s", sample_emoji_utf8);
|
||||
|
||||
ck_assert_int_eq(rc, sizeof(sample_emoji_utf16le));
|
||||
ck_assert(memcmp(output, sample_emoji_utf16le,
|
||||
sizeof(sample_emoji_utf16le)) == 0);
|
||||
|
||||
rc = ratbag_utf8_to_enc(output, sizeof(sample_single_char_utf16le),
|
||||
"UTF-16LE", "%s", "A");
|
||||
|
||||
ck_assert_int_eq(rc, sizeof(sample_single_char_utf16le));
|
||||
ck_assert(memcmp(output, sample_single_char_utf16le,
|
||||
sizeof(sample_single_char_utf16le)) == 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(iconv_convert_from_utf16le)
|
||||
{
|
||||
char input[4096];
|
||||
char *output;
|
||||
ssize_t rc;
|
||||
|
||||
memcpy(input, sample_utf16le, sizeof(sample_utf16le));
|
||||
rc = ratbag_utf8_from_enc(input, sizeof(sample_utf16le),
|
||||
"UTF-16LE", &output);
|
||||
|
||||
ck_assert_int_eq(rc, sizeof("Foo"));
|
||||
ck_assert(memcmp(output, "Foo", sizeof("Foo")) == 0);
|
||||
free(output);
|
||||
|
||||
memcpy(input, sample_emoji_utf16le, sizeof(sample_emoji_utf16le));
|
||||
rc = ratbag_utf8_from_enc(input, sizeof(sample_emoji_utf16le),
|
||||
"UTF-16LE", &output);
|
||||
|
||||
ck_assert_int_eq(rc, sizeof(sample_emoji_utf8));
|
||||
ck_assert(memcmp(output, sample_emoji_utf8,
|
||||
sizeof(sample_emoji_utf8)) == 0);
|
||||
free(output);
|
||||
|
||||
memcpy(input, sample_single_char_utf16le,
|
||||
sizeof(sample_single_char_utf16le));
|
||||
rc = ratbag_utf8_from_enc(input, sizeof(sample_single_char_utf16le),
|
||||
"UTF-16LE", &output);
|
||||
|
||||
ck_assert_int_eq(rc, sizeof("A"));
|
||||
ck_assert(memcmp(output, "A", sizeof("A")) == 0);
|
||||
free(output);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(iconv_invalid_encoding)
|
||||
{
|
||||
char output[10] = { 0 };
|
||||
ssize_t rc;
|
||||
|
||||
rc = ratbag_utf8_to_enc(output, sizeof(output),
|
||||
"This encoding is invalid", "%s", "Foo");
|
||||
|
||||
ck_assert_int_eq(rc, -EINVAL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(iconv_bad_utf16le)
|
||||
{
|
||||
char odd_numbered[] = { 'F', '\0', 'o' };
|
||||
char single_char[] = { 'F' };
|
||||
char single_null[] = { '\0' };
|
||||
char double_null[] = { 'F', '\0', '\0', 'o', '\0', 'o', '\0' };
|
||||
char *output;
|
||||
ssize_t rc;
|
||||
|
||||
rc = ratbag_utf8_from_enc(odd_numbered, sizeof(odd_numbered),
|
||||
"UTF-16LE", &output);
|
||||
ck_assert_int_eq(rc, -EINVAL);
|
||||
|
||||
rc = ratbag_utf8_from_enc(single_char, sizeof(single_char), "UTF-16LE",
|
||||
&output);
|
||||
ck_assert_int_eq(rc, -EINVAL);
|
||||
|
||||
rc = ratbag_utf8_from_enc(single_null, sizeof(single_null), "UTF-16LE",
|
||||
&output);
|
||||
ck_assert_int_eq(rc, -EINVAL);
|
||||
|
||||
rc = ratbag_utf8_from_enc(double_null, sizeof(double_null), "UTF-16LE",
|
||||
&output);
|
||||
ck_assert_int_eq(rc, -EINVAL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static Suite *
|
||||
test_context_suite(void)
|
||||
{
|
||||
TCase *tc;
|
||||
Suite *s;
|
||||
|
||||
s = suite_create("iconv-helper");
|
||||
tc = tcase_create("iconv-helper");
|
||||
tcase_add_test(tc, iconv_convert_to_utf16le);
|
||||
tcase_add_test(tc, iconv_convert_from_utf16le);
|
||||
tcase_add_test(tc, iconv_invalid_encoding);
|
||||
tcase_add_test(tc, iconv_bad_utf16le);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int nfailed;
|
||||
Suite *s;
|
||||
SRunner *sr;
|
||||
|
||||
s = test_context_suite();
|
||||
sr = srunner_create(s);
|
||||
|
||||
srunner_run_all(sr, CK_ENV);
|
||||
nfailed = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
|
||||
return (nfailed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
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_LDFLAGS = -no-install
|
||||
lur_command_CFLAGS = -I$(top_srcdir)/src
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -111,6 +111,8 @@ main(int argc, char **argv)
|
||||
|
||||
hidpp_device_init(&base, fd);
|
||||
dev = hidpp20_device_new(&base, 0xff);
|
||||
if (!dev)
|
||||
error(1, 0, "Failed to open %s as a HID++ 2.0 device", path);
|
||||
|
||||
if (argc == 2)
|
||||
rc = dump_everything(dev);
|
||||
|
||||
@@ -41,8 +41,9 @@ enum options {
|
||||
static struct lur_receiver *
|
||||
open_receiver(const char *path)
|
||||
{
|
||||
struct lur_receiver *receiver;
|
||||
struct lur_receiver *receiver = NULL;
|
||||
int fd = -1;
|
||||
int rc;
|
||||
|
||||
fd = open(path, O_RDWR);
|
||||
if (fd < 0) {
|
||||
@@ -50,8 +51,8 @@ open_receiver(const char *path)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
receiver = lur_receiver_new_from_hidraw(fd, NULL);
|
||||
if (!receiver)
|
||||
rc = lur_receiver_new_from_hidraw(fd, NULL, &receiver);
|
||||
if (rc != 0)
|
||||
close(fd);
|
||||
|
||||
return receiver;
|
||||
@@ -242,7 +243,7 @@ main(int argc, char **argv)
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
index = atoi(argv[3]);
|
||||
index = atoi(argv[2]);
|
||||
disconnect_device(receiver, index);
|
||||
} else {
|
||||
usage();
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
@@ -58,6 +59,7 @@ enum cmd_flags {
|
||||
FLAG_NEED_PROFILE = 1 << 11,
|
||||
FLAG_NEED_RESOLUTION = 1 << 12,
|
||||
FLAG_NEED_BUTTON = 1 << 13,
|
||||
FLAG_NEED_LED = 1 << 14,
|
||||
};
|
||||
|
||||
struct ratbag_cmd_options {
|
||||
@@ -66,6 +68,7 @@ struct ratbag_cmd_options {
|
||||
struct ratbag_profile *profile;
|
||||
struct ratbag_resolution *resolution;
|
||||
struct ratbag_button *button;
|
||||
struct ratbag_led *led;
|
||||
};
|
||||
|
||||
struct ratbag_cmd {
|
||||
@@ -101,6 +104,8 @@ usage(void)
|
||||
"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 enable N Enable profile N\n"
|
||||
" profile disable N Disable profile N\n"
|
||||
" profile N {COMMAND} Use profile N for COMMAND\n"
|
||||
"\n"
|
||||
"Resolution Commands\n"
|
||||
@@ -143,12 +148,27 @@ usage(void)
|
||||
"\n"
|
||||
" switch-etekcity Switch the Etekcity mouse active profile\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"
|
||||
"\n"
|
||||
"Examples:\n"
|
||||
" %s profile active get\n"
|
||||
" %s profile 0 resolution active set 4\n"
|
||||
" %s profile 0 resolution 1 dpi get\n"
|
||||
" %s resolution 4 rate get\n"
|
||||
" %s dpi set 800\n"
|
||||
" %s profile 0 led 0 set mode on\n"
|
||||
" %s profile 0 led 0 set color ff00ff\n"
|
||||
" %s profile 0 led 0 set rate 20\n"
|
||||
"\n"
|
||||
"Exit codes:\n"
|
||||
" 0 Success\n"
|
||||
@@ -161,6 +181,9 @@ usage(void)
|
||||
program_invocation_short_name,
|
||||
program_invocation_short_name,
|
||||
program_invocation_short_name,
|
||||
program_invocation_short_name,
|
||||
program_invocation_short_name,
|
||||
program_invocation_short_name,
|
||||
program_invocation_short_name);
|
||||
}
|
||||
|
||||
@@ -194,9 +217,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;
|
||||
@@ -215,9 +237,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;
|
||||
@@ -316,9 +337,11 @@ ratbag_cmd_info(const struct ratbag_cmd *cmd,
|
||||
struct ratbag_device *device;
|
||||
struct ratbag_profile *profile;
|
||||
struct ratbag_button *button;
|
||||
struct ratbag_led *led;
|
||||
char *action;
|
||||
int num_profiles, num_buttons;
|
||||
int i, j, b;
|
||||
int num_profiles, num_buttons, num_leds;
|
||||
int b, l;
|
||||
struct ratbag_color color;
|
||||
|
||||
device = options->device;
|
||||
|
||||
@@ -337,24 +360,31 @@ ratbag_cmd_info(const struct ratbag_cmd *cmd,
|
||||
if (ratbag_device_has_capability(device,
|
||||
RATBAG_DEVICE_CAP_BUTTON_MACROS))
|
||||
printf(" btn-macros");
|
||||
if (ratbag_device_has_capability(device,
|
||||
RATBAG_DEVICE_CAP_LED))
|
||||
printf(" led");
|
||||
printf("\n");
|
||||
|
||||
num_buttons = ratbag_device_get_num_buttons(device);
|
||||
printf("Number of buttons: %d\n", num_buttons);
|
||||
|
||||
num_leds = ratbag_device_get_num_leds(device);
|
||||
printf("Number of leds: %d\n", num_leds);
|
||||
|
||||
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)
|
||||
continue;
|
||||
|
||||
printf(" Profile %d%s\n", i,
|
||||
printf(" Profile %d (%s)%s\n", i,
|
||||
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);
|
||||
@@ -390,6 +420,21 @@ ratbag_cmd_info(const struct ratbag_cmd *cmd,
|
||||
button = ratbag_button_unref(button);
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
led = ratbag_led_unref(led);
|
||||
}
|
||||
|
||||
profile = ratbag_profile_unref(profile);
|
||||
}
|
||||
|
||||
@@ -472,7 +517,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 */
|
||||
@@ -556,13 +601,13 @@ ratbag_cmd_change_button(const struct ratbag_cmd *cmd,
|
||||
struct ratbag_device *device;
|
||||
struct ratbag_button *button = NULL;
|
||||
struct ratbag_profile *profile = NULL;
|
||||
struct ratbag_button_macro *m = NULL;
|
||||
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;
|
||||
@@ -630,17 +675,18 @@ ratbag_cmd_change_button(const struct ratbag_cmd *cmd,
|
||||
rc = ratbag_button_set_special(button, special);
|
||||
break;
|
||||
case RATBAG_BUTTON_ACTION_TYPE_MACRO:
|
||||
rc = ratbag_button_set_macro(button, macro.name);
|
||||
for (i = 0; i < ARRAY_LENGTH(macro.events); i++) {
|
||||
m = ratbag_button_macro_new(macro.name);
|
||||
for (size_t i = 0; i < ARRAY_LENGTH(macro.events); i++) {
|
||||
if (macro.events[i].type == RATBAG_MACRO_EVENT_NONE)
|
||||
break;
|
||||
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
i,
|
||||
macro.events[i].type,
|
||||
macro.events[i].data);
|
||||
}
|
||||
rc = ratbag_button_write_macro(button);
|
||||
rc = ratbag_button_set_macro(button, m);
|
||||
ratbag_button_macro_unref(m);
|
||||
break;
|
||||
default:
|
||||
error("well, that shouldn't have happened\n");
|
||||
@@ -1265,15 +1311,15 @@ ratbag_cmd_button_set_macro(const struct ratbag_cmd *cmd,
|
||||
{
|
||||
struct ratbag_device *device;
|
||||
struct ratbag_button *button;
|
||||
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, " ");
|
||||
}
|
||||
@@ -1289,17 +1335,18 @@ ratbag_cmd_button_set_macro(const struct ratbag_cmd *cmd,
|
||||
return ERR_UNSUPPORTED;
|
||||
|
||||
button = options->button;
|
||||
rc = ratbag_button_set_macro(button, macro.name);
|
||||
for (i = 0; i < ARRAY_LENGTH(macro.events); i++) {
|
||||
m = ratbag_button_macro_new(macro.name);
|
||||
for (size_t i = 0; i < ARRAY_LENGTH(macro.events); i++) {
|
||||
if (macro.events[i].type == RATBAG_MACRO_EVENT_NONE)
|
||||
break;
|
||||
|
||||
ratbag_button_set_macro_event(button,
|
||||
ratbag_button_macro_set_event(m,
|
||||
i,
|
||||
macro.events[i].type,
|
||||
macro.events[i].data);
|
||||
}
|
||||
rc = ratbag_button_write_macro(button);
|
||||
rc = ratbag_button_set_macro(button, m);
|
||||
ratbag_button_macro_unref(m);
|
||||
if (rc != 0)
|
||||
return ERR_DEVICE;
|
||||
|
||||
@@ -1427,6 +1474,285 @@ static const struct ratbag_cmd cmd_button = {
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
ratbag_cmd_led_set_brightness(const struct ratbag_cmd *cmd,
|
||||
struct ratbag *ratbag,
|
||||
struct ratbag_cmd_options *options,
|
||||
int argc, char **argv)
|
||||
{
|
||||
struct ratbag_led *led;
|
||||
int brightness;
|
||||
int rc;
|
||||
|
||||
if (argc < 1)
|
||||
return ERR_USAGE;
|
||||
|
||||
led = options->led;
|
||||
brightness = atoi(argv[0]);
|
||||
|
||||
rc = ratbag_led_set_brightness(led, brightness);
|
||||
if (rc != 0)
|
||||
return ERR_DEVICE;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
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 = {
|
||||
NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
ratbag_cmd_led_set_effect_rate(const struct ratbag_cmd *cmd,
|
||||
struct ratbag *ratbag,
|
||||
struct ratbag_cmd_options *options,
|
||||
int argc, char **argv)
|
||||
{
|
||||
|
||||
struct ratbag_led *led;
|
||||
char *str, *endptr;
|
||||
int hz;
|
||||
int rc;
|
||||
|
||||
if (argc < 1)
|
||||
return ERR_USAGE;
|
||||
|
||||
led = options->led;
|
||||
str = argv[0];
|
||||
hz = strtoul(str, &endptr, 10);
|
||||
if (*endptr != '\0')
|
||||
return ERR_USAGE;
|
||||
|
||||
rc = ratbag_led_set_effect_rate(led, hz);
|
||||
if (rc != 0)
|
||||
return ERR_DEVICE;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static const struct ratbag_cmd cmd_led_set_effect_rate = {
|
||||
.name = "rate",
|
||||
.cmd = ratbag_cmd_led_set_effect_rate,
|
||||
.flags = FLAG_NEED_DEVICE | FLAG_NEED_PROFILE | FLAG_NEED_LED,
|
||||
.subcommands = {
|
||||
NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
ratbag_cmd_led_set_color(const struct ratbag_cmd *cmd,
|
||||
struct ratbag *ratbag,
|
||||
struct ratbag_cmd_options *options,
|
||||
int argc, char **argv)
|
||||
{
|
||||
struct ratbag_led *led;
|
||||
struct ratbag_color color;
|
||||
int rc;
|
||||
char red[2], green[2], blue[2];
|
||||
char *p;
|
||||
|
||||
if (argc < 1)
|
||||
return ERR_USAGE;
|
||||
|
||||
led = options->led;
|
||||
|
||||
sscanf(argv[0], "%2s%2s%2s", red, green, blue);
|
||||
|
||||
color.red = strtoul(red, &p, 16);
|
||||
color.green = strtoul(green, &p, 16);
|
||||
color.blue = strtoul(blue, &p, 16);
|
||||
|
||||
rc = ratbag_led_set_color(led, color);
|
||||
if (rc != 0)
|
||||
return ERR_DEVICE;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static const struct ratbag_cmd cmd_led_set_color = {
|
||||
.name = "color",
|
||||
.cmd = ratbag_cmd_led_set_color,
|
||||
.flags = FLAG_NEED_DEVICE | FLAG_NEED_PROFILE | FLAG_NEED_LED,
|
||||
.subcommands = {
|
||||
NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
ratbag_cmd_led_set_mode(const struct ratbag_cmd *cmd,
|
||||
struct ratbag *ratbag,
|
||||
struct ratbag_cmd_options *options,
|
||||
int argc, char **argv)
|
||||
{
|
||||
struct ratbag_led *led;
|
||||
struct ratbag_color color;
|
||||
enum ratbag_led_mode mode;
|
||||
char *str;
|
||||
int rc;
|
||||
|
||||
if (argc < 1)
|
||||
return ERR_USAGE;
|
||||
|
||||
led = options->led;
|
||||
str = argv[0];
|
||||
|
||||
if (streq(str, "off"))
|
||||
mode = RATBAG_LED_OFF;
|
||||
else if (streq(str, "on"))
|
||||
mode = RATBAG_LED_ON;
|
||||
else if (streq(str, "cycle"))
|
||||
mode = RATBAG_LED_CYCLE;
|
||||
else if (streq(str, "breathing"))
|
||||
mode = RATBAG_LED_BREATHING;
|
||||
else {
|
||||
usage();
|
||||
return ERR_USAGE;
|
||||
}
|
||||
|
||||
/* set default rate and brightness */
|
||||
switch (mode) {
|
||||
case RATBAG_LED_ON:
|
||||
color.red = 255;
|
||||
color.green = 255;
|
||||
color.blue = 255;
|
||||
ratbag_led_set_color(led, color);
|
||||
break;
|
||||
case RATBAG_LED_CYCLE:
|
||||
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;
|
||||
}
|
||||
|
||||
static const struct ratbag_cmd cmd_led_set_mode = {
|
||||
.name = "mode",
|
||||
.cmd = ratbag_cmd_led_set_mode,
|
||||
.flags = FLAG_NEED_DEVICE | FLAG_NEED_PROFILE | FLAG_NEED_LED,
|
||||
.subcommands = {
|
||||
NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
ratbag_cmd_led_set(const struct ratbag_cmd *cmd,
|
||||
struct ratbag *ratbag,
|
||||
struct ratbag_cmd_options *options,
|
||||
int argc, char **argv)
|
||||
{
|
||||
if (argc < 1)
|
||||
return ERR_USAGE;
|
||||
|
||||
return run_subcommand(argv[0], cmd, ratbag, options,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
static const struct ratbag_cmd cmd_led_set = {
|
||||
.name = "set",
|
||||
.cmd = ratbag_cmd_led_set,
|
||||
.flags = FLAG_NEED_DEVICE | FLAG_NEED_PROFILE | FLAG_NEED_LED,
|
||||
.subcommands = {
|
||||
&cmd_led_set_mode,
|
||||
&cmd_led_set_color,
|
||||
&cmd_led_set_effect_rate,
|
||||
&cmd_led_set_brightness,
|
||||
NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
ratbag_cmd_led_get(const struct ratbag_cmd *cmd,
|
||||
struct ratbag *ratbag,
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static const struct ratbag_cmd cmd_led_get = {
|
||||
.name = "get",
|
||||
.cmd = ratbag_cmd_led_get,
|
||||
.flags = FLAG_NEED_DEVICE | FLAG_NEED_PROFILE | FLAG_NEED_LED,
|
||||
.subcommands = {
|
||||
NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
ratbag_cmd_led(const struct ratbag_cmd *cmd,
|
||||
struct ratbag *ratbag,
|
||||
struct ratbag_cmd_options *options,
|
||||
int argc, char **argv)
|
||||
{
|
||||
struct ratbag_profile *profile;
|
||||
struct ratbag_led *led;
|
||||
int rc, index;
|
||||
|
||||
if (argc < 1)
|
||||
return ERR_USAGE;
|
||||
|
||||
profile = options->profile;
|
||||
|
||||
index = atoi(argv[0]);
|
||||
|
||||
led = ratbag_profile_get_led(profile, index);
|
||||
if (!led) {
|
||||
error("Invalid led %d\n", index);
|
||||
return ERR_UNSUPPORTED;
|
||||
}
|
||||
options->led = led;
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
rc = run_subcommand(argv[0], cmd, ratbag, options,
|
||||
argc, argv);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct ratbag_cmd cmd_led = {
|
||||
.name = "led",
|
||||
.cmd = ratbag_cmd_led,
|
||||
.flags = FLAG_NEED_DEVICE | FLAG_NEED_PROFILE,
|
||||
.subcommands = {
|
||||
&cmd_led_get,
|
||||
&cmd_led_set,
|
||||
NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
ratbag_cmd_profile_active_set(const struct ratbag_cmd *cmd,
|
||||
struct ratbag *ratbag,
|
||||
@@ -1558,6 +1884,60 @@ static const struct ratbag_cmd cmd_profile_active = {
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
ratbag_cmd_profile_enable(const struct ratbag_cmd *cmd,
|
||||
struct ratbag *ratbag,
|
||||
struct ratbag_cmd_options *options,
|
||||
int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!ratbag_device_has_capability(options->device,
|
||||
RATBAG_DEVICE_CAP_DISABLE_PROFILE))
|
||||
return ERR_UNSUPPORTED;
|
||||
|
||||
ratbag_profile_set_enabled(options->profile, true);
|
||||
rc = ratbag_device_commit(options->device);
|
||||
|
||||
return rc ? ERR_DEVICE : SUCCESS;
|
||||
}
|
||||
|
||||
static const struct ratbag_cmd cmd_profile_enable = {
|
||||
.name = "enable",
|
||||
.cmd = ratbag_cmd_profile_enable,
|
||||
.flags = FLAG_NEED_DEVICE | FLAG_NEED_PROFILE,
|
||||
.subcommands = {
|
||||
NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
ratbag_cmd_profile_disable(const struct ratbag_cmd *cmd,
|
||||
struct ratbag *ratbag,
|
||||
struct ratbag_cmd_options *options,
|
||||
int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!ratbag_device_has_capability(options->device,
|
||||
RATBAG_DEVICE_CAP_DISABLE_PROFILE))
|
||||
return ERR_UNSUPPORTED;
|
||||
|
||||
ratbag_profile_set_enabled(options->profile, false);
|
||||
rc = ratbag_device_commit(options->device);
|
||||
|
||||
return rc ? ERR_DEVICE : SUCCESS;
|
||||
}
|
||||
|
||||
static const struct ratbag_cmd cmd_profile_disable = {
|
||||
.name = "disable",
|
||||
.cmd = ratbag_cmd_profile_disable,
|
||||
.flags = FLAG_NEED_DEVICE | FLAG_NEED_PROFILE,
|
||||
.subcommands = {
|
||||
NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
ratbag_cmd_profile(const struct ratbag_cmd *cmd,
|
||||
struct ratbag *ratbag,
|
||||
@@ -1609,8 +1989,11 @@ static const struct ratbag_cmd cmd_profile = {
|
||||
.flags = FLAG_NEED_DEVICE,
|
||||
.subcommands = {
|
||||
&cmd_profile_active,
|
||||
&cmd_profile_enable,
|
||||
&cmd_profile_disable,
|
||||
&cmd_resolution,
|
||||
&cmd_button,
|
||||
&cmd_led,
|
||||
NULL,
|
||||
},
|
||||
};
|
||||
@@ -1697,9 +2080,14 @@ main(int argc, char **argv)
|
||||
ratbag,
|
||||
&options,
|
||||
argc, argv);
|
||||
|
||||
if (options.device)
|
||||
rc = ratbag_device_commit(options.device);
|
||||
|
||||
out:
|
||||
ratbag_resolution_unref(options.resolution);
|
||||
ratbag_button_unref(options.button);
|
||||
ratbag_led_unref(options.led);
|
||||
ratbag_profile_unref(options.profile);
|
||||
ratbag_device_unref(options.device);
|
||||
ratbag_unref(ratbag);
|
||||
|
||||
141
tools/ratbag-command.man
Normal file
@@ -0,0 +1,141 @@
|
||||
.TH RATBAG_COMMAND "1" "@version@"
|
||||
.SH NAME
|
||||
ratbag-command \- Query or change a device's settings
|
||||
.SH SYNOPSIS
|
||||
.B ratbag-command [OPTIONS] {COMMAND} ... /path/to/device
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The
|
||||
.I ratbag-commandq
|
||||
tool query or change 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
|
||||
.TP 8
|
||||
.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
|
||||
Print the help.
|
||||
.SH General Commands
|
||||
.TP 8
|
||||
.B list
|
||||
List supported devices (does not take a device argument)
|
||||
.SH Device Commands
|
||||
.TP 8
|
||||
.B info
|
||||
Print information about a device
|
||||
.SH Profile Commands
|
||||
.TP 8
|
||||
.B profile active get
|
||||
Print the currently active profile
|
||||
.TP 8
|
||||
.B profile active set N
|
||||
Set profile N as to the active profile
|
||||
.TP 8
|
||||
.B profile N {COMMAND}
|
||||
Use profile N for COMMAND
|
||||
.SH Resolution Commands
|
||||
Resolution commands work on the given profile, or on the active profile if none
|
||||
is given.
|
||||
.TP 8
|
||||
.B resolution active get
|
||||
Print the currently active resolution
|
||||
.TP 8
|
||||
.B resolution active set N
|
||||
Set resolution N as the active resolution
|
||||
.TP 8
|
||||
.B resolution N {COMMAND}
|
||||
Use resolution N for COMMAND
|
||||
.SH DPI Commands
|
||||
DPI commands work on the given profile and resolution, or on the active
|
||||
resolution of the active profile if none are given.
|
||||
.TP 8
|
||||
.B dpi get
|
||||
Print the dpi value
|
||||
.TP 8
|
||||
.B dpi set N
|
||||
Set the dpi value to N
|
||||
.TP 8
|
||||
.B rate get
|
||||
Print the report rate in Hz
|
||||
.TP 8
|
||||
.B rate set N
|
||||
Set the report rate in N Hz
|
||||
.SH Button Commands
|
||||
Button commands work on the given profile, or on the active profile if none is
|
||||
given.
|
||||
.TP 8
|
||||
.B button count
|
||||
Print the number of buttons
|
||||
.TP 8
|
||||
.B button N action get
|
||||
Print the button action
|
||||
.TP 8
|
||||
.B button N action set button B
|
||||
Set the button action to button B
|
||||
.TP 8
|
||||
.B button N action set special S
|
||||
Set the button action to special action S
|
||||
.TP 8
|
||||
.B button N action set macro ...
|
||||
Set the button action to the given macro
|
||||
.PP
|
||||
.B Macro syntax:
|
||||
.HP 8
|
||||
A macro is a series of key events or waiting periods. Keys must be specified
|
||||
in linux/input.h key names.
|
||||
.RS
|
||||
.TP 8
|
||||
.B KEY_A
|
||||
Press and release 'a'
|
||||
.TP 8
|
||||
.B +KEY_A
|
||||
Press 'a'
|
||||
.TP 8
|
||||
.B -KEY_A
|
||||
Release 'a'
|
||||
.TP 8
|
||||
.B t300
|
||||
Wait 300ms
|
||||
.RE
|
||||
.SH Special Commands
|
||||
These commands are for testing purposes and may be removed without notice
|
||||
.TP 8
|
||||
.B switch-etekcity
|
||||
Switch the Etekcity mouse active profile
|
||||
.SH Examples
|
||||
.TP 8
|
||||
ratbag-command profile active get
|
||||
.TP 8
|
||||
ratbag-command profile 0 resolution active set 4
|
||||
.TP 8
|
||||
ratbag-command profile 0 resolution 1 dpi get
|
||||
.TP 8
|
||||
ratbag-command resolution 4 rate get
|
||||
.TP 8
|
||||
ratbag-command dpi set 800
|
||||
.SH Exit codes
|
||||
.TP 8
|
||||
.B 0
|
||||
Success
|
||||
.TP 8
|
||||
.B 1
|
||||
Unsupported feature or index out of available range
|
||||
.TP 8
|
||||
.B 2
|
||||
Commandline arguments are invalid
|
||||
.TP 8
|
||||
.B 3
|
||||
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
|
||||
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.
|
||||
@@ -48,6 +48,48 @@ udev_device_from_path(struct udev *udev, const char *path)
|
||||
return udev_device;
|
||||
}
|
||||
|
||||
const char*
|
||||
led_type_to_str(enum ratbag_led_type type)
|
||||
{
|
||||
const char *str = "UNKNOWN";
|
||||
|
||||
switch(type) {
|
||||
case RATBAG_LED_TYPE_UNKNOWN:
|
||||
str = "unknown";
|
||||
break;
|
||||
case RATBAG_LED_TYPE_LOGO:
|
||||
str = "logo";
|
||||
break;
|
||||
case RATBAG_LED_TYPE_SIDE:
|
||||
str = "side";
|
||||
break;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
const char *
|
||||
led_mode_to_str(enum ratbag_led_mode mode)
|
||||
{
|
||||
const char *str = "UNKNOWN";
|
||||
switch (mode) {
|
||||
case RATBAG_LED_OFF:
|
||||
str = "off";
|
||||
break;
|
||||
case RATBAG_LED_ON:
|
||||
str = "on";
|
||||
break;
|
||||
case RATBAG_LED_CYCLE:
|
||||
str = "cycle";
|
||||
break;
|
||||
case RATBAG_LED_BREATHING:
|
||||
str = "breath";
|
||||
break;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
const char*
|
||||
button_type_to_str(enum ratbag_button_type type)
|
||||
{
|
||||
@@ -87,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[] = {
|
||||
@@ -99,9 +141,11 @@ const static struct map {
|
||||
{ RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_RIGHT, "wheel right" },
|
||||
{ RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_UP, "wheel up" },
|
||||
{ RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_DOWN, "wheel down" },
|
||||
{ RATBAG_BUTTON_ACTION_SPECIAL_RATCHET_MODE_SWITCH, "ratchet mode switch" },
|
||||
|
||||
/* DPI switch */
|
||||
{ RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_UP, "resolution cycle up" },
|
||||
{ RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_DOWN, "resolution cycle down" },
|
||||
{ RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_UP, "resolution up" },
|
||||
{ RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_DOWN, "resolution down" },
|
||||
{ RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_ALTERNATE, "resolution alternate" },
|
||||
@@ -109,6 +153,7 @@ const static struct map {
|
||||
|
||||
/* Profile */
|
||||
{ RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_CYCLE_UP, "profile cycle up" },
|
||||
{ RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_CYCLE_DOWN, "profile cycle down" },
|
||||
{ RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_UP, "profile up" },
|
||||
{ RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_DOWN, "profile down" },
|
||||
|
||||
@@ -174,18 +219,20 @@ static const char *strip_ev_key(int key)
|
||||
char *
|
||||
button_action_macro_to_str(struct ratbag_button *button)
|
||||
{
|
||||
struct ratbag_button_macro *macro;
|
||||
char str[4096] = {0};
|
||||
const char *name;
|
||||
int offset;
|
||||
unsigned int i;
|
||||
|
||||
name = ratbag_button_get_macro_name(button);
|
||||
macro = ratbag_button_get_macro(button);
|
||||
name = ratbag_button_macro_get_name(macro);
|
||||
offset = snprintf(str, sizeof(str), "macro \"%s\":",
|
||||
name ? name : "UNKNOWN");
|
||||
for (i = 0; i < MAX_MACRO_EVENTS; i++) {
|
||||
enum ratbag_macro_event_type type = ratbag_button_get_macro_event_type(button, i);
|
||||
int key = ratbag_button_get_macro_event_key(button, i);
|
||||
int timeout = ratbag_button_get_macro_event_timeout(button, i);
|
||||
enum ratbag_macro_event_type type = ratbag_button_macro_get_event_type(macro, i);
|
||||
int key = ratbag_button_macro_get_event_key(macro, i);
|
||||
int timeout = ratbag_button_macro_get_event_timeout(macro, i);
|
||||
|
||||
if (type == RATBAG_MACRO_EVENT_NONE)
|
||||
break;
|
||||
@@ -205,6 +252,8 @@ button_action_macro_to_str(struct ratbag_button *button)
|
||||
}
|
||||
}
|
||||
|
||||
ratbag_button_macro_unref(macro);
|
||||
|
||||
return strdup_safe(str);
|
||||
}
|
||||
|
||||
@@ -236,13 +285,17 @@ ratbag_cmd_open_device(struct ratbag *ratbag, const char *path)
|
||||
struct ratbag_device *device;
|
||||
_cleanup_udev_unref_ struct udev *udev = NULL;
|
||||
_cleanup_udev_device_unref_ struct udev_device *udev_device = NULL;
|
||||
enum ratbag_error_code error;
|
||||
|
||||
udev = udev_new();
|
||||
udev_device = udev_device_from_path(udev, path);
|
||||
if (!udev_device)
|
||||
return NULL;
|
||||
|
||||
device = ratbag_device_new_from_udev_device(ratbag, udev_device);
|
||||
error = ratbag_device_new_from_udev_device(ratbag, udev_device,
|
||||
&device);
|
||||
if (error != RATBAG_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,12 @@ udev_device_from_path(struct udev *udev, const char *path);
|
||||
const char*
|
||||
button_type_to_str(enum ratbag_button_type type);
|
||||
|
||||
const char*
|
||||
led_type_to_str(enum ratbag_led_type type);
|
||||
|
||||
const char *
|
||||
led_mode_to_str(enum ratbag_led_mode mode);
|
||||
|
||||
const char *
|
||||
button_action_special_to_str(struct ratbag_button *button);
|
||||
|
||||
|
||||
@@ -58,7 +58,12 @@ cmds+=("profile 0 button 0 action set key KEY_ENTER")
|
||||
cmds+=("button 0 action set special doubleclick")
|
||||
cmds+=("profile 0 button 0 action set special doubleclick")
|
||||
cmds+=("profile 0 button 0 action set macro +KEY_ENTER t05 -KEY_ENTER")
|
||||
|
||||
cmds+=("profile 0 led 0 get")
|
||||
cmds+=("profile 0 led side get")
|
||||
cmds+=("profile 0 led 0 set mode on")
|
||||
cmds+=("profile 0 led 0 set color ffffff")
|
||||
cmds+=("profile 0 led 0 set rate 1")
|
||||
cmds+=("profile 0 led 0 set brightness 1")
|
||||
for i in "${cmds[@]}"; do
|
||||
echo "Testing arguments '$i $device'"
|
||||
eval $command "$i" $device
|
||||
|
||||