Compare commits
121 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
549a6c47b8 | ||
|
|
400451efe1 | ||
|
|
2ee88948f3 | ||
|
|
ace60f76da | ||
|
|
451af331b9 | ||
|
|
b87a770970 | ||
|
|
e59ef319b0 | ||
|
|
8a1487f6f4 | ||
|
|
44d36d2bf0 | ||
|
|
635865efa5 | ||
|
|
38949013f7 | ||
|
|
e1879818b4 | ||
|
|
9b2614109f | ||
|
|
abe99fec6a | ||
|
|
21936db58b | ||
|
|
74f01f3de4 | ||
|
|
53ba4d975d | ||
|
|
97306ddd5a | ||
|
|
16e052d846 | ||
|
|
1586913fc7 | ||
|
|
cf9a3e48b7 | ||
|
|
ec835e2e82 | ||
|
|
b86211204c | ||
|
|
1d6995be72 | ||
|
|
536576fe8b | ||
|
|
b514f49b08 | ||
|
|
46a466ffe1 | ||
|
|
15f1667fa4 | ||
|
|
284c13b2fe | ||
|
|
e9bb4f98ae | ||
|
|
45b8d792cc | ||
|
|
b93dfcfda4 | ||
|
|
3ffdc8daa0 | ||
|
|
e38bc7a760 | ||
|
|
2dca516afa | ||
|
|
b489ac871d | ||
|
|
50fb898138 | ||
|
|
c676fcefb1 | ||
|
|
bb4dd2aae0 | ||
|
|
9b11340e91 | ||
|
|
3cd5a1f986 | ||
|
|
874d7eccb8 | ||
|
|
44c4b901e2 | ||
|
|
2371960a1d | ||
|
|
874aa8e63e | ||
|
|
1225f421c0 | ||
|
|
5f0f5d2843 | ||
|
|
1d464767e1 | ||
|
|
9551dddbb8 | ||
|
|
563c274705 | ||
|
|
71ed64a843 | ||
|
|
efb3efc828 | ||
|
|
982e6cc7fe | ||
|
|
44dc754e31 | ||
|
|
18887e4c86 | ||
|
|
46d5fae2e5 | ||
|
|
4b31945e1d | ||
|
|
7e685f5196 | ||
|
|
050db150f6 | ||
|
|
a3de0e1ff7 | ||
|
|
acc0066f08 | ||
|
|
eb9f98e58d | ||
|
|
6d996bf1aa | ||
|
|
34fbfe105c | ||
|
|
dfeac1bcbc | ||
|
|
3d345570eb | ||
|
|
6000688c30 | ||
|
|
9b409822c3 | ||
|
|
363eab80f0 | ||
|
|
66fc7b545e | ||
|
|
bb4b673df8 | ||
|
|
e104eca02c | ||
|
|
01c362eadc | ||
|
|
fff3589a20 | ||
|
|
a4e1e1690d | ||
|
|
38dce69838 | ||
|
|
23ff4e753d | ||
|
|
f24cb6dc66 | ||
|
|
b738136154 | ||
|
|
447931d779 | ||
|
|
920b71d94c | ||
|
|
a786aaf390 | ||
|
|
d395db1a11 | ||
|
|
ad0b7e53d9 | ||
|
|
0ed621db8f | ||
|
|
5ae473dcd1 | ||
|
|
ac384137bd | ||
|
|
e43cf7ab08 | ||
|
|
acb65a1bc8 | ||
|
|
e5f4b49e36 | ||
|
|
31d0fa00d9 | ||
|
|
d28f330d43 | ||
|
|
a29adaf913 | ||
|
|
ea3e68cf7d | ||
|
|
158594ec20 | ||
|
|
6e51849ae5 | ||
|
|
29731aa578 | ||
|
|
4d0ef4f2c1 | ||
|
|
e7d03448cc | ||
|
|
2725a55770 | ||
|
|
e5be1a70eb | ||
|
|
26493aceaf | ||
|
|
c4f5bd5218 | ||
|
|
7c65b0b4a9 | ||
|
|
d81c68d94f | ||
|
|
a5a2ea1a70 | ||
|
|
507d10378a | ||
|
|
08f3f7daf2 | ||
|
|
9b848084fd | ||
|
|
e1ebf7ad1b | ||
|
|
38f46a9be8 | ||
|
|
d07b7582db | ||
|
|
af194a22f0 | ||
|
|
d8c7050f6f | ||
|
|
30e834b18b | ||
|
|
49770a22e7 | ||
|
|
de8cba13cf | ||
|
|
1fab318dd3 | ||
|
|
e2190964c2 | ||
|
|
8eddf99823 | ||
|
|
9fede0e68d |
22
README.md
@@ -6,7 +6,17 @@ way to access the various features exposed by these mice and abstracts away
|
||||
hardware-specific and kernel-specific quirks.
|
||||
|
||||
libratbag exports the devices over a DBus daemon called **ratbagd**, see the
|
||||
[ratbagd DBus Interface description](DBusInterface.md).
|
||||
[ratbagd DBus Interface description](https://libratbag.github.io/).
|
||||
Users interact through a GUI like
|
||||
[Piper](https://github.com/libratbag/piper/). For developers, the
|
||||
`ratbagctl` tool is the prime tool for debugging.
|
||||
|
||||
Installing libratbag from system packages
|
||||
-----------------------------------------
|
||||
|
||||
libratbag is packaged for some distributions, you can use your system's
|
||||
package manager to install it. See [the
|
||||
wiki](https://github.com/libratbag/libratbag/wiki/Installation) for details.
|
||||
|
||||
Compiling libratbag
|
||||
-------------------
|
||||
@@ -17,7 +27,11 @@ libratbag and initialize the build:
|
||||
|
||||
git clone https://github.com/libratbag/libratbag.git
|
||||
cd libratbag
|
||||
meson builddir --prefix=/usr/
|
||||
meson builddir
|
||||
|
||||
This will inititialize libratbag so that it installs under `/usr/local`,
|
||||
i.e. it will not overwrite the system installation. For more information,
|
||||
see [the wiki](https://github.com/libratbag/libratbag/wiki/Installation).
|
||||
|
||||
And to build or re-build after code-changes, run:
|
||||
|
||||
@@ -27,9 +41,9 @@ And to build or re-build after code-changes, run:
|
||||
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=false
|
||||
meson configure builddir -Denable-documentation=false
|
||||
|
||||
Run `mesonconf builddir` to list the options.
|
||||
Run `meson configure builddir` to list the options.
|
||||
|
||||
Running ratbagd as DBus-activated systemd service
|
||||
-------------------------------------------------
|
||||
|
||||
23
circle.yml
@@ -29,6 +29,13 @@ libratbag_references:
|
||||
run:
|
||||
name: Installing
|
||||
command: ninja -C build install
|
||||
check_install: &check_install
|
||||
run:
|
||||
name: Checking installation
|
||||
command: |
|
||||
PREFIX=/usr/local/
|
||||
diff -u <(cd data/devices; ls *.device) <(cd $PREFIX/share/libratbag/devices; ls *.device)
|
||||
diff -u <(cd data/gnome; ls *.svg) <(cd $PREFIX/share/libratbag/gnome; ls *.svg)
|
||||
check_uninstall: &check_uninstall
|
||||
run:
|
||||
name: Checking if any files are left after uninstall
|
||||
@@ -94,6 +101,7 @@ fedora_settings: &fedora_settings
|
||||
- *start_dbus
|
||||
- *build_and_test
|
||||
- *install
|
||||
- *check_install
|
||||
- *check_uninstall
|
||||
- *export_logs
|
||||
|
||||
@@ -113,6 +121,7 @@ ubuntu_settings: &ubuntu_settings
|
||||
- *start_dbus
|
||||
- *build_and_test
|
||||
- *install
|
||||
- *check_install
|
||||
- *check_uninstall
|
||||
- *export_logs
|
||||
|
||||
@@ -124,13 +133,13 @@ scan_build_run: &scan_build_run
|
||||
- *fedora_install
|
||||
- run:
|
||||
name: Install clang and find
|
||||
command: dnf install -y clang-analyzer findutils
|
||||
command: dnf install -y clang-analyzer findutils python3-beautifulsoup4
|
||||
- checkout
|
||||
- *ninja_scan_build
|
||||
- *export_logs
|
||||
- run:
|
||||
name: Check scan-build results
|
||||
command: test ! -d ~/libratbag/build/meson-logs/scanbuild || test $(find ~/libratbag/build/meson-logs/scanbuild -maxdepth 0 ! -empty -exec echo "not empty" \; | wc -l) -eq 0 || (echo "Check scan-build results" && false)
|
||||
command: python3 ~/libratbag/tools/check_scan_build.py ~/libratbag/build/meson-logs/scanbuild
|
||||
|
||||
doc_build: &doc_build
|
||||
<<: *default_settings
|
||||
@@ -197,11 +206,11 @@ jobs:
|
||||
fedora_cache:
|
||||
<<: *fedora_prep_cache
|
||||
docker:
|
||||
- image: fedora:latest
|
||||
- image: fedora:28
|
||||
fedora_latest:
|
||||
<<: *fedora_settings
|
||||
docker:
|
||||
- image: fedora:latest
|
||||
- image: fedora:28
|
||||
ubuntu_17_10:
|
||||
<<: *ubuntu_settings
|
||||
docker:
|
||||
@@ -209,15 +218,15 @@ jobs:
|
||||
doc_build:
|
||||
<<: *doc_build
|
||||
docker:
|
||||
- image: fedora:latest
|
||||
- image: fedora:28
|
||||
scan_build:
|
||||
<<: *scan_build_run
|
||||
docker:
|
||||
- image: fedora:latest
|
||||
- image: fedora:28
|
||||
doc_deploy:
|
||||
<<: *docs_deploy
|
||||
docker:
|
||||
- image: fedora:latest
|
||||
- image: fedora:28
|
||||
|
||||
|
||||
workflows:
|
||||
|
||||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
@@ -32,6 +32,15 @@ import configparser
|
||||
# Set on commandline with --svg-dir
|
||||
svg_dirs = []
|
||||
|
||||
def assertIn(element, l):
|
||||
if element not in l:
|
||||
raise AssertionError('{} must be in {}'.format(element, l))
|
||||
|
||||
|
||||
def assertNotIn(element, l):
|
||||
if element in l:
|
||||
raise AssertionError('{} must not be in {}'.format(element, l))
|
||||
|
||||
|
||||
def check_svg_str(string):
|
||||
assert(string.endswith('.svg'))
|
||||
@@ -55,7 +64,7 @@ def check_match_str(string):
|
||||
|
||||
parts = match.split(':')
|
||||
assert(len(parts) == 3)
|
||||
assert(parts[0] in bustypes)
|
||||
assertIn(parts[0], bustypes)
|
||||
vid = parts[1]
|
||||
assert(vid == '{:04x}'.format(int(vid, 16)))
|
||||
pid = parts[2]
|
||||
@@ -70,7 +79,7 @@ def check_ledtypes_str(string):
|
||||
if not t: # emtpy string if trailing ;
|
||||
continue
|
||||
|
||||
assert(t in permitted_types)
|
||||
assertIn(t, permitted_types)
|
||||
|
||||
|
||||
def check_section_device(section):
|
||||
@@ -78,10 +87,10 @@ def check_section_device(section):
|
||||
permitted_keys = required_keys + ['Svg', 'LedTypes']
|
||||
|
||||
for key in section.keys():
|
||||
assert(key in permitted_keys)
|
||||
assertIn(key, permitted_keys)
|
||||
|
||||
for r in required_keys:
|
||||
assert(r in section)
|
||||
assertIn(r, section)
|
||||
|
||||
try:
|
||||
check_svg_str(section['Svg'])
|
||||
@@ -132,13 +141,13 @@ def check_dpi_list_str(string):
|
||||
|
||||
def check_profile_type_str(string):
|
||||
types = ['G9', 'G500', 'G700']
|
||||
assert(string in types)
|
||||
assertIn(string, types)
|
||||
|
||||
|
||||
def check_section_hidpp10(section):
|
||||
permitted = ['Profiles', 'ProfileType', 'DpiRange', 'DpiList', 'DeviceIndex', 'Leds']
|
||||
for key in section.keys():
|
||||
assert(key in permitted)
|
||||
assertIn(key, permitted)
|
||||
|
||||
try:
|
||||
nprofiles = int(section['Profiles'])
|
||||
@@ -156,13 +165,13 @@ def check_section_hidpp10(section):
|
||||
|
||||
try:
|
||||
check_dpi_range_str(section['DpiRange'])
|
||||
assert('DpiList' not in section.keys())
|
||||
assertNotIn('DpiList', section.keys())
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
check_dpi_list_str(section['DpiList'])
|
||||
assert('DpiRange' not in section.keys())
|
||||
assertNotIn('DpiRange', section.keys())
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
@@ -182,7 +191,7 @@ def check_section_hidpp10(section):
|
||||
def check_section_hidpp20(section):
|
||||
permitted = ['DeviceIndex']
|
||||
for key in section.keys():
|
||||
assert(key in permitted)
|
||||
assertIn(key, permitted)
|
||||
|
||||
try:
|
||||
index = int(section['DeviceIndex'])
|
||||
@@ -208,7 +217,7 @@ def parse_data_file(path):
|
||||
data.optionxform = lambda option: option
|
||||
data.read(path)
|
||||
|
||||
assert('Device' in data.sections())
|
||||
assertIn('Device', data.sections())
|
||||
check_section_device(data['Device'])
|
||||
|
||||
driver = data['Device']['Driver']
|
||||
@@ -216,7 +225,7 @@ def parse_data_file(path):
|
||||
|
||||
permitted_sections = ['Device', driver_section]
|
||||
for s in data.sections():
|
||||
assert(s in permitted_sections)
|
||||
assertIn(s, permitted_sections)
|
||||
|
||||
if data.has_section(driver_section):
|
||||
check_section_driver(driver, data[driver_section])
|
||||
|
||||
5
data/devices/logitech-MX-Anywhere2.device
Normal file
@@ -0,0 +1,5 @@
|
||||
[Device]
|
||||
Name=Logitech MX Anywhere 2
|
||||
DeviceMatch=usb:046d:404a;bluetooth:046d:b013
|
||||
Driver=hidpp20
|
||||
Svg=logitech-mx-anywhere2.svg
|
||||
5
data/devices/logitech-MX-Anywhere2S.device
Normal file
@@ -0,0 +1,5 @@
|
||||
[Device]
|
||||
Name=Logitech MX Anywhere 2S
|
||||
DeviceMatch=usb:046d:406a
|
||||
Driver=hidpp20
|
||||
Svg=logitech-mx-anywhere2.svg
|
||||
6
data/devices/logitech-MX-Master-2S.device
Normal file
@@ -0,0 +1,6 @@
|
||||
# Logitech MX Master 2S
|
||||
[Device]
|
||||
Name=Logitech MX Master 2S
|
||||
DeviceMatch=bluetooth:046d:b019;usb:046d:4069
|
||||
Driver=hidpp20
|
||||
Svg=logitech-mx-master-2s.svg
|
||||
@@ -1,6 +1,6 @@
|
||||
# Logitech MX Master
|
||||
[Device]
|
||||
Name=Logitech MX Master
|
||||
DeviceMatch=usb:046d:4041;bluetooth:046d:b012
|
||||
DeviceMatch=usb:046d:4041;bluetooth:046d:b012;usb:046d:4060
|
||||
Driver=hidpp20
|
||||
Svg=logitech-mx_master.svg
|
||||
Svg=logitech-mx-master.svg
|
||||
|
||||
9
data/devices/logitech-g-pro-wireless.device
Normal file
@@ -0,0 +1,9 @@
|
||||
[Device]
|
||||
Name=Logitech G Pro Wireless
|
||||
DeviceMatch=usb:046d:c539;usb:046d:c088
|
||||
Svg=logitech-g-pro-wireless.svg
|
||||
LedTypes=logo;battery;dpi;
|
||||
Driver=hidpp20
|
||||
|
||||
[Driver/hidpp20]
|
||||
DeviceIndex=1
|
||||
6
data/devices/logitech-g-pro.device
Normal file
@@ -0,0 +1,6 @@
|
||||
[Device]
|
||||
Name=Logitech Gaming Mouse G Pro
|
||||
DeviceMatch=usb:046d:c085
|
||||
Svg=logitech-g-pro.svg
|
||||
Driver=hidpp20
|
||||
LedTypes=logo;side
|
||||
7
data/devices/logitech-g102-g203.device
Normal file
@@ -0,0 +1,7 @@
|
||||
# G102 and G203 (USB)
|
||||
[Device]
|
||||
Name=Logitech Gaming Mouse G102/G103
|
||||
DeviceMatch=usb:046d:c084
|
||||
Svg=logitech-g102-g203.svg
|
||||
Driver=hidpp20
|
||||
LedTypes=logo;side;
|
||||
7
data/devices/logitech-g302.device
Normal file
@@ -0,0 +1,7 @@
|
||||
# G302 over USB
|
||||
[Device]
|
||||
Name=Logitech Gaming Mouse G302
|
||||
DeviceMatch=usb:046d:c07f
|
||||
Svg=logitech-g303.svg
|
||||
Driver=hidpp20
|
||||
LedTypes=logo;side;
|
||||
6
data/devices/logitech-g402.device
Executable file
@@ -0,0 +1,6 @@
|
||||
# Logitech G402 Gaming Mouse USB
|
||||
[Device]
|
||||
Name=Logitech G402 Gaming Mouse
|
||||
DeviceMatch=usb:046d:c07e
|
||||
Driver=hidpp20
|
||||
Svg=logitech-g402.svg
|
||||
6
data/devices/logitech-g502-HERO-over-USB.device
Normal file
@@ -0,0 +1,6 @@
|
||||
# Logitech G502 HERO over USB
|
||||
[Device]
|
||||
Name=Logitech G502 HERO
|
||||
DeviceMatch=usb:046d:c08b
|
||||
Driver=hidpp20
|
||||
Svg=logitech-g502.svg
|
||||
6
data/devices/logitech-g600.device
Normal file
@@ -0,0 +1,6 @@
|
||||
# WARNING: this file was automatically converted and has not yet been vetted
|
||||
[Device]
|
||||
Name=Logitech G600
|
||||
DeviceMatch=usb:046d:c24a
|
||||
Driver=logitech_g600
|
||||
Svg=logitech-g600.svg
|
||||
@@ -1,6 +1,6 @@
|
||||
# Logitech G900 and G403 over wireless USB
|
||||
# Logitech G900, G903 and G403 over wireless USB
|
||||
[Device]
|
||||
Name=Logitech G900, G403
|
||||
Name=Logitech G900, G903, G403
|
||||
DeviceMatch=usb:046d:c539
|
||||
Driver=hidpp20
|
||||
Svg=logitech-g900.svg
|
||||
|
||||
6
data/devices/logitech-g903.device
Normal file
@@ -0,0 +1,6 @@
|
||||
# Logitech G903 over USB
|
||||
[Device]
|
||||
Name=Logitech G903
|
||||
DeviceMatch=usb:046d:c086
|
||||
Driver=hidpp20
|
||||
Svg=logitech-g900.svg
|
||||
9
data/devices/logitech-gpowerplay-wireless.device
Normal file
@@ -0,0 +1,9 @@
|
||||
# Logitech G PowerPlay mouse pad + wireless USB receiver.
|
||||
[Device]
|
||||
Name=Logitech G PowerPlay mouse pad.
|
||||
DeviceMatch=usb:046d:c53a
|
||||
Driver=hidpp20
|
||||
Svg=logitech-g900.svg
|
||||
|
||||
[Driver/hidpp20]
|
||||
DeviceIndex=1
|
||||
12
data/devices/steelseries-rival-600.device
Normal file
@@ -0,0 +1,12 @@
|
||||
[Device]
|
||||
Name=SteelSeries Rival 600
|
||||
DeviceMatch=usb:1038:1724
|
||||
Driver=steelseries
|
||||
Svg=steelseries-rival600.svg
|
||||
|
||||
[Driver/steelseries]
|
||||
DeviceVersion=3
|
||||
Buttons=7
|
||||
Leds=8
|
||||
DpiRange=100:12000@100
|
||||
MacroLength=1
|
||||
15
data/devices/steelseries-sensei-raw.device
Normal file
@@ -0,0 +1,15 @@
|
||||
[Device]
|
||||
Name=SteelSeries Sensei Raw
|
||||
DeviceMatch=usb:1038:1369
|
||||
Driver=steelseries
|
||||
Svg=steelseries-senseiraw.svg
|
||||
LedTypes=logo;dpi
|
||||
|
||||
[Driver/steelseries]
|
||||
DeviceVersion=1
|
||||
Buttons=8
|
||||
Leds=1
|
||||
DpiRange=90:5670@90
|
||||
MacroLength=1
|
||||
MonoLed=1
|
||||
ShortButton=1
|
||||
@@ -49,7 +49,7 @@ def check_layers(root):
|
||||
def check_elements(root, prefix, required=0):
|
||||
"""
|
||||
Checks for elements of the form 'prefixN' in the root tag. Any elements
|
||||
found must be consecutive or an error is printed, i.e. if there's a
|
||||
found must be consecutive or an warning is printed, i.e. if there's a
|
||||
'button8' there has to be a 'button7'.
|
||||
|
||||
If required is nonzero, an error is logged for any missing element with
|
||||
@@ -66,13 +66,14 @@ def check_elements(root, prefix, required=0):
|
||||
highest = -1
|
||||
for idx in range(0, 20):
|
||||
e = '{}{}'.format(prefix, idx)
|
||||
previous = '{}{}'.format(prefix, idx - 1)
|
||||
leader = '{}{}-leader'.format(prefix, idx)
|
||||
path = '{}{}-path'.format(prefix, idx)
|
||||
if e in element_ids:
|
||||
highest = idx
|
||||
previous = '{}{}'.format(prefix, idx - 1)
|
||||
if idx > 0 and previous not in element_ids:
|
||||
logger.error("Non-consecutive {}: {}".format(prefix, e))
|
||||
logger.warning("Non-consecutive {}: {}".format(prefix, e))
|
||||
|
||||
leader = '{}{}-leader'.format(prefix, idx)
|
||||
if leader not in element_ids:
|
||||
logger.error("Missing {} for {}".format(leader, e))
|
||||
else:
|
||||
@@ -80,9 +81,12 @@ def check_elements(root, prefix, required=0):
|
||||
if element is None or len(element) != 1 or element[0] is None:
|
||||
logger.error("Missing style property for {}".format(leader))
|
||||
|
||||
path = '{}{}-path'.format(prefix, idx)
|
||||
if path not in element_ids:
|
||||
logger.error("Missing {} for {}".format(path, e))
|
||||
elif leader in element_ids:
|
||||
logger.error("Have {} but not {}".format(leader, e))
|
||||
elif path in element_ids:
|
||||
logger.error("Have {} but not {}".format(path, e))
|
||||
elif idx < required:
|
||||
logger.error("Missing {}: {}".format(prefix, e))
|
||||
|
||||
|
||||
358
data/gnome/logitech-g-pro-wireless.svg
Normal file
@@ -0,0 +1,358 @@
|
||||
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="417.20001"
|
||||
height="407.25"
|
||||
viewBox="0 0 417.20001 407.24999"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.2 2405546, 2018-03-11"
|
||||
sodipodi:docname="logitech-g-pro-wireless.svg"
|
||||
inkscape:export-filename="/home/jimmac/logitech-g-pro.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<defs
|
||||
id="defs2">
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect4193"
|
||||
is_visible="true" />
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect4185"
|
||||
is_visible="true" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.2804595"
|
||||
inkscape:cx="68.346407"
|
||||
inkscape:cy="156.12394"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="Device"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
borderlayer="true"
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:pagecheckerboard="false"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1016"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="20"
|
||||
fit-margin-left="20"
|
||||
fit-margin-bottom="20"
|
||||
fit-margin-right="0"
|
||||
inkscape:guide-bbox="true"
|
||||
guidetolerance="10"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
inkscape:snap-object-midpoints="true"
|
||||
inkscape:snap-others="true"
|
||||
inkscape:snap-global="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid956"
|
||||
originx="-68.791593"
|
||||
originy="1.2767161" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<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 />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="Device"
|
||||
inkscape:label="Device"
|
||||
transform="translate(-68.791597,-394.02675)"
|
||||
style="display:inline">
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccccccccccsccccsccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1292"
|
||||
d="m 360.53959,454.98488 c 3.74994,7.11792 5.22331,12.82285 5.80424,19.98939 1.3281,12.56244 0.9478,23.81846 0.96947,36.4814 l -3.17737,93.86839 c 2.16614,21.37627 5.56926,62.75825 5.56926,62.75825 0.65653,8.98996 -0.46847,26.48228 -0.46847,26.48228 -2.86905,23.33152 -10.5133,37.74934 -19.00067,50.59334 -18.20786,20.92677 -40.13338,36.77577 -73.78077,36.6144 -27.02249,-2.01448 -53.27969,-9.87305 -76.17266,-43.4221 -9.26342,-15.31303 -16.69901,-34.15568 -15.08733,-70.46891 0.62849,-14.11561 1.69038,-28.25238 4.18994,-49.46082 l -0.49311,-29.00325 1.18979,-1.57231 -0.0795,-4.45976 c -1.39215,-1.83047 -1.66233,-3.22446 -1.77535,-5.08282 -0.64341,-16.4181 -3.4946,-31.1865 -1.60176,-47.4595 l 1.47194,-0.0964 c -0.37849,-21.34319 -3.11342,-49.72121 2.66511,-66.67692 1.24485,-3.65274 1.80259,-6.37401 3.52312,-8.88212 l 1.05297,-0.01 c 0.54288,1.3278 1.67594,1.1345 2.10889,-0.024 v -5.52825 c 3.59201,-4.68158 7.50203,-9.54243 12.85097,-13.19967 15.55153,-10.63308 32.80347,-19.96687 65.99229,-22.56979 l -0.0387,6.48824 h 2.2079 l -0.01,-6.47842 c 23.50552,1.65098 57.68029,9.24243 79.04493,36.21112 l -0.0104,4.95885 0.5328,0.02 c -0.0202,1.38148 1.14549,1.60947 1.23348,-0.0306 z"
|
||||
style="fill:#d3d3ce;fill-opacity:1;stroke:#babdb6;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="button4"
|
||||
d="m 188.09729,530.74646 c 1.24811,16.49039 3.84562,32.89212 4.67165,49.41274 -0.23358,2.47096 -1.75447,3.01485 -2.76648,3.22598 -1.40633,-1.85652 -1.95252,-3.40284 -2.12696,-4.9258 -0.5931,-13.32083 -2.99544,-30.31661 -1.59655,-47.61652 z"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:label="#path1308" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccczzc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="button3"
|
||||
d="m 193.52072,585.08288 -4.67671,4.33437 c -0.0827,14.62518 0.50637,29.18789 1.55352,43.76306 0.38765,1.69742 1.72362,5.2371 2.9655,5.04628 1.24187,-0.19081 2.03429,-4.00811 2.05005,-4.80974 0.0158,-0.80162 -1.89236,-48.33397 -1.89236,-48.33397 z"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:label="#path1310" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="button0"
|
||||
width="21.618355"
|
||||
height="54.844131"
|
||||
x="-288.2897"
|
||||
y="458.7883"
|
||||
rx="10.20224"
|
||||
ry="9.3806696"
|
||||
inkscape:label="#rect932"
|
||||
transform="scale(-1,1)" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="button1"
|
||||
d="m 348.93916,572.45034 c -0.55088,2.3786 -2.02369,4.23561 -5.30087,5.25105 l -65.10412,-0.0533 -0.056,-61.16607 c 6.69027,-0.62851 12.7931,-2.33598 13.40584,-12.8421 l 0.11678,-35.30516 c -0.67751,-4.76842 -1.92823,-11.08275 -13.43942,-12.70653 l -0.11153,-41.76267 c 28.32131,1.35252 61.44583,12.93152 79.04493,36.21112 -0.49018,45.87326 -3.70717,82.71393 -8.55561,122.37369 z"
|
||||
style="fill:#e6e6e4;fill-opacity:1;stroke:#babdb6;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:label="#path1314" />
|
||||
<path
|
||||
style="fill:#e6e6e4;fill-opacity:1;stroke:#babdb6;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 206.00299,572.3517 c 0.55088,2.3786 2.02369,4.23561 5.30087,5.25105 l 65.10412,-0.0533 -0.0153,-61.06743 c -6.69027,-0.62851 -12.72181,-2.43462 -13.33455,-12.94074 l -0.11678,-35.30516 c 0.67751,-4.76842 2.20116,-11.4932 13.43942,-12.70653 l 0.11153,-41.76267 c -28.7246,1.50375 -63.81513,13.58686 -79.04493,35.85825 0.49018,45.87326 3.70717,83.0668 8.55561,122.72656 z"
|
||||
id="button2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccc"
|
||||
inkscape:label="#path1316" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1318"
|
||||
d="m 360.53959,454.98488 c 0.43129,16.08426 -0.23059,32.16852 -1.31311,48.25278 -2.19193,26.2623 -4.67884,48.98479 -7.12913,72.1468 -1.46408,3.93001 -3.86084,5.76149 -6.84397,6.27364 -43.14472,-1.05018 -87.90934,-1.3804 -135.88124,-0.28516 -2.36085,-0.76628 -4.72268,-1.52623 -6.5588,-5.70331 -2.11905,-20.75413 -4.2381,-39.15076 -6.35715,-65.36609 -1.04644,-16.292 -1.64275,-37.04208 -2.17067,-55.11612"
|
||||
style="fill:none;stroke:#babdb6;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<g
|
||||
transform="translate(0.23449552,400.00009)"
|
||||
style="display:inline"
|
||||
id="led0">
|
||||
<g
|
||||
transform="translate(427.72943,-408.9487)"
|
||||
id="g1304"
|
||||
style="display:inline">
|
||||
<ellipse
|
||||
style="fill:#babdb6;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="ellipse1298"
|
||||
cx="-150.51967"
|
||||
cy="622.58923"
|
||||
rx="1.8137393"
|
||||
ry="1.9375004" />
|
||||
<ellipse
|
||||
ry="1.9375004"
|
||||
rx="1.8137393"
|
||||
cy="610.96423"
|
||||
cx="-150.51967"
|
||||
id="ellipse1300"
|
||||
style="fill:#babdb6;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<ellipse
|
||||
style="fill:#babdb6;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="ellipse1302"
|
||||
cx="-150.51967"
|
||||
cy="599.15173"
|
||||
rx="1.8137393"
|
||||
ry="1.9375004" />
|
||||
</g>
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;vector-effect:none;fill:none;fill-opacity:1;stroke:#babdb6;stroke-width:10;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="led0-3"
|
||||
sodipodi:type="arc"
|
||||
sodipodi:cx="-284.0806"
|
||||
sodipodi:cy="277.20975"
|
||||
sodipodi:rx="19.936752"
|
||||
sodipodi:ry="19.936752"
|
||||
sodipodi:start="0.78539816"
|
||||
sodipodi:end="5.4977871"
|
||||
sodipodi:arc-type="arc"
|
||||
d="m -269.98318,291.30716 a 19.936752,19.936752 0 0 1 -28.19483,0 19.936752,19.936752 0 0 1 0,-28.19483 19.936752,19.936752 0 0 1 28.19483,0"
|
||||
sodipodi:open="true"
|
||||
transform="rotate(-90)"
|
||||
inkscape:label="#path883" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="Buttons"
|
||||
inkscape:label="Buttons"
|
||||
style="display:inline"
|
||||
transform="translate(-68.791597,5.973336)">
|
||||
<g
|
||||
id="button0-path"
|
||||
inkscape:label="#button0-path">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path960"
|
||||
d="m 485.19274,86.21028 -207.71221,10e-7"
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
y="82.710281"
|
||||
x="273.98053"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect970"
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
inkscape:label="#rect871"
|
||||
style="color:#000000;text-align:start;overflow:visible;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button0-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="485"
|
||||
y="85.710289" />
|
||||
</g>
|
||||
<g
|
||||
id="button4-path"
|
||||
inkscape:label="#g979">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path964"
|
||||
d="m 186.12905,161.04893 -116.990518,0.0625"
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
inkscape:label="#rect875"
|
||||
style="color:#000000;text-align:end;overflow:visible;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.99999994;stroke-linecap:round"
|
||||
id="button4-leader"
|
||||
width="0.32565016"
|
||||
height="1"
|
||||
x="-69.138535"
|
||||
y="160.58018" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
y="157.58018"
|
||||
x="-189.79312"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect974"
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
</g>
|
||||
<g
|
||||
id="button3-path"
|
||||
inkscape:label="#g984">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 187.9817,205.35644 H 69.129695"
|
||||
id="path966"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect976"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="-191.91962"
|
||||
y="201.85645" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
y="204.85645"
|
||||
x="-69.1297"
|
||||
height="1"
|
||||
width="0.32190493"
|
||||
id="button3-leader"
|
||||
style="color:#000000;text-align:end;overflow:visible;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round"
|
||||
inkscape:label="#rect875" />
|
||||
</g>
|
||||
<g
|
||||
id="button1-path"
|
||||
inkscape:label="#button1-path">
|
||||
<path
|
||||
sodipodi:nodetypes="ccc"
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 316.65466,47.839954 25.8491,-28.270742 H 485"
|
||||
id="path958"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
inkscape:label="#rect867"
|
||||
style="color:#000000;text-align:start;overflow:visible;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button1-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="485"
|
||||
y="19.069216" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect968"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="313.15466"
|
||||
y="44.339954" />
|
||||
</g>
|
||||
<g
|
||||
id="button2-path"
|
||||
inkscape:label="#g974">
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
inkscape:label="#rect869"
|
||||
y="19.069212"
|
||||
x="-69.800262"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button2-leader"
|
||||
style="color:#000000;text-align:end;overflow:visible;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1398"
|
||||
d="M 237.81014,47.839954 211.96104,19.569212 H 69.464797"
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect910"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="234.31013"
|
||||
y="44.339954" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="LEDs"
|
||||
inkscape:label="LEDs"
|
||||
style="display:inline"
|
||||
transform="translate(-68.791597,5.973336)">
|
||||
<g
|
||||
id="led0-path">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path877"
|
||||
d="m 484.99999,289.92309 -182.37295,10e-6"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
y="286.4231"
|
||||
x="299.12704"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect879"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
inkscape:label="#rect881"
|
||||
y="289.4231"
|
||||
x="485"
|
||||
height="1"
|
||||
width="1"
|
||||
id="led0-leader"
|
||||
style="color:#000000;text-align:start;display:inline;overflow:visible;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 18 KiB |
401
data/gnome/logitech-g-pro.svg
Normal file
@@ -0,0 +1,401 @@
|
||||
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="417.20001"
|
||||
height="407.25"
|
||||
viewBox="0 0 417.20001 407.24999"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.2 2405546, 2018-03-11"
|
||||
sodipodi:docname="logitech-g-pro.svg"
|
||||
inkscape:export-filename="/home/jimmac/logitech-g-pro.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<defs
|
||||
id="defs2">
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect4193"
|
||||
is_visible="true" />
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect4185"
|
||||
is_visible="true" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.9881757"
|
||||
inkscape:cx="89.311243"
|
||||
inkscape:cy="190.59507"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="LEDs"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
borderlayer="true"
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:pagecheckerboard="false"
|
||||
showguides="true"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1381"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="20"
|
||||
fit-margin-left="20"
|
||||
fit-margin-bottom="20"
|
||||
fit-margin-right="0"
|
||||
inkscape:guide-bbox="true"
|
||||
guidetolerance="10"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
inkscape:snap-global="true"
|
||||
inkscape:snap-object-midpoints="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid956"
|
||||
originx="-68.791593"
|
||||
originy="1.2767161" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<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="Device"
|
||||
inkscape:label="Device"
|
||||
transform="translate(-68.791597,-394.02675)"
|
||||
style="display:inline" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="Buttons"
|
||||
inkscape:label="Buttons"
|
||||
style="display:inline"
|
||||
transform="translate(-68.791597,5.973336)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;fill:#d3d3ce;fill-opacity:1;stroke:#babdb6;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 266.16642,15.04496 c -22.92467,4.66104 -61.30054,24.9861 -69.63884,36.00461 -12.61957,47.68515 -14.80528,106.34213 -15.92423,155.87459 -2.00552,88.77814 32.07323,172.95939 100.58708,173.36506 46.62862,0.10701 67.422,-29.01299 84.50986,-68.69579 14.62944,-39.36304 14.98472,-73.16931 15.71414,-103.07446 0.40991,-66.33641 -5.20115,-105.262 -13.70975,-157.25734 C 354.76319,35.15715 299.72236,14.28047 297.61469,15.04496 v 5.05311 h -3.45953 v -5.05311 l -25.2862,3.5e-4 v 5.05276 l -2.70254,-10e-6 z"
|
||||
id="path870"
|
||||
sodipodi:nodetypes="ccscccccccccccc" />
|
||||
<path
|
||||
style="display:inline;fill:#989896;stroke:#babdb6;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
|
||||
d="M 229.17383 21.009766 C 229.00748 20.992194 228.88813 20.993688 228.82227 21.017578 L 228.82227 26.072266 L 225.36328 26.072266 L 225.36328 21.017578 L 200.07812 21.019531 L 200.07812 26.072266 L 197.375 26.072266 L 197.375 21.017578 C 174.45033 25.678618 136.07463 46.004927 127.73633 57.023438 C 116.35922 100.01374 113.47533 151.86101 112.19531 197.96094 L 112.19727 197.96289 L 194.28711 159.88281 C 194.19011 159.92441 192.73412 179.58139 211.27148 179.11133 C 229.80884 178.64127 228.7988 160.0586 228.82227 160.05078 L 312.53125 197.98242 L 312.58008 197.88281 C 312.02168 141.36823 306.68242 104.71806 298.91211 57.234375 C 286.37504 41.63316 234.33067 21.554483 229.17383 21.009766 z "
|
||||
id="path1006"
|
||||
transform="translate(68.791597,-5.973336)" />
|
||||
<rect
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:0.99999982;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="button2"
|
||||
width="21.314863"
|
||||
height="55.109035"
|
||||
x="270.83594"
|
||||
y="53.880791"
|
||||
rx="10.657432"
|
||||
ry="11.054664"
|
||||
inkscape:label="#button2" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;fill:none;fill-opacity:1;stroke:#babdb6;stroke-width:10;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="led0"
|
||||
sodipodi:type="arc"
|
||||
sodipodi:cx="-328.60678"
|
||||
sodipodi:cy="280.97754"
|
||||
sodipodi:rx="13.376111"
|
||||
sodipodi:ry="13.525835"
|
||||
sodipodi:start="0.78539816"
|
||||
sodipodi:end="5.4977871"
|
||||
sodipodi:arc-type="arc"
|
||||
d="m -319.14844,290.54175 a 13.376111,13.525835 0 0 1 -18.91668,0 13.376111,13.525835 0 0 1 0,-19.12842 13.376111,13.525835 0 0 1 18.91668,0"
|
||||
sodipodi:open="true"
|
||||
transform="rotate(-90)"
|
||||
inkscape:label="#led0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;fill:#d3d3ce;fill-opacity:1;stroke:#bfc2bb;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 297.61497,15.045758 v 5.052735 h -0.004 c -0.072,38.851502 0.17641,91.903097 0.004,129.455077 l 76.24024,35.0039 C 371.4683,138.46428 370.62141,92.883297 359.46263,43.866071 348.69198,36.04897 332.00497,28.07624 318.64622,22.491071 307.62271,18.054789 298.7509,15.065752 297.61497,15.045758 Z"
|
||||
id="button1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 183.47044,134.90318 -3.23828,3.46679 -2.36328,40.83203 3.375,2.76368 c 0.0158,-0.0318 0.0292,-0.0639 0.0449,-0.0957 0.4971,-15.01188 1.2161,-30.49256 2.37305,-45.99218 -0.0654,-0.32133 -0.12562,-0.6554 -0.19141,-0.97461 z"
|
||||
id="button4" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 180.98802,191.98911 -3.65625,3.90235 0.70171,41.21448 3.55024,4.1781 c -0.0255,-0.32903 -0.0218,-0.78636 -0.0254,-1.21094 -0.88777,-10.87151 -1.20752,-21.97334 -0.95508,-33.14844 0.11017,-4.87659 0.24499,-9.90124 0.38477,-14.93555 z"
|
||||
id="button3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccsc" />
|
||||
<path
|
||||
style="display:inline;opacity:1;fill:#d3d3ce;fill-opacity:1;stroke:#babdb6;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 267.69435,112.88968 25.82029,0.0837 0.40098,45.62246 c -3.09214,13.17174 -23.47755,15.50099 -27.35134,0 z"
|
||||
id="rect1003"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<rect
|
||||
inkscape:label="#button5"
|
||||
ry="5.2884812"
|
||||
rx="6.152226"
|
||||
y="132.22084"
|
||||
x="273.28256"
|
||||
height="31.288317"
|
||||
width="13.468106"
|
||||
id="button5"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;fill:#d3d3ce;fill-opacity:1;stroke:#babdb6;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect985"
|
||||
width="25.286205"
|
||||
height="35.886375"
|
||||
x="268.86896"
|
||||
y="15.044975"
|
||||
rx="0"
|
||||
ry="0" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;fill:#d3d3ce;fill-opacity:1;stroke:#bfc2bb;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 266.16185,15.045758 c -18.53203,3.769004 -47.15067,17.769904 -61.84571,28.81836 -11.15926,49.01809 -14.18353,94.599442 -16.57028,140.693352 l 75.52927,-35.0039 2.89062,-129.455077 h -0.004 z"
|
||||
id="button0"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc"
|
||||
inkscape:label="#button0" />
|
||||
<path
|
||||
style="display:inline;fill:#d3d3ce;stroke:#babdb6;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
|
||||
d="M 132.05273 52.619141 C 130.22394 54.195066 128.75358 55.679201 127.73633 57.023438 C 116.71194 98.680923 113.6505 148.70889 112.30664 193.71484 L 112.35938 193.70117 L 116.07812 191.96875 C 117.08353 147.52982 122.45967 94.477962 132.07227 52.640625 C 132.0735 52.635269 132.0547 52.625295 132.05273 52.619141 z "
|
||||
transform="translate(68.791597,-5.973336)"
|
||||
id="path1008" />
|
||||
<path
|
||||
style="display:inline;fill:#d3d3ce;stroke:#babdb6;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
|
||||
d="M 294.34961 52.697266 C 302.02365 91.016721 306.47025 145.70637 307.9375 192.13477 L 312.22852 194.4668 L 312.54297 194.60547 C 311.81356 139.93715 306.53143 103.79539 298.91211 57.234375 C 297.72345 55.755196 296.17495 54.236496 294.34961 52.697266 z "
|
||||
id="path1010"
|
||||
transform="translate(68.791597,-5.973336)" />
|
||||
<g
|
||||
id="button4-path">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path964"
|
||||
d="M 69.397827,158.3947 H 177.72623"
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
inkscape:label="#rect875"
|
||||
style="color:#000000;text-align:end;overflow:visible;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button4-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="68.806679"
|
||||
y="157.8947" />
|
||||
<rect
|
||||
y="154.8947"
|
||||
x="174.22623"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect974"
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
</g>
|
||||
<g
|
||||
id="button3-path">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 69.516354,216.62752 H 176.10094"
|
||||
id="path966"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
y="216.12752"
|
||||
x="68.814278"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button3-leader"
|
||||
style="color:#000000;text-align:end;overflow:visible;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#rect875" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect976"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="172.60094"
|
||||
y="213.12752" />
|
||||
</g>
|
||||
<g
|
||||
id="button5-path">
|
||||
<rect
|
||||
y="147.48535"
|
||||
x="485"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button5-leader"
|
||||
style="color:#000000;text-align:start;overflow:visible;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#rect871" />
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 484.55132,147.9915 H 280.86242"
|
||||
id="path51"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect53"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="276.5166"
|
||||
y="144.36501" />
|
||||
</g>
|
||||
<g
|
||||
id="button2-path"
|
||||
inkscape:label="#g997">
|
||||
<rect
|
||||
inkscape:label="#rect869"
|
||||
y="80.93531"
|
||||
x="485"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button2-leader"
|
||||
style="color:#000000;text-align:start;overflow:visible;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round" />
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 281.49336,81.435307 203.01408,2e-6"
|
||||
id="path908"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect910"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="277.99338"
|
||||
y="77.935318" />
|
||||
</g>
|
||||
<g
|
||||
id="button1-path"
|
||||
inkscape:label="#g1002">
|
||||
<rect
|
||||
inkscape:label="#rect867"
|
||||
style="color:#000000;text-align:start;overflow:visible;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button1-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="485"
|
||||
y="52.581367" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 329.18291,53.081369 H 485.00002"
|
||||
id="path958"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect968"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="325.29486"
|
||||
y="49.581367" />
|
||||
</g>
|
||||
<g
|
||||
id="button0-path"
|
||||
inkscape:label="#button0-path">
|
||||
<rect
|
||||
inkscape:label="#rect871"
|
||||
style="color:#000000;text-align:end;overflow:visible;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button0-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="68.718681"
|
||||
y="52.581367" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path960"
|
||||
d="m 236.34967,53.081367 -166.192195,2e-6"
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
y="49.581367"
|
||||
x="232.84967"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect970"
|
||||
style="color:#000000;overflow:visible;opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="ccccsccsccccc"
|
||||
id="led1"
|
||||
d="m 381.38813,191.93864 c 0.0522,5.34015 0.0617,10.85826 0.0263,16.58033 -0.72942,29.90515 -1.0847,63.71142 -15.71414,103.07446 -17.08786,39.6828 -37.88124,68.8028 -84.50986,68.69579 -68.51385,-0.40567 -102.5926,-84.58692 -100.58708,-173.36506 0.11095,-4.91156 0.2425,-9.86517 0.38356,-14.93656 l 2.19839,0.0215 c -0.13796,4.95985 -0.26661,11.86142 -0.37513,16.66495 -1.96142,86.82554 31.36807,166.8792 98.37558,167.27594 45.60344,0.10466 65.93966,-26.09877 82.65183,-64.90878 14.30779,-38.49728 14.65526,-71.56001 15.36865,-100.80742 0.0346,-5.59622 0.0253,-13.00199 -0.0257,-18.22469 z"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;fill:#babdb6;fill-opacity:1;stroke:#babdb6;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="#led1" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="LEDs"
|
||||
inkscape:label="LEDs"
|
||||
style="display:inline"
|
||||
transform="translate(-68.791597,5.973336)">
|
||||
<g
|
||||
id="led0-path">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path877"
|
||||
d="m 485,329.52026 -203.94584,0"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
y="326.02026"
|
||||
x="277.47754"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect879"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
inkscape:label="#rect881"
|
||||
y="329.02026"
|
||||
x="485"
|
||||
height="1"
|
||||
width="1"
|
||||
id="led0-leader"
|
||||
style="color:#000000;text-align:start;display:inline;overflow:visible;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round" />
|
||||
</g>
|
||||
<g
|
||||
id="led1-path">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 484.99745,272.95285 -105.75862,0"
|
||||
id="path4525"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;text-align:start;display:inline;overflow:visible;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="led1-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="485"
|
||||
y="272.45285"
|
||||
inkscape:label="#rect881" />
|
||||
<rect
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect4544"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="375.73883"
|
||||
y="269.45285" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 22 KiB |
1
data/gnome/logitech-g102-g203.svg
Symbolic link
@@ -0,0 +1 @@
|
||||
logitech-g-pro.svg
|
||||
479
data/gnome/logitech-g402.svg
Normal file
@@ -0,0 +1,479 @@
|
||||
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="467.83105"
|
||||
height="400.87393"
|
||||
viewBox="0 0 467.83105 398.87393"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="logitech-g402.svg"
|
||||
inkscape:export-filename="/home/daniele/Scrivania/logitech-g402.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.8284271"
|
||||
inkscape:cx="247.98208"
|
||||
inkscape:cy="192.40531"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="Device"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
borderlayer="true"
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:pagecheckerboard="false"
|
||||
showguides="true"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="992"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-global="false"
|
||||
fit-margin-top="20"
|
||||
fit-margin-bottom="20"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid956"
|
||||
originx="-16.168953"
|
||||
originy="-1.1260801" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<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 />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="Device"
|
||||
inkscape:label="Device"
|
||||
transform="translate(-16.168953,-400)"
|
||||
style="display:inline">
|
||||
<g
|
||||
transform="translate(-374,-4.864278e-6)"
|
||||
id="g1170">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path981"
|
||||
d="m 617.52893,453.41998 -49.99065,26.66899 c -2.22449,1.86937 -2.81832,3.35837 -3.6652,5.83317 l -15.9563,53.34684 c -0.49748,2.25523 -0.34218,3.74811 0.48513,6.46679 l 3.99946,10.9325 -3.53186,0.74244 -1.35901,12.37091 -1.50378,2.8507 2.09912,18.55549 c 0,0 -13.03638,4.81768 -18.22998,15.00854 -5.19361,10.19086 -9.29541,53.53534 -6.03613,59.82001 3.25927,6.28467 25.6018,33.9057 28.70703,40.07849 3.10522,6.17279 24.79553,45.22613 30.93054,51.77106 6.13501,6.54492 35.79895,19.27618 35.79895,19.27618 6.39358,-5.0822 15.98738,-6.80155 23.61682,-0.45557 0,0 31.72192,-10.76812 43.56091,-26.60644 11.83899,-15.83832 24.57691,-52.0235 24.57691,-52.0235 0,0 -2.04663,-1.98694 -2.04663,-9.06775 0,-7.08081 3.24377,-9.90655 3.24377,-9.90655 l -7.41565,-77.33204 c 0,0 0.90478,-68.51501 -1.01514,-76.49939 -1.57946,-6.56849 -5.90589,-29.81348 -7.88675,-38.02183 -0.42699,-1.76936 -0.95122,-1.65743 -2.07882,-3.29921 l -52.65222,-36.341 4.00378,32.1344 h -28.47082 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#d3d3ce;fill-opacity:1;stroke:#babdb6;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
sodipodi:nodetypes="ccccccccccsccsccscsccssccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccscssccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1014"
|
||||
d="m 648.06347,618.15601 34.51828,10.05586 c 2.62858,0.8078 3.9256,5.47034 3.9256,5.47034 l -0.44831,35.46611 23.5331,26.29168 c 0,0 -9.4414,38.41029 -27.23181,57.70209 -11.60967,12.58946 -39.46726,23.54443 -39.46726,23.54443 0,0 -4.87562,-48.51623 -9.30469,-56.255 -4.42908,-7.73877 -35.48734,-18.11903 -50.81543,-30.61249 -5.82123,-4.7447 -15.27906,-16.55719 -15.27906,-16.55719 l -4.00329,-23.86047 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#d3d3ce;fill-opacity:1;stroke:#bfc2bb;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccsc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1144"
|
||||
d="m 620.3461,775.42623 3.91771,-44.34657 c 1.3829,-6.28113 -0.99643,-10.76025 -6.48071,-12.64329 0,0 -33.9759,-17.94313 -41.16454,-25.32697 -7.18863,-7.38383 -16.89702,-24.84664 -16.89702,-24.84664"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;vector-effect:none;fill:none;fill-opacity:1;stroke:#babdb6;stroke-width:8;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="led1"
|
||||
sodipodi:type="arc"
|
||||
sodipodi:cx="-664.05457"
|
||||
sodipodi:cy="598.10364"
|
||||
sodipodi:rx="12.162673"
|
||||
sodipodi:ry="12.162673"
|
||||
sodipodi:start="0.78539816"
|
||||
sodipodi:end="5.4977871"
|
||||
sodipodi:arc-type="arc"
|
||||
d="m -655.45426,606.70395 a 12.162673,12.162673 0 0 1 -17.20061,0 12.162673,12.162673 0 0 1 0,-17.20062 12.162673,12.162673 0 0 1 17.20061,0"
|
||||
sodipodi:open="true"
|
||||
transform="rotate(-90)"
|
||||
inkscape:label="#path1012" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccsccsc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1030"
|
||||
d="m 548.10584,591.18781 -1.39021,19.03606 c 0,0 -6.51942,1.07248 -9.54983,9.44719 -3.03041,8.37471 -8.01844,25.6823 -7.19278,55.16199 -3.80454,-3.92381 -8.20043,-7.54825 -7.93855,-14.11229 0.0565,-12.69733 0.50177,-31.56063 5.66468,-49.88965 3.26585,-11.59423 10.35698,-16.87164 20.40669,-19.6433 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#d9dad7;fill-opacity:1;stroke:#babdb6;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="button0"
|
||||
d="m 616.72979,453.87813 -43.21475,23.25557 -2.30905,111.85791 -3.27924,2.29913 8.95587,40.68384 43.49634,-20.81641 c 0,0 -6.29272,-57.3948 -6.04248,-82.96182 0.25025,-25.56702 2.39331,-74.31822 2.39331,-74.31822 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
sodipodi:nodetypes="ccccccsc"
|
||||
inkscape:label="#path1060" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="button1"
|
||||
d="m 641.35924,447.84438 c 0,0 6.82136,40.56938 7.71833,77.06871 0.89697,36.49932 0.60175,77.20425 0.60175,77.20425 l 43.91543,12.95245 c 0,0 2.9472,-62.03698 1.5412,-81.15454 -1.4061,-19.11755 -6.51723,-50.97735 -8.90483,-54.50845 -2.3876,-3.5311 -44.87188,-31.56242 -44.87188,-31.56242 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
sodipodi:nodetypes="cscccsc"
|
||||
inkscape:label="#path1062" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1066"
|
||||
d="m 624.73297,570.54019 2.51941,13.45651 14.86756,-0.0507 1.26654,-13.4599 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="button2"
|
||||
width="17.152637"
|
||||
height="51.954956"
|
||||
x="623.8761"
|
||||
y="503.84464"
|
||||
rx="8.5763187"
|
||||
ry="8.5763187"
|
||||
inkscape:label="#rect1068" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="button7"
|
||||
d="m 569.97595,534.59994 -16.73181,-6.63336 13.09595,-44.4487 3.95538,-3.11892 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
inkscape:label="#path1098" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="button6"
|
||||
d="m 569.97595,534.59994 -15.81811,4.41446 13.12378,48.26233 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
inkscape:label="#path1100" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 550.97571,556.55099 -1.73137,22.23376 c 0,0 -8.07466,-0.0385 -6.10341,-6.67814 0.79661,-2.68321 1.88213,-11.10134 3.54027,-13.80998 2.44498,-3.99399 4.29451,-1.74564 4.29451,-1.74564 z"
|
||||
id="button5"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccsc"
|
||||
inkscape:label="#path1473" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="button4"
|
||||
d="m 553.91685,576.77039 3.78851,43.20785 -3.52893,1.40018 -4.18952,-2.67337 -1.94029,-38.13895 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
sodipodi:nodetypes="cccccc"
|
||||
inkscape:label="#path1118" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="button3"
|
||||
d="m 557.29072,626.42287 -4.13718,-0.69442 -1.90659,6.11048 8.04212,38.1661 3.30713,3.0868 4.6499,-1.78876 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
inkscape:label="#path1120" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="led0"
|
||||
d="m 554.07316,558.40614 18.36886,76.63506 -10.78213,5.31523 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
inkscape:label="#path1122" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1138"
|
||||
d="m 561.0357,599.31803 1.68542,4.21409 -3.19735,5.27031 -0.72068,-4.52978 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1140"
|
||||
d="m 564.53845,610.12329 0.75,2.84987 -3.50226,8.03142 -0.75,-4.13156 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1142"
|
||||
d="m 566.94537,619.35785 1.45849,3.46056 -4.29748,11.03294 -1.04318,-4.82295 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 608.6358,526.99557 v 7.97553 l -3.83318,-3.83321 z"
|
||||
id="path1148"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="Buttons"
|
||||
inkscape:label="Buttons"
|
||||
style="display:inline"
|
||||
transform="translate(-16.168953)">
|
||||
<g
|
||||
id="button0-path"
|
||||
inkscape:label="#g442">
|
||||
<path
|
||||
sodipodi:nodetypes="ccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path954"
|
||||
d="m 234.68702,62.49186 41.9857,-41.98571 H 483"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
y="62"
|
||||
x="230"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect952"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
inkscape:label="#rect865"
|
||||
y="20"
|
||||
x="483"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button0-leader"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round" />
|
||||
</g>
|
||||
<g
|
||||
id="button1-path"
|
||||
inkscape:label="#g437">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 275.03741,60.50615 H 483.05562"
|
||||
id="path958"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect968"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="273"
|
||||
y="57" />
|
||||
<rect
|
||||
inkscape:label="#rect867"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button1-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="483"
|
||||
y="60" />
|
||||
</g>
|
||||
<g
|
||||
id="button2-path"
|
||||
inkscape:label="#g432">
|
||||
<path
|
||||
sodipodi:nodetypes="ccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path960"
|
||||
d="M 483.15129,100.50615 H 266.97374 l -7.07445,7.07445"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
y="106.05299"
|
||||
x="254.86905"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect970"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
inkscape:label="#rect869"
|
||||
y="100"
|
||||
x="483"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button2-leader"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round" />
|
||||
</g>
|
||||
<g
|
||||
id="button6-path"
|
||||
inkscape:label="#g427">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 483,140.50615 H 189.32589"
|
||||
id="path962"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect972"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="188"
|
||||
y="137" />
|
||||
<rect
|
||||
inkscape:label="#rect871"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button6-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="483"
|
||||
y="140" />
|
||||
</g>
|
||||
<g
|
||||
id="button4-path"
|
||||
inkscape:label="#g402">
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 17.16895,226.39549 151.60272,0.0884 8.22787,-9.92565"
|
||||
id="path896"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<rect
|
||||
y="-219.98177"
|
||||
x="-181.00188"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect1297"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
transform="scale(-1)" />
|
||||
<rect
|
||||
inkscape:label="#rect873"
|
||||
y="-226.98393"
|
||||
x="-17.168953"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button4-leader"
|
||||
style="color:#000000;text-align:end;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
transform="scale(-1)" />
|
||||
</g>
|
||||
<g
|
||||
id="button7-path"
|
||||
inkscape:label="#g300">
|
||||
<rect
|
||||
inkscape:label="#rect873"
|
||||
y="-62.912788"
|
||||
x="-17.168953"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button7-leader"
|
||||
style="color:#000000;text-align:end;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
transform="scale(-1)" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path914"
|
||||
d="M 17.317611,62.412787 H 178.90504 l 15.75447,23.87718"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect912"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="191.28058"
|
||||
y="85.438072" />
|
||||
</g>
|
||||
<g
|
||||
id="button3-path"
|
||||
inkscape:label="#g407">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1295"
|
||||
d="m 17.294405,266.46958 168.568675,0.0407"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
transform="scale(-1)"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect1301"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="-191.68813"
|
||||
y="-269.40173" />
|
||||
<rect
|
||||
transform="scale(-1)"
|
||||
style="color:#000000;text-align:end;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round"
|
||||
id="button3-leader"
|
||||
width="1.1351269"
|
||||
height="1"
|
||||
x="-17.294409"
|
||||
y="-266.98993"
|
||||
inkscape:label="#rect873" />
|
||||
</g>
|
||||
<g
|
||||
id="button5-path"
|
||||
inkscape:label="#g422">
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 483.13134,180.50551 -295.64539,-0.25 -14.35505,-20.22553"
|
||||
id="path890"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<rect
|
||||
y="-163.30751"
|
||||
x="-175.13875"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect894"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
transform="scale(-1)" />
|
||||
<rect
|
||||
transform="scale(-1)"
|
||||
style="color:#000000;text-align:start;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button5-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="-484.00677"
|
||||
y="-181.00594"
|
||||
inkscape:label="#rect873" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="LEDs"
|
||||
inkscape:label="LEDs"
|
||||
style="display:inline"
|
||||
transform="translate(-16.168953)">
|
||||
<g
|
||||
id="led0-path"
|
||||
inkscape:label="#g417">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 191.93858,220.50615 H 483.10224"
|
||||
id="path966"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect976"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="188"
|
||||
y="217" />
|
||||
<rect
|
||||
inkscape:label="#rect875"
|
||||
style="color:#000000;text-align:start;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="led0-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="483"
|
||||
y="220" />
|
||||
</g>
|
||||
<g
|
||||
id="led1-path"
|
||||
inkscape:label="#g412">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path877"
|
||||
d="M 214.64438,260.50615 H 483"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
y="257"
|
||||
x="210"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect879"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
inkscape:label="#rect881"
|
||||
y="260"
|
||||
x="483"
|
||||
height="1"
|
||||
width="1"
|
||||
id="led1-leader"
|
||||
style="color:#000000;text-align:start;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 28 KiB |
@@ -213,7 +213,7 @@
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 608.6358,526.99557 v 7.97553 l -3.83318,-3.83321 z"
|
||||
id="path1148"
|
||||
id="button10"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
|
||||
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
1190
data/gnome/logitech-g600.svg
Normal file
|
After Width: | Height: | Size: 95 KiB |
331
data/gnome/logitech-g603.svg
Normal file
@@ -0,0 +1,331 @@
|
||||
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="409.2084"
|
||||
height="411.271"
|
||||
viewBox="0 0 409.2084 411.27099"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="logitech-g603.svg"
|
||||
inkscape:export-filename="/home/jimmac/logitech-g403.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.656854"
|
||||
inkscape:cx="141.15425"
|
||||
inkscape:cy="248.38223"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="Device"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
borderlayer="true"
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:pagecheckerboard="false"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="-4"
|
||||
inkscape:window-y="-4"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="20"
|
||||
fit-margin-left="20"
|
||||
fit-margin-bottom="20"
|
||||
fit-margin-right="0"
|
||||
inkscape:snap-smooth-nodes="false"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:guide-bbox="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid956"
|
||||
originx="-68.791593"
|
||||
originy="1.2767161" />
|
||||
<sodipodi:guide
|
||||
position="126.53125,259.03126"
|
||||
orientation="0,1"
|
||||
id="guide4772"
|
||||
inkscape:locked="false" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<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 />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="Device"
|
||||
inkscape:label="Device"
|
||||
transform="translate(-68.791597,-390.00576)"
|
||||
style="display:inline">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#d3d3ce;fill-opacity:1;stroke:#babdb6;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 175.34499,424.02062 c -24.661,4.08226 -60.18056,22.01925 -69.18502,28.18484 -7.932853,5.43184 -10.801193,13.70196 -10.925233,20.94538 -0.72438,42.30084 10.273313,88.0482 7.561093,130.50252 -1.21026,18.94414 -7.437413,51.01218 -9.969593,64.24176 -1.65073,6.85296 -2.50133,13.87513 -2.53464,20.92508 2.7e-4,50.2338 40.610433,90.95628 90.705683,90.95655 45.46938,-0.0495 82.39643,-34.07041 89.82748,-79.05254 10.66083,-64.53278 10.42629,-136.39723 11.98541,-204.91567 0.28464,-12.50912 -1.94334,-23.29335 -8.32377,-31.80289 -13.26086,-21.57098 -66.73071,-40.02924 -66.73071,-40.02924 v 7.19061 h -32.4107 z"
|
||||
id="path870"
|
||||
sodipodi:nodetypes="cssscccssccccc" />
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 208.56756,431.16702 -3,141.31424 c -0.14923,7.02936 -6.07063,12.69123 -13.61129,12.69123 -7.54065,0 -13.46205,-5.66187 -13.61128,-12.69123 l -3,-141.31424 z"
|
||||
id="rect913"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cssscc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cscsc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path950"
|
||||
d="m 95.373251,486.43435 c 38.955159,101.12102 48.667459,140.67087 51.422819,177.84397 2.03646,27.47435 -36.96151,79.62933 -36.96151,79.62933 0,0 -24.033873,-37.15986 -19.463976,-61.45137 10.258966,-54.53208 19.996276,-75.99616 5.002667,-196.02193 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#bfc2bb;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 104.9358,539.80779 c 2.40195,-0.25238 2.7176,0.9048 2.96999,3.30675 l 5.69164,54.1678 c 0.25238,2.40194 -1.47813,4.53882 -3.88008,4.7912 -2.40195,0.25239 -5.44876,-8.75375 -5.55682,-11.1665 l -2.02953,-45.3135 c -0.10806,-2.41275 0.40286,-5.53337 2.8048,-5.78575 z"
|
||||
id="button4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="sssssss"
|
||||
inkscape:label="#rect921" />
|
||||
<path
|
||||
sodipodi:nodetypes="sssssss"
|
||||
inkscape:connector-curvature="0"
|
||||
id="button3"
|
||||
d="m 109.77779,602.64876 c 2.40195,-0.25239 4.53882,1.47813 4.79121,3.88007 l 5.69164,54.1678 c 0.25238,2.40195 -1.47814,4.53883 -3.88008,4.79121 -2.40195,0.25238 -7.77772,-8.87659 -7.89239,-11.28904 l -1.91843,-40.36308 c -0.11466,-2.41244 0.8061,-10.93458 3.20805,-11.18696 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
inkscape:label="#path924" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="button2"
|
||||
width="23.155933"
|
||||
height="69.467796"
|
||||
x="180.55382"
|
||||
y="454.99139"
|
||||
rx="11.577967"
|
||||
ry="11.577967"
|
||||
inkscape:label="#rect932" />
|
||||
<path
|
||||
sodipodi:nodetypes="cssscc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="button5"
|
||||
d="m 201.20722,545.97605 -0.65676,17.92859 c -0.16469,4.49569 -3.83301,8.12045 -8.59419,8.12045 -4.76117,0 -8.49995,-3.62273 -8.59417,-8.12045 l -0.65677,-17.92859 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
inkscape:label="#path942" />
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#bfc2bb;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 281.45725,491.14612 c -30.15796,102.59778 -42.11413,137.63368 -50.74442,173.1322 -6.50823,26.76995 22.13723,79.62933 22.13723,79.62933 0,0 13.58979,-21.97214 16.0745,-32.60727 16.80373,-71.92371 12.53269,-220.15426 12.53269,-220.15426 z"
|
||||
id="path946"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cscsc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccsc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="button0"
|
||||
d="m 174.91314,423.64614 3.0021,129.78071 -48.65044,25.07759 -32.826242,-92.02794 c -1.027151,-19.85446 -0.810142,-28.0624 15.700932,-37.87909 17.32775,-10.30224 41.981,-20.75843 62.77365,-24.95127 z"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#d3d3ce;fill-opacity:1;stroke:#bfc2bb;stroke-width:1.98825693;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
inkscape:label="#path948" />
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#d3d3ce;fill-opacity:1;stroke:#bfc2bb;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 207.75569,423.97641 -1.77476,128.93066 47.9684,25.54626 27.50793,-87.30721 c 4.86457,-36.68335 -44.6715,-55.30429 -73.70157,-67.16971 z"
|
||||
id="button1"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:label="#path944" />
|
||||
<g
|
||||
style="display:inline"
|
||||
id="g1304"
|
||||
transform="translate(337.51617,-37.32483)">
|
||||
<ellipse
|
||||
ry="1.9375004"
|
||||
rx="1.8137393"
|
||||
cy="614.46423"
|
||||
cx="-145.51083"
|
||||
id="ellipse1298"
|
||||
style="fill:#babdb6;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="Buttons"
|
||||
inkscape:label="Buttons"
|
||||
style="display:inline"
|
||||
transform="translate(-68.791597,9.994236)">
|
||||
<g
|
||||
id="button1-path"
|
||||
inkscape:label="#g131">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 242.94764,50.505764 H 477"
|
||||
id="path958"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect968"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="237"
|
||||
y="47.005764" />
|
||||
<rect
|
||||
inkscape:label="#rect867"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button1-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="477"
|
||||
y="50.005764" />
|
||||
</g>
|
||||
<g
|
||||
id="button0-path"
|
||||
inkscape:label="#g141">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path960"
|
||||
d="M 477,130.50576 H 161.34398"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
y="127.00576"
|
||||
x="157"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect970"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
inkscape:label="#rect871"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button0-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="477"
|
||||
y="130.00577" />
|
||||
</g>
|
||||
<g
|
||||
id="button4-path"
|
||||
inkscape:label="#g151">
|
||||
<path
|
||||
sodipodi:nodetypes="ccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path964"
|
||||
d="M 109.31232,181.51438 137.74787,210.44326 477,210.50576"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
inkscape:label="#rect875"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button4-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="477"
|
||||
y="210.00577" />
|
||||
<rect
|
||||
y="177"
|
||||
x="105"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect974"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
</g>
|
||||
<g
|
||||
id="button2-path"
|
||||
inkscape:label="#g136">
|
||||
<rect
|
||||
inkscape:label="#rect869"
|
||||
y="90.00576"
|
||||
x="477"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button2-leader"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round" />
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 195.97852,108.49147 17.9857,-17.98571 H 477"
|
||||
id="path908"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect910"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="194"
|
||||
y="104" />
|
||||
</g>
|
||||
<g
|
||||
id="button3-path"
|
||||
inkscape:label="#g156">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 114.17805,250.50576 H 477"
|
||||
id="path966"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect976"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="108"
|
||||
y="247.00577" />
|
||||
<rect
|
||||
y="250.00575"
|
||||
x="477"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button3-leader"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#rect875" />
|
||||
</g>
|
||||
<g
|
||||
id="button5-path"
|
||||
inkscape:label="#g146"
|
||||
transform="translate(0,-6)">
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 476.55132,170.50615 H 193.34398"
|
||||
id="path51"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect53"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="189"
|
||||
y="167" />
|
||||
<rect
|
||||
y="170"
|
||||
x="477"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button5-leader"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#rect871" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="LEDs"
|
||||
inkscape:label="LEDs"
|
||||
style="display:inline"
|
||||
transform="translate(-68.791597,9.994236)" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 18 KiB |
@@ -14,8 +14,8 @@
|
||||
viewBox="0 0 129.64583 129.64583"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
sodipodi:docname="G9.svg"
|
||||
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
|
||||
sodipodi:docname="logitech-g9.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
enable-background="new">
|
||||
<defs
|
||||
id="defs2">
|
||||
@@ -38,16 +38,16 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="108.9024"
|
||||
inkscape:cy="270.58583"
|
||||
inkscape:zoom="8.0000004"
|
||||
inkscape:cx="264.58829"
|
||||
inkscape:cy="370.72481"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="LEDs"
|
||||
inkscape:current-layer="Device"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="false"
|
||||
showguides="false"
|
||||
showguides="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-height="1016"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
@@ -55,8 +55,8 @@
|
||||
inkscape:guide-bbox="true"
|
||||
units="px"
|
||||
inkscape:snap-global="false"
|
||||
inkscape:measure-start="200.26,379.645"
|
||||
inkscape:measure-end="199.294,334.274">
|
||||
inkscape:measure-start="296.875,398.125"
|
||||
inkscape:measure-end="288.375,379.75">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid78" />
|
||||
@@ -71,12 +71,12 @@
|
||||
id="guide81"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="51.756014,88.614617"
|
||||
position="-0.18708866,88.492936"
|
||||
orientation="0,1"
|
||||
id="guide83"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="57.778386,76.729167"
|
||||
position="13.758333,76.993746"
|
||||
orientation="0,1"
|
||||
id="guide85"
|
||||
inkscape:locked="false" />
|
||||
@@ -156,13 +156,13 @@
|
||||
<path
|
||||
style="fill:#d9dad7;fill-opacity:1;stroke:#babdb6;stroke-width:0.61647916;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 34.611402,214.21326 -0.467722,5.00462 16.18317,-1.07576 0.04677,-4.77076 z"
|
||||
id="button3"
|
||||
id="button9"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="#path896" />
|
||||
<path
|
||||
style="fill:#d9dad7;fill-opacity:1;stroke:#babdb6;stroke-width:0.61647916;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 64.405272,212.43591 -14.066729,0.93544 0.02888,4.76741 13.98589,-0.84138 z"
|
||||
id="button4"
|
||||
id="button8"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:label="#path898" />
|
||||
@@ -184,14 +184,14 @@
|
||||
<path
|
||||
style="fill:#d9dad7;fill-opacity:1;stroke:#babdb6;stroke-width:0.61647916;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 24.274755,248.26339 c -0.124726,-9.60388 -0.342996,-10.78877 0.748354,-17.86696 0.576857,0.0935 1.153713,0.18709 1.73057,0.28063 -0.826308,5.86211 -1.652616,11.72422 -2.478924,17.58633 z"
|
||||
id="button6"
|
||||
id="button3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="#path4606" />
|
||||
<path
|
||||
style="fill:#d9dad7;fill-opacity:1;stroke:#babdb6;stroke-width:0.61647916;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 27.104469,228.7594 c -0.561265,-0.0779 -1.122531,-0.15591 -1.683796,-0.23386 0.919852,-4.78635 2.120338,-8.77758 3.671614,-12.95589 -0.662606,4.39658 -1.325212,8.79317 -1.987818,13.18975 z"
|
||||
id="button5"
|
||||
id="button4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="#path4608" />
|
||||
@@ -207,6 +207,20 @@
|
||||
id="button1"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="#path4612" />
|
||||
<path
|
||||
transform="translate(0,164.70833)"
|
||||
id="button6"
|
||||
d="m 62.980849,30.452818 a 0.06589785,0.06589785 0 0 0 -0.046,0.02066 l -1.13998,1.23145 a 0.06589785,0.06589785 0 0 0 0.002,0.09147 l 1.13947,1.139465 a 0.06589785,0.06589785 0 0 0 0.10697,-0.07338 l -0.50385,-1.113628 0.50488,-1.205093 a 0.06589785,0.06589785 0 0 0 -0.0636,-0.09095 z"
|
||||
style="display:inline;color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.25282338;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="#path1016" />
|
||||
<path
|
||||
transform="translate(0,164.70833)"
|
||||
id="button7"
|
||||
d="m 75.28463,30.433444 a 0.06589785,0.06589785 0 0 1 0.046,0.02066 l 1.13998,1.23145 a 0.06589785,0.06589785 0 0 1 -0.002,0.09147 l -1.13947,1.139465 a 0.06589785,0.06589785 0 0 1 -0.10697,-0.07338 l 0.50385,-1.113628 -0.50488,-1.205093 a 0.06589785,0.06589785 0 0 1 0.0636,-0.09095 z"
|
||||
style="display:inline;color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.25282338;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="#path1016-3" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
@@ -215,26 +229,26 @@
|
||||
transform="translate(0,-2.6458338)"
|
||||
style="display:inline">
|
||||
<g
|
||||
transform="matrix(0.26458333,0,0,0.26458333,40.502648,-13.272558)"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,40.502648,-1.1017221)"
|
||||
style="display:inline"
|
||||
id="button2-path"
|
||||
inkscape:label="#g146">
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 336.91912,170.14213 -225.57514,0.36405"
|
||||
d="M 336.91912,169.83277 147.21994,169.67013 109.21898,124.50618"
|
||||
id="path51"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect53"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="107.41756"
|
||||
y="166.91161" />
|
||||
x="106.00334"
|
||||
y="120.59612" />
|
||||
<rect
|
||||
y="169.75269"
|
||||
x="336.91913"
|
||||
y="169.31075"
|
||||
x="336.56558"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button2-leader"
|
||||
@@ -244,7 +258,7 @@
|
||||
<g
|
||||
transform="matrix(-0.26458333,0,0,-0.26458333,116.08398,94.455601)"
|
||||
style="display:inline"
|
||||
id="button3-path"
|
||||
id="button9-path"
|
||||
inkscape:label="#g146">
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
@@ -264,7 +278,7 @@
|
||||
x="438.04599"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button3-leader"
|
||||
id="button9-leader"
|
||||
style="color:#000000;text-align:end;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#rect871" />
|
||||
</g>
|
||||
@@ -323,13 +337,13 @@
|
||||
inkscape:label="#rect871" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.26458333,0,0,-0.26458333,13.573867,94.421678)"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,13.573867,4.9859563)"
|
||||
style="display:inline"
|
||||
id="button4-path"
|
||||
id="button8-path"
|
||||
inkscape:label="#g146">
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 438.04598,191.7488 H 193.48839 l -29.95691,-26.43012"
|
||||
d="m 438.04598,191.7488 -249.80759,-0.5 -23.58191,-19.43012"
|
||||
id="path51-1-9-6-8-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
@@ -338,21 +352,21 @@
|
||||
id="rect53-2-3-2-7-4"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="160.13437"
|
||||
y="161.68198" />
|
||||
x="161.75937"
|
||||
y="169.05698" />
|
||||
<rect
|
||||
y="191.3428"
|
||||
x="438.04599"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button4-leader"
|
||||
id="button8-leader"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#rect871" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(-0.26458333,0,0,-0.26458333,116.07548,106.30868)"
|
||||
style="display:inline"
|
||||
id="button5-path"
|
||||
id="button4-path"
|
||||
inkscape:label="#g146">
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
@@ -372,14 +386,14 @@
|
||||
x="438.04599"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button5-leader"
|
||||
id="button4-leader"
|
||||
style="color:#000000;text-align:end;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#rect871" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(-0.26458333,0,0,-0.26458333,116.05287,118.29899)"
|
||||
style="display:inline"
|
||||
id="button6-path"
|
||||
id="button3-path"
|
||||
inkscape:label="#g146">
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
@@ -399,8 +413,62 @@
|
||||
x="438.04599"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button3-leader"
|
||||
style="color:#000000;text-align:end;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#rect871" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(-0.29294531,0,0,0.26458333,70.05035,-34.688457)"
|
||||
style="display:inline"
|
||||
id="button6-path"
|
||||
inkscape:label="#g156">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 33.59277,251.21287 205.11339,-0.0974"
|
||||
id="path966-9-6"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect976-8-7"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="29.446411"
|
||||
y="247.53609" />
|
||||
<rect
|
||||
y="250.62447"
|
||||
x="238.5843"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button6-leader"
|
||||
style="color:#000000;text-align:end;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#rect875" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.26458333,0,0,0.26458333,40.372307,-13.288752)"
|
||||
style="display:inline"
|
||||
id="button7-path"
|
||||
inkscape:label="#g146">
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 336.91912,170.14213 -196.70014,0.23905"
|
||||
id="path51-1-6"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect53-0-7"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="137.97041"
|
||||
y="166.84467" />
|
||||
<rect
|
||||
y="169.75269"
|
||||
x="336.91913"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button7-leader"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#rect871" />
|
||||
</g>
|
||||
</g>
|
||||
@@ -411,13 +479,13 @@
|
||||
transform="translate(0,-2.6458338)"
|
||||
style="display:inline">
|
||||
<g
|
||||
transform="matrix(0.26458333,0,0,-0.26458333,13.686363,102.7808)"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,13.592814,20.269951)"
|
||||
style="display:inline"
|
||||
id="led0-path"
|
||||
inkscape:label="#g146">
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 438.04598,178.25732 H 151.75439 l -10.41041,-7.75114"
|
||||
d="m 438.04598,178.25732 -267.54159,0.25 -31.41041,-32.75114"
|
||||
id="path51-1-9-6-0"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
@@ -426,8 +494,8 @@
|
||||
id="rect53-2-3-2-2"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="137.02765"
|
||||
y="165.93933" />
|
||||
x="135.77765"
|
||||
y="141.93933" />
|
||||
<rect
|
||||
y="177.79317"
|
||||
x="438.04599"
|
||||
|
||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 26 KiB |
349
data/gnome/logitech-mx-anywhere2.svg
Normal file
@@ -0,0 +1,349 @@
|
||||
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="svg942"
|
||||
width="450"
|
||||
height="450"
|
||||
viewBox="0 0 450 450.00001"
|
||||
sodipodi:docname="logitech-mx-anywhere2.svg"
|
||||
inkscape:version="0.92.2 2405546, 2018-03-11">
|
||||
<metadata
|
||||
id="metadata948">
|
||||
<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>
|
||||
<defs
|
||||
id="defs946" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="3200"
|
||||
inkscape:window-height="1677"
|
||||
id="namedview944"
|
||||
showgrid="true"
|
||||
inkscape:object-paths="true"
|
||||
inkscape:object-nodes="false"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:zoom="5.6568542"
|
||||
inkscape:cx="132.29246"
|
||||
inkscape:cy="334.55769"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Device"
|
||||
inkscape:snap-object-midpoints="true"
|
||||
inkscape:snap-grids="false"
|
||||
inkscape:snap-to-guides="false"
|
||||
inkscape:snap-others="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:snap-bbox-midpoints="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid880" />
|
||||
</sodipodi:namedview>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="Device"
|
||||
inkscape:label="Device"
|
||||
style="display:inline"
|
||||
transform="translate(0,321.03999)">
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#d3d3ce;fill-opacity:1;fill-rule:evenodd;stroke:#babdb6;stroke-width:3.41371107px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 218.69405,-299.42426 c 23.35649,1.73474 46.18087,5.06587 68.35514,10.34733 23.75734,6.5434 34.95965,18.75684 40.44869,33.55046 14.75489,46.96997 14.92489,97.01791 12.09878,148.09014 -0.22053,69.160277 9.88471,151.952398 -41.25946,193.685563 C 257.44112,119.62007 184.10794,116.48359 139.99157,87.503464 100.63876,61.652557 96.65491,4.57244 95.843246,-38.897519 c -0.639505,-34.2499 -4.904947,-68.500891 -3.243152,-102.716411 1.744881,-35.9262 7.356301,-78.71605 13.841016,-107.01431 3.99526,-15.72475 12.19144,-29.89698 35.27502,-38.56736 23.0293,-5.08776 48.5148,-9.23085 76.97792,-12.22866 z"
|
||||
id="path958"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccassaccc" />
|
||||
<path
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#babdb6;stroke-width:2.04822683;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 219.40508,-294.00752 67.6238,14.41163 c 10.27506,3.52994 19.61317,7.79609 21.7283,17.7374 34.47843,139.54316 2.38187,235.179053 -22.17174,337.675524 -2.70961,6.974963 -4.75518,14.198956 -16.6288,17.737404 -33.62713,9.347182 -67.25427,11.307342 -100.8814,0 C 159.63341,88.719872 154.6317,82.405292 150.45098,75.817034 125.18112,-36.599477 94.771098,-127.54074 128.50096,-260.97161 c 1.682,-10.88963 9.98626,-14.60515 18.62426,-17.95912 z"
|
||||
id="path970"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccc" />
|
||||
<path
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#babdb6;stroke-width:2.38959765;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 191.52096,-288.19118 c 1.4779,64.07686 0.63073,131.09048 4.38208,189.294959 0.53834,8.352647 23.14409,12.010754 23.14409,12.010754 0,0 22.57181,-3.520747 23.2016,-11.833881 4.83394,-63.807432 1.5673,-125.647242 3.26713,-189.723552"
|
||||
id="path960"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cscsc" />
|
||||
<path
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#babdb6;stroke-width:2.04822683;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="M 300.42159,70.944985 C 339.27478,43.967826 336.69108,-80.871179 335.23506,-108.90368 325.41759,-45.455804 296.49373,32.142014 300.42159,70.944985 Z"
|
||||
id="path974"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#babdb6;stroke-width:3.41371107px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 91.703995,-152.38566 c -7.529254,25.22562 -5.874086,43.32648 -5.814066,51.60811 l 5.653792,1.441169 z"
|
||||
id="button3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="" />
|
||||
<path
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#babdb6;stroke-width:3.41371107px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 86.425202,-87.164219 c 1.984551,13.294118 0.345072,23.115228 8.757835,42.569729 l -2.771465,-46.006346 z"
|
||||
id="button4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#babdb6;stroke-width:2.38959765;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="M 219.40508,-293.35803 V -87.543322"
|
||||
id="path1908"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#d9dad7;fill-opacity:1;stroke:#babdb6;stroke-width:3.07234001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill"
|
||||
id="rect972"
|
||||
width="10.198998"
|
||||
height="20.619715"
|
||||
x="214.33723"
|
||||
y="-122.47431"
|
||||
ry="5.0994992" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#d9dad7;fill-opacity:1;stroke:#babdb6;stroke-width:3.07234001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill"
|
||||
id="button2"
|
||||
width="23.3599"
|
||||
height="23.830233"
|
||||
x="207.57869"
|
||||
y="-163.18437"
|
||||
ry="4.7033353"
|
||||
inkscape:label="" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#d9dad7;fill-opacity:1;stroke:#babdb6;stroke-width:3.07234001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill"
|
||||
id="rect966"
|
||||
width="30.414902"
|
||||
height="60.202698"
|
||||
x="203.64337"
|
||||
y="-248.47151"
|
||||
ry="8.4660034" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.04822683;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 136.54246,-257.72138 -16.3049,112.56651 63.0247,-0.6271 1.25422,-131.0663 z"
|
||||
id="button0"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="" />
|
||||
<path
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.04822683;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 299.43465,-259.28913 16.30489,112.56648 -63.0247,-0.6271 -1.25422,-131.0663 z"
|
||||
id="button1"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="" />
|
||||
<path
|
||||
style="display:inline;fill:none;fill-rule:evenodd;stroke:#babdb6;stroke-width:2.56880355px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 199.80869,-221.82015 -3.90101,2.25227 3.90101,2.25225"
|
||||
id="button5"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="" />
|
||||
<path
|
||||
style="display:inline;fill:none;fill-rule:evenodd;stroke:#babdb6;stroke-width:2.56880355px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 237.6341,-221.8517 3.90101,2.25227 -3.90101,2.25225"
|
||||
id="button6"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="Buttons"
|
||||
inkscape:label="Buttons"
|
||||
transform="translate(0,321.03999)"
|
||||
style="display:inline">
|
||||
<g
|
||||
id="button5-path"
|
||||
inkscape:label="">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path884"
|
||||
d="m 198.00952,-210.78264 -29.43205,29.43205 H 0.35355339"
|
||||
style="display:inline;fill:none;fill-rule:evenodd;stroke:#888a85;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<rect
|
||||
inkscape:label=""
|
||||
y="-181.85059"
|
||||
x="0.10401335"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button5-leader"
|
||||
style="text-align:end;display:inline;opacity:1;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
|
||||
<rect
|
||||
y="-214.28264"
|
||||
x="194.50952"
|
||||
height="7"
|
||||
width="7"
|
||||
id="rect2047"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
|
||||
</g>
|
||||
<g
|
||||
id="button3-path"
|
||||
inkscape:label="">
|
||||
<rect
|
||||
inkscape:label=""
|
||||
y="-125.62335"
|
||||
x="0.05242718"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button3-leader"
|
||||
style="text-align:end;display:inline;opacity:1;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2119"
|
||||
d="M 80.53685,-125.12076 H 0.51959257"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
y="-128.62076"
|
||||
x="77.03685"
|
||||
height="7"
|
||||
width="7"
|
||||
id="rect2047-9"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
|
||||
</g>
|
||||
<g
|
||||
id="button4-path"
|
||||
inkscape:label="">
|
||||
<rect
|
||||
inkscape:label=""
|
||||
y="-74.184525"
|
||||
x="0.0703125"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button4-leader"
|
||||
style="text-align:end;display:inline;opacity:1;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2121"
|
||||
d="M 81.835831,-73.68108 H 0.51959257"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
y="-77.181084"
|
||||
x="78.335831"
|
||||
height="7"
|
||||
width="7"
|
||||
id="rect2047-87"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
|
||||
</g>
|
||||
<g
|
||||
style="display:inline"
|
||||
id="button0-path"
|
||||
inkscape:label="">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2117"
|
||||
d="M 154.83858,-230.33824 96.384414,-288.7924 H 0.51959257"
|
||||
style="display:inline;fill:none;fill-rule:evenodd;stroke:#888a85;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<rect
|
||||
inkscape:label=""
|
||||
y="-289.29233"
|
||||
x="0.25592589"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button0-leader"
|
||||
style="text-align:end;display:inline;opacity:1;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
|
||||
<rect
|
||||
y="-233.83824"
|
||||
x="151.33858"
|
||||
height="7"
|
||||
width="7"
|
||||
id="rect2047-7"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
|
||||
</g>
|
||||
<g
|
||||
id="button1-path"
|
||||
inkscape:label="">
|
||||
<path
|
||||
sodipodi:nodetypes="ccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2125"
|
||||
d="m 284.47693,-230.07844 55.72631,-55.72631 h 109.63402"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
y="-233.57845"
|
||||
x="280.97693"
|
||||
height="7"
|
||||
width="7"
|
||||
id="rect2047-0"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
|
||||
<rect
|
||||
y="-286.3056"
|
||||
x="448.96484"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button1-leader"
|
||||
style="text-align:start;display:inline;opacity:1;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill"
|
||||
inkscape:label="" />
|
||||
</g>
|
||||
<g
|
||||
id="button2-path"
|
||||
inkscape:label="">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2129"
|
||||
d="m 219.25864,-151.26926 42.56584,42.56585 h 187.62309"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
y="-154.76926"
|
||||
x="215.75864"
|
||||
height="7"
|
||||
width="7"
|
||||
id="rect2047-08"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
|
||||
<rect
|
||||
inkscape:label=""
|
||||
y="-109.20406"
|
||||
x="448.96875"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button2-leader"
|
||||
style="text-align:start;display:inline;opacity:1;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
|
||||
</g>
|
||||
<g
|
||||
id="button6-path"
|
||||
inkscape:label="">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path891"
|
||||
d="m 239.67007,-210.78999 29.97581,29.97581 h 180.25081"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#888a85;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<rect
|
||||
inkscape:label=""
|
||||
y="-181.31418"
|
||||
x="448.96875"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button6-leader"
|
||||
style="text-align:start;display:inline;opacity:1;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
|
||||
<rect
|
||||
y="-214.28999"
|
||||
x="236.17007"
|
||||
height="7"
|
||||
width="7"
|
||||
id="rect2047-8"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="LEDs"
|
||||
inkscape:label="LEDs"
|
||||
style="display:inline" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 18 KiB |
1
data/gnome/logitech-mx-anywhere2s.svg
Symbolic link
@@ -0,0 +1 @@
|
||||
logitech-mx-anywhere2.svg
|
||||
359
data/gnome/logitech-mx-master-2s.svg
Normal file
@@ -0,0 +1,359 @@
|
||||
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="485"
|
||||
height="445"
|
||||
viewBox="0 0 128.32296 117.73977"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
sodipodi:docname="logitech-mx-master-2s.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.979899"
|
||||
inkscape:cx="189.95565"
|
||||
inkscape:cy="227.78986"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="Buttons"
|
||||
showgrid="true"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1376"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
units="px"
|
||||
showguides="false"
|
||||
inkscape:snap-global="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid5521"
|
||||
spacingy="10.583333"
|
||||
spacingx="264583.33"
|
||||
originy="5.2916751" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<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="Device"
|
||||
inkscape:label="Device"
|
||||
style="display:inline"
|
||||
transform="translate(0,-179.26022)">
|
||||
<path
|
||||
style="fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 19.866021,223.53772 c 0,0 -0.785103,0.71829 -2.204974,1.68714 -1.419868,0.96885 -3.558026,2.2885 -4.877667,3.35758 -1.319644,1.06907 -2.004523,2.37202 -2.622585,3.77518 -0.6180575,1.40317 -1.4031635,5.06142 -2.121448,9.92238 -0.718287,4.86097 -1.102486,9.43796 -1.2194155,13.69757 -0.11693,4.2596 -0.451017,4.79414 0.868623,8.76978 1.5191735,3.4768 3.2046955,4.45805 4.2429035,5.41221 1.085782,0.83521 6.965712,5.3955 11.72645,8.30206 4.760738,2.90655 11.225936,6.8707 14.699824,8.16842 1.860286,0.69493 2.586897,1.04147 4.032189,1.46211 1.219513,0.35492 2.417778,0.58726 4.971452,0.8765 4.324451,0.48981 9.010044,-0.72432 11.943604,-2.20498 2.83974,-1.63702 7.75082,-4.94448 11.04158,-8.70296 3.29075,-3.75848 4.17608,-4.69392 4.91107,-7.76752 0.73499,-3.0736 1.23612,-9.6217 1.11919,-15.31788 -0.11693,-5.69619 -0.7851,-13.64745 -1.41987,-18.67546 -0.63476,-5.02801 -1.26952,-7.684 -1.26952,-7.684"
|
||||
id="path5225"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csccsscccsssccsscc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cscssscsc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="button5"
|
||||
d="m 19.676541,228.60285 c 0,0 -5.707153,4.07215 -6.676005,5.10782 -0.968853,1.03567 -1.5368,2.70611 -1.703845,3.74178 -0.167042,1.03567 -1.169302,7.58377 -1.5702065,12.56167 -0.4009035,4.97789 -0.7015815,6.98241 -0.233862,9.32102 0.467722,2.33861 1.4365735,3.64155 2.2383825,4.30972 0.801809,0.66817 13.229842,9.2208 15.969354,10.7576 0.342743,-3.52158 1.597747,-7.89241 -0.165219,-10.5636 -4.912482,-7.44322 -8.870526,-19.92797 -7.858599,-35.23601 z"
|
||||
style="fill:#d3d3ce;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:label="#path5657" />
|
||||
<path
|
||||
style="fill:#d3d3ce;fill-opacity:1;stroke:#babdb6;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 19.676541,228.60285 c 0,0 -5.707153,4.07215 -6.676005,5.10782 -0.968853,1.03567 -1.5368,2.70611 -1.703845,3.74178 -0.167042,1.03567 -1.169302,7.58377 -1.5702065,12.56167 -0.4009035,4.97789 -0.7015815,6.98241 -0.233862,9.32102 0.467722,2.33861 1.4365735,3.64155 2.2383825,4.30972 0.801809,0.66817 14.365737,9.78875 17.105249,11.32555 2.739514,1.5368 8.352173,4.57699 12.127356,5.34539 3.775181,0.7684 7.249684,1.20271 12.127357,0.93544 4.87767,-0.26727 11.35895,-4.00904 13.0962,-5.57925 1.73725,-1.57021 6.38106,-7.18287 7.38333,-10.08942 1.00226,-2.90656 1.77066,-11.42578 1.26952,-20.21226 -0.50113,-8.78649 -1.06907,-15.30119 -1.1693,-16.5039 -0.10022,-1.20271 -0.0334,-7.58377 -0.93544,-18.40819 -0.90204,-10.82441 -1.36976,-11.99372 -2.20498,-14.26551 -0.83522,-2.27179 -7.85104,-5.47902 -11.22532,-6.84878 -3.37427,-1.36976 -9.585632,-3.70469 -11.541371,-3.84016 -1.955737,-0.13547 -8.938152,2.40359 -11.944935,3.77334 -3.006783,1.36976 -8.073472,4.0577 -8.073472,4.0577 -4.468114,9.08817 -5.960983,22.63921 -8.068658,35.26804 z"
|
||||
id="path78"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cscssssssscccsscsscc" />
|
||||
<rect
|
||||
id="button6"
|
||||
width="5.315289"
|
||||
height="5.3152866"
|
||||
x="45.235897"
|
||||
y="221.81316"
|
||||
style="opacity:1;vector-effect:none;fill:#d3d3ce;fill-opacity:1;stroke:#babdb6;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
rx="0.69999999"
|
||||
ry="0.69999999"
|
||||
inkscape:label="#rect5215" />
|
||||
<rect
|
||||
style="opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="button2"
|
||||
width="7.0870538"
|
||||
height="14.552083"
|
||||
x="44.220081"
|
||||
y="199.01646"
|
||||
rx="0.70000017"
|
||||
ry="0.70000017"
|
||||
inkscape:label="#rect5217" />
|
||||
<path
|
||||
id="button0"
|
||||
style="fill:#d3d3ce;fill-opacity:1;stroke:#babdb6;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 47.762508,195.6666 c -1.892311,0.0167 -3.873176,0.0377 -4.226442,0.0417 -0.709932,0.008 -1.720551,0.96885 -1.737251,1.72054 -0.0141,0.63483 -0.159624,28.13451 -0.171424,28.86684 -0.01181,0.73233 -0.563567,1.23439 -0.747315,1.40144 -0.183748,0.16704 -17.283331,6.12265 -17.708555,6.24077 -0.425221,0.11811 -0.761454,0.3511 -1.039434,-0.40751 -0.347226,-0.94758 -0.07087,-7.39416 0.87407,-17.9775 0.944941,-10.58333 4.739037,-22.21806 4.739037,-22.21806 0,0 5.066694,-2.68795 8.073477,-4.05771 3.006783,-1.36975 9.989198,-3.90881 11.944936,-3.77211 z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccscccc"
|
||||
inkscape:label="#path5627" />
|
||||
<path
|
||||
id="button1"
|
||||
style="fill:#d3d3ce;fill-opacity:1;stroke:#babdb6;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 47.763608,185.50377 v 10.08368 m -0.01842,0.0784 c 1.690105,-0.0156 3.321588,-0.0284 3.692045,-0.0244 0.944073,0.0103 2.438833,1.06072 2.488943,2.38872 0.0535,1.41886 0.18375,26.82718 0.23387,27.92966 0.0501,1.10249 0.14727,1.2276 0.71424,1.66464 0.56696,0.43703 13.97331,5.5279 14.74107,5.65783 0.76776,0.12993 0.88588,-0.14174 0.95675,-0.68508 0.0709,-0.54334 0.50944,-11.58187 0.27558,-14.7557 -0.23387,-3.17383 -1.089962,-16.77534 -2.799869,-24.09699 -2.565285,-1.75722 -6.479518,-3.48182 -8.74284,-4.4006 -3.37427,-1.36976 -9.585632,-3.70469 -11.541371,-3.84016"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccsccccc"
|
||||
inkscape:label="#path5631" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#d3d3ce;fill-opacity:1;stroke:#babdb6;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 24.70574,258.91885 c 0,0 -2.944259,-4.70523 -3.525604,-7.81361 0.07137,0.16032 1.142052,1.76828 1.374962,1.88086"
|
||||
id="button3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc"
|
||||
inkscape:label="#path5636" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#d3d3ce;fill-opacity:1;stroke:#babdb6;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 20.347215,244.33435 c 0,0 0.503997,5.22172 0.804675,6.62488 0.300678,1.40317 1.186008,1.85418 1.186008,1.85418"
|
||||
id="button4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc"
|
||||
inkscape:label="#path5634" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 27.745199,193.33481 c 0,0 -1.681865,1.10395 -2.416856,2.12291 -0.734991,1.01897 -3.240643,8.4524 -4.510173,19.00955 -1.269531,10.55714 -0.985557,10.80771 -1.085783,14.51607 -0.100226,3.70837 0.06098,11.98844 0.627949,15.41385 0.566964,3.42541 2.69308,11.19754 4.086867,13.98512 1.393787,2.78757 2.944127,5.32102 3.061057,5.37113 0.116931,0.0501 0.175396,0.10858 0.400904,-0.0334 0.225509,-0.14198 1.03567,-0.92709 1.127544,-1.30294 0.09187,-0.37584 0.200452,-0.77675 0.04176,-1.17765 -0.158692,-0.40091 -2.029578,-3.25735 -2.38037,-4.14268 -0.350791,-0.88533 -2.15486,-4.86097 -2.873147,-8.4357 -0.718287,-3.57473 -1.503391,-7.51695 -1.753956,-9.83885 -0.250566,-2.32191 -0.183748,-4.09257 -0.183748,-5.04472 0,-0.95214 0.09187,-2.02958 0.09187,-2.02958 0.279608,-13.8572 2.014074,-26.7818 5.766082,-38.41311 z"
|
||||
id="path5223"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csssccccccsssscc" />
|
||||
<g
|
||||
id="g1137"
|
||||
transform="translate(-3.6416254,5.291675)">
|
||||
<rect
|
||||
y="193.85353"
|
||||
x="48.915695"
|
||||
height="14.312759"
|
||||
width="1.8040693"
|
||||
id="rect1131"
|
||||
style="opacity:1;vector-effect:none;fill:#d3d3ce;fill-opacity:1;stroke:none;stroke-width:0.26502112px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:1;vector-effect:none;fill:#d3d3ce;fill-opacity:1;stroke:none;stroke-width:0.26502112px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect1133"
|
||||
width="1.8040693"
|
||||
height="14.312759"
|
||||
x="52.090698"
|
||||
y="193.85353" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="Buttons"
|
||||
inkscape:label="Buttons"
|
||||
transform="translate(0,-179.26022)">
|
||||
<g
|
||||
transform="matrix(0.26458333,0,0,0.26458333,2.1166624,183.016)"
|
||||
style="display:inline"
|
||||
id="button1-path"
|
||||
inkscape:label="#g131">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 242.94764,50.505764 H 477"
|
||||
id="path958"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect968"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="237"
|
||||
y="47.005764" />
|
||||
<rect
|
||||
inkscape:label="#rect867"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button1-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="477"
|
||||
y="50.005764" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="#g131"
|
||||
id="button6-path"
|
||||
style="display:inline"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,2.1166624,213.83995)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5469"
|
||||
d="M 173.32645,40.025431 193.47816,54.00578 H 477.59978"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<rect
|
||||
y="36.559353"
|
||||
x="169.85715"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect5471"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
y="53.505779"
|
||||
x="477"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button6-leader"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#rect867" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.26458333,0,0,0.26458333,2.1166624,204.05037)"
|
||||
style="display:inline"
|
||||
id="button0-path"
|
||||
inkscape:label="#g131">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 132.23335,50.505764 H 477"
|
||||
id="path5477"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect5479"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="128.42857"
|
||||
y="47.005764" />
|
||||
<rect
|
||||
inkscape:label="#rect867"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button0-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="477"
|
||||
y="50.005764" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="#g131"
|
||||
id="button2-path"
|
||||
style="display:inline"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,2.1166624,193.59933)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5485"
|
||||
d="M 168.43093,50.505764 H 477"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.94604886;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
y="47.005764"
|
||||
x="167.35715"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect5487"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
y="50.005764"
|
||||
x="477"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button2-leader"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#rect867" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.26458333,0,0,0.26458333,2.1166624,225.21704)"
|
||||
style="display:inline"
|
||||
id="button5-path"
|
||||
inkscape:label="#g131">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1.17770362;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 55.283671,50.505764 H 477"
|
||||
id="path5493"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect5495"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="48.428574"
|
||||
y="47.005764" />
|
||||
<rect
|
||||
inkscape:label="#rect867"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button5-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="477"
|
||||
y="50.005764" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="#g131"
|
||||
id="button4-path"
|
||||
style="display:inline"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,2.1166624,235.80037)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5503"
|
||||
d="M 69.460332,50.505764 H 477"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1.13811326;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
y="47.005764"
|
||||
x="67.665703"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect5505"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
y="50.005764"
|
||||
x="477"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button4-leader"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#rect867" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.26458333,0,0,0.26458333,2.1166624,246.3837)"
|
||||
style="display:inline"
|
||||
id="button3-path"
|
||||
inkscape:label="#g131">
|
||||
<path
|
||||
sodipodi:nodetypes="ccc"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1.12054801;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 78.817927,36.487907 105.14285,50.505764 H 477"
|
||||
id="path5513"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect5515"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="75.454132"
|
||||
y="33.075569" />
|
||||
<rect
|
||||
inkscape:label="#rect867"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button3-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="477"
|
||||
y="50.005764" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="LEDs"
|
||||
inkscape:label="LEDs"
|
||||
transform="translate(0,-14.552099)" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 21 KiB |
1
data/gnome/logitech-mx-master.svg
Symbolic link
@@ -0,0 +1 @@
|
||||
logitech-mx-master-2s.svg
|
||||
|
Before Width: | Height: | Size: 739 KiB After Width: | Height: | Size: 15 KiB |
637
data/gnome/steelseries-rival600.svg
Normal file
@@ -0,0 +1,637 @@
|
||||
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="499"
|
||||
height="499"
|
||||
viewBox="0 0 132.02708 132.02709"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.2 2405546, 2018-03-11"
|
||||
sodipodi:docname="steelseries-rival600.svg">
|
||||
<defs
|
||||
id="defs2">
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath4634">
|
||||
<rect
|
||||
style="fill:#3d1400;fill-opacity:0.54140128;stroke:#000000;stroke-width:0.2117648;stroke-opacity:1"
|
||||
id="rect4636"
|
||||
width="107.04193"
|
||||
height="199.41115"
|
||||
x="30.877195"
|
||||
y="155.32713" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="4.0000002"
|
||||
inkscape:cx="257.92153"
|
||||
inkscape:cy="362.68056"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="Device"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1012"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
units="px"
|
||||
showguides="false"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:snap-global="true"
|
||||
inkscape:measure-start="305.625,430.5"
|
||||
inkscape:measure-end="269.5,430.75">
|
||||
<sodipodi:guide
|
||||
position="66.14583,85.422621"
|
||||
orientation="1,0"
|
||||
id="guide4638"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="115.99497,127"
|
||||
orientation="0,1"
|
||||
id="guide4640"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,0,255)" />
|
||||
<sodipodi:guide
|
||||
position="9.354433,5.2916666"
|
||||
orientation="0,1"
|
||||
id="guide4642"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,0,255)" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<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 />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="Device"
|
||||
inkscape:label="Device"
|
||||
style="display:inline"
|
||||
transform="translate(0,-0.26458333)">
|
||||
<path
|
||||
sodipodi:nodetypes="csccccccccsscccccccssssssscccccccccccscsssc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4673"
|
||||
d="m 40.02385,14.984554 c 1.580795,-2.51549 5.975285,-3.539984 9.385335,-4.965329 3.128814,-1.3077924 9.164225,-4.4175966 9.164225,-4.4175966 l 3.236676,-0.3099634 -0.0053,8.952208 1.214482,-5.705833 6.015962,-0.014436 1.88187,5.552463 -0.06133,-8.784402 2.895343,0.3674956 c 0,0 5.054486,2.5992473 7.544173,3.9686799 5.3036,2.9172035 11.440444,3.4069705 11.658567,6.9089765 l 2.434325,39.08341 2.530042,28.965015 c 0,0 0.286756,7.495044 -0.371079,10.115766 l -3.292458,-3.010664 -0.559771,0.835476 1.951257,2.541965 c 0.442734,0.62875 1.161707,2.907068 1.161707,2.907068 0,0 -0.1,2.252347 -0.334606,3.189677 -1.586764,6.33968 -6.10449,11.6792 -9.236308,15.53526 -2.544851,3.13335 -5.161521,5.64996 -8.518934,7.38326 -3.502718,1.80832 -7.474043,2.75126 -11.412536,2.91659 -4.30071,0.18053 -6.918836,0.23282 -12.770724,-1.91491 -4.175515,-1.53248 -7.367165,-5.08869 -9.121485,-7.10927 -9.051815,-10.4256 -9.37199,-18.857963 -8.769367,-19.894766 L 39.845444,91.905117 39.425142,90.803985 37.552215,94.320171 37.160224,93.903502 37.128144,92.93534 38.295133,81.010098 37.99214,64.407639 38.450135,63.977055 37.8061,63.559233 36.932233,47.808124 36.554461,47.459545 c 0,0 0.05032,-2.921717 0.06444,-3.330011 0.09797,-2.831675 0.826526,-3.731517 0.826526,-3.731517 0,0 0.08006,-10.762552 0.583863,-15.991305 0.174175,-1.807686 0.853434,-1.118453 0.93179,-1.886883 0.337789,-3.312656 -0.515822,-5.023298 1.062766,-7.535275 z"
|
||||
style="display:inline;fill:#d3d3ce;fill-opacity:1;stroke:#babdb6;stroke-width:1.32291663;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:#eeeeec;fill-opacity:1;stroke:none;stroke-width:1.57558382;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 232.34375,93.232422 v 60.628908 c 0.50061,1.14157 1.4678,2.62577 3.32617,4.04492 h 0.60742 V 93.232422 Z m 31.91406,0 v 64.673828 h 1.83985 c 0.83119,-0.78541 1.40627,-1.64516 1.81054,-2.55664 V 93.232422 Z"
|
||||
transform="matrix(0.26458334,0,0,0.26458334,0,0.26458333)"
|
||||
id="led0"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:1.99999988;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||
d="m 243.77734,85.634766 c -4.155,0 -7.5,3.345 -7.5,7.5 v 65.191404 c 2.23306,1.53273 5.55795,2.93721 10.59375,3.66211 l -0.0527,4.12695 h 6.42578 v -4.08593 c 5.24654,-0.45952 8.69408,-1.43412 10.98047,-2.7461 0.0194,-0.22077 0.0332,-0.44199 0.0332,-0.66797 V 93.134766 c 0,-4.155 -3.345,-7.5 -7.5,-7.5 z"
|
||||
transform="matrix(0.26458334,0,0,0.26458334,0,0.26458333)"
|
||||
id="button2"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="#button2" />
|
||||
<rect
|
||||
style="fill:#d3d3ce;fill-opacity:1;stroke:#babdb6;stroke-width:0.52916664;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||
id="button6"
|
||||
width="5.0028081"
|
||||
height="14.072443"
|
||||
x="63.525414"
|
||||
y="49.707458"
|
||||
ry="0.89731663"
|
||||
inkscape:label="#button6" />
|
||||
<path
|
||||
style="fill:#d3d3ce;fill-opacity:1;stroke:#babdb6;stroke-width:2;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||
d="m 231.80196,19.999994 -10.42305,1.171881 c 0,0 -22.80933,11.752475 -34.63477,16.695313 -12.88838,5.38713 -29.498,9.260214 -35.47266,18.767578 -5.45964,8.687822 -3.23027,14.853779 -3.78906,25.429687 l 0.89286,110.357427 c 0.75974,6.5985 8.53258,13.62191 67.64583,28.30897 l 20.49636,0.59268 0.20962,-34.60642 c 1.20454,-5.7407 4.81879,-6.03597 9.92297,-6.35918 l 0.22147,-17.37007 c -14.80392,-2.13101 -15.06957,-10.10154 -15.06957,-10.10154 z"
|
||||
transform="scale(0.26458333)"
|
||||
id="button0"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccssccccccccc"
|
||||
inkscape:label="#button0" />
|
||||
<path
|
||||
style="fill:#d3d3ce;fill-opacity:1;stroke:#babdb6;stroke-width:2;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||
d="m 268.57227,20.097656 0.34526,131.616644 c -0.47516,5.1884 -1.66448,10.08839 -15.67427,11.31543 l 6.2e-4,17.28677 c 4.75243,0.31401 8.60528,1.4133 9.36291,7.0537 l 0.15706,34.28927 23.61411,-0.28538 c 59.2439,-12.2777 65.79173,-21.56131 66.69622,-30.52428 V 90.634766 l -1.75195,-28.132813 c -0.82441,-13.235928 -24.01935,-15.08763 -44.06446,-26.113281 -9.40984,-5.175808 -28.51367,-15 -28.51367,-15 z"
|
||||
id="button1"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccscc"
|
||||
inkscape:label="#button1"
|
||||
transform="scale(0.26458333)" />
|
||||
<path
|
||||
style="fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 141.16016,153.26562 c -0.75439,1.32491 -2.46978,5.19815 -2.75782,13.52344 -0.0534,1.54316 -0.24414,12.58594 -0.24414,12.58594 l 1.42774,1.31641 v 0 l 2.08789,0.006 v -27.43148 z"
|
||||
transform="scale(0.26458333)"
|
||||
id="button5"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc"
|
||||
inkscape:label="#button5" />
|
||||
<path
|
||||
style="fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 139.70312,182.80273 3.17774,57.26563 h 4.10547 l -3.40926,-57.51817 z"
|
||||
transform="scale(0.26458333)"
|
||||
id="button4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:label="#button4" />
|
||||
<path
|
||||
style="fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 143.60352,244.08398 2.65262,62.72071 4.65625,16.10854 -0.46289,-21.07144 -2.32143,-57.75782 z"
|
||||
transform="scale(0.26458333)"
|
||||
id="button3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccc"
|
||||
inkscape:label="#button3" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="display:inline;opacity:1;fill:none;fill-opacity:0.39215686;stroke:#babdb6;stroke-width:3.62082291;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="led1"
|
||||
sodipodi:cx="66.014069"
|
||||
sodipodi:cy="113.27822"
|
||||
sodipodi:rx="6.5174346"
|
||||
sodipodi:ry="6.5174413"
|
||||
d="m 70.622591,108.66969 a 6.5174346,6.5174413 0 0 1 0,9.21706 6.5174346,6.5174413 0 0 1 -9.217044,0 6.5174346,6.5174413 0 0 1 -10e-7,-9.21706"
|
||||
sodipodi:start="5.4977871"
|
||||
sodipodi:end="3.9269907"
|
||||
sodipodi:open="true"
|
||||
sodipodi:arc-type="arc"
|
||||
inkscape:label="#led1" />
|
||||
<path
|
||||
style="fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:0.39687499;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 53.883876,61.201732 c 0.701684,-1.04199 1.713438,-1.252361 2.700948,-1.273296 -1.062711,6.124293 -2.23957,15.448337 -2.929315,17.714841 l -2.279083,-0.01181 c 0.921085,-4.981084 1.8723,-11.917817 2.50745,-16.429735 z"
|
||||
id="led2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:label="#led2" />
|
||||
<path
|
||||
style="fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:0.39687499;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 51.098164,78.550869 2.137416,0.0032 c -2.45902,3.08502 -5.645313,5.394855 -8.68164,7.870003 l 0.01274,-1.902901 c 2.26525,-2.119478 4.965592,-3.807868 6.531484,-5.970314 z"
|
||||
id="led4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:label="#led4" />
|
||||
<path
|
||||
style="fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:0.38111177;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 39.904215,90.216504 c 2.946365,-4.10277 2.992207,-3.879322 3.87751,-4.907952 v 1.643592 c -1.069962,1.220999 -2.14185,2.446029 -3.652074,4.588366 -0.34675,-0.266319 -0.171896,-0.86875 -0.225436,-1.324006 z"
|
||||
id="led6"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:label="#led6" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="led3"
|
||||
d="m 77.958921,61.201732 c -0.701684,-1.04199 -1.713438,-1.252361 -2.700948,-1.273296 1.062711,6.124293 2.23957,15.448337 2.929315,17.714841 l 2.279083,-0.01181 c -0.921085,-4.981084 -1.8723,-11.917817 -2.50745,-16.429735 z"
|
||||
style="fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:0.39687499;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:label="#led3" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="led5"
|
||||
d="m 80.744633,78.550869 -2.137416,0.0032 c 2.45902,3.08502 5.645313,5.394855 8.68164,7.870003 l -0.01274,-1.902901 c -2.26525,-2.119478 -4.965592,-3.807868 -6.531484,-5.970314 z"
|
||||
style="fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:0.39687499;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:label="#led5" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="led7"
|
||||
d="M 93.828039,91.01326 C 90.782971,87.489788 88.89285,86.252223 88.034855,85.182947 l 0.02219,1.740055 c 1.135212,1.088123 3.299661,3.204904 5.082908,5.26536 0.341405,-0.26364 0.635364,-0.724423 0.688079,-1.175102 z"
|
||||
style="fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:0.37625623;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:label="#led7" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="Buttons"
|
||||
inkscape:label="Buttons"
|
||||
transform="translate(0,-0.26458333)">
|
||||
<g
|
||||
id="button0-path"
|
||||
inkscape:label="#button0-path">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path966"
|
||||
d="m 50.609489,18.387576 -50.47151772,0.0019"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.26270351;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
y="17.462502"
|
||||
x="-51.329166"
|
||||
height="1.8520831"
|
||||
width="1.8520833"
|
||||
id="rect976"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.50289863;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
transform="scale(-1,1)" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
y="18.25625"
|
||||
x="-0.26458332"
|
||||
height="0.26458332"
|
||||
width="0.26458332"
|
||||
id="button0-leader"
|
||||
style="color:#000000;text-align:end;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.26458335;stroke-linecap:round"
|
||||
inkscape:label="#button0-leader" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="#button5-path"
|
||||
id="button5-path"
|
||||
transform="matrix(1,0,0,0.99991172,-13.551005,26.460036)">
|
||||
<path
|
||||
sodipodi:nodetypes="ccc"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.26290539;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 50.998437,18.983827 37.196023,5.1572762 H 13.68371"
|
||||
id="path8646"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.50289863;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect8648"
|
||||
width="1.8520833"
|
||||
height="1.8520831"
|
||||
x="-51.329166"
|
||||
y="17.462502" />
|
||||
<rect
|
||||
inkscape:label="#button5-leader"
|
||||
style="color:#000000;text-align:end;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.26458335;stroke-linecap:round"
|
||||
id="button5-leader"
|
||||
width="0.26458332"
|
||||
height="0.26458332"
|
||||
x="-13.815588"
|
||||
y="5.0258474"
|
||||
transform="scale(-1,1)" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1,0,0,0.99991171,-13.551005,26.460037)"
|
||||
id="button4-path"
|
||||
inkscape:label="#button4-path">
|
||||
<path
|
||||
sodipodi:nodetypes="ccc"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.27385584;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 51.951929,30.017489 40.205394,18.387452 H 13.749442"
|
||||
id="path8646-1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
y="28.52924"
|
||||
x="-52.315731"
|
||||
height="1.8520831"
|
||||
width="1.8520833"
|
||||
id="rect8648-0"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.50289863;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
transform="scale(-1,1)" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
y="18.256182"
|
||||
x="-13.815588"
|
||||
height="0.26458332"
|
||||
width="0.26458332"
|
||||
id="button4-leader"
|
||||
style="color:#000000;text-align:end;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.26458335;stroke-linecap:round"
|
||||
inkscape:label="#button4-leader" />
|
||||
</g>
|
||||
<g
|
||||
id="button3-path"
|
||||
inkscape:label="#button3-path">
|
||||
<path
|
||||
style="fill:none;stroke:#888a85;stroke-width:0.26771936px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 0.13358648,58.076072 H 27.970024 l 10.933108,10.675053"
|
||||
id="path8774"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.50287646;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect8648-0-7"
|
||||
width="1.8520833"
|
||||
height="1.8519195"
|
||||
x="-39.559853"
|
||||
y="67.568466" />
|
||||
<rect
|
||||
inkscape:label="#button3-leader"
|
||||
style="color:#000000;text-align:end;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.26457167;stroke-linecap:round"
|
||||
id="button3-leader"
|
||||
width="0.26458332"
|
||||
height="0.26455995"
|
||||
x="-0.26458332"
|
||||
y="57.943771"
|
||||
transform="scale(-1,1)" />
|
||||
</g>
|
||||
<g
|
||||
id="button1-path"
|
||||
inkscape:label="#button1-path">
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.26376939px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="M 131.97389,18.386474 H 80.896353"
|
||||
id="path8957"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.50289863;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect976-6"
|
||||
width="1.8520833"
|
||||
height="1.8520831"
|
||||
x="-81.801758"
|
||||
y="17.4625" />
|
||||
<rect
|
||||
inkscape:label="#button1-leader"
|
||||
style="color:#000000;text-align:start;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.26458335;stroke-linecap:round"
|
||||
id="button1-leader"
|
||||
width="0.26458332"
|
||||
height="0.26458332"
|
||||
x="-132.02708"
|
||||
y="18.25625"
|
||||
transform="scale(-1,1)" />
|
||||
</g>
|
||||
<g
|
||||
id="button2-path"
|
||||
inkscape:label="#button2-path">
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.26416048px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="M 131.95474,31.62391 H 66.14583"
|
||||
id="path8993"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
y="30.632051"
|
||||
x="-67.080887"
|
||||
height="1.8520831"
|
||||
width="1.8520833"
|
||||
id="rect976-6-9"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.50289863;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
transform="scale(-1,1)" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
y="31.485416"
|
||||
x="-132.02708"
|
||||
height="0.26458332"
|
||||
width="0.26458332"
|
||||
id="button2-leader"
|
||||
style="color:#000000;text-align:start;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.26458335;stroke-linecap:round"
|
||||
inkscape:label="#button2-leader" />
|
||||
</g>
|
||||
<g
|
||||
id="button6-path"
|
||||
inkscape:label="#button6-path">
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.26408577px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="M 131.91236,58.082243 H 66.14583"
|
||||
id="path9075"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.50289863;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect976-6-9-2"
|
||||
width="1.8520833"
|
||||
height="1.8520831"
|
||||
x="-67.0345"
|
||||
y="57.148987" />
|
||||
<rect
|
||||
inkscape:label="#button6-leader"
|
||||
style="color:#000000;text-align:start;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.26458335;stroke-linecap:round"
|
||||
id="button6-leader"
|
||||
width="0.26458332"
|
||||
height="0.26458332"
|
||||
x="-132.02708"
|
||||
y="57.943748"
|
||||
transform="scale(-1,1)" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="LEDs"
|
||||
inkscape:label="LEDs"
|
||||
transform="translate(0,-0.26458333)">
|
||||
<g
|
||||
id="led2-path"
|
||||
inkscape:label="#led2-path">
|
||||
<path
|
||||
style="fill:none;stroke:#888a85;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 0.12402344,71.315542 H 53.647675"
|
||||
id="path8810"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
y="70.379326"
|
||||
x="-54.539886"
|
||||
height="1.8519195"
|
||||
width="1.8520833"
|
||||
id="rect8648-0-7-5"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.50287646;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
transform="scale(-1,1)" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
y="71.172935"
|
||||
x="-0.26458332"
|
||||
height="0.26455995"
|
||||
width="0.26458332"
|
||||
id="led2-leader"
|
||||
style="color:#000000;text-align:end;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.26457167;stroke-linecap:round"
|
||||
inkscape:label="#led2-leader" />
|
||||
</g>
|
||||
<g
|
||||
id="led4-path"
|
||||
inkscape:label="#led4-path">
|
||||
<path
|
||||
style="fill:none;stroke:#888a85;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 0.12862346,84.537282 H 27.648958 l 2.241759,-2.400562 h 18.612019"
|
||||
id="path8848"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.50287646;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect8648-0-7-5-7"
|
||||
width="1.8520833"
|
||||
height="1.8519195"
|
||||
x="-49.503178"
|
||||
y="81.204086" />
|
||||
<rect
|
||||
inkscape:label="#led4-leader"
|
||||
style="color:#000000;text-align:end;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.26457167;stroke-linecap:round"
|
||||
id="led4-leader"
|
||||
width="0.26458332"
|
||||
height="0.26455995"
|
||||
x="-0.26458332"
|
||||
y="84.402107"
|
||||
transform="scale(-1,1)" />
|
||||
</g>
|
||||
<g
|
||||
id="led6-path"
|
||||
inkscape:label="#led6-path">
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 0.12277694,97.767959 25.38364906,4e-5 9.304738,-9.437079 7.003154,-4e-5"
|
||||
id="path8884"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<rect
|
||||
y="87.419861"
|
||||
x="-42.752739"
|
||||
height="1.8519195"
|
||||
width="1.8520833"
|
||||
id="rect8648-0-7-5-7-7"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.50287646;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
transform="scale(-1,1)" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
y="97.631271"
|
||||
x="-0.26458332"
|
||||
height="0.26455995"
|
||||
width="0.26458332"
|
||||
id="led6-leader"
|
||||
style="color:#000000;text-align:end;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.26457167;stroke-linecap:round"
|
||||
inkscape:label="#led6-leader" />
|
||||
</g>
|
||||
<g
|
||||
id="led1-path"
|
||||
inkscape:label="#led1-path"
|
||||
transform="matrix(-1,0,0,1,132.29166,0)">
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.26420629px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="M 0.31955082,110.99571 H 27.672239 l 2.158822,2.42958 H 66.14583"
|
||||
id="path8920"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.50287646;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect8648-0-7-5-7-7-6"
|
||||
width="1.8520833"
|
||||
height="1.8519195"
|
||||
x="-67.071869"
|
||||
y="112.48402" />
|
||||
<rect
|
||||
inkscape:label="#led1-leader"
|
||||
style="color:#000000;text-align:start;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.26457167;stroke-linecap:round"
|
||||
id="led1-leader"
|
||||
width="0.26458332"
|
||||
height="0.26455995"
|
||||
x="-0.52915835"
|
||||
y="110.86044"
|
||||
transform="scale(-1,1)" />
|
||||
</g>
|
||||
<g
|
||||
id="led0-path"
|
||||
inkscape:label="#led0-path">
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.26413852px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="M 131.9564,44.847906 H 106.24218 L 100.20967,38.95381 H 70.511457"
|
||||
id="path9031"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<rect
|
||||
y="38.02457"
|
||||
x="-71.448746"
|
||||
height="1.8519195"
|
||||
width="1.8520833"
|
||||
id="rect8648-0-7-5-7-7-6-4"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.50287646;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
transform="scale(-1,1)" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
y="44.714607"
|
||||
x="-132.02708"
|
||||
height="0.26455995"
|
||||
width="0.26458332"
|
||||
id="led0-leader"
|
||||
style="color:#000000;text-align:start;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.26457167;stroke-linecap:round"
|
||||
inkscape:label="#led0-leader" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="#led3-path"
|
||||
id="led3-path"
|
||||
transform="matrix(-1,0,0,1,131.90105,0)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path9077"
|
||||
d="M -0.02273763,71.315542 H 53.647675"
|
||||
style="fill:none;stroke:#888a85;stroke-width:0.26494581px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.50287646;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect9079"
|
||||
width="1.8520833"
|
||||
height="1.8519195"
|
||||
x="-54.539886"
|
||||
y="70.379326" />
|
||||
<rect
|
||||
inkscape:label="#led3-leader"
|
||||
style="color:#000000;text-align:start;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.26457167;stroke-linecap:round"
|
||||
id="led3-leader"
|
||||
width="0.26458332"
|
||||
height="0.26455995"
|
||||
x="-0.13854833"
|
||||
y="71.172935"
|
||||
transform="scale(-1,1)" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="#led5-path"
|
||||
id="led5-path"
|
||||
transform="matrix(-1,0,0,1,131.90105,0)">
|
||||
<path
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path9085"
|
||||
d="M -0.08572876,84.537282 H 27.556552 l 2.251693,-2.400562 h 18.694491"
|
||||
style="fill:none;stroke:#888a85;stroke-width:0.26516888px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<rect
|
||||
y="81.204086"
|
||||
x="-49.503178"
|
||||
height="1.8519195"
|
||||
width="1.8520833"
|
||||
id="rect9087"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.50287646;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
transform="scale(-1,1)" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
y="84.402107"
|
||||
x="-0.13854833"
|
||||
height="0.26455995"
|
||||
width="0.26458332"
|
||||
id="led5-leader"
|
||||
style="color:#000000;text-align:start;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.26457167;stroke-linecap:round"
|
||||
inkscape:label="#led5-leader" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="#led7-path"
|
||||
id="led7-path"
|
||||
transform="matrix(-1,0,0,1,131.90105,0)">
|
||||
<path
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path9093"
|
||||
d="m 0.02270835,97.767959 25.44457565,4e-5 9.327071,-9.437079 7.019963,-4e-5"
|
||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.26490065px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
transform="scale(-1,1)"
|
||||
style="color:#000000;display:inline;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.50287646;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect9095"
|
||||
width="1.8520833"
|
||||
height="1.8519195"
|
||||
x="-42.752739"
|
||||
y="87.419861" />
|
||||
<rect
|
||||
inkscape:label="#led7-leader"
|
||||
style="color:#000000;text-align:start;display:inline;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-width:0.26457167;stroke-linecap:round"
|
||||
id="led7-leader"
|
||||
width="0.26458332"
|
||||
height="0.26455995"
|
||||
x="-0.13854833"
|
||||
y="97.631271"
|
||||
transform="scale(-1,1)" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 33 KiB |
497
data/gnome/steelseries-senseiraw.svg
Normal file
@@ -0,0 +1,497 @@
|
||||
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="490"
|
||||
height="490"
|
||||
viewBox="0 0 129.64583 129.64583"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
sodipodi:docname="steelseries-senseiraw.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4986862"
|
||||
inkscape:cx="234.07051"
|
||||
inkscape:cy="291.38143"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="Device"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="false"
|
||||
showguides="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1149"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
showborder="true"
|
||||
inkscape:guide-bbox="true"
|
||||
units="px"
|
||||
inkscape:snap-global="false"
|
||||
inkscape:measure-start="0,0"
|
||||
inkscape:measure-end="0,0">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid78" />
|
||||
<sodipodi:guide
|
||||
position="58.722772,112.40709"
|
||||
orientation="0,1"
|
||||
id="guide79"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="39.611923,100.54373"
|
||||
orientation="0,1"
|
||||
id="guide81"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="51.756014,88.614617"
|
||||
orientation="0,1"
|
||||
id="guide83"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="57.778386,76.729167"
|
||||
orientation="0,1"
|
||||
id="guide85"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="45.047078,64.795712"
|
||||
orientation="0,1"
|
||||
inkscape:locked="false"
|
||||
id="guide87" />
|
||||
<sodipodi:guide
|
||||
position="57.646696,52.899321"
|
||||
orientation="0,1"
|
||||
id="guide89"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="64.732676,142.09384"
|
||||
orientation="1,0"
|
||||
id="guide913"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="-45.462545,31.805073"
|
||||
orientation="0,1"
|
||||
inkscape:locked="false"
|
||||
id="guide944" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<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 />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
inkscape:label="Image"
|
||||
style="display:none"
|
||||
sodipodi:insensitive="true" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="Device"
|
||||
inkscape:label="Device"
|
||||
style="display:inline;opacity:1"
|
||||
transform="translate(0,-167.35416)">
|
||||
<path
|
||||
style="display:inline;fill:#d3d3ce;fill-opacity:1;fill-rule:evenodd;stroke:#babdb6;stroke-width:0.98636663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 61.118815,173.57187 c -6.81302,0.0662 -11.972394,1.52136 -16.073435,3.37344 -2.88728,1.31189 -4.888218,3.54982 -6.680729,5.62239 -2.215885,3.43407 -3.375386,5.63618 -3.970698,8.86355 -0.919394,7.49385 -0.194949,14.47321 -0.225672,22.62187 -0.0441,2.92144 0.321327,3.9908 0.09533,6.28385 -0.132292,4.05143 -0.413412,7.82174 -0.79375,11.90625 l -0.859895,11.9724 -1.190625,16.27187 c -0.0248,0.94258 -1e-6,1.65364 0.198437,2.57969 0.171855,0.8399 0.352238,1.03153 0.463021,1.52135 0.595312,2.4033 0.529166,3.99631 1.785937,7.2099 2.116666,4.23333 3.604948,6.84609 6.746875,10.71562 3.858506,4.06797 6.928936,5.67685 11.575518,7.34219 4.293136,1.39044 7.919768,1.65835 12.633854,1.78594 0,0 8.340581,-0.39932 12.633718,-1.78976 4.646582,-1.66534 7.717012,-3.27422 11.575518,-7.34219 3.141927,-3.86953 4.630209,-6.48229 6.746875,-10.71562 1.256771,-3.21359 1.190625,-4.8066 1.785937,-7.2099 0.110783,-0.48982 0.291166,-0.68145 0.463021,-1.52135 0.198438,-0.92605 0.223237,-1.63711 0.198437,-2.57969 l -1.190625,-16.27187 -0.717876,-8.98999 c -0.380338,-4.08451 -0.803477,-10.83723 -0.935769,-14.88866 -0.225999,-2.29305 -0.28663,-3.36241 -0.33073,-6.28385 -0.03072,-8.14866 0.835741,-15.12802 -0.08365,-22.62187 -0.595312,-3.22737 -1.470774,-5.42948 -3.686659,-8.86355 -1.792511,-2.07257 -3.793449,-4.3105 -6.680729,-5.62239 -4.101041,-1.85208 -9.260416,-3.30724 -16.073436,-3.37344 -3.028432,-0.0919 -5.294794,0.0499 -7.4082,0.004 z"
|
||||
id="path926"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccccccccccccccccccccccc" />
|
||||
<path
|
||||
id="path5205"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#babdb6;stroke-width:0.98636663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
|
||||
d="m 68.894015,173.48626 c 0.01741,1.97468 0.845255,8.1474 1.684943,11.60161 1.369264,5.63272 0.266853,23.47034 0.266853,23.47034 0,0 -2.042025,17.37272 -6.022897,17.27166 -3.980871,0.16348 -6.022896,-17.20924 -6.022896,-17.20924 0,0 -1.10241,-17.83762 0.266854,-23.47034 0.839687,-3.45421 1.667532,-9.62693 1.684942,-11.60161 z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cscccscc" />
|
||||
<path
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:0.98636663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 64.695108,222.94948 c -0.606916,-0.009 -3.440676,-6.06643 -3.513997,-9.56014 -0.02982,-1.42071 0.176696,-1.66675 3.591511,-1.70532 3.503766,-0.0396 3.702586,0.22584 3.694867,1.62781 -0.01799,3.26716 -3.27008,9.64508 -3.772381,9.63765 z"
|
||||
id="button7"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="sssss"
|
||||
mask="none"
|
||||
clip-path="none" />
|
||||
<path
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:0.98636663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 95.121771,209.18914 c 0,0 -0.197205,17.71196 -1.241986,33.44373 -0.483924,7.28668 -1.491683,12.97597 -2.130552,18.3934 -0.45519,3.85988 0.58105,6.73694 2.373267,7.24471 1.728139,0.48961 3.747262,-3.87217 3.747262,-3.87217"
|
||||
id="path4742"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csssc" />
|
||||
<path
|
||||
sodipodi:nodetypes="csssc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4744"
|
||||
d="m 34.385075,208.66134 c 0,0 0.197205,17.71196 1.241986,33.44373 0.483924,7.28668 1.491683,12.97597 2.130552,18.3934 0.45519,3.85988 -0.58105,6.73694 -2.373267,7.24471 -1.728139,0.48961 -3.747262,-3.87217 -3.747262,-3.87217"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#eeeeec;fill-opacity:1;stroke:#babdb6;stroke-width:0.98636663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<path
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#babdb6;stroke-width:0.98636663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 33.794256,226.79927 0.594666,-18.07871"
|
||||
id="path58"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:0.98636663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 35.720073,242.99898 c 0,0 -1.305894,-0.86732 -1.520495,-1.08633 -0.214601,-0.21901 -0.406023,-15.1316 -0.406023,-15.1316 l 1.116802,0.0102"
|
||||
id="path56"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="czcc" />
|
||||
<path
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#babdb6;stroke-width:0.98636663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 95.452345,226.07744 -0.362533,-16.8175"
|
||||
id="path54"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:0.98636663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 93.827188,242.82115 c 0,0 1.385456,-0.49501 1.574101,-0.65851 0.188645,-0.16351 0.05639,-16.17317 0.05639,-16.17317 l -0.703725,-0.17593"
|
||||
id="path52"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="czcc" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="display:inline;opacity:1;fill:none;fill-opacity:0.39215686;stroke:#babdb6;stroke-width:3.62082291;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="led0"
|
||||
sodipodi:cx="64.822914"
|
||||
sodipodi:cy="280.68228"
|
||||
sodipodi:rx="6.5174346"
|
||||
sodipodi:ry="6.5174413"
|
||||
d="m 69.431436,276.07375 a 6.5174346,6.5174413 0 0 1 10e-7,9.21706 6.5174346,6.5174413 0 0 1 -9.217045,0 6.5174346,6.5174413 0 0 1 -10e-7,-9.21705"
|
||||
sodipodi:start="5.4977871"
|
||||
sodipodi:end="3.9269907"
|
||||
sodipodi:open="true"
|
||||
sodipodi:arc-type="arc"
|
||||
inkscape:label="#led1" />
|
||||
<path
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#babdb6;stroke-width:0.98636663;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
|
||||
d="m 62.181167,187.21067 -0.0053,13.99772 c 0.798868,1.60491 0.79411,1.60258 2.56045,1.60804 1.9255,-0.003 1.931661,-0.005 2.733645,-1.59929 l -0.0049,-14.01641 c -0.79057,-1.56574 -0.793119,-1.57885 -2.72281,-1.60756 -1.766557,0.0242 -1.762015,0.025 -2.561099,1.6175 z"
|
||||
id="button2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<rect
|
||||
id="button0"
|
||||
width="18.360525"
|
||||
height="26.481527"
|
||||
x="37.983463"
|
||||
y="180.65782"
|
||||
style="display:inline;fill:none;stroke-width:0.26458332"
|
||||
inkscape:label="#button0" />
|
||||
<rect
|
||||
id="button1"
|
||||
width="19.0667"
|
||||
height="26.834612"
|
||||
x="72.056366"
|
||||
y="179.95164"
|
||||
style="display:inline;fill:none;stroke-width:0.26458332"
|
||||
inkscape:label="#button1" />
|
||||
<rect
|
||||
id="button4"
|
||||
width="3.8839571"
|
||||
height="16.242002"
|
||||
x="32.334072"
|
||||
y="209.96404"
|
||||
style="display:inline;fill:none;stroke-width:0.26458332"
|
||||
inkscape:label="#button4" />
|
||||
<rect
|
||||
id="button3"
|
||||
width="4.0605006"
|
||||
height="15.006199"
|
||||
x="32.334072"
|
||||
y="227.2653"
|
||||
style="display:inline;fill:none;stroke-width:0.26458332"
|
||||
inkscape:label="#button3" />
|
||||
<rect
|
||||
id="button5"
|
||||
width="3.177783"
|
||||
height="14.653111"
|
||||
x="93.594673"
|
||||
y="210.67021"
|
||||
style="display:inline;fill:none;stroke-width:0.26458332"
|
||||
inkscape:label="#button5" />
|
||||
<rect
|
||||
id="button6"
|
||||
width="3.3543267"
|
||||
height="15.712373"
|
||||
x="93.594673"
|
||||
y="226.91222"
|
||||
style="display:inline;fill:none;stroke-width:0.26458332"
|
||||
inkscape:label="#button6" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="Buttons"
|
||||
inkscape:label="Buttons"
|
||||
transform="translate(0,-2.6458338)"
|
||||
style="display:inline">
|
||||
<g
|
||||
transform="matrix(-0.29294531,0,0,0.26458333,70.223399,-40.717196)"
|
||||
style="display:inline"
|
||||
id="button0-path"
|
||||
inkscape:label="#button0-path">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 81.663449,250.50576 157.960771,0.0352"
|
||||
id="path966"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect976"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="79.083046"
|
||||
y="247.00577" />
|
||||
<rect
|
||||
y="250.00575"
|
||||
x="238.62422"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button0-leader"
|
||||
style="color:#000000;text-align:end;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#button0-leader" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.26458333,0,0,0.26458333,40.529257,-19.549003)"
|
||||
style="display:inline"
|
||||
id="button1-path"
|
||||
inkscape:label="#button1-path">
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 336.91912,170.14213 -183.57514,0.36405"
|
||||
id="path51"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect53"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="149"
|
||||
y="167" />
|
||||
<rect
|
||||
y="169.75269"
|
||||
x="336.91913"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button1-leader"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#button1-leader" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(-0.2847136,0,0,0.26458333,87.395313,-3.7692874)"
|
||||
style="display:inline;opacity:1"
|
||||
id="button2-path"
|
||||
inkscape:label="#button2-path">
|
||||
<path
|
||||
sodipodi:nodetypes="ccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path964-6"
|
||||
d="m 79.210952,122.6933 62.691188,68.76371 165.40155,1e-5"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
inkscape:label="#button2-leader"
|
||||
style="color:#000000;text-align:end;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button2-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="306.40533"
|
||||
y="190.93378" />
|
||||
<rect
|
||||
y="117.94263"
|
||||
x="76.303352"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect974-5"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.26458333,0,0,0.26458333,13.523106,5.8698781)"
|
||||
style="display:inline"
|
||||
id="button7-path"
|
||||
inkscape:label="#button7-path">
|
||||
<path
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="M 438.5178,161.34199 H 204.22621 l -10.41041,7.75114"
|
||||
id="path51-1-9-6-0"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect53-2-3-2-2"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="189"
|
||||
y="167" />
|
||||
<rect
|
||||
y="160.86166"
|
||||
x="437.87918"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button7-leader"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#button7-leader" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="#button3-path"
|
||||
id="button3-path"
|
||||
style="display:inline"
|
||||
transform="matrix(-0.29294531,0,0,0.26458333,58.364063,-10.132593)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path64"
|
||||
d="m 81.659897,250.49954 118.042313,0.0476"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1.00572562;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
y="247.00577"
|
||||
x="79.083046"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect66"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
inkscape:label="#button3-leader"
|
||||
style="color:#000000;text-align:end;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button3-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="199.22597"
|
||||
y="250.00575" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(-0.29294531,0,0,0.26458333,58.488898,4.7227855)"
|
||||
style="display:inline"
|
||||
id="button4-path"
|
||||
inkscape:label="#button4-path">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1.00572562;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 81.659897,250.49954 118.042313,0.0476"
|
||||
id="path72"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect74"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="79.083046"
|
||||
y="247.00577" />
|
||||
<rect
|
||||
y="250.00575"
|
||||
x="199.15065"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button4-leader"
|
||||
style="color:#000000;text-align:end;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#button4-leader" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.29294531,0,0,0.26458333,71.117413,-9.779506)"
|
||||
style="display:inline"
|
||||
id="button5-path"
|
||||
inkscape:label="#button5-path">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1.00572562;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 81.659897,250.49954 118.042313,0.0476"
|
||||
id="path80"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect82"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="79.083046"
|
||||
y="247.00577" />
|
||||
<rect
|
||||
y="250.00575"
|
||||
x="199.22597"
|
||||
height="1"
|
||||
width="1"
|
||||
id="button5-leader"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#button5-leader" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="#button6-path"
|
||||
id="button6-path"
|
||||
style="display:inline"
|
||||
transform="matrix(0.29294531,0,0,0.26458333,70.992573,5.0758725)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path88"
|
||||
d="m 81.659897,250.49954 118.042313,0.0476"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1.00572562;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
y="247.00577"
|
||||
x="79.083046"
|
||||
height="6.999999"
|
||||
width="6.999999"
|
||||
id="rect90"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
|
||||
<rect
|
||||
inkscape:label="#button6-leader"
|
||||
style="color:#000000;text-align:start;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
id="button6-leader"
|
||||
width="1"
|
||||
height="1"
|
||||
x="199.15065"
|
||||
y="250.00575" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="LEDs"
|
||||
inkscape:label="LEDs"
|
||||
transform="translate(0,-2.6458338)"
|
||||
style="display:inline">
|
||||
<g
|
||||
transform="matrix(-0.29294531,0,0,0.26458333,70.145744,50.590488)"
|
||||
style="display:inline"
|
||||
id="led0-path"
|
||||
inkscape:label="#led0-path">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
d="m 19.28901,250.49471 219.01243,0.008"
|
||||
id="path966-0-2"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="color:#000000;overflow:visible;opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
|
||||
id="rect976-2-1"
|
||||
width="6.999999"
|
||||
height="6.999999"
|
||||
x="16.834169"
|
||||
y="246.63705" />
|
||||
<rect
|
||||
y="249.97328"
|
||||
x="237.7849"
|
||||
height="1"
|
||||
width="1"
|
||||
id="led0-leader"
|
||||
style="color:#000000;text-align:end;overflow:visible;vector-effect:none;fill:#888a85;fill-opacity:1;stroke:none;stroke-linecap:round"
|
||||
inkscape:label="#rect875" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 25 KiB |
13
doc/dbus.rst
@@ -129,6 +129,19 @@ org.freedesktop.ratbag1.Device
|
||||
This is the case if the device has SVGs available but not
|
||||
for the given theme.
|
||||
|
||||
.. js:function:: GetSvgFd(s) → (h)
|
||||
|
||||
:param s: the theme name
|
||||
:returns: An open file descriptor to the SVG for the given theme
|
||||
|
||||
Returns an open file descriptor to the SVG for the given theme or an
|
||||
errno on error. The theme must be one of :js:attr:`Themes`.
|
||||
|
||||
The theme **'default'** is guaranteed to be available.
|
||||
ratbagd may return ENOENT if a file doesn't exist.
|
||||
This is the case if the device has SVGs available but not
|
||||
for the given theme.
|
||||
|
||||
.. js:function:: Resync()
|
||||
|
||||
:type: Signal
|
||||
|
||||
214
meson.build
@@ -1,8 +1,8 @@
|
||||
project('libratbag', 'c', 'cpp',
|
||||
version : '0.9.902',
|
||||
version : '0.9.904',
|
||||
license : 'MIT/Expat',
|
||||
default_options : [ 'c_std=gnu99', 'warning_level=2' ],
|
||||
meson_version : '>= 0.38.0')
|
||||
meson_version : '>= 0.40.0')
|
||||
|
||||
libratbag_version = meson.project_version().split('.')
|
||||
|
||||
@@ -38,6 +38,7 @@ add_project_arguments(cppflags, language: 'cpp')
|
||||
# is generated at the end of this file
|
||||
config_h = configuration_data()
|
||||
config_h.set('_GNU_SOURCE', '1')
|
||||
config_h.set_quoted('RATBAG_VERSION', meson.project_version())
|
||||
config_h.set_quoted('FALLBACK_SVG_NAME', 'fallback.svg')
|
||||
libratbag_data_dir = join_paths(get_option('prefix'),
|
||||
get_option('datadir'),
|
||||
@@ -45,15 +46,43 @@ libratbag_data_dir = join_paths(get_option('prefix'),
|
||||
libratbag_data_dir_devel = join_paths(meson.source_root(), 'data')
|
||||
config_h.set_quoted('LIBRATBAG_DATA_DIR', libratbag_data_dir)
|
||||
|
||||
# Coverity breaks because it doesn't define _Float128 correctly, you'll end
|
||||
# up with a bunch of messages in the form:
|
||||
# "/usr/include/stdlib.h", line 133: error #20: identifier "_Float128" is
|
||||
# undefined
|
||||
# extern _Float128 strtof128 (const char *__restrict __nptr,
|
||||
# ^
|
||||
# We don't use float128 ourselves, it gets pulled in from math.h or
|
||||
# something, so let's just define it as uint128 and move on.
|
||||
# Unfortunately we can't detect the coverity build at meson configure
|
||||
# time, we only know it fails at runtime. So make this an option instead, to
|
||||
# be removed when coverity fixes this again.
|
||||
if get_option('coverity')
|
||||
config_h.set('_Float128', '__uint128_t')
|
||||
config_h.set('_Float32', 'int')
|
||||
config_h.set('_Float32x', 'int')
|
||||
config_h.set('_Float64', 'long')
|
||||
config_h.set('_Float64x', 'long')
|
||||
endif
|
||||
|
||||
# dependencies
|
||||
pkgconfig = import('pkgconfig')
|
||||
dep_udev = dependency('libudev')
|
||||
dep_libevdev = dependency('libevdev')
|
||||
dep_libsystemd = dependency('libsystemd', version : '>=227')
|
||||
dep_systemd = dependency('systemd')
|
||||
dep_glib = dependency('glib-2.0')
|
||||
dep_lm = cc.find_library('m')
|
||||
|
||||
if get_option('logind-provider') == 'elogind'
|
||||
logind_dep = dependency('libelogind', version : '>=227')
|
||||
else
|
||||
logind_dep = dependency('libsystemd', version : '>=227')
|
||||
endif
|
||||
|
||||
enable_systemd = get_option('systemd')
|
||||
if enable_systemd
|
||||
dep_systemd = dependency('systemd')
|
||||
endif
|
||||
|
||||
#### libutil.a ####
|
||||
src_libutil = [
|
||||
'src/libratbag-util.c',
|
||||
@@ -131,6 +160,7 @@ src_libratbag = [
|
||||
'src/driver-hidpp20.c',
|
||||
'src/driver-hidpp10.c',
|
||||
'src/driver-logitech-g300.c',
|
||||
'src/driver-logitech-g600.c',
|
||||
'src/driver-roccat.c',
|
||||
'src/driver-gskill.c',
|
||||
'src/driver-steelseries.c',
|
||||
@@ -155,15 +185,6 @@ deps_libratbag = [
|
||||
dep_libhidpp,
|
||||
]
|
||||
|
||||
libratbag_version_h_config = configuration_data()
|
||||
libratbag_version_h_config.set_quoted('LIBRATBAG_VERSION', meson.project_version())
|
||||
|
||||
libratbag_version_h = configure_file(
|
||||
output : 'libratbag-version.h',
|
||||
configuration : libratbag_version_h_config,
|
||||
install: false,
|
||||
)
|
||||
|
||||
lib_libratbag = static_library('ratbag',
|
||||
src_libratbag,
|
||||
include_directories : include_directories('.'),
|
||||
@@ -241,40 +262,56 @@ man_lur_command = configure_file (
|
||||
)
|
||||
|
||||
#### data files ####
|
||||
# list ordered by git ls-files data/devices/*.device
|
||||
data_files = files(
|
||||
'data/devices/etekcity-scroll-alpha.device',
|
||||
'data/devices/gskill-MX-780.device',
|
||||
'data/devices/logitech-g300.device',
|
||||
'data/devices/logitech-g303.device',
|
||||
'data/devices/logitech-g403.device',
|
||||
'data/devices/logitech-g500.device',
|
||||
'data/devices/logitech-g500s.device',
|
||||
'data/devices/logitech-g502-Proteus-Core-over-USB.device',
|
||||
'data/devices/logitech-g502-Proteus-Spectrum-over-USB.device',
|
||||
'data/devices/logitech-g5-2007.device',
|
||||
'data/devices/logitech-g5.device',
|
||||
'data/devices/logitech-g602.device',
|
||||
'data/devices/logitech-g700.device',
|
||||
'data/devices/logitech-g700s.device',
|
||||
'data/devices/logitech-g700s-wireless.device',
|
||||
'data/devices/logitech-g700-wireless.device',
|
||||
'data/devices/logitech-g703.device',
|
||||
'data/devices/logitech-g7.device',
|
||||
'data/devices/logitech-g900.device',
|
||||
'data/devices/logitech-g900-wireless.device',
|
||||
'data/devices/logitech-g9.device',
|
||||
'data/devices/logitech-g9x-[Call-of-Duty-MW3-Edition].device',
|
||||
'data/devices/logitech-g9x-[Original].device',
|
||||
'data/devices/logitech-M325.device',
|
||||
'data/devices/logitech-M570.device',
|
||||
'data/devices/logitech-M705.device',
|
||||
'data/devices/logitech-MX-Master.device',
|
||||
'data/devices/logitech-MX-Master-2S.device',
|
||||
'data/devices/logitech-T650.device',
|
||||
'data/devices/logitech-Wireless-Touchpad.device',
|
||||
'data/devices/logitech-g-pro-wireless.device',
|
||||
'data/devices/logitech-g-pro.device',
|
||||
'data/devices/logitech-g102-g203.device',
|
||||
'data/devices/logitech-g300.device',
|
||||
'data/devices/logitech-g302.device',
|
||||
'data/devices/logitech-g303.device',
|
||||
'data/devices/logitech-g402.device',
|
||||
'data/devices/logitech-g403.device',
|
||||
'data/devices/logitech-g5-2007.device',
|
||||
'data/devices/logitech-g5.device',
|
||||
'data/devices/logitech-g500.device',
|
||||
'data/devices/logitech-g500s.device',
|
||||
'data/devices/logitech-g502-HERO-over-USB.device',
|
||||
'data/devices/logitech-g502-Proteus-Core-over-USB.device',
|
||||
'data/devices/logitech-g502-Proteus-Spectrum-over-USB.device',
|
||||
'data/devices/logitech-g600.device',
|
||||
'data/devices/logitech-g602.device',
|
||||
'data/devices/logitech-g7.device',
|
||||
'data/devices/logitech-g700-wireless.device',
|
||||
'data/devices/logitech-g700.device',
|
||||
'data/devices/logitech-g700s-wireless.device',
|
||||
'data/devices/logitech-g700s.device',
|
||||
'data/devices/logitech-g703.device',
|
||||
'data/devices/logitech-g9.device',
|
||||
'data/devices/logitech-g900-wireless.device',
|
||||
'data/devices/logitech-g900.device',
|
||||
'data/devices/logitech-g903.device',
|
||||
'data/devices/logitech-g9x-[Call-of-Duty-MW3-Edition].device',
|
||||
'data/devices/logitech-g9x-[Original].device',
|
||||
'data/devices/logitech-gpowerplay-wireless.device',
|
||||
'data/devices/logitech-MX-Anywhere2.device',
|
||||
'data/devices/logitech-MX-Anywhere2S.device',
|
||||
'data/devices/roccat-kone-xtd.device',
|
||||
'data/devices/steelseries-kinzu-v2.device',
|
||||
'data/devices/steelseries-rival-310.device',
|
||||
'data/devices/steelseries-rival-600.device',
|
||||
'data/devices/steelseries-rival.device',
|
||||
'data/devices/steelseries-sensei-310.device',
|
||||
'data/devices/steelseries-sensei-raw.device',
|
||||
)
|
||||
|
||||
install_data(data_files,
|
||||
@@ -286,23 +323,36 @@ test('data-parse-test', data_parse_test,
|
||||
'--svg-dir', join_paths(meson.source_root(), 'data/gnome') ] + data_files)
|
||||
|
||||
#### svg files ####
|
||||
|
||||
# list ordered by git ls-files data/gnome/*.svg
|
||||
gnome_svg_files = files(
|
||||
'data/gnome/fallback.svg',
|
||||
'data/gnome/logitech-g102-g203.svg',
|
||||
'data/gnome/logitech-g300.svg',
|
||||
'data/gnome/logitech-g303.svg',
|
||||
'data/gnome/logitech-g402.svg',
|
||||
'data/gnome/logitech-g403.svg',
|
||||
'data/gnome/logitech-g500.svg',
|
||||
'data/gnome/logitech-g500s.svg',
|
||||
'data/gnome/logitech-g502.svg',
|
||||
'data/gnome/logitech-g600.svg',
|
||||
'data/gnome/logitech-g603.svg',
|
||||
'data/gnome/logitech-g700.svg',
|
||||
'data/gnome/logitech-g703.svg',
|
||||
'data/gnome/logitech-g9.svg',
|
||||
'data/gnome/logitech-g900.svg',
|
||||
'data/gnome/logitech-g-pro.svg',
|
||||
'data/gnome/logitech-g-pro-wireless.svg',
|
||||
'data/gnome/logitech-mx-anywhere2.svg',
|
||||
'data/gnome/logitech-mx-anywhere2s.svg',
|
||||
'data/gnome/logitech-mx-master-2s.svg',
|
||||
'data/gnome/logitech-mx-master.svg',
|
||||
'data/gnome/roccat-kone-xtd.svg',
|
||||
'data/gnome/steelseries-kinzu-v2.svg',
|
||||
'data/gnome/steelseries-rival.svg',
|
||||
'data/gnome/steelseries-rival310.svg',
|
||||
'data/gnome/steelseries-rival600.svg',
|
||||
'data/gnome/steelseries-sensei310.svg',
|
||||
'data/gnome/steelseries-senseiraw.svg',
|
||||
)
|
||||
install_data(gnome_svg_files,
|
||||
install_dir : join_paths(get_option('datadir'), 'libratbag', 'gnome'))
|
||||
@@ -311,7 +361,7 @@ test_svg_files = find_program('data/gnome/check-svg.py')
|
||||
test('check-svg', test_svg_files, args : gnome_svg_files)
|
||||
|
||||
#### tests ####
|
||||
enable_tests = get_option('enable-tests')
|
||||
enable_tests = get_option('tests')
|
||||
if enable_tests
|
||||
dep_check = dependency('check', version: '>= 0.9.10')
|
||||
|
||||
@@ -399,7 +449,7 @@ src_ratbagd = [
|
||||
|
||||
deps_ratbagd = [
|
||||
dep_udev,
|
||||
dep_libsystemd,
|
||||
logind_dep,
|
||||
dep_libratbag,
|
||||
]
|
||||
|
||||
@@ -430,35 +480,39 @@ configure_file(input : 'dbus/org.freedesktop.ratbag_devel1.conf.in',
|
||||
configuration : config_ratbagd_devel)
|
||||
|
||||
#### unit file ####
|
||||
unitdir = get_option('systemd-unit-dir')
|
||||
if unitdir == ''
|
||||
libdir = get_option('libdir')
|
||||
default_unitdir = dep_systemd.get_pkgconfig_variable('systemdsystemunitdir')
|
||||
# Fedora uses lib64 but systemd is in lib. Hack around this so it
|
||||
# works out of the box.
|
||||
intended_unitdir = join_paths(get_option('prefix'), get_option('libdir'), 'systemd')
|
||||
if get_option('prefix') == '/usr' and intended_unitdir != default_unitdir
|
||||
message('''
|
||||
systemd unitdir libdir mismatch detected, changing unitdir to
|
||||
@0@
|
||||
or specify with
|
||||
mesonconf -Dsystemd-unit-dir=<path>
|
||||
if enable_systemd
|
||||
unitdir = get_option('systemd-unit-dir')
|
||||
if unitdir == ''
|
||||
libdir = get_option('libdir')
|
||||
default_unitdir = dep_systemd.get_pkgconfig_variable('systemdsystemunitdir')
|
||||
# Fedora uses lib64 but systemd is in lib. Hack around this so it
|
||||
# works out of the box.
|
||||
intended_unitdir = join_paths(get_option('prefix'), get_option('libdir'), 'systemd')
|
||||
if get_option('prefix') == '/usr' and intended_unitdir != default_unitdir
|
||||
message('''
|
||||
systemd unitdir libdir mismatch detected, changing unitdir to
|
||||
@0@
|
||||
or specify with
|
||||
mesonconf -Dsystemd-unit-dir=<path>
|
||||
|
||||
See https://github.com/libratbag/libratbag/issues/188
|
||||
'''.format(default_unitdir))
|
||||
unitdir = default_unitdir
|
||||
else
|
||||
unitdir = intended_unitdir
|
||||
See https://github.com/libratbag/libratbag/issues/188
|
||||
'''.format(default_unitdir))
|
||||
unitdir = default_unitdir
|
||||
else
|
||||
unitdir = intended_unitdir
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
config_bindir = configuration_data()
|
||||
config_bindir.set('bindir', join_paths(get_option('prefix'), get_option('bindir')))
|
||||
|
||||
configure_file(input : 'ratbagd/ratbagd.service.in',
|
||||
output : 'ratbagd.service',
|
||||
configuration : config_bindir,
|
||||
install_dir : unitdir)
|
||||
if enable_systemd
|
||||
configure_file(input : 'ratbagd/ratbagd.service.in',
|
||||
output : 'ratbagd.service',
|
||||
configuration : config_bindir,
|
||||
install_dir : unitdir)
|
||||
endif
|
||||
|
||||
dbusdir = get_option('dbus-root-dir')
|
||||
if dbusdir == ''
|
||||
@@ -489,9 +543,15 @@ configure_file(input : 'dbus/org.freedesktop.ratbag1.conf.in',
|
||||
|
||||
#### tools ####
|
||||
|
||||
python = import('python3')
|
||||
py3 = python.find_python()
|
||||
if meson.version().version_compare('<0.48.0')
|
||||
python = import('python3')
|
||||
py3 = python.find_python()
|
||||
else
|
||||
pymod = import('python')
|
||||
py3 = pymod.find_installation()
|
||||
endif
|
||||
|
||||
# ratbagctl calls ratbagd over DBus
|
||||
custom_target('ratbagctl',
|
||||
output : 'ratbagctl',
|
||||
input : ['tools/ratbagctl.in', 'tools/ratbagd.py'],
|
||||
@@ -515,27 +575,25 @@ config_ratbagctl_devel = configuration_data()
|
||||
config_ratbagctl_devel.set('ratbagd_sha', ratbagd_sha)
|
||||
config_ratbagctl_devel.set('MESON_BUILD_ROOT', meson.build_root())
|
||||
config_ratbagctl_devel.set('LIBRATBAG_DATA_DIR', libratbag_data_dir_devel)
|
||||
|
||||
configure_file(input : 'tools/toolbox.py',
|
||||
output : 'toolbox.py',
|
||||
configuration : config_ratbagctl_devel)
|
||||
# ratbagctl.devel starts a custom ratbagd and interacts with that over DBus
|
||||
configure_file(input : 'tools/ratbagctl.devel.in',
|
||||
output : 'ratbagctl.devel',
|
||||
configuration : config_ratbagctl_devel)
|
||||
# ratbagctl.test starts a custom ratbagd and interacts with that over DBus
|
||||
configure_file(input : 'tools/ratbagctl.test.in',
|
||||
output : 'ratbagctl.test',
|
||||
configuration : config_ratbagctl_devel)
|
||||
|
||||
env_test = environment()
|
||||
env_test.set('LIBRATBAG_DATA_DIR', libratbag_data_dir_devel)
|
||||
ratbagctl_test = find_program(join_paths(meson.build_root(), 'ratbagctl.test'))
|
||||
test('ratbagctl-test', ratbagctl_test, args: ['-v'], env : env_test)
|
||||
|
||||
configure_file(input : 'tools/toolbox.py',
|
||||
output : 'toolbox.py',
|
||||
configuration : config_ratbagctl_devel)
|
||||
|
||||
#### output files ####
|
||||
configure_file(output: 'config.h', install: false, configuration: config_h)
|
||||
|
||||
subdir('doc')
|
||||
|
||||
#### swig generated ####
|
||||
# ratbag-command uses Swig bindings to call libratbag directly
|
||||
swig = find_program('swig')
|
||||
swig_gen = generator(
|
||||
swig,
|
||||
@@ -566,13 +624,23 @@ shared_library(
|
||||
install: false,
|
||||
)
|
||||
|
||||
|
||||
# ratbagc is the layer that maps ratbagctl to the swig bindings
|
||||
ratbagc_py_conf = configuration_data()
|
||||
ratbagc_py_conf.set('LIBRATBAG_DATA_DIR', libratbag_data_dir_devel)
|
||||
ratbagc_py = configure_file(input: 'tools/ratbagc.py.in',
|
||||
output: 'ratbagc.py',
|
||||
configuration: ratbagc_py_conf)
|
||||
custom_target('ratbag-command',
|
||||
output : 'ratbag-command',
|
||||
input : ['tools/ratbagctl.in', 'tools/ratbagc.py'],
|
||||
input : ['tools/ratbagctl.in', ratbagc_py],
|
||||
build_by_default : true,
|
||||
command : [py3, join_paths(meson.source_root(), 'tools', 'merge_ratbagd.py'),
|
||||
'@INPUT@',
|
||||
'--output', '@OUTPUT@',
|
||||
'--version', meson.project_version()],
|
||||
install: false)
|
||||
|
||||
#### output files ####
|
||||
configure_file(output: 'config.h', install: false, configuration: config_h)
|
||||
|
||||
subdir('doc')
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
option('udev-dir',
|
||||
type: 'string',
|
||||
value: '',
|
||||
description: 'udev base directory [default=$prefix/lib/udev]')
|
||||
type: 'string',
|
||||
value: '',
|
||||
description: 'udev base directory [default=$prefix/lib/udev]')
|
||||
|
||||
option('enable-tests',
|
||||
option('tests',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'Build the tests (default=yes)')
|
||||
@@ -27,3 +27,19 @@ option('dbus-group',
|
||||
type: 'string',
|
||||
value : '',
|
||||
description : 'The UNIX group that is granted access to the ratbagd D-Bus service. By default all users may access it.')
|
||||
|
||||
option('systemd',
|
||||
type : 'boolean',
|
||||
value : true,
|
||||
description : 'Build systemd unit files')
|
||||
|
||||
option('logind-provider',
|
||||
type : 'combo',
|
||||
choices: [ 'elogind', 'systemd'],
|
||||
value : 'systemd',
|
||||
description : 'Which logind provider to use')
|
||||
|
||||
option('coverity',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Enable coverity build fixes, see meson.build for details [default=false]')
|
||||
|
||||
@@ -58,6 +58,8 @@ static int ratbagd_button_get_type(sd_bus *bus,
|
||||
|
||||
t = ratbag_button_get_type(button->lib_button);
|
||||
|
||||
verify_unsigned_int(t);
|
||||
|
||||
return sd_bus_message_append(reply, "u", t);
|
||||
}
|
||||
|
||||
@@ -74,6 +76,8 @@ static int ratbagd_button_get_button(sd_bus *bus,
|
||||
|
||||
b = ratbag_button_get_button(button->lib_button);
|
||||
|
||||
verify_unsigned_int(b);
|
||||
|
||||
return sd_bus_message_append(reply, "u", b);
|
||||
}
|
||||
|
||||
@@ -128,8 +132,14 @@ static int ratbagd_button_get_special(sd_bus *bus,
|
||||
enum ratbag_button_action_special special;
|
||||
|
||||
special = ratbag_button_get_special(button->lib_button);
|
||||
if (special == RATBAG_BUTTON_ACTION_SPECIAL_INVALID)
|
||||
special = RATBAG_BUTTON_ACTION_SPECIAL_UNKNOWN;
|
||||
|
||||
return sd_bus_message_append(reply, "u", special);
|
||||
verify_unsigned_int(special);
|
||||
|
||||
CHECK_CALL(sd_bus_message_append(reply, "u", special));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_button_set_special(sd_bus *bus,
|
||||
@@ -144,9 +154,7 @@ static int ratbagd_button_set_special(sd_bus *bus,
|
||||
enum ratbag_button_action_special special;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_read(m, "u", &special);
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_read(m, "u", &special));
|
||||
|
||||
r = ratbag_button_set_special(button->lib_button, special);
|
||||
|
||||
@@ -180,12 +188,9 @@ static int ratbagd_button_get_macro(sd_bus *bus,
|
||||
{
|
||||
struct ratbagd_button *button = userdata;
|
||||
_cleanup_(ratbag_button_macro_unrefp) struct ratbag_button_macro *macro = NULL;
|
||||
int r;
|
||||
unsigned int idx;
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "(uu)");
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_open_container(reply, 'a', "(uu)"));
|
||||
|
||||
macro = ratbag_button_get_macro(button->lib_button);
|
||||
if (!macro)
|
||||
@@ -213,13 +218,16 @@ static int ratbagd_button_get_macro(sd_bus *bus,
|
||||
abort();
|
||||
}
|
||||
|
||||
r = sd_bus_message_append(reply, "(uu)", type, value);
|
||||
if (r < 0)
|
||||
return r;
|
||||
verify_unsigned_int(type);
|
||||
verify_unsigned_int(value);
|
||||
|
||||
CHECK_CALL(sd_bus_message_append(reply, "(uu)", type, value));
|
||||
}
|
||||
|
||||
out:
|
||||
return sd_bus_message_close_container(reply);
|
||||
CHECK_CALL(sd_bus_message_close_container(reply));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_button_set_macro(sd_bus *bus,
|
||||
@@ -235,9 +243,7 @@ static int ratbagd_button_set_macro(sd_bus *bus,
|
||||
int r, idx = 0;
|
||||
_cleanup_(ratbag_button_macro_unrefp) struct ratbag_button_macro *macro = NULL;
|
||||
|
||||
r = sd_bus_message_enter_container(m, 'a', "(uu)");
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_enter_container(m, 'a', "(uu)"));
|
||||
|
||||
macro = ratbag_button_macro_new("macro");
|
||||
while ((r = sd_bus_message_read(m, "(uu)", &type, &value)) > 0) {
|
||||
@@ -251,9 +257,7 @@ static int ratbagd_button_set_macro(sd_bus *bus,
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_exit_container(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_exit_container(m));
|
||||
|
||||
r = ratbag_button_set_macro(button->lib_button, macro);
|
||||
if (r < 0) {
|
||||
@@ -295,7 +299,11 @@ static int ratbagd_button_get_action_type(sd_bus *bus,
|
||||
if (type == RATBAG_BUTTON_ACTION_TYPE_KEY)
|
||||
type = RATBAG_BUTTON_ACTION_TYPE_UNKNOWN;
|
||||
|
||||
return sd_bus_message_append(reply, "u", type);
|
||||
verify_unsigned_int(type);
|
||||
|
||||
CHECK_CALL(sd_bus_message_append(reply, "u", type));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_button_get_action_types(sd_bus *bus,
|
||||
@@ -307,7 +315,6 @@ static int ratbagd_button_get_action_types(sd_bus *bus,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
struct ratbagd_button *button = userdata;
|
||||
int r;
|
||||
enum ratbag_button_action_type types[] = {
|
||||
RATBAG_BUTTON_ACTION_TYPE_BUTTON,
|
||||
RATBAG_BUTTON_ACTION_TYPE_SPECIAL,
|
||||
@@ -316,20 +323,19 @@ static int ratbagd_button_get_action_types(sd_bus *bus,
|
||||
enum ratbag_button_action_type *t;
|
||||
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "u");
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_open_container(reply, 'a', "u"));
|
||||
|
||||
ARRAY_FOR_EACH(types, t) {
|
||||
if (!ratbag_button_has_action_type(button->lib_button, *t))
|
||||
continue;
|
||||
|
||||
r = sd_bus_message_append(reply, "u", *t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
verify_unsigned_int(*t);
|
||||
CHECK_CALL(sd_bus_message_append(reply, "u", *t));
|
||||
}
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
CHECK_CALL(sd_bus_message_close_container(reply));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_button_disable(sd_bus_message *m,
|
||||
@@ -339,9 +345,7 @@ static int ratbagd_button_disable(sd_bus_message *m,
|
||||
struct ratbagd_button *button = userdata;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_read(m, "");
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_read(m, ""));
|
||||
|
||||
r = ratbag_button_disable(button->lib_button);
|
||||
if (r < 0) {
|
||||
@@ -351,7 +355,9 @@ static int ratbagd_button_disable(sd_bus_message *m,
|
||||
return r;
|
||||
}
|
||||
|
||||
return sd_bus_reply_method_return(m, "u", 0);
|
||||
CHECK_CALL(sd_bus_reply_method_return(m, "u", 0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const sd_bus_vtable ratbagd_button_vtable[] = {
|
||||
@@ -427,3 +433,15 @@ struct ratbagd_button *ratbagd_button_free(struct ratbagd_button *button)
|
||||
return mfree(button);
|
||||
}
|
||||
|
||||
int ratbagd_button_resync(sd_bus *bus,
|
||||
struct ratbagd_button *button)
|
||||
{
|
||||
return sd_bus_emit_properties_changed(bus,
|
||||
button->path,
|
||||
RATBAGD_NAME_ROOT ".Button",
|
||||
"ButtonMapping",
|
||||
"SpecialMapping",
|
||||
"Macro",
|
||||
"ActionType",
|
||||
NULL);
|
||||
}
|
||||
|
||||
@@ -130,7 +130,9 @@ static int ratbagd_device_get_device_name(sd_bus *bus,
|
||||
name = "";
|
||||
}
|
||||
|
||||
return sd_bus_message_append(reply, "s", name);
|
||||
CHECK_CALL(sd_bus_message_append(reply, "s", name));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_device_get_svg(sd_bus *bus,
|
||||
@@ -151,7 +153,9 @@ static int ratbagd_device_get_svg(sd_bus *bus,
|
||||
svg = "";
|
||||
}
|
||||
|
||||
return sd_bus_message_append(reply, "s", svg);
|
||||
CHECK_CALL(sd_bus_message_append(reply, "s", svg));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_device_get_theme_svg(sd_bus_message *m,
|
||||
@@ -162,17 +166,13 @@ static int ratbagd_device_get_theme_svg(sd_bus_message *m,
|
||||
char svg_path[PATH_MAX] = {0};
|
||||
const char *theme;
|
||||
const char *svg;
|
||||
int r;
|
||||
const char *datadir;
|
||||
|
||||
datadir = getenv("LIBRATBAG_DATA_DIR");
|
||||
if (!datadir)
|
||||
datadir = LIBRATBAG_DATA_DIR;
|
||||
|
||||
r = sd_bus_message_read(m, "s", &theme);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
CHECK_CALL(sd_bus_message_read(m, "s", &theme));
|
||||
|
||||
svg = ratbag_device_get_svg_name(device->lib_device);
|
||||
if (!svg) {
|
||||
@@ -183,7 +183,48 @@ static int ratbagd_device_get_theme_svg(sd_bus_message *m,
|
||||
|
||||
snprintf(svg_path, sizeof(svg_path), "%s/%s/%s", datadir, theme, svg);
|
||||
|
||||
return sd_bus_reply_method_return(m, "s", svg_path);
|
||||
CHECK_CALL(sd_bus_reply_method_return(m, "s", svg_path));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_device_get_theme_svg_fd(sd_bus_message *m,
|
||||
void *userdata,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
struct ratbagd_device *device = userdata;
|
||||
char svg_path[PATH_MAX] = {0};
|
||||
const char *theme;
|
||||
const char *svg;
|
||||
const char *datadir;
|
||||
_cleanup_close_ int fd = -1;
|
||||
|
||||
datadir = getenv("LIBRATBAG_DATA_DIR");
|
||||
if (!datadir)
|
||||
datadir = LIBRATBAG_DATA_DIR;
|
||||
|
||||
CHECK_CALL(sd_bus_message_read(m, "s", &theme));
|
||||
|
||||
svg = ratbag_device_get_svg_name(device->lib_device);
|
||||
if (!svg) {
|
||||
log_error("%s: failed to fetch SVG, using fallback\n",
|
||||
ratbagd_device_get_sysname(device));
|
||||
svg = FALLBACK_SVG_NAME;
|
||||
}
|
||||
|
||||
snprintf(svg_path, sizeof(svg_path), "%s/%s/%s", datadir, theme, svg);
|
||||
|
||||
fd = open(svg_path, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
log_error("%s: failed to open SVG '%s' (%m)\n",
|
||||
ratbagd_device_get_sysname(device),
|
||||
svg_path);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
CHECK_CALL(sd_bus_reply_method_return(m, "h", fd));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_device_get_profiles(sd_bus *bus,
|
||||
@@ -197,25 +238,32 @@ static int ratbagd_device_get_profiles(sd_bus *bus,
|
||||
struct ratbagd_device *device = userdata;
|
||||
struct ratbagd_profile *profile;
|
||||
unsigned int i;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "o");
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_open_container(reply, 'a', "o"));
|
||||
|
||||
for (i = 0; i < device->n_profiles; ++i) {
|
||||
profile = device->profiles[i];
|
||||
if (!profile)
|
||||
continue;
|
||||
|
||||
r = sd_bus_message_append(reply,
|
||||
"o",
|
||||
ratbagd_profile_get_path(profile));
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_append(reply,
|
||||
"o",
|
||||
ratbagd_profile_get_path(profile)));
|
||||
}
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
CHECK_CALL(sd_bus_message_close_container(reply));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ratbagd_device_commit_pending(void *data)
|
||||
{
|
||||
struct ratbagd_device *device = data;
|
||||
int r;
|
||||
|
||||
r = ratbag_device_commit(device->lib_device);
|
||||
if (r < 0)
|
||||
ratbagd_device_resync(device, device->ctx->bus);
|
||||
}
|
||||
|
||||
static int ratbagd_device_commit(sd_bus_message *m,
|
||||
@@ -223,17 +271,14 @@ static int ratbagd_device_commit(sd_bus_message *m,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
struct ratbagd_device *device = userdata;
|
||||
int r;
|
||||
|
||||
r = ratbag_device_commit(device->lib_device);
|
||||
if (r < 0) {
|
||||
sd_bus *bus = sd_bus_message_get_bus(m);
|
||||
r = ratbagd_device_resync(device, bus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
ratbagd_schedule_task(device->ctx,
|
||||
ratbagd_device_commit_pending,
|
||||
device);
|
||||
|
||||
return sd_bus_reply_method_return(m, "u", 0);
|
||||
CHECK_CALL(sd_bus_reply_method_return(m, "u", 0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -261,23 +306,20 @@ ratbagd_device_get_capabilities(sd_bus *bus,
|
||||
RATBAG_DEVICE_CAP_BUTTON_MACROS,
|
||||
RATBAG_DEVICE_CAP_LED,
|
||||
};
|
||||
int r;
|
||||
size_t i;
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "u");
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_open_container(reply, 'a', "u"));
|
||||
|
||||
for (i = 0; i < ELEMENTSOF(caps); i++) {
|
||||
cap = caps[i];
|
||||
if (ratbag_device_has_capability(lib_device, cap)) {
|
||||
r = sd_bus_message_append(reply, "u", cap);
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_append(reply, "u", cap));
|
||||
}
|
||||
}
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
CHECK_CALL(sd_bus_message_close_container(reply));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const sd_bus_vtable ratbagd_device_vtable[] = {
|
||||
@@ -288,6 +330,7 @@ const sd_bus_vtable ratbagd_device_vtable[] = {
|
||||
SD_BUS_PROPERTY("Svg", "s", ratbagd_device_get_svg, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Profiles", "ao", ratbagd_device_get_profiles, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_METHOD("GetSvg", "s", "s", ratbagd_device_get_theme_svg, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("GetSvgFd", "s", "h", ratbagd_device_get_theme_svg_fd, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("Commit", "", "u", ratbagd_device_commit, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_SIGNAL("Resync", "", 0),
|
||||
SD_BUS_VTABLE_END,
|
||||
@@ -324,10 +367,10 @@ int ratbagd_device_new(struct ratbagd_device **out,
|
||||
device->n_profiles = ratbag_device_get_num_profiles(device->lib_device);
|
||||
device->profiles = zalloc(device->n_profiles * sizeof(*device->profiles));
|
||||
|
||||
log_verbose("%s: \"%s\", %d profiles\n",
|
||||
sysname,
|
||||
ratbag_device_get_name(lib_device),
|
||||
device->n_profiles);
|
||||
log_info("%s: \"%s\", %d profiles\n",
|
||||
sysname,
|
||||
ratbag_device_get_name(lib_device),
|
||||
device->n_profiles);
|
||||
|
||||
for (i = 0; i < device->n_profiles; ++i) {
|
||||
profile = ratbag_device_get_profile(device->lib_device, i);
|
||||
@@ -400,6 +443,10 @@ int ratbagd_device_resync(struct ratbagd_device *device, sd_bus *bus)
|
||||
{
|
||||
assert(device);
|
||||
assert(bus);
|
||||
|
||||
ratbagd_for_each_profile_signal(bus, device,
|
||||
ratbagd_profile_resync);
|
||||
|
||||
return sd_bus_emit_signal(bus,
|
||||
device->path,
|
||||
RATBAGD_NAME_ROOT ".Device",
|
||||
|
||||
@@ -50,20 +50,19 @@ static int ratbagd_led_get_modes(sd_bus *bus,
|
||||
{
|
||||
struct ratbagd_led *led = userdata;
|
||||
enum ratbag_led_mode mode = 0;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "u");
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_open_container(reply, 'a', "u"));
|
||||
|
||||
|
||||
while (mode <= RATBAG_LED_BREATHING) {
|
||||
if (ratbag_led_has_mode(led->lib_led, mode))
|
||||
sd_bus_message_append(reply, "u", mode);
|
||||
CHECK_CALL(sd_bus_message_append(reply, "u", mode));
|
||||
mode++;
|
||||
}
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
CHECK_CALL(sd_bus_message_close_container(reply));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_led_get_mode(sd_bus *bus,
|
||||
@@ -78,7 +77,12 @@ static int ratbagd_led_get_mode(sd_bus *bus,
|
||||
enum ratbag_led_mode mode;
|
||||
|
||||
mode = ratbag_led_get_mode(led->lib_led);
|
||||
return sd_bus_message_append(reply, "u", mode);
|
||||
|
||||
verify_unsigned_int(mode);
|
||||
|
||||
CHECK_CALL(sd_bus_message_append(reply, "u", mode));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_led_set_mode(sd_bus *bus,
|
||||
@@ -93,9 +97,7 @@ static int ratbagd_led_set_mode(sd_bus *bus,
|
||||
enum ratbag_led_mode mode;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_read(m, "u", &mode);
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_read(m, "u", &mode));
|
||||
|
||||
r = ratbag_led_set_mode(led->lib_led, mode);
|
||||
|
||||
@@ -124,7 +126,11 @@ static int ratbagd_led_get_type(sd_bus *bus,
|
||||
|
||||
type = ratbag_led_get_type(led->lib_led);
|
||||
|
||||
return sd_bus_message_append(reply, "u", type);
|
||||
verify_unsigned_int(type);
|
||||
|
||||
CHECK_CALL(sd_bus_message_append(reply, "u", type));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_led_get_color(sd_bus *bus,
|
||||
@@ -139,7 +145,9 @@ static int ratbagd_led_get_color(sd_bus *bus,
|
||||
struct ratbag_color c;
|
||||
|
||||
c = ratbag_led_get_color(led->lib_led);
|
||||
return sd_bus_message_append(reply, "(uuu)", c.red, c.green, c.blue);
|
||||
CHECK_CALL(sd_bus_message_append(reply, "(uuu)", c.red, c.green, c.blue));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_led_set_color(sd_bus *bus,
|
||||
@@ -154,9 +162,7 @@ static int ratbagd_led_set_color(sd_bus *bus,
|
||||
struct ratbag_color c;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_read(m, "(uuu)", &c.red, &c.green, &c.blue);
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_read(m, "(uuu)", &c.red, &c.green, &c.blue));
|
||||
|
||||
if (c.red > 255)
|
||||
c.red = 255;
|
||||
@@ -191,7 +197,12 @@ static int ratbagd_led_get_effect_duration(sd_bus *bus,
|
||||
int rate;
|
||||
|
||||
rate = ratbag_led_get_effect_duration(led->lib_led);
|
||||
return sd_bus_message_append(reply, "u", rate);
|
||||
|
||||
verify_unsigned_int(rate);
|
||||
|
||||
CHECK_CALL(sd_bus_message_append(reply, "u", rate));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_led_set_effect_duration(sd_bus *bus,
|
||||
@@ -206,9 +217,7 @@ static int ratbagd_led_set_effect_duration(sd_bus *bus,
|
||||
unsigned int rate;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_read(m, "u", &rate);
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_read(m, "u", &rate));
|
||||
|
||||
if (rate > 10000)
|
||||
rate = 10000;
|
||||
@@ -239,7 +248,12 @@ static int ratbagd_led_get_brightness(sd_bus *bus,
|
||||
unsigned int brightness;
|
||||
|
||||
brightness = ratbag_led_get_brightness(led->lib_led);
|
||||
return sd_bus_message_append(reply, "u", brightness);
|
||||
|
||||
verify_unsigned_int(brightness);
|
||||
|
||||
CHECK_CALL(sd_bus_message_append(reply, "u", brightness));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_led_set_brightness(sd_bus *bus,
|
||||
@@ -254,9 +268,7 @@ static int ratbagd_led_set_brightness(sd_bus *bus,
|
||||
unsigned int brightness;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_read(m, "u", &brightness);
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_read(m, "u", &brightness));
|
||||
|
||||
if (brightness > 255)
|
||||
brightness = 255;
|
||||
@@ -348,3 +360,15 @@ struct ratbagd_led *ratbagd_led_free(struct ratbagd_led *led)
|
||||
return mfree(led);
|
||||
}
|
||||
|
||||
int ratbagd_led_resync(sd_bus *bus,
|
||||
struct ratbagd_led *led)
|
||||
{
|
||||
return sd_bus_emit_properties_changed(bus,
|
||||
led->path,
|
||||
RATBAGD_NAME_ROOT ".Led",
|
||||
"Mode",
|
||||
"Color",
|
||||
"EffectDuration",
|
||||
"Brightness",
|
||||
NULL);
|
||||
}
|
||||
|
||||
@@ -102,25 +102,22 @@ static int ratbagd_profile_get_resolutions(sd_bus *bus,
|
||||
struct ratbagd_profile *profile = userdata;
|
||||
struct ratbagd_resolution *resolution;
|
||||
unsigned int i;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "o");
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_open_container(reply, 'a', "o"));
|
||||
|
||||
for (i = 0; i < profile->n_resolutions; ++i) {
|
||||
resolution = profile->resolutions[i];
|
||||
if (!resolution)
|
||||
continue;
|
||||
|
||||
r = sd_bus_message_append(reply,
|
||||
"o",
|
||||
ratbagd_resolution_get_path(resolution));
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_append(reply,
|
||||
"o",
|
||||
ratbagd_resolution_get_path(resolution)));
|
||||
}
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
CHECK_CALL(sd_bus_message_close_container(reply));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_profile_get_buttons(sd_bus *bus,
|
||||
@@ -134,25 +131,22 @@ static int ratbagd_profile_get_buttons(sd_bus *bus,
|
||||
struct ratbagd_profile *profile = userdata;
|
||||
struct ratbagd_button *button;
|
||||
unsigned int i;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "o");
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_open_container(reply, 'a', "o"));
|
||||
|
||||
for (i = 0; i < profile->n_buttons; ++i) {
|
||||
button = profile->buttons[i];
|
||||
if (!button)
|
||||
continue;
|
||||
|
||||
r = sd_bus_message_append(reply,
|
||||
CHECK_CALL(sd_bus_message_append(reply,
|
||||
"o",
|
||||
ratbagd_button_get_path(button));
|
||||
if (r < 0)
|
||||
return r;
|
||||
ratbagd_button_get_path(button)));
|
||||
}
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
CHECK_CALL(sd_bus_message_close_container(reply));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_profile_get_leds(sd_bus *bus,
|
||||
@@ -166,25 +160,22 @@ static int ratbagd_profile_get_leds(sd_bus *bus,
|
||||
struct ratbagd_profile *profile = userdata;
|
||||
struct ratbagd_led *led;
|
||||
unsigned int i;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "o");
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_open_container(reply, 'a', "o"));
|
||||
|
||||
for (i = 0; i < profile->n_leds; ++i) {
|
||||
led = profile->leds[i];
|
||||
if (!led)
|
||||
continue;
|
||||
|
||||
r = sd_bus_message_append(reply,
|
||||
"o",
|
||||
ratbagd_led_get_path(led));
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_append(reply,
|
||||
"o",
|
||||
ratbagd_led_get_path(led)));
|
||||
}
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
CHECK_CALL(sd_bus_message_close_container(reply));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_profile_is_active(sd_bus *bus,
|
||||
@@ -198,9 +189,11 @@ static int ratbagd_profile_is_active(sd_bus *bus,
|
||||
struct ratbagd_profile *profile = userdata;
|
||||
int is_active;
|
||||
|
||||
is_active = !!ratbag_profile_is_active(profile->lib_profile);
|
||||
is_active = ratbag_profile_is_active(profile->lib_profile);
|
||||
|
||||
return sd_bus_message_append(reply, "b", is_active);
|
||||
CHECK_CALL(sd_bus_message_append(reply, "b", is_active));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_profile_find_button(sd_bus *bus,
|
||||
@@ -286,9 +279,7 @@ static int ratbagd_profile_set_active(sd_bus_message *m,
|
||||
struct ratbagd_profile *profile = userdata;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_read(m, "");
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_read(m, ""));
|
||||
|
||||
r = ratbag_profile_set_active(profile->lib_profile);
|
||||
if (r < 0) {
|
||||
@@ -302,7 +293,9 @@ static int ratbagd_profile_set_active(sd_bus_message *m,
|
||||
profile->device,
|
||||
ratbagd_profile_active_signal_cb);
|
||||
|
||||
return sd_bus_reply_method_return(m, "u", 0);
|
||||
CHECK_CALL(sd_bus_reply_method_return(m, "u", 0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -318,9 +311,7 @@ ratbagd_profile_set_enabled(sd_bus *bus,
|
||||
int enabled;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_read(m, "b", &enabled);
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_read(m, "b", &enabled));
|
||||
|
||||
r = ratbag_profile_set_enabled(profile->lib_profile, enabled);
|
||||
if (r == 0) {
|
||||
@@ -347,7 +338,9 @@ ratbagd_profile_is_enabled(sd_bus *bus,
|
||||
struct ratbagd_profile *profile = userdata;
|
||||
int enabled = ratbag_profile_is_enabled(profile->lib_profile) != 0;
|
||||
|
||||
return sd_bus_message_append(reply, "b", enabled);
|
||||
CHECK_CALL(sd_bus_message_append(reply, "b", enabled));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -363,9 +356,7 @@ ratbagd_profile_set_name(sd_bus *bus,
|
||||
char *name;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_read(m, "s", &name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_read(m, "s", &name));
|
||||
|
||||
r = ratbag_profile_set_name(profile->lib_profile, name);
|
||||
|
||||
@@ -392,7 +383,9 @@ ratbagd_profile_get_name(sd_bus *bus,
|
||||
struct ratbagd_profile *profile = userdata;
|
||||
const char *name = ratbag_profile_get_name(profile->lib_profile);
|
||||
|
||||
return sd_bus_message_append(reply, "s", name);
|
||||
CHECK_CALL(sd_bus_message_append(reply, "s", name));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -410,23 +403,20 @@ ratbagd_profile_get_capabilities(sd_bus *bus,
|
||||
enum ratbag_profile_capability caps[] = {
|
||||
RATBAG_PROFILE_CAP_WRITABLE_NAME,
|
||||
};
|
||||
int r;
|
||||
size_t i;
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "u");
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_open_container(reply, 'a', "u"));
|
||||
|
||||
for (i = 0; i < ELEMENTSOF(caps); i++) {
|
||||
cap = caps[i];
|
||||
if (ratbag_profile_has_capability(lib_profile, cap)) {
|
||||
r = sd_bus_message_append(reply, "u", cap);
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_append(reply, "u", cap));
|
||||
}
|
||||
}
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
CHECK_CALL(sd_bus_message_close_container(reply));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const sd_bus_vtable ratbagd_profile_vtable[] = {
|
||||
@@ -798,3 +788,47 @@ int ratbagd_for_each_resolution_signal(sd_bus *bus,
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ratbagd_for_each_button_signal(sd_bus *bus,
|
||||
struct ratbagd_profile *profile,
|
||||
int (*func)(sd_bus *bus,
|
||||
struct ratbagd_button *button))
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
for (size_t i = 0; rc == 0 && i < profile->n_buttons; i++)
|
||||
rc = func(bus, profile->buttons[i]);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ratbagd_for_each_led_signal(sd_bus *bus,
|
||||
struct ratbagd_profile *profile,
|
||||
int (*func)(sd_bus *bus,
|
||||
struct ratbagd_led *button))
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
for (size_t i = 0; rc == 0 && i < profile->n_leds; i++)
|
||||
rc = func(bus, profile->leds[i]);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int ratbagd_profile_resync(sd_bus *bus,
|
||||
struct ratbagd_profile *profile)
|
||||
{
|
||||
ratbagd_for_each_resolution_signal(bus, profile, ratbagd_resolution_resync);
|
||||
ratbagd_for_each_button_signal(bus, profile, ratbagd_button_resync);
|
||||
ratbagd_for_each_led_signal(bus, profile, ratbagd_led_resync);
|
||||
|
||||
return sd_bus_emit_properties_changed(bus,
|
||||
profile->path,
|
||||
RATBAGD_NAME_ROOT ".Profile",
|
||||
"Resolutions",
|
||||
"Buttons",
|
||||
"Leds",
|
||||
"IsActive",
|
||||
NULL);
|
||||
}
|
||||
|
||||
@@ -45,6 +45,19 @@ struct ratbagd_resolution {
|
||||
char *path;
|
||||
};
|
||||
|
||||
int ratbagd_resolution_resync(sd_bus *bus,
|
||||
struct ratbagd_resolution *resolution)
|
||||
{
|
||||
return sd_bus_emit_properties_changed(bus,
|
||||
resolution->path,
|
||||
RATBAGD_NAME_ROOT ".Resolution",
|
||||
"IsDefault",
|
||||
"Resolution",
|
||||
"ReportRate",
|
||||
"IsActive",
|
||||
NULL);
|
||||
}
|
||||
|
||||
static int ratbagd_resolution_active_signal_cb(sd_bus *bus,
|
||||
struct ratbagd_resolution *resolution)
|
||||
{
|
||||
@@ -167,7 +180,7 @@ ratbagd_resolution_is_active(sd_bus *bus,
|
||||
struct ratbag_resolution *lib_resolution = resolution->lib_resolution;
|
||||
int is_active;
|
||||
|
||||
is_active = !!ratbag_resolution_is_active(lib_resolution);
|
||||
is_active = ratbag_resolution_is_active(lib_resolution);
|
||||
|
||||
return sd_bus_message_append(reply, "b", is_active);
|
||||
}
|
||||
@@ -185,7 +198,7 @@ ratbagd_resolution_is_default(sd_bus *bus,
|
||||
struct ratbag_resolution *lib_resolution = resolution->lib_resolution;
|
||||
int is_default;
|
||||
|
||||
is_default = !!ratbag_resolution_is_default(lib_resolution);
|
||||
is_default = ratbag_resolution_is_default(lib_resolution);
|
||||
|
||||
return sd_bus_message_append(reply, "b", is_default);
|
||||
}
|
||||
@@ -214,6 +227,7 @@ ratbagd_resolution_get_resolutions(sd_bus *bus,
|
||||
assert(ndpis <= ARRAY_LENGTH(dpis));
|
||||
|
||||
for (unsigned int i = 0; i < ndpis; i++) {
|
||||
verify_unsigned_int(dpis[i]);
|
||||
r = sd_bus_message_append(reply, "u", dpis[i]);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -238,6 +252,9 @@ ratbagd_resolution_get_resolution(sd_bus *bus,
|
||||
xres = ratbag_resolution_get_dpi_x(lib_resolution);
|
||||
yres = ratbag_resolution_get_dpi_y(lib_resolution);
|
||||
|
||||
verify_unsigned_int(xres);
|
||||
verify_unsigned_int(yres);
|
||||
|
||||
return sd_bus_message_append(reply, "(uu)", xres, yres);
|
||||
}
|
||||
|
||||
@@ -293,6 +310,7 @@ ratbagd_resolution_get_report_rate(sd_bus *bus,
|
||||
int rate;
|
||||
|
||||
rate = ratbag_resolution_get_report_rate(lib_resolution);
|
||||
verify_unsigned_int(rate);
|
||||
return sd_bus_message_append(reply, "u", rate);
|
||||
}
|
||||
|
||||
@@ -307,7 +325,7 @@ ratbagd_resolution_get_report_rates(sd_bus *bus,
|
||||
{
|
||||
struct ratbagd_resolution *resolution = userdata;
|
||||
struct ratbag_resolution *lib_resolution = resolution->lib_resolution;
|
||||
unsigned int rates[5];
|
||||
unsigned int rates[8];
|
||||
unsigned int nrates = ARRAY_LENGTH(rates);
|
||||
int r;
|
||||
|
||||
@@ -320,6 +338,7 @@ ratbagd_resolution_get_report_rates(sd_bus *bus,
|
||||
assert(nrates <= ARRAY_LENGTH(rates));
|
||||
|
||||
for (unsigned int i = 0; i < nrates; i++) {
|
||||
verify_unsigned_int(rates[i]);
|
||||
r = sd_bus_message_append(reply, "u", rates[i]);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -42,8 +42,12 @@
|
||||
|
||||
#include "ratbagd-test.h"
|
||||
|
||||
static bool verbose = false;
|
||||
static bool verbose_raw = false;
|
||||
enum log_level {
|
||||
LL_QUIET = 1,
|
||||
LL_INFO,
|
||||
LL_VERBOSE,
|
||||
LL_RAW,
|
||||
} log_level = LL_INFO;
|
||||
|
||||
static const char *SVG_THEMES[] = {
|
||||
"default",
|
||||
@@ -51,13 +55,23 @@ static const char *SVG_THEMES[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
void log_info(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
if (log_level >= LL_INFO)
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void log_verbose(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
|
||||
if (verbose)
|
||||
if (log_level >= LL_VERBOSE)
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
@@ -142,21 +156,18 @@ static int ratbagd_get_devices(sd_bus *bus,
|
||||
{
|
||||
struct ratbagd *ctx = userdata;
|
||||
struct ratbagd_device *device;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "o");
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_open_container(reply, 'a', "o"));
|
||||
|
||||
RATBAGD_DEVICE_FOREACH(device, ctx) {
|
||||
r = sd_bus_message_append(reply,
|
||||
"o",
|
||||
ratbagd_device_get_path(device));
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_append(reply,
|
||||
"o",
|
||||
ratbagd_device_get_path(device)));
|
||||
}
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
CHECK_CALL(sd_bus_message_close_container(reply));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_get_themes(sd_bus *bus,
|
||||
@@ -169,23 +180,18 @@ static int ratbagd_get_themes(sd_bus *bus,
|
||||
{
|
||||
struct ratbagd *ctx = userdata;
|
||||
const char **theme;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "s");
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_open_container(reply, 'a', "s"));
|
||||
|
||||
theme = ctx->themes;
|
||||
while(*theme) {
|
||||
r = sd_bus_message_append(reply,
|
||||
"s",
|
||||
*theme);
|
||||
if (r < 0)
|
||||
return r;
|
||||
CHECK_CALL(sd_bus_message_append(reply, "s", *theme));
|
||||
theme++;
|
||||
}
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
CHECK_CALL(sd_bus_message_close_container(reply));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const sd_bus_vtable ratbagd_vtable[] = {
|
||||
@@ -384,10 +390,10 @@ static int ratbagd_new(struct ratbagd **out)
|
||||
if (!ctx->lib_ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
if (verbose_raw)
|
||||
if (log_level >= LL_RAW)
|
||||
ratbag_log_set_priority(ctx->lib_ctx,
|
||||
RATBAG_LOG_PRIORITY_RAW);
|
||||
else if (verbose)
|
||||
else if (log_level >= LL_VERBOSE)
|
||||
ratbag_log_set_priority(ctx->lib_ctx,
|
||||
RATBAG_LOG_PRIORITY_DEBUG);
|
||||
|
||||
@@ -483,6 +489,26 @@ exit:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int on_timeout_cb(sd_event_source *s, uint64_t usec, void *userdata)
|
||||
{
|
||||
log_info("Exiting after idle\n");
|
||||
sd_event_exit(sd_event_source_get_event(s), 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int before_idle_cb(sd_event_source *s, void *userdata)
|
||||
{
|
||||
struct ratbagd *ctx = userdata;
|
||||
uint64_t usec;
|
||||
|
||||
sd_event_now(sd_event_source_get_event(s), CLOCK_MONOTONIC, &usec);
|
||||
#define min2us(us_) (us_ * 1000000 * 60)
|
||||
usec += min2us(20);
|
||||
sd_event_source_set_time(ctx->timeout_source, usec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sighandler(sd_event_source *source,
|
||||
const struct signalfd_siginfo *si,
|
||||
void *userdata)
|
||||
@@ -496,18 +522,6 @@ static int ratbagd_run(struct ratbagd *ctx)
|
||||
{
|
||||
int r;
|
||||
|
||||
/*
|
||||
* TODO: We should support exit-on-idle and bus-activation. Note that
|
||||
* we don't store any state on our own, hence, all we have to do
|
||||
* is to make sure we advertise device add/remove events via the
|
||||
* bus (in case there is a listener).
|
||||
* To track such events, we should store devices we already
|
||||
* advertised in /run/ratbagd/devices/ and read it out on
|
||||
* activation.
|
||||
* Note that this feature requires udev-activation, which might
|
||||
* not be possible, yet.
|
||||
*/
|
||||
|
||||
r = ratbagd_run_enumerate(ctx);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -518,6 +532,24 @@ static int ratbagd_run(struct ratbagd *ctx)
|
||||
sigprocmask(SIG_BLOCK, &sigset, NULL);
|
||||
sd_event_add_signal(ctx->event, NULL, SIGINT, sighandler, NULL);
|
||||
|
||||
/* exit-on-idle: we set up a timer to simply exit. Since we don't
|
||||
* store anything, it doesn't matter and we can just restart next
|
||||
* time someone wants us.
|
||||
*
|
||||
* since we don't want to monitor every single dbus call, we just
|
||||
* set up a post source that gets called before we go idle. That
|
||||
* resets the timer, so as long as something is happening, ratbagd
|
||||
* won't exit.
|
||||
*/
|
||||
sd_event_add_time(ctx->event,
|
||||
&ctx->timeout_source,
|
||||
CLOCK_MONOTONIC,
|
||||
-1, /* infinite, see before_idle_cb */
|
||||
min2us(1), /* accuracy doesn't matter */
|
||||
on_timeout_cb,
|
||||
ctx);
|
||||
sd_event_add_post(ctx->event, NULL, before_idle_cb, ctx);
|
||||
|
||||
return sd_event_loop(ctx->event);
|
||||
}
|
||||
|
||||
@@ -533,12 +565,17 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
if (streq(argv[1], "--verbose=raw")) {
|
||||
verbose_raw = true;
|
||||
if (streq(argv[1], "--version")) {
|
||||
printf("%s\n", RATBAG_VERSION);
|
||||
return 0;
|
||||
} else if (streq(argv[1], "--quiet")) {
|
||||
log_level = LL_QUIET;
|
||||
} else if (streq(argv[1], "--verbose=raw")) {
|
||||
log_level = LL_RAW;
|
||||
} else if (streq(argv[1], "--verbose")) {
|
||||
verbose = true;
|
||||
log_level = LL_VERBOSE;
|
||||
} else {
|
||||
fprintf(stderr, "Usage: %s [--verbose[=raw]]\n",
|
||||
fprintf(stderr, "Usage: %s [--version | --quiet | --verbose[=raw]]\n",
|
||||
program_invocation_short_name);
|
||||
r = -EINVAL;
|
||||
goto exit;
|
||||
@@ -557,10 +594,46 @@ exit:
|
||||
ratbagd_free(ctx);
|
||||
|
||||
if (r < 0) {
|
||||
errno = -r;
|
||||
log_error("Failed to start ratbagd: %m\n");
|
||||
if (r == -EEXIST) {
|
||||
log_error("Bus name is taken, another instance of ratbagd is already running.\n");
|
||||
} else {
|
||||
errno = -r;
|
||||
log_error("Failed to start ratbagd: %m\n");
|
||||
}
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
struct ratbagd_callback
|
||||
{
|
||||
ratbagd_callback_t callback;
|
||||
void *userdata;
|
||||
};
|
||||
|
||||
static int ratbagd_callback_handler(sd_event_source *s, void *userdata)
|
||||
{
|
||||
struct ratbagd_callback *cb = userdata;
|
||||
|
||||
cb->callback(cb->userdata);
|
||||
|
||||
sd_event_source_set_enabled(s, SD_EVENT_OFF);
|
||||
sd_event_source_unref(s);
|
||||
free(cb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ratbagd_schedule_task(struct ratbagd *ctx,
|
||||
ratbagd_callback_t callback,
|
||||
void *userdata)
|
||||
{
|
||||
struct ratbagd_callback *cb = zalloc(sizeof *cb);
|
||||
sd_event_source *source;
|
||||
|
||||
cb->callback = callback;
|
||||
cb->userdata = userdata;
|
||||
|
||||
sd_event_add_post(ctx->event, &source, ratbagd_callback_handler, cb);
|
||||
}
|
||||
|
||||
@@ -54,9 +54,20 @@ struct ratbagd_resolution;
|
||||
struct ratbagd_button;
|
||||
struct ratbagd_led;
|
||||
|
||||
void log_info(const char *fmt, ...) _printf_(1, 2);
|
||||
void log_verbose(const char *fmt, ...) _printf_(1, 2);
|
||||
void log_error(const char *fmt, ...) _printf_(1, 2);
|
||||
|
||||
#define CHECK_CALL(_call) \
|
||||
do { \
|
||||
int _r = _call; \
|
||||
if (_r < 0) { \
|
||||
log_error("%s: '%s' failed with: %s\n", __func__, #_call, strerror(-_r)); \
|
||||
return _r; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Profiles
|
||||
*/
|
||||
@@ -89,6 +100,15 @@ int ratbagd_for_each_resolution_signal(sd_bus *bus,
|
||||
struct ratbagd_profile *profile,
|
||||
int (*func)(sd_bus *bus,
|
||||
struct ratbagd_resolution *resolution));
|
||||
int ratbagd_for_each_button_signal(sd_bus *bus,
|
||||
struct ratbagd_profile *profile,
|
||||
int (*func)(sd_bus *bus,
|
||||
struct ratbagd_button *button));
|
||||
int ratbagd_for_each_led_signal(sd_bus *bus,
|
||||
struct ratbagd_profile *profile,
|
||||
int (*func)(sd_bus *bus,
|
||||
struct ratbagd_led *led));
|
||||
int ratbagd_profile_resync(sd_bus *bus, struct ratbagd_profile *profile);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct ratbagd_profile *, ratbagd_profile_free);
|
||||
|
||||
@@ -104,6 +124,7 @@ int ratbagd_resolution_new(struct ratbagd_resolution **out,
|
||||
unsigned int index);
|
||||
struct ratbagd_resolution *ratbagd_resolution_free(struct ratbagd_resolution *resolution);
|
||||
const char *ratbagd_resolution_get_path(struct ratbagd_resolution *resolution);
|
||||
int ratbagd_resolution_resync(sd_bus *bus, struct ratbagd_resolution *resolution);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct ratbagd_resolution *, ratbagd_resolution_free);
|
||||
|
||||
@@ -119,6 +140,7 @@ int ratbagd_button_new(struct ratbagd_button **out,
|
||||
unsigned int index);
|
||||
struct ratbagd_button *ratbagd_button_free(struct ratbagd_button *button);
|
||||
const char *ratbagd_button_get_path(struct ratbagd_button *button);
|
||||
int ratbagd_button_resync(sd_bus *bus, struct ratbagd_button *button);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct ratbagd_button *, ratbagd_button_free);
|
||||
|
||||
@@ -134,6 +156,7 @@ int ratbagd_led_new(struct ratbagd_led **out,
|
||||
unsigned int index);
|
||||
struct ratbagd_led *ratbagd_led_free(struct ratbagd_led *led);
|
||||
const char *ratbagd_led_get_path(struct ratbagd_led *led);
|
||||
int ratbagd_led_resync(sd_bus *bus, struct ratbagd_led *led);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct ratbagd_led *, ratbagd_led_free);
|
||||
|
||||
@@ -176,6 +199,19 @@ struct ratbagd_device *ratbagd_device_next(struct ratbagd_device *device);
|
||||
(_device); \
|
||||
_device = (_safe), \
|
||||
_safe = (_safe) ? ratbagd_device_next(_safe) : NULL)
|
||||
|
||||
/* Verify that _val is not -1. This traps DBus API errors where we end up
|
||||
* sending a valid-looking index across and then fail on the other side.
|
||||
*
|
||||
* do {} while(0) so we can terminate with a ; without the compiler
|
||||
* complaining about an empty statement;
|
||||
* */
|
||||
#define verify_unsigned_int(_val) \
|
||||
do { if ((int)_val == -1) { \
|
||||
log_error("%s:%d - %s: expected unsigned int, got -1\n", __FILE__, __LINE__, __func__); \
|
||||
return -EINVAL; \
|
||||
} } while(0)
|
||||
|
||||
/*
|
||||
* Context
|
||||
*/
|
||||
@@ -184,6 +220,7 @@ struct ratbagd {
|
||||
sd_event *event;
|
||||
struct ratbag *lib_ctx;
|
||||
struct udev_monitor *monitor;
|
||||
sd_event_source *timeout_source;
|
||||
sd_event_source *monitor_source;
|
||||
sd_bus *bus;
|
||||
|
||||
@@ -192,3 +229,9 @@ struct ratbagd {
|
||||
|
||||
const char **themes; /* NULL-terminated */
|
||||
};
|
||||
|
||||
typedef void (*ratbagd_callback_t)(void *userdata);
|
||||
|
||||
void ratbagd_schedule_task(struct ratbagd *ctx,
|
||||
ratbagd_callback_t callback,
|
||||
void *userdata);
|
||||
|
||||
@@ -987,7 +987,7 @@ gskill_read_resolutions(struct ratbag_profile *profile,
|
||||
hz = GSKILL_MAX_POLLING_RATE / (report->polling_rate + 1);
|
||||
|
||||
for (i = 0; i < report->dpi_num; i++) {
|
||||
_cleanup_resolution_ struct ratbag_resolution *resolution;
|
||||
_cleanup_resolution_ struct ratbag_resolution *resolution = NULL;
|
||||
unsigned int rates[] = { 500, 1000 }; /* let's assume that is true */
|
||||
|
||||
dpi_x = report->dpi_levels[i].x * GSKILL_DPI_UNIT;
|
||||
@@ -1108,7 +1108,7 @@ gskill_update_resolutions(struct ratbag_profile *profile)
|
||||
* lost on exit
|
||||
*/
|
||||
for (i = 0; i < GSKILL_NUM_DPI; i++) {
|
||||
_cleanup_resolution_ struct ratbag_resolution *res;
|
||||
_cleanup_resolution_ struct ratbag_resolution *res = NULL;
|
||||
struct gskill_raw_dpi_level *level =
|
||||
&report->dpi_levels[report->dpi_num];
|
||||
|
||||
|
||||
@@ -407,8 +407,14 @@ hidpp10drv_read_profile(struct ratbag_profile *profile)
|
||||
if (rc)
|
||||
return;
|
||||
|
||||
ratbag_profile_set_cap(profile, RATBAG_PROFILE_CAP_WRITABLE_NAME);
|
||||
|
||||
profile->is_enabled = p.enabled;
|
||||
|
||||
if (profile->name)
|
||||
free(profile->name);
|
||||
profile->name = strdup_safe((char*)p.name);
|
||||
|
||||
rc = hidpp10_get_current_profile(hidpp10, &idx);
|
||||
if (rc == 0 && (unsigned int)idx == profile->index)
|
||||
profile->is_active = true;
|
||||
@@ -543,6 +549,7 @@ hidpp10drv_commit(struct ratbag_device *device)
|
||||
return rc;
|
||||
|
||||
p.enabled = profile->is_enabled;
|
||||
strncpy_safe((char*)p.name, profile->name, 24);
|
||||
|
||||
ratbag_profile_for_each_resolution(profile, resolution) {
|
||||
p.dpi_modes[resolution->index].xres = resolution->dpi_x;
|
||||
@@ -605,7 +612,7 @@ hidpp10drv_probe(struct ratbag_device *device)
|
||||
goto err;
|
||||
|
||||
drv_data = zalloc(sizeof(*drv_data));
|
||||
hidpp_device_init(&base, device->hidraw.fd);
|
||||
hidpp_device_init(&base, device->hidraw[0].fd);
|
||||
hidpp_device_set_log_handler(&base, hidpp10_log, HIDPP_LOG_PRIORITY_RAW, device);
|
||||
|
||||
typestr = ratbag_device_data_hidpp10_get_profile_type(device->data);
|
||||
@@ -689,6 +696,18 @@ hidpp10drv_probe(struct ratbag_device *device)
|
||||
ratbag_device_for_each_profile(device, profile)
|
||||
hidpp10drv_read_profile(profile);
|
||||
|
||||
if (device->num_profiles == 1) {
|
||||
_cleanup_profile_ struct ratbag_profile *profile;
|
||||
|
||||
profile = ratbag_device_get_profile(device, 0);
|
||||
if (!profile->is_active) {
|
||||
log_debug(device->ratbag,
|
||||
"%s: forcing profile 0 to active.\n",
|
||||
device->name);
|
||||
profile->is_active = true;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
free(drv_data);
|
||||
|
||||
@@ -90,7 +90,7 @@ hidpp20drv_read_button_1b04(struct ratbag_button *button)
|
||||
|
||||
control = &drv_data->controls[button->index];
|
||||
mapping = control->control_id;
|
||||
if (control->reporting.divert || control->reporting.persist)
|
||||
if (control->reporting.remapped)
|
||||
mapping = control->reporting.remapped;
|
||||
log_raw(device->ratbag,
|
||||
" - button%d: %s (%02x) %s%s:%d\n",
|
||||
@@ -197,6 +197,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;
|
||||
unsigned int modifiers = 0;
|
||||
int rc;
|
||||
|
||||
if (!(drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100))
|
||||
@@ -215,6 +216,7 @@ hidpp20drv_read_button_8100(struct ratbag_button *button)
|
||||
button->action.type = RATBAG_BUTTON_ACTION_TYPE_KEY;
|
||||
button->action.action.key.key = ratbag_hidraw_get_keycode_from_keyboard_usage(device,
|
||||
profile->buttons[button->index].keyboard_keys.key);
|
||||
modifiers = profile->buttons[button->index].keyboard_keys.modifier_flags;
|
||||
break;
|
||||
case HIDPP20_BUTTON_HID_TYPE_CONSUMER_CONTROL:
|
||||
button->action.type = RATBAG_BUTTON_ACTION_TYPE_KEY;
|
||||
@@ -237,6 +239,20 @@ hidpp20drv_read_button_8100(struct ratbag_button *button)
|
||||
break;
|
||||
}
|
||||
|
||||
if (button->action.type == RATBAG_BUTTON_ACTION_TYPE_KEY) {
|
||||
int rc;
|
||||
|
||||
rc = ratbag_button_macro_new_from_keycode(button,
|
||||
button->action.action.key.key,
|
||||
modifiers);
|
||||
if (rc < 0) {
|
||||
log_error(device->ratbag,
|
||||
"Error while reading button %d\n",
|
||||
button->index);
|
||||
button->action.type = RATBAG_BUTTON_ACTION_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -421,9 +437,6 @@ hidpp20drv_update_button_1b04(struct ratbag_button *button)
|
||||
control->reporting.updated = 1;
|
||||
|
||||
rc = hidpp20_special_key_mouse_set_control(drv_data->dev, control);
|
||||
if (rc == HIDPP20_ERR_INVALID_ARGUMENT)
|
||||
return -EINVAL;
|
||||
|
||||
if (rc)
|
||||
log_error(device->ratbag,
|
||||
"Error while writing profile: '%s' (%d)\n",
|
||||
@@ -440,6 +453,8 @@ hidpp20drv_update_button_8100(struct ratbag_button *button)
|
||||
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
|
||||
struct hidpp20_profile *profile;
|
||||
struct ratbag_button_action *action = &button->action;
|
||||
unsigned int modifiers, key;
|
||||
int rc;
|
||||
uint8_t code, type, subtype;
|
||||
|
||||
if (!(drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100))
|
||||
@@ -453,6 +468,34 @@ hidpp20drv_update_button_8100(struct ratbag_button *button)
|
||||
profile->buttons[button->index].button.subtype = HIDPP20_BUTTON_HID_TYPE_MOUSE;
|
||||
profile->buttons[button->index].button.buttons = action->action.button;
|
||||
break;
|
||||
case RATBAG_BUTTON_ACTION_TYPE_MACRO:
|
||||
type = HIDPP20_BUTTON_HID_TYPE;
|
||||
subtype = HIDPP20_BUTTON_HID_TYPE_KEYBOARD;
|
||||
rc = ratbag_action_keycode_from_macro(action,
|
||||
&key,
|
||||
&modifiers);
|
||||
if (rc < 0) {
|
||||
log_error(device->ratbag,
|
||||
"Error while writing macro for button %d\n",
|
||||
button->index);
|
||||
}
|
||||
|
||||
code = ratbag_hidraw_get_keyboard_usage_from_keycode(device, key);
|
||||
if (code == 0) {
|
||||
subtype = HIDPP20_BUTTON_HID_TYPE_CONSUMER_CONTROL;
|
||||
code = ratbag_hidraw_get_consumer_usage_from_keycode(device, action->action.key.key);
|
||||
if (code == 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
profile->buttons[button->index].subany.type = type;
|
||||
profile->buttons[button->index].subany.subtype = subtype;
|
||||
if (subtype == HIDPP20_BUTTON_HID_TYPE_KEYBOARD) {
|
||||
profile->buttons[button->index].keyboard_keys.key = code;
|
||||
profile->buttons[button->index].keyboard_keys.modifier_flags = modifiers;
|
||||
} else {
|
||||
profile->buttons[button->index].consumer_control.consumer_control = code;
|
||||
}
|
||||
break;
|
||||
case RATBAG_BUTTON_ACTION_TYPE_KEY:
|
||||
type = HIDPP20_BUTTON_HID_TYPE;
|
||||
subtype = HIDPP20_BUTTON_HID_TYPE_KEYBOARD;
|
||||
@@ -477,7 +520,6 @@ hidpp20drv_update_button_8100(struct ratbag_button *button)
|
||||
profile->buttons[button->index].special.type = HIDPP20_BUTTON_SPECIAL;
|
||||
profile->buttons[button->index].special.special = code;
|
||||
break;
|
||||
case RATBAG_BUTTON_ACTION_TYPE_MACRO:
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
@@ -546,6 +588,20 @@ hidpp20drv_update_led_1300(struct ratbag_led *led, struct hidpp20drv_data *data)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/*
|
||||
* We revert to HW control of the LEDs.
|
||||
* This effectively disable the capability of changing the DPI/profile
|
||||
* LEDs, but this allows to make them work with the internal DPI/profile
|
||||
* switches.
|
||||
*
|
||||
* The net result is:
|
||||
* - DPI/profiles can't be controlled (but who wants this?)
|
||||
* - The logo can properly controlled
|
||||
*/
|
||||
rc = hidpp20_led_sw_control_set_sw_ctrl(data->dev, false);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return RATBAG_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -716,6 +772,9 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile)
|
||||
struct ratbag_device *device = profile->device;
|
||||
struct ratbag *ratbag = device->ratbag;
|
||||
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
|
||||
struct ratbag_resolution *res;
|
||||
unsigned int default_dpi = 1000;
|
||||
unsigned int default_rate = 500;
|
||||
int rc;
|
||||
|
||||
if (drv_data->capabilities & HIDPP_CAP_RESOLUTION_2200) {
|
||||
@@ -734,8 +793,6 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile)
|
||||
}
|
||||
|
||||
if (drv_data->capabilities & HIDPP_CAP_SWITCHABLE_RESOLUTION_2201) {
|
||||
struct ratbag_resolution *res;
|
||||
|
||||
rc = hidpp20drv_read_resolution_dpi_2201(device);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
@@ -756,13 +813,12 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile)
|
||||
* they are from different sensors */
|
||||
res->is_active = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
ratbag_profile_for_each_resolution(profile, res)
|
||||
ratbag_resolution_set_dpi_list(res, &default_dpi, 1);
|
||||
}
|
||||
|
||||
if (drv_data->capabilities & HIDPP_CAP_ADJUSTIBLE_REPORT_RATE_8060) {
|
||||
struct ratbag_resolution *res;
|
||||
|
||||
rc = hidpp20drv_read_report_rate_8060(device);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
@@ -771,6 +827,9 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile)
|
||||
ratbag_resolution_set_report_rate_list(res,
|
||||
drv_data->report_rates,
|
||||
drv_data->num_report_rates);
|
||||
} else {
|
||||
ratbag_profile_for_each_resolution(profile, res)
|
||||
ratbag_resolution_set_report_rate_list(res, &default_rate, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1049,7 +1108,7 @@ hidpp20drv_init_feature(struct ratbag_device *device, uint16_t feature)
|
||||
/* we read the profile once to get the correct number of
|
||||
* supported buttons. */
|
||||
if (!hidpp20drv_read_special_key_mouse(device))
|
||||
device->num_buttons = drv_data->num_controls;
|
||||
drv_data->num_buttons = drv_data->num_controls;
|
||||
break;
|
||||
}
|
||||
case HIDPP_PAGE_BATTERY_LEVEL_STATUS: {
|
||||
@@ -1074,7 +1133,7 @@ hidpp20drv_init_feature(struct ratbag_device *device, uint16_t feature)
|
||||
/* we read the profile once to get the correct number of
|
||||
* supported buttons. */
|
||||
if (!hidpp20drv_read_kbd_reprogrammable_key(device))
|
||||
device->num_buttons = drv_data->num_controls;
|
||||
drv_data->num_buttons = drv_data->num_controls;
|
||||
break;
|
||||
}
|
||||
case HIDPP_PAGE_ADJUSTABLE_REPORT_RATE: {
|
||||
@@ -1120,6 +1179,9 @@ hidpp20drv_init_feature(struct ratbag_device *device, uint16_t feature)
|
||||
drv_data->capabilities |= HIDPP_CAP_ONBOARD_PROFILES_8100;
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_PROFILE);
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_DISABLE_PROFILE);
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON);
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_KEY);
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS);
|
||||
|
||||
rc = hidpp20_onboard_profiles_allocate(drv_data->dev, &drv_data->profiles);
|
||||
if (rc < 0)
|
||||
@@ -1163,8 +1225,6 @@ hidpp20drv_commit(struct ratbag_device *device)
|
||||
if (!profile->dirty)
|
||||
continue;
|
||||
|
||||
drv_data->profiles->profiles[profile->index].enabled = profile->is_enabled;
|
||||
|
||||
ratbag_profile_for_each_resolution(profile, resolution) {
|
||||
if (resolution->is_active)
|
||||
dpi_index = resolution->index;
|
||||
@@ -1197,6 +1257,9 @@ hidpp20drv_commit(struct ratbag_device *device)
|
||||
}
|
||||
|
||||
if (drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100) {
|
||||
list_for_each(profile, &device->profiles, link)
|
||||
drv_data->profiles->profiles[profile->index].enabled = profile->is_enabled;
|
||||
|
||||
rc = hidpp20_onboard_profiles_commit(drv_data->dev,
|
||||
drv_data->profiles);
|
||||
if (rc)
|
||||
@@ -1306,7 +1369,7 @@ hidpp20drv_probe(struct ratbag_device *device)
|
||||
|
||||
drv_data = zalloc(sizeof(*drv_data));
|
||||
ratbag_set_drv_data(device, drv_data);
|
||||
hidpp_device_init(&base, device->hidraw.fd);
|
||||
hidpp_device_init(&base, device->hidraw[0].fd);
|
||||
hidpp_device_set_log_handler(&base, hidpp20_log, HIDPP_LOG_PRIORITY_RAW, device);
|
||||
|
||||
device_idx = ratbag_device_data_hidpp20_get_index(device->data);
|
||||
@@ -1335,7 +1398,7 @@ 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;
|
||||
drv_data->num_leds = 0;
|
||||
|
||||
rc = hidpp20drv_20_probe(device);
|
||||
if (rc)
|
||||
|
||||
671
src/driver-logitech-g600.c
Normal file
@@ -0,0 +1,671 @@
|
||||
/*
|
||||
* Copyright © 2018 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_G600_NUM_PROFILES 3
|
||||
#define LOGITECH_G600_NUM_BUTTONS 20
|
||||
#define LOGITECH_G600_NUM_DPI 4
|
||||
#define LOGITECH_G600_NUM_LED 1
|
||||
#define LOGITECH_G600_DPI_MIN 200
|
||||
#define LOGITECH_G600_DPI_MAX 8200
|
||||
|
||||
#define LOGITECH_G600_REPORT_ID_GET_ACTIVE 0xF0
|
||||
#define LOGITECH_G600_REPORT_ID_SET_ACTIVE 0xF0
|
||||
#define LOGITECH_G600_REPORT_ID_PROFILE_0 0xF3
|
||||
#define LOGITECH_G600_REPORT_ID_PROFILE_1 0xF4
|
||||
#define LOGITECH_G600_REPORT_ID_PROFILE_2 0xF5
|
||||
|
||||
#define LOGITECH_G600_REPORT_SIZE_PROFILE 154
|
||||
|
||||
#define LOGITECH_G600_LED_SOLID 0x00
|
||||
#define LOGITECH_G600_LED_BREATHE 0x01
|
||||
#define LOGITECH_G600_LED_CYCLE 0x02
|
||||
|
||||
struct logitech_g600_button {
|
||||
uint8_t code;
|
||||
uint8_t modifier;
|
||||
uint8_t key;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct logitech_g600_profile_report {
|
||||
uint8_t id;
|
||||
uint8_t led_red;
|
||||
uint8_t led_green;
|
||||
uint8_t led_blue;
|
||||
uint8_t led_effect;
|
||||
uint8_t led_duration;
|
||||
uint8_t unknown1[5];
|
||||
uint8_t frequency; /* frequency = 1000 / (value + 1) */
|
||||
uint8_t dpi_shift; /* value is a linear range between 200->0x04, 8200->0xa4, so value * 50, 0x00 is disabled */
|
||||
uint8_t dpi_default; /* between 1 and 4*/
|
||||
uint8_t dpi[4]; /* value is a linear range between 200->0x04, 8200->0xa4, so value * 50, 0x00 is disabled */
|
||||
uint8_t unknown2[13];
|
||||
struct logitech_g600_button buttons[20];
|
||||
uint8_t g_shift_color[3]; /* can't assign it in LGS, but the 3rd profile has one that shows the feature :) */
|
||||
struct logitech_g600_button g_shift_buttons[20];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct logitech_g600_active_profile_report {
|
||||
uint8_t id;
|
||||
uint8_t unknown1 :1;
|
||||
uint8_t resolution :2;
|
||||
uint8_t unknown2 :1;
|
||||
uint8_t profile :4;
|
||||
uint8_t unknown3;
|
||||
uint8_t unknown4;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct logitech_g600_profile_data {
|
||||
struct logitech_g600_profile_report report;
|
||||
};
|
||||
|
||||
struct logitech_g600_data {
|
||||
struct logitech_g600_profile_data profile_data[LOGITECH_G600_NUM_PROFILES];
|
||||
};
|
||||
|
||||
_Static_assert(sizeof(struct logitech_g600_profile_report) == LOGITECH_G600_REPORT_SIZE_PROFILE,
|
||||
"Size of logitech_g600_profile_report is wrong");
|
||||
|
||||
struct logitech_g600_button_type_mapping {
|
||||
uint8_t raw;
|
||||
enum ratbag_button_type type;
|
||||
};
|
||||
|
||||
static const struct logitech_g600_button_type_mapping logitech_g600_button_type_mapping[] = {
|
||||
{ 0, RATBAG_BUTTON_TYPE_LEFT },
|
||||
{ 1, RATBAG_BUTTON_TYPE_RIGHT },
|
||||
{ 2, RATBAG_BUTTON_TYPE_MIDDLE },
|
||||
{ 3, RATBAG_BUTTON_TYPE_WHEEL_LEFT },
|
||||
{ 4, RATBAG_BUTTON_TYPE_WHEEL_RIGHT },
|
||||
{ 5, RATBAG_BUTTON_TYPE_PINKIE },
|
||||
{ 6, RATBAG_BUTTON_TYPE_PROFILE_CYCLE_UP },
|
||||
{ 7, RATBAG_BUTTON_TYPE_RESOLUTION_CYCLE_UP },
|
||||
{ 8, RATBAG_BUTTON_TYPE_SIDE }, // 8 = G9 ... 19 = G20
|
||||
{ 9, RATBAG_BUTTON_TYPE_SIDE },
|
||||
{ 10, RATBAG_BUTTON_TYPE_SIDE },
|
||||
{ 11, RATBAG_BUTTON_TYPE_SIDE },
|
||||
{ 12, RATBAG_BUTTON_TYPE_SIDE },
|
||||
{ 13, RATBAG_BUTTON_TYPE_SIDE },
|
||||
{ 14, RATBAG_BUTTON_TYPE_SIDE },
|
||||
{ 15, RATBAG_BUTTON_TYPE_SIDE },
|
||||
{ 16, RATBAG_BUTTON_TYPE_SIDE },
|
||||
{ 17, RATBAG_BUTTON_TYPE_SIDE },
|
||||
{ 18, RATBAG_BUTTON_TYPE_SIDE },
|
||||
{ 19, RATBAG_BUTTON_TYPE_SIDE },
|
||||
};
|
||||
|
||||
static enum ratbag_button_type
|
||||
logitech_g600_raw_to_button_type(uint8_t data)
|
||||
{
|
||||
const struct logitech_g600_button_type_mapping *mapping;
|
||||
|
||||
ARRAY_FOR_EACH(logitech_g600_button_type_mapping, mapping) {
|
||||
if (mapping->raw == data)
|
||||
return mapping->type;
|
||||
}
|
||||
|
||||
return RATBAG_BUTTON_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
struct logitech_g600_button_mapping {
|
||||
uint8_t raw;
|
||||
struct ratbag_button_action action;
|
||||
};
|
||||
|
||||
static struct logitech_g600_button_mapping logitech_g600_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) },
|
||||
{ 0x11, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_UP) },
|
||||
{ 0x12, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_DOWN) },
|
||||
{ 0x13, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_UP) },
|
||||
{ 0x14, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_CYCLE_UP) },
|
||||
{ 0x15, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_ALTERNATE) },
|
||||
{ 0x17, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_SECOND_MODE) },
|
||||
};
|
||||
|
||||
static const struct ratbag_button_action*
|
||||
logitech_g600_raw_to_button_action(uint8_t data)
|
||||
{
|
||||
struct logitech_g600_button_mapping *mapping;
|
||||
|
||||
ARRAY_FOR_EACH(logitech_g600_button_mapping, mapping) {
|
||||
if (mapping->raw == data)
|
||||
return &mapping->action;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint8_t logitech_g600_modifier_to_raw(int modifier_flags)
|
||||
{
|
||||
uint8_t modifiers = 0x00;
|
||||
|
||||
if (modifier_flags & MODIFIER_LEFTCTRL)
|
||||
modifiers |= 0x01;
|
||||
if (modifier_flags & MODIFIER_LEFTSHIFT)
|
||||
modifiers |= 0x02;
|
||||
if (modifier_flags & MODIFIER_LEFTALT)
|
||||
modifiers |= 0x04;
|
||||
if (modifier_flags & MODIFIER_LEFTMETA)
|
||||
modifiers |= 0x08;
|
||||
if (modifier_flags & MODIFIER_RIGHTCTRL)
|
||||
modifiers |= 0x10;
|
||||
if (modifier_flags & MODIFIER_RIGHTSHIFT)
|
||||
modifiers |= 0x20;
|
||||
if (modifier_flags & MODIFIER_RIGHTALT)
|
||||
modifiers |= 0x40;
|
||||
if (modifier_flags & MODIFIER_RIGHTMETA)
|
||||
modifiers |= 0x80;
|
||||
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
static int logitech_g600_raw_to_modifiers(uint8_t data)
|
||||
{
|
||||
int modifiers = 0;
|
||||
|
||||
if (data & 0x01)
|
||||
modifiers |= MODIFIER_LEFTCTRL;
|
||||
if (data & 0x02)
|
||||
modifiers |= MODIFIER_LEFTSHIFT;
|
||||
if (data & 0x04)
|
||||
modifiers |= MODIFIER_LEFTALT;
|
||||
if (data & 0x08)
|
||||
modifiers |= MODIFIER_LEFTMETA;
|
||||
if (data & 0x10)
|
||||
modifiers |= MODIFIER_RIGHTCTRL;
|
||||
if (data & 0x20)
|
||||
modifiers |= MODIFIER_RIGHTSHIFT;
|
||||
if (data & 0x40)
|
||||
modifiers |= MODIFIER_RIGHTALT;
|
||||
if (data & 0x80)
|
||||
modifiers |= MODIFIER_RIGHTMETA;
|
||||
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
logitech_g600_button_action_to_raw(const struct ratbag_button_action *action)
|
||||
{
|
||||
struct logitech_g600_button_mapping *mapping;
|
||||
|
||||
ARRAY_FOR_EACH(logitech_g600_button_mapping, mapping) {
|
||||
if (ratbag_button_action_match(&mapping->action, action))
|
||||
return mapping->raw;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
logitech_g600_get_active_profile_and_resolution(struct ratbag_device *device)
|
||||
{
|
||||
struct ratbag_profile *profile;
|
||||
struct logitech_g600_active_profile_report buf;
|
||||
int ret;
|
||||
|
||||
ret = ratbag_hidraw_raw_request(device, LOGITECH_G600_REPORT_ID_GET_ACTIVE,
|
||||
(uint8_t*)&buf, sizeof(buf),
|
||||
HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (ret != sizeof(buf))
|
||||
return -EIO;
|
||||
|
||||
list_for_each(profile, &device->profiles, link) {
|
||||
struct ratbag_resolution *resolution;
|
||||
|
||||
if (profile->index != buf.profile)
|
||||
continue;
|
||||
|
||||
profile->is_active = true;
|
||||
ratbag_profile_for_each_resolution(profile, resolution) {
|
||||
resolution->is_active = resolution->index == buf.resolution;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
logitech_g600_set_current_resolution(struct ratbag_device *device, unsigned int index)
|
||||
{
|
||||
uint8_t buf[] = {LOGITECH_G600_REPORT_ID_SET_ACTIVE, 0x40 | (index << 1), 0x00, 0x00};
|
||||
int ret;
|
||||
|
||||
log_debug(device->ratbag, "Setting active resolution to %d\n", index);
|
||||
|
||||
if (index >= LOGITECH_G600_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;
|
||||
}
|
||||
|
||||
static int
|
||||
logitech_g600_set_active_profile(struct ratbag_device *device, unsigned int index)
|
||||
{
|
||||
struct ratbag_profile *profile;
|
||||
uint8_t buf[] = {LOGITECH_G600_REPORT_ID_SET_ACTIVE, 0x80 | (index << 4), 0x00, 0x00};
|
||||
int ret, active_resolution = 0;
|
||||
|
||||
if (index >= LOGITECH_G600_NUM_PROFILES)
|
||||
return -EINVAL;
|
||||
|
||||
ret = ratbag_hidraw_raw_request(device, buf[0], buf, sizeof(buf),
|
||||
HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
|
||||
|
||||
if (ret != sizeof(buf))
|
||||
return ret;
|
||||
|
||||
/* Update the active resolution. After profile change the default is used. */
|
||||
list_for_each(profile, &device->profiles, link) {
|
||||
struct ratbag_resolution *resolution;
|
||||
|
||||
if (profile->index != index)
|
||||
continue;
|
||||
|
||||
ratbag_profile_for_each_resolution(profile, resolution) {
|
||||
resolution->is_active = resolution->is_default;
|
||||
|
||||
if (resolution->is_active)
|
||||
active_resolution = resolution->index;
|
||||
}
|
||||
}
|
||||
|
||||
ret = logitech_g600_set_current_resolution(device, active_resolution);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
logitech_g600_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_g600_data *drv_data = device->drv_data;
|
||||
struct logitech_g600_profile_data *pdata;
|
||||
struct logitech_g600_profile_report *profile_report;
|
||||
struct logitech_g600_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);
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_MACRO);
|
||||
|
||||
button->type = logitech_g600_raw_to_button_type(button->index);
|
||||
|
||||
action = logitech_g600_raw_to_button_action(button_report->code);
|
||||
if (action) {
|
||||
ratbag_button_set_action(button, action);
|
||||
}
|
||||
else if (button_report->code == 0x00 && (button_report->modifier > 0x00 || button_report->key > 0x00))
|
||||
{
|
||||
unsigned int key, modifiers;
|
||||
int rc;
|
||||
|
||||
key = ratbag_hidraw_get_keycode_from_keyboard_usage(device,
|
||||
button_report->key);
|
||||
modifiers = logitech_g600_raw_to_modifiers(button_report->modifier);
|
||||
|
||||
rc = ratbag_button_macro_new_from_keycode(button, key, modifiers);
|
||||
if (rc < 0) {
|
||||
log_error(device->ratbag,
|
||||
"Error while reading button %d\n",
|
||||
button->index);
|
||||
button->action.type = RATBAG_BUTTON_ACTION_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
logitech_g600_read_led(struct ratbag_led *led)
|
||||
{
|
||||
struct ratbag_profile *profile = led->profile;
|
||||
struct ratbag_device *device = profile->device;
|
||||
struct logitech_g600_data *drv_data = device->drv_data;
|
||||
struct logitech_g600_profile_data *pdata;
|
||||
struct logitech_g600_profile_report *report;
|
||||
|
||||
pdata = &drv_data->profile_data[profile->index];
|
||||
report = &pdata->report;
|
||||
|
||||
led->type = RATBAG_LED_TYPE_SIDE;
|
||||
led->colordepth = RATBAG_LED_COLORDEPTH_RGB_888;
|
||||
ratbag_led_set_mode_capability(led, RATBAG_LED_OFF);
|
||||
ratbag_led_set_mode_capability(led, RATBAG_LED_ON);
|
||||
ratbag_led_set_mode_capability(led, RATBAG_LED_BREATHING);
|
||||
ratbag_led_set_mode_capability(led, RATBAG_LED_CYCLE);
|
||||
|
||||
switch (report->led_effect) {
|
||||
case LOGITECH_G600_LED_SOLID:
|
||||
led->mode = RATBAG_LED_ON;
|
||||
break;
|
||||
case LOGITECH_G600_LED_BREATHE:
|
||||
led->mode = RATBAG_LED_BREATHING;
|
||||
led->ms = report->led_duration * 1000;
|
||||
break;
|
||||
case LOGITECH_G600_LED_CYCLE:
|
||||
led->mode = RATBAG_LED_CYCLE;
|
||||
led->ms = report->led_duration * 1000;
|
||||
break;
|
||||
}
|
||||
led->color.red = report->led_red;
|
||||
led->color.green = report->led_green;
|
||||
led->color.blue = report->led_blue;
|
||||
}
|
||||
|
||||
static void
|
||||
logitech_g600_read_profile(struct ratbag_profile *profile)
|
||||
{
|
||||
struct ratbag_device *device = profile->device;
|
||||
struct logitech_g600_data *drv_data = device->drv_data;
|
||||
struct logitech_g600_profile_data *pdata;
|
||||
struct logitech_g600_profile_report *report;
|
||||
struct ratbag_resolution *resolution;
|
||||
unsigned int report_rates[] = { 125, 142, 166, 200, 250, 333, 500, 1000 };
|
||||
uint8_t report_id;
|
||||
int rc;
|
||||
struct ratbag_button *button;
|
||||
struct ratbag_led *led;
|
||||
|
||||
assert(profile->index < LOGITECH_G600_NUM_PROFILES);
|
||||
|
||||
pdata = &drv_data->profile_data[profile->index];
|
||||
report = &pdata->report;
|
||||
|
||||
switch (profile->index) {
|
||||
case 0: report_id = LOGITECH_G600_REPORT_ID_PROFILE_0; break;
|
||||
case 1: report_id = LOGITECH_G600_REPORT_ID_PROFILE_1; break;
|
||||
case 2: report_id = LOGITECH_G600_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 < (int)sizeof(*report)) {
|
||||
log_error(device->ratbag,
|
||||
"Error while requesting profile: %d\n", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ratbag_profile_for_each_resolution(profile, resolution) {
|
||||
resolution->dpi_x = report->dpi[resolution->index] * 50;
|
||||
resolution->dpi_y = report->dpi[resolution->index] * 50;
|
||||
resolution->hz = 1000 / (report->frequency + 1);
|
||||
resolution->is_default = report->dpi_default - 1U == resolution->index;
|
||||
resolution->is_active = resolution->is_default;
|
||||
|
||||
ratbag_resolution_set_dpi_list_from_range(resolution,
|
||||
LOGITECH_G600_DPI_MIN,
|
||||
LOGITECH_G600_DPI_MAX);
|
||||
ratbag_resolution_set_report_rate_list(resolution, report_rates,
|
||||
ARRAY_LENGTH(report_rates));
|
||||
}
|
||||
|
||||
ratbag_profile_for_each_button(profile, button)
|
||||
logitech_g600_read_button(button);
|
||||
|
||||
ratbag_profile_for_each_led(profile, led)
|
||||
logitech_g600_read_led(led);
|
||||
|
||||
log_debug(device->ratbag, "Unknown data in profile %d\n", profile->index);
|
||||
log_buf_debug(device->ratbag, " profile->unknown1: ",
|
||||
report->unknown1, 5);
|
||||
log_buf_debug(device->ratbag, " profile->unknown2: ",
|
||||
report->unknown2, 13);
|
||||
}
|
||||
|
||||
static int
|
||||
logitech_g600_test_hidraw(struct ratbag_device *device)
|
||||
{
|
||||
return ratbag_hidraw_has_report(device, LOGITECH_G600_REPORT_ID_GET_ACTIVE);
|
||||
}
|
||||
|
||||
static int
|
||||
logitech_g600_probe(struct ratbag_device *device)
|
||||
{
|
||||
int rc;
|
||||
struct logitech_g600_data *drv_data = NULL;
|
||||
struct ratbag_profile *profile;
|
||||
|
||||
rc = ratbag_find_hidraw(device, logitech_g600_test_hidraw);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
drv_data = zalloc(sizeof(*drv_data));
|
||||
ratbag_set_drv_data(device, drv_data);
|
||||
|
||||
ratbag_device_init_profiles(device,
|
||||
LOGITECH_G600_NUM_PROFILES,
|
||||
LOGITECH_G600_NUM_DPI,
|
||||
LOGITECH_G600_NUM_BUTTONS,
|
||||
LOGITECH_G600_NUM_LED);
|
||||
|
||||
ratbag_device_for_each_profile(device, profile)
|
||||
logitech_g600_read_profile(profile);
|
||||
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_RESOLUTION);
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION);
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_PROFILE);
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_PROFILE);
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON);
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_KEY);
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS);
|
||||
|
||||
rc = logitech_g600_get_active_profile_and_resolution(device);
|
||||
|
||||
if (rc < 0) {
|
||||
log_error(device->ratbag,
|
||||
"Can't talk to the mouse: '%s' (%d)\n",
|
||||
strerror(-rc),
|
||||
rc);
|
||||
rc = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
free(drv_data);
|
||||
ratbag_set_drv_data(device, NULL);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
logitech_g600_write_profile(struct ratbag_profile *profile)
|
||||
{
|
||||
struct ratbag_device *device = profile->device;
|
||||
struct logitech_g600_data *drv_data = device->drv_data;
|
||||
struct logitech_g600_profile_data *pdata;
|
||||
struct logitech_g600_profile_report *report;
|
||||
struct ratbag_resolution *resolution;
|
||||
struct ratbag_button *button;
|
||||
struct ratbag_led *led;
|
||||
|
||||
uint8_t *buf;
|
||||
int rc, active_resolution = 0;
|
||||
|
||||
pdata = &drv_data->profile_data[profile->index];
|
||||
report = &pdata->report;
|
||||
|
||||
ratbag_profile_for_each_resolution(profile, resolution) {
|
||||
report->dpi[resolution->index] = resolution->dpi_x / 50;
|
||||
|
||||
if (resolution->is_default)
|
||||
report->dpi_default = resolution->index + 1;
|
||||
|
||||
if (profile->is_active && resolution->is_active)
|
||||
active_resolution = resolution->index;
|
||||
|
||||
/* The same hz is used for all resolutions */
|
||||
if (resolution->index == 0)
|
||||
report->frequency = (1000 / resolution->hz) - 1;
|
||||
}
|
||||
|
||||
list_for_each(button, &profile->buttons, link) {
|
||||
struct ratbag_button_action *action = &button->action;
|
||||
struct logitech_g600_button *raw_button;
|
||||
|
||||
raw_button = &report->buttons[button->index];
|
||||
|
||||
raw_button->code = logitech_g600_button_action_to_raw(action);
|
||||
raw_button->modifier = 0x00;
|
||||
raw_button->key = 0x00;
|
||||
|
||||
if (action->type == RATBAG_BUTTON_ACTION_TYPE_MACRO) {
|
||||
unsigned int key, modifiers;
|
||||
|
||||
rc = ratbag_action_keycode_from_macro(action,
|
||||
&key,
|
||||
&modifiers);
|
||||
if (rc < 0) {
|
||||
log_error(device->ratbag,
|
||||
"Error while writing macro for button %d\n",
|
||||
button->index);
|
||||
}
|
||||
|
||||
raw_button->key = ratbag_hidraw_get_keyboard_usage_from_keycode(
|
||||
device, key);
|
||||
raw_button->modifier = logitech_g600_modifier_to_raw(modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each(led, &profile->leds, link) {
|
||||
report->led_red = led->color.red;
|
||||
report->led_green = led->color.green;
|
||||
report->led_blue = led->color.blue;
|
||||
|
||||
switch (led->mode) {
|
||||
case RATBAG_LED_ON:
|
||||
report->led_effect = LOGITECH_G600_LED_SOLID;
|
||||
break;
|
||||
case RATBAG_LED_OFF:
|
||||
report->led_effect = LOGITECH_G600_LED_SOLID;
|
||||
report->led_red = 0x00;
|
||||
report->led_green = 0x00;
|
||||
report->led_blue = 0x00;
|
||||
break;
|
||||
case RATBAG_LED_BREATHING:
|
||||
report->led_effect = LOGITECH_G600_LED_BREATHE;
|
||||
report->led_duration = led->ms / 1000;
|
||||
break;
|
||||
case RATBAG_LED_CYCLE:
|
||||
report->led_effect = LOGITECH_G600_LED_CYCLE;
|
||||
report->led_duration = led->ms / 1000;
|
||||
break;
|
||||
}
|
||||
|
||||
if (report->led_duration > 0x0f)
|
||||
report->led_duration = 0x0f;
|
||||
}
|
||||
|
||||
buf = (uint8_t*)report;
|
||||
|
||||
rc = ratbag_hidraw_raw_request(device, report->id,
|
||||
buf,
|
||||
sizeof(*report),
|
||||
HID_FEATURE_REPORT,
|
||||
HID_REQ_SET_REPORT);
|
||||
|
||||
if (rc < (int)sizeof(*report)) {
|
||||
log_error(device->ratbag,
|
||||
"Error while writing profile: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (profile->is_active) {
|
||||
rc = logitech_g600_set_current_resolution(device, active_resolution);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
logitech_g600_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_g600_write_profile(profile);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
logitech_g600_remove(struct ratbag_device *device)
|
||||
{
|
||||
ratbag_close_hidraw(device);
|
||||
free(ratbag_get_drv_data(device));
|
||||
}
|
||||
|
||||
struct ratbag_driver logitech_g600_driver = {
|
||||
.name = "Logitech G600",
|
||||
.id = "logitech_g600",
|
||||
.probe = logitech_g600_probe,
|
||||
.remove = logitech_g600_remove,
|
||||
.commit = logitech_g600_commit,
|
||||
.set_active_profile = logitech_g600_set_active_profile,
|
||||
};
|
||||
@@ -748,6 +748,7 @@ roccat_read_profile(struct ratbag_profile *profile)
|
||||
|
||||
ratbag_resolution_set_report_rate_list(resolution, report_rates,
|
||||
ARRAY_LENGTH(report_rates));
|
||||
ratbag_resolution_set_dpi_list_from_range(resolution, 200, 8200);
|
||||
}
|
||||
|
||||
ratbag_profile_for_each_button(profile, button)
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
|
||||
#define STEELSERIES_NUM_PROFILES 1
|
||||
#define STEELSERIES_NUM_DPI 2
|
||||
#define STEELSERIES_INPUT_ENDPOINT 0
|
||||
#define STEELSERIES_INPUT_HIDRAW 1
|
||||
|
||||
/* not sure these two are used for */
|
||||
#define STEELSERIES_REPORT_ID_1 0x01
|
||||
@@ -48,6 +50,7 @@
|
||||
|
||||
#define STEELSERIES_ID_DPI_SHORT 0x03
|
||||
#define STEELSERIES_ID_REPORT_RATE_SHORT 0x04
|
||||
#define STEELSERIES_ID_LED_INTENSITY_SHORT 0x05
|
||||
#define STEELSERIES_ID_LED_EFFECT_SHORT 0x07
|
||||
#define STEELSERIES_ID_LED_COLOR_SHORT 0x08
|
||||
#define STEELSERIES_ID_SAVE_SHORT 0x09
|
||||
@@ -57,14 +60,58 @@
|
||||
#define STEELSERIES_ID_REPORT_RATE 0x54
|
||||
#define STEELSERIES_ID_LED 0x5b
|
||||
#define STEELSERIES_ID_SAVE 0x59
|
||||
#define STEELSERIES_ID_FIRMWARE 0x90
|
||||
#define STEELSERIES_ID_SETTTINGS 0x92
|
||||
|
||||
#define STEELSERIES_ID_DPI_PROTOCOL3 0x03
|
||||
#define STEELSERIES_ID_REPORT_RATE_PROTOCOL3 0x04
|
||||
#define STEELSERIES_ID_LED_PROTOCOL3 0x05
|
||||
#define STEELSERIES_ID_SAVE_PROTOCOL3 0x09
|
||||
#define STEELSERIES_ID_FIRMWARE_PROTOCOL3 0x10
|
||||
#define STEELSERIES_ID_SETTTINGS_PROTOCOL3 0x16
|
||||
|
||||
#define STEELSERIES_BUTTON_OFF 0x00
|
||||
#define STEELSERIES_BUTTON_RES_CYCLE 0x30
|
||||
#define STEELSERIES_BUTTON_WHEEL_UP 0x31
|
||||
#define STEELSERIES_BUTTON_WHEEL_DOWN 0x32
|
||||
#define STEELSERIES_BUTTON_KEY 0x10
|
||||
#define STEELSERIES_BUTTON_KBD 0x51
|
||||
#define STEELSERIES_BUTTON_CONSUMER 0x61
|
||||
|
||||
struct steelseries_data {
|
||||
int firmware_major;
|
||||
int firmware_minor;
|
||||
};
|
||||
|
||||
struct steelseries_point {
|
||||
struct list link;
|
||||
|
||||
struct ratbag_color color; /* point color */
|
||||
uint8_t pos; /* relative position in the cycle */
|
||||
};
|
||||
|
||||
struct steelseries_led_cycle {
|
||||
uint8_t led_id; /* led id */
|
||||
uint16_t duration; /* cycle duration */
|
||||
bool repeat; /* if the cycle restarts automatically */
|
||||
uint8_t trigger_buttons; /* trigger button combination */
|
||||
struct list points; /* colors in the cycle */
|
||||
};
|
||||
|
||||
struct steelseries_led_cycle_spec {
|
||||
int hid_report_type; /* either HID_OUTPUT_REPORT or HID_FEATURE_REPORT */
|
||||
int header_len; /* number of bytes in the header */
|
||||
uint8_t cmd_val; /* command value for the color command */
|
||||
bool has_2_led_ids; /* some mice have 2 fields for led id */
|
||||
|
||||
int led_id_idx; /* index of the led id field */
|
||||
int led_id2_idx; /* 2nd led id index (if required by protocol) */
|
||||
int duration_idx; /* index of the cycle duration field */
|
||||
int repeat_idx; /* index of the repeat field */
|
||||
int trigger_idx; /* index of the trigger mask field */
|
||||
int point_count_idx; /* index of the point counter field */
|
||||
};
|
||||
|
||||
static int
|
||||
steelseries_test_hidraw(struct ratbag_device *device)
|
||||
{
|
||||
@@ -98,6 +145,10 @@ button_defaults_for_layout(struct ratbag_button *button, int button_count)
|
||||
button_actions[5].action.special = RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_UP;
|
||||
button_actions[6].type = RATBAG_BUTTON_ACTION_TYPE_NONE;
|
||||
button_actions[7].type = RATBAG_BUTTON_ACTION_TYPE_NONE;
|
||||
} else if (button_count == 7) {
|
||||
button_actions[6].type = RATBAG_BUTTON_ACTION_TYPE_SPECIAL;
|
||||
button_actions[6].action.special = RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_UP;
|
||||
button_actions[7].type = RATBAG_BUTTON_ACTION_TYPE_NONE;
|
||||
} else {
|
||||
button_actions[7].type = RATBAG_BUTTON_ACTION_TYPE_SPECIAL;
|
||||
button_actions[7].action.special = RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_UP;
|
||||
@@ -110,6 +161,9 @@ button_defaults_for_layout(struct ratbag_button *button, int button_count)
|
||||
button_types[4] = RATBAG_BUTTON_TYPE_THUMB2;
|
||||
if (button_count <= 6) {
|
||||
button_types[5] = RATBAG_BUTTON_TYPE_RESOLUTION_CYCLE_UP;
|
||||
} else if (button_count == 7) {
|
||||
button_types[5] = RATBAG_BUTTON_TYPE_THUMB3;
|
||||
button_types[6] = RATBAG_BUTTON_TYPE_RESOLUTION_CYCLE_UP;
|
||||
} else {
|
||||
button_types[5] = RATBAG_BUTTON_TYPE_PINKIE;
|
||||
button_types[6] = RATBAG_BUTTON_TYPE_PINKIE2;
|
||||
@@ -120,14 +174,103 @@ button_defaults_for_layout(struct ratbag_button *button, int button_count)
|
||||
ratbag_button_set_action(button, &button_actions[button->index]);
|
||||
}
|
||||
|
||||
static int
|
||||
steelseries_get_firmware_version(struct ratbag_device *device)
|
||||
{
|
||||
struct steelseries_data *drv_data = device->drv_data;
|
||||
int device_version = ratbag_device_data_steelseries_get_device_version(device->data);
|
||||
size_t buf_len = STEELSERIES_REPORT_SIZE;
|
||||
uint8_t buf[STEELSERIES_REPORT_SIZE] = {0};
|
||||
int ret;
|
||||
|
||||
if (device_version == 2)
|
||||
buf[0] = STEELSERIES_ID_FIRMWARE;
|
||||
else if (device_version == 3)
|
||||
buf[0] = STEELSERIES_ID_FIRMWARE_PROTOCOL3;
|
||||
else
|
||||
return -ENOTSUP;
|
||||
|
||||
msleep(10);
|
||||
ret = ratbag_hidraw_output_report(device, buf, buf_len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ratbag_hidraw_read_input_report_index(device, buf, buf_len, STEELSERIES_INPUT_HIDRAW);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
drv_data->firmware_major = buf[1];
|
||||
drv_data->firmware_minor = buf[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
steelseries_read_settings(struct ratbag_device *device)
|
||||
{
|
||||
int device_version = ratbag_device_data_steelseries_get_device_version(device->data);
|
||||
struct ratbag_profile *profile = NULL;
|
||||
struct ratbag_resolution *resolution;
|
||||
struct ratbag_led *led;
|
||||
|
||||
size_t buf_len = STEELSERIES_REPORT_SIZE;
|
||||
uint8_t buf[STEELSERIES_REPORT_SIZE] = {0};
|
||||
int ret;
|
||||
unsigned int active_resolution;
|
||||
|
||||
if (device_version == 2)
|
||||
buf[0] = STEELSERIES_ID_SETTTINGS;
|
||||
else if (device_version == 3)
|
||||
buf[0] = STEELSERIES_ID_SETTTINGS_PROTOCOL3;
|
||||
else
|
||||
return -ENOTSUP;
|
||||
|
||||
msleep(10);
|
||||
ret = ratbag_hidraw_output_report(device, buf, buf_len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ratbag_hidraw_read_input_report_index(device, buf, buf_len, STEELSERIES_INPUT_HIDRAW);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (device_version == 2) {
|
||||
active_resolution = buf[1] - 1;
|
||||
ratbag_device_for_each_profile(device, profile) {
|
||||
ratbag_profile_for_each_resolution(profile, resolution) {
|
||||
resolution->is_active = resolution->index == active_resolution;
|
||||
|
||||
resolution->dpi_x = 100 * (1 + buf[2 + resolution->index*2]);
|
||||
resolution->dpi_y = resolution->dpi_x;
|
||||
}
|
||||
|
||||
ratbag_profile_for_each_led(profile, led) {
|
||||
led->color.red = buf[6 + led->index * 3];
|
||||
led->color.green = buf[7 + led->index * 3];
|
||||
led->color.blue = buf[8 + led->index * 3];
|
||||
}
|
||||
}
|
||||
} else if (device_version == 3) {
|
||||
active_resolution = buf[0] - 1;
|
||||
ratbag_device_for_each_profile(device, profile) {
|
||||
ratbag_profile_for_each_resolution(profile, resolution) {
|
||||
resolution->is_active = resolution->index == active_resolution;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
steelseries_probe(struct ratbag_device *device)
|
||||
{
|
||||
struct steelseries_data *drv_data = NULL;
|
||||
struct ratbag_profile *profile = NULL;
|
||||
struct ratbag_resolution *resolution;
|
||||
struct ratbag_button *button;
|
||||
struct ratbag_led *led;
|
||||
int rc, button_count, led_count, device_version;
|
||||
int rc, button_count, led_count, device_version, mono_led, short_button;
|
||||
_cleanup_(dpi_list_freep) struct dpi_list *dpilist = NULL;
|
||||
_cleanup_(freep) struct dpi_range *dpirange = NULL;
|
||||
|
||||
@@ -137,11 +280,19 @@ steelseries_probe(struct ratbag_device *device)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = ratbag_open_hidraw_index(device,
|
||||
STEELSERIES_INPUT_ENDPOINT,
|
||||
STEELSERIES_INPUT_HIDRAW);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
device_version = ratbag_device_data_steelseries_get_device_version(device->data);
|
||||
button_count = ratbag_device_data_steelseries_get_button_count(device->data);
|
||||
led_count = ratbag_device_data_steelseries_get_led_count(device->data);
|
||||
dpirange = ratbag_device_data_steelseries_get_dpi_range(device->data);
|
||||
dpilist = ratbag_device_data_steelseries_get_dpi_list(device->data);
|
||||
mono_led = ratbag_device_data_steelseries_get_mono_led(device->data);
|
||||
short_button = ratbag_device_data_steelseries_get_short_button(device->data);
|
||||
|
||||
ratbag_device_init_profiles(device,
|
||||
STEELSERIES_NUM_PROFILES,
|
||||
@@ -154,7 +305,9 @@ steelseries_probe(struct ratbag_device *device)
|
||||
/* set these caps manually as they are not assumed with only 1 profile */
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON);
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_KEY);
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS);
|
||||
if (short_button == 0) {
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS);
|
||||
}
|
||||
}
|
||||
|
||||
ratbag_device_unset_capability(device, RATBAG_DEVICE_CAP_QUERY_CONFIGURATION);
|
||||
@@ -193,7 +346,9 @@ steelseries_probe(struct ratbag_device *device)
|
||||
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);
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_MACRO);
|
||||
if (short_button == 0) {
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_MACRO);
|
||||
}
|
||||
|
||||
button_defaults_for_layout(button, button_count);
|
||||
}
|
||||
@@ -201,10 +356,15 @@ steelseries_probe(struct ratbag_device *device)
|
||||
ratbag_profile_for_each_led(profile, led) {
|
||||
led->type = led->index == 0 ? RATBAG_LED_TYPE_LOGO : RATBAG_LED_TYPE_WHEEL;
|
||||
led->mode = RATBAG_LED_ON;
|
||||
led->colordepth = RATBAG_LED_COLORDEPTH_RGB_888;
|
||||
led->color.red = 0;
|
||||
led->color.green = 0;
|
||||
led->color.blue = 255;
|
||||
if (mono_led) {
|
||||
led->colordepth = RATBAG_LED_COLORDEPTH_MONOCHROME;
|
||||
led->brightness = 255;
|
||||
} else {
|
||||
led->colordepth = RATBAG_LED_COLORDEPTH_RGB_888;
|
||||
led->color.red = 0;
|
||||
led->color.green = 0;
|
||||
led->color.blue = 255;
|
||||
}
|
||||
ratbag_led_set_mode_capability(led, RATBAG_LED_OFF);
|
||||
ratbag_led_set_mode_capability(led, RATBAG_LED_ON);
|
||||
ratbag_led_set_mode_capability(led, RATBAG_LED_BREATHING);
|
||||
@@ -213,6 +373,16 @@ steelseries_probe(struct ratbag_device *device)
|
||||
}
|
||||
}
|
||||
|
||||
drv_data = zalloc(sizeof(*drv_data));
|
||||
ratbag_set_drv_data(device, drv_data);
|
||||
|
||||
steelseries_get_firmware_version(device);
|
||||
log_debug(device->ratbag, "SteelSeries firmware version %d.%d\n",
|
||||
drv_data->firmware_major,
|
||||
drv_data->firmware_minor);
|
||||
|
||||
steelseries_read_settings(device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -248,12 +418,20 @@ steelseries_write_dpi(struct ratbag_resolution *resolution)
|
||||
buf[0] = STEELSERIES_ID_DPI_SHORT;
|
||||
buf[1] = resolution->index + 1;
|
||||
buf[2] = i;
|
||||
} else {
|
||||
} else if (device_version == 2) {
|
||||
buf_len = STEELSERIES_REPORT_SIZE;
|
||||
buf[0] = STEELSERIES_ID_DPI;
|
||||
buf[2] = resolution->index + 1;
|
||||
buf[3] = resolution->dpi_x / dpirange->step - 1;
|
||||
buf[6] = 0x42; /* not sure if needed */
|
||||
} else if (device_version == 3) {
|
||||
buf_len = STEELSERIES_REPORT_SIZE;
|
||||
buf[0] = STEELSERIES_ID_DPI_PROTOCOL3;
|
||||
buf[2] = resolution->index + 1;
|
||||
buf[3] = resolution->dpi_x / dpirange->step - 1;
|
||||
buf[5] = 0x42; /* not sure if needed */
|
||||
} else {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
msleep(10);
|
||||
@@ -277,10 +455,16 @@ steelseries_write_report_rate(struct ratbag_resolution *resolution)
|
||||
buf_len = STEELSERIES_REPORT_SIZE_SHORT;
|
||||
buf[0] = STEELSERIES_ID_REPORT_RATE_SHORT;
|
||||
buf[2] = 1000 / resolution->hz;
|
||||
} else {
|
||||
} else if (device_version == 2) {
|
||||
buf_len = STEELSERIES_REPORT_SIZE;
|
||||
buf[0] = STEELSERIES_ID_REPORT_RATE;
|
||||
buf[2] = 1000 / resolution->hz;
|
||||
} else if (device_version == 3) {
|
||||
buf_len = STEELSERIES_REPORT_SIZE;
|
||||
buf[0] = STEELSERIES_ID_REPORT_RATE_PROTOCOL3;
|
||||
buf[2] = 1000 / resolution->hz;
|
||||
} else {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
msleep(10);
|
||||
@@ -295,13 +479,21 @@ static int
|
||||
steelseries_write_buttons(struct ratbag_profile *profile)
|
||||
{
|
||||
struct ratbag_device *device = profile->device;
|
||||
uint8_t buf[STEELSERIES_REPORT_LONG_SIZE] = {0};
|
||||
struct ratbag_button *button;
|
||||
int device_version = ratbag_device_data_steelseries_get_device_version(device->data);
|
||||
int ret;
|
||||
|
||||
if (ratbag_device_data_steelseries_get_macro_length(device->data) == 0)
|
||||
return 0;
|
||||
|
||||
int short_button = ratbag_device_data_steelseries_get_short_button(device->data);
|
||||
int button_size = (short_button == 0) ? 5 : 3;
|
||||
int report_size = (short_button == 0) ? STEELSERIES_REPORT_LONG_SIZE : STEELSERIES_REPORT_SIZE_SHORT;
|
||||
int max_modifiers = (short_button == 0) ? 3 : 0;
|
||||
|
||||
uint8_t buf[report_size];
|
||||
memset(buf, 0, report_size);
|
||||
|
||||
buf[0] = STEELSERIES_ID_BUTTONS;
|
||||
|
||||
ratbag_profile_for_each_button(profile, button) {
|
||||
@@ -310,8 +502,8 @@ steelseries_write_buttons(struct ratbag_profile *profile)
|
||||
unsigned int key, modifiers;
|
||||
int idx;
|
||||
|
||||
/* Each button takes up 5 bytes starting from index 2 */
|
||||
idx = 2 + button->index * 5;
|
||||
/* Each button takes up 3 or 5 bytes starting from index 2 */
|
||||
idx = 2 + button->index * button_size;
|
||||
|
||||
switch (action->type) {
|
||||
case RATBAG_BUTTON_ACTION_TYPE_BUTTON:
|
||||
@@ -322,34 +514,38 @@ steelseries_write_buttons(struct ratbag_profile *profile)
|
||||
ratbag_action_keycode_from_macro(action, &key, &modifiers);
|
||||
|
||||
/* There is only space for 3 modifiers */
|
||||
if (__builtin_popcount(modifiers > 3)) {
|
||||
log_debug(device->ratbag,
|
||||
"Too many modifiers in macro for button %d\n",
|
||||
button->index);
|
||||
if (__builtin_popcount(modifiers) > max_modifiers) {
|
||||
log_error(device->ratbag,
|
||||
"Too many modifiers in macro for button %d (maximum %d)\n",
|
||||
button->index, max_modifiers);
|
||||
break;
|
||||
}
|
||||
|
||||
code = ratbag_hidraw_get_keyboard_usage_from_keycode(
|
||||
device, key);
|
||||
if (code) {
|
||||
buf[idx] = STEELSERIES_BUTTON_KBD;
|
||||
if (short_button) {
|
||||
buf[idx] = STEELSERIES_BUTTON_KEY;
|
||||
} else {
|
||||
buf[idx] = STEELSERIES_BUTTON_KBD;
|
||||
|
||||
if (modifiers & MODIFIER_LEFTCTRL)
|
||||
buf[++idx] = 0xE0;
|
||||
if (modifiers & MODIFIER_LEFTSHIFT)
|
||||
buf[++idx] = 0xE1;
|
||||
if (modifiers & MODIFIER_LEFTALT)
|
||||
buf[++idx] = 0xE2;
|
||||
if (modifiers & MODIFIER_LEFTMETA)
|
||||
buf[++idx] = 0xE3;
|
||||
if (modifiers & MODIFIER_RIGHTCTRL)
|
||||
buf[++idx] = 0xE4;
|
||||
if (modifiers & MODIFIER_RIGHTSHIFT)
|
||||
buf[++idx] = 0xE5;
|
||||
if (modifiers & MODIFIER_RIGHTALT)
|
||||
buf[++idx] = 0xE6;
|
||||
if (modifiers & MODIFIER_RIGHTMETA)
|
||||
buf[++idx] = 0xE7;
|
||||
if (modifiers & MODIFIER_LEFTCTRL)
|
||||
buf[++idx] = 0xE0;
|
||||
if (modifiers & MODIFIER_LEFTSHIFT)
|
||||
buf[++idx] = 0xE1;
|
||||
if (modifiers & MODIFIER_LEFTALT)
|
||||
buf[++idx] = 0xE2;
|
||||
if (modifiers & MODIFIER_LEFTMETA)
|
||||
buf[++idx] = 0xE3;
|
||||
if (modifiers & MODIFIER_RIGHTCTRL)
|
||||
buf[++idx] = 0xE4;
|
||||
if (modifiers & MODIFIER_RIGHTSHIFT)
|
||||
buf[++idx] = 0xE5;
|
||||
if (modifiers & MODIFIER_RIGHTALT)
|
||||
buf[++idx] = 0xE6;
|
||||
if (modifiers & MODIFIER_RIGHTMETA)
|
||||
buf[++idx] = 0xE7;
|
||||
}
|
||||
|
||||
buf[idx + 1] = code;
|
||||
} else {
|
||||
@@ -385,7 +581,12 @@ steelseries_write_buttons(struct ratbag_profile *profile)
|
||||
}
|
||||
|
||||
msleep(10);
|
||||
ret = ratbag_hidraw_output_report(device, buf, sizeof(buf));
|
||||
if (device_version == 3)
|
||||
ret = ratbag_hidraw_raw_request(device, STEELSERIES_ID_BUTTONS,
|
||||
buf,sizeof(buf),HID_FEATURE_REPORT,HID_REQ_SET_REPORT);
|
||||
else
|
||||
ret = ratbag_hidraw_output_report(device, buf, sizeof(buf));
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -421,11 +622,24 @@ steelseries_write_led_v1(struct ratbag_led *led)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
buf[0] = STEELSERIES_ID_LED_COLOR_SHORT;
|
||||
buf[1] = led->index + 1;
|
||||
buf[2] = led->color.red;
|
||||
buf[3] = led->color.green;
|
||||
buf[4] = led->color.blue;
|
||||
int mono_led = ratbag_device_data_steelseries_get_mono_led(device->data);
|
||||
|
||||
if (mono_led) {
|
||||
buf[0] = STEELSERIES_ID_LED_INTENSITY_SHORT;
|
||||
buf[1] = led->index + 1;
|
||||
if (led->mode == RATBAG_LED_OFF || led->brightness == 0) {
|
||||
buf[2] = 1;
|
||||
} else {
|
||||
//split the brightness into roughly 3 equal intensities
|
||||
buf[2] = (led->brightness / 86) + 2;
|
||||
}
|
||||
} else {
|
||||
buf[0] = STEELSERIES_ID_LED_COLOR_SHORT;
|
||||
buf[1] = led->index + 1;
|
||||
buf[2] = led->color.red;
|
||||
buf[3] = led->color.green;
|
||||
buf[4] = led->color.blue;
|
||||
}
|
||||
|
||||
msleep(10);
|
||||
ret = ratbag_hidraw_output_report(device, buf, sizeof(buf));
|
||||
@@ -435,112 +649,194 @@ steelseries_write_led_v1(struct ratbag_led *led)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
create_cycle(struct steelseries_led_cycle *cycle)
|
||||
{
|
||||
cycle->led_id = 0x00;
|
||||
cycle->duration = 5000;
|
||||
cycle->repeat = true;
|
||||
cycle->trigger_buttons = 0x00;
|
||||
|
||||
list_init(&cycle->points);
|
||||
}
|
||||
|
||||
static void
|
||||
construct_cycle_buffer(struct steelseries_led_cycle *cycle,
|
||||
struct steelseries_led_cycle_spec *spec,
|
||||
uint8_t *buf,
|
||||
uint8_t buf_size)
|
||||
{
|
||||
struct steelseries_point *point;
|
||||
uint16_t duration;
|
||||
uint8_t npoints = 0;
|
||||
uint16_t cycle_size = 0;
|
||||
|
||||
buf[0] = spec->cmd_val;
|
||||
buf[spec->led_id_idx] = cycle->led_id;
|
||||
if (spec->has_2_led_ids)
|
||||
buf[spec->led_id2_idx] = cycle->led_id;
|
||||
|
||||
if (!cycle->repeat)
|
||||
buf[spec->repeat_idx] = 0x01;
|
||||
|
||||
buf[spec->trigger_idx] = cycle->trigger_buttons;
|
||||
|
||||
int color_idx = spec->header_len;
|
||||
|
||||
list_for_each(point, &cycle->points, link) {
|
||||
if(npoints == 0){
|
||||
/* this is not a mistake,
|
||||
we need to write the first
|
||||
point as the first data after the header */
|
||||
buf[color_idx++] = point->color.red;
|
||||
buf[color_idx++] = point->color.green;
|
||||
buf[color_idx++] = point->color.blue;
|
||||
}
|
||||
|
||||
cycle_size += point->pos;
|
||||
assert(cycle_size < 256);
|
||||
assert(34 + npoints*4 <= buf_size);
|
||||
|
||||
buf[(color_idx ) + npoints*4] = point->color.red;
|
||||
buf[(color_idx+1) + npoints*4] = point->color.green;
|
||||
buf[(color_idx+2) + npoints*4] = point->color.blue;
|
||||
buf[(color_idx+3) + npoints*4] = point->pos;
|
||||
|
||||
npoints++;
|
||||
}
|
||||
|
||||
buf[spec->point_count_idx] = npoints;
|
||||
|
||||
/* this seems to be the minimum allowed */
|
||||
duration = max(buf[spec->point_count_idx] * 330, cycle->duration);
|
||||
|
||||
hidpp_set_unaligned_le_u16(&buf[spec->duration_idx], duration);
|
||||
}
|
||||
|
||||
static int
|
||||
steelseries_write_led_v2(struct ratbag_led *led)
|
||||
steelseries_write_led_cycle(struct ratbag_led *led,
|
||||
struct steelseries_led_cycle_spec *cycle_spec)
|
||||
{
|
||||
struct ratbag_device *device = led->profile->device;
|
||||
uint8_t buf[STEELSERIES_REPORT_SIZE] = {0};
|
||||
uint16_t duration, min_duration;
|
||||
int ret;
|
||||
|
||||
buf[0] = STEELSERIES_ID_LED;
|
||||
buf[2] = led->index;
|
||||
struct steelseries_led_cycle cycle;
|
||||
struct steelseries_point point[4];
|
||||
|
||||
/* not sure if these two are needed */
|
||||
buf[15] = 0x01;
|
||||
buf[17] = 0x01;
|
||||
const struct ratbag_color black = { 0x00 };
|
||||
const struct ratbag_color red = { 0xFF, 0x00, 0x00 };
|
||||
const struct ratbag_color green = { 0x00, 0xFF, 0x00 };
|
||||
const struct ratbag_color blue = { 0x00, 0x00, 0xFF };
|
||||
|
||||
create_cycle(&cycle);
|
||||
cycle.led_id = led->index;
|
||||
|
||||
switch(led->mode) {
|
||||
case RATBAG_LED_OFF:
|
||||
buf[19] = 0x01;
|
||||
buf[27] = 0x01;
|
||||
buf[28] = buf[31] = 0x00;
|
||||
buf[29] = buf[32] = 0x00;
|
||||
buf[30] = buf[33] = 0x00;
|
||||
/* not sure why the duration is set for the steady color or why
|
||||
it is different for the two LEDs */
|
||||
duration = led->index == 0 ? 10000 : 5000; /* 0x1027 or 0x8813 */
|
||||
cycle.repeat = false;
|
||||
|
||||
point[0].color = black;
|
||||
point[0].pos = 0x00;
|
||||
|
||||
list_append(&cycle.points, &point[0].link);
|
||||
break;
|
||||
case RATBAG_LED_ON:
|
||||
buf[19] = 0x01;
|
||||
buf[27] = 0x01;
|
||||
buf[28] = buf[31] = led->color.red;
|
||||
buf[29] = buf[32] = led->color.green;
|
||||
buf[30] = buf[33] = led->color.blue;
|
||||
cycle.repeat = false;
|
||||
|
||||
/* not sure why the duration is set for the steady color or why
|
||||
it is different for the two LEDs */
|
||||
duration = led->index == 0 ? 10000 : 5000; /* 0x1027 or 0x8813 */
|
||||
point[0].color = led->color;
|
||||
point[0].pos = 0x00;
|
||||
|
||||
list_append(&cycle.points, &point[0].link);
|
||||
break;
|
||||
case RATBAG_LED_CYCLE:
|
||||
buf[27] = 0x04; /* number of steps in cycle */
|
||||
case RATBAG_LED_CYCLE:
|
||||
point[0].color = red;
|
||||
point[0].pos = 0x00;
|
||||
|
||||
/* start color */
|
||||
buf[28] = buf[31] = 0xFF;
|
||||
buf[29] = buf[32] = 0x00;
|
||||
buf[30] = buf[33] = 0x00;
|
||||
point[1].color = green;
|
||||
point[1].pos = 0x55;
|
||||
|
||||
/* Cycle to green */
|
||||
buf[35] = 0x00;
|
||||
buf[36] = 0xFF;
|
||||
buf[37] = 0x00;
|
||||
buf[38] = 0x54; /* normalized time share of animation */
|
||||
point[2].color = blue;
|
||||
point[2].pos = 0x55;
|
||||
|
||||
/* Cycle to blue */
|
||||
buf[39] = 0x00;
|
||||
buf[40] = 0x00;
|
||||
buf[41] = 0xFF;
|
||||
buf[42] = 0x54; /* normalized time share of animation */
|
||||
point[3].color = red;
|
||||
point[3].pos = 0x55;
|
||||
|
||||
/* Cycle to red */
|
||||
buf[43] = 0xFF;
|
||||
buf[44] = 0x00;
|
||||
buf[45] = 0x00;
|
||||
buf[46] = 0x56; /* normalized time share of animation */
|
||||
list_append(&cycle.points, &point[0].link);
|
||||
list_append(&cycle.points, &point[1].link);
|
||||
list_append(&cycle.points, &point[2].link);
|
||||
list_append(&cycle.points, &point[3].link);
|
||||
|
||||
duration = led->ms;
|
||||
cycle.duration = led->ms;
|
||||
break;
|
||||
case RATBAG_LED_BREATHING:
|
||||
buf[27] = 0x03; /* number of steps in cycle */
|
||||
point[0].color = black;
|
||||
point[0].pos = 0x00;
|
||||
|
||||
/* start color */
|
||||
buf[28] = buf[31] = led->color.red;
|
||||
buf[29] = buf[32] = led->color.green;
|
||||
buf[30] = buf[33] = led->color.blue;
|
||||
point[1].color = led->color;
|
||||
point[1].pos = 0x7F;
|
||||
|
||||
/* Cycle to black */
|
||||
buf[35] = 0x00;
|
||||
buf[36] = 0x00;
|
||||
buf[37] = 0x00;
|
||||
buf[38] = 0x7F; /* normalized time share of animation */
|
||||
point[2].color = black;
|
||||
point[2].pos = 0x7F;
|
||||
|
||||
list_append(&cycle.points, &point[0].link);
|
||||
list_append(&cycle.points, &point[1].link);
|
||||
list_append(&cycle.points, &point[2].link);
|
||||
|
||||
/* Cycle to selected color */
|
||||
buf[39] = led->color.red;
|
||||
buf[40] = led->color.green;
|
||||
buf[41] = led->color.blue;
|
||||
buf[42] = 0x7F; /* normalized time share of animation */
|
||||
|
||||
duration = led->ms;
|
||||
cycle.duration = led->ms;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* this seems to be the minimum allowed */
|
||||
min_duration = buf[27] * 330;
|
||||
if (duration < min_duration)
|
||||
duration = min_duration;
|
||||
|
||||
hidpp_set_unaligned_le_u16(&buf[3], duration);
|
||||
construct_cycle_buffer(&cycle, cycle_spec, buf, sizeof(buf));
|
||||
|
||||
msleep(10);
|
||||
ret = ratbag_hidraw_output_report(device, buf, sizeof(buf));
|
||||
ret = ratbag_hidraw_raw_request(device, cycle_spec->cmd_val, buf,
|
||||
sizeof(buf), cycle_spec->hid_report_type, HID_REQ_SET_REPORT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
steelseries_write_led_v2(struct ratbag_led *led)
|
||||
{
|
||||
struct steelseries_led_cycle_spec spec;
|
||||
|
||||
spec.hid_report_type = HID_OUTPUT_REPORT;
|
||||
spec.header_len = 28;
|
||||
spec.cmd_val = STEELSERIES_ID_LED;
|
||||
spec.has_2_led_ids = false;
|
||||
spec.led_id_idx = 2;
|
||||
spec.duration_idx = 3;
|
||||
spec.repeat_idx = 19;
|
||||
spec.trigger_idx = 23;
|
||||
spec.point_count_idx = 27;
|
||||
|
||||
return steelseries_write_led_cycle(led, &spec);
|
||||
}
|
||||
|
||||
static int
|
||||
steelseries_write_led_v3(struct ratbag_led *led)
|
||||
{
|
||||
struct steelseries_led_cycle_spec spec;
|
||||
|
||||
spec.hid_report_type = HID_FEATURE_REPORT;
|
||||
spec.header_len = 30;
|
||||
spec.cmd_val = STEELSERIES_ID_LED_PROTOCOL3;
|
||||
spec.has_2_led_ids = true;
|
||||
spec.led_id_idx = 2;
|
||||
spec.led_id2_idx = 7;
|
||||
spec.duration_idx = 8;
|
||||
spec.repeat_idx = 24;
|
||||
spec.trigger_idx = 25;
|
||||
spec.point_count_idx = 29;
|
||||
|
||||
return steelseries_write_led_cycle(led, &spec);
|
||||
}
|
||||
|
||||
static int
|
||||
steelseries_write_led(struct ratbag_led *led)
|
||||
{
|
||||
@@ -551,6 +847,8 @@ steelseries_write_led(struct ratbag_led *led)
|
||||
return steelseries_write_led_v1(led);
|
||||
else if (device_version == 2)
|
||||
return steelseries_write_led_v2(led);
|
||||
else if (device_version == 3)
|
||||
return steelseries_write_led_v3(led);
|
||||
|
||||
return -ENOTSUP;
|
||||
}
|
||||
@@ -566,9 +864,14 @@ steelseries_write_save(struct ratbag_device *device)
|
||||
if (device_version == 1) {
|
||||
buf_len = STEELSERIES_REPORT_SIZE_SHORT;
|
||||
buf[0] = STEELSERIES_ID_SAVE_SHORT;
|
||||
} else {
|
||||
} else if (device_version == 2) {
|
||||
buf_len = STEELSERIES_REPORT_SIZE;
|
||||
buf[0] = STEELSERIES_ID_SAVE;
|
||||
} else if (device_version == 3) {
|
||||
buf_len = STEELSERIES_REPORT_SIZE;
|
||||
buf[0] = STEELSERIES_ID_SAVE_PROTOCOL3;
|
||||
} else {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
msleep(20);
|
||||
@@ -658,7 +961,9 @@ steelseries_commit(struct ratbag_device *device)
|
||||
static void
|
||||
steelseries_remove(struct ratbag_device *device)
|
||||
{
|
||||
ratbag_close_hidraw(device);
|
||||
ratbag_close_hidraw_index(device, 0);
|
||||
ratbag_close_hidraw_index(device, 1);
|
||||
free(ratbag_get_drv_data(device));
|
||||
}
|
||||
|
||||
struct ratbag_driver steelseries_driver = {
|
||||
|
||||
@@ -190,7 +190,7 @@ test_read_profile(struct ratbag_profile *profile)
|
||||
r0 = &p0->resolutions[0];
|
||||
|
||||
for (i = 0; i < d->num_resolutions; i++) {
|
||||
_cleanup_resolution_ struct ratbag_resolution *res;
|
||||
_cleanup_resolution_ struct ratbag_resolution *res = NULL;
|
||||
size_t nrates = 0;
|
||||
|
||||
r = &p->resolutions[i];
|
||||
@@ -225,7 +225,7 @@ test_read_profile(struct ratbag_profile *profile)
|
||||
|
||||
/* special case triggered by the test suite when num_resolutions is 0 */
|
||||
if (d->num_resolutions) {
|
||||
_cleanup_resolution_ struct ratbag_resolution *res;
|
||||
_cleanup_resolution_ struct ratbag_resolution *res = NULL;
|
||||
|
||||
res = ratbag_profile_get_resolution(profile, 0);
|
||||
assert(res);
|
||||
|
||||
@@ -149,6 +149,7 @@ static const struct hidpp20_1b04_physical_mapping hidpp20_1b04_physical_mapping[
|
||||
BUTTON_PHYS_MAPPING(98, "Do Nothing" , RATBAG_BUTTON_TYPE_UNKNOWN),
|
||||
BUTTON_PHYS_MAPPING(156, "Gesture Button" , RATBAG_BUTTON_TYPE_UNKNOWN),
|
||||
BUTTON_PHYS_MAPPING(157, "SmartShift" , RATBAG_BUTTON_TYPE_WHEEL_RATCHET_MODE_SHIFT),
|
||||
BUTTON_PHYS_MAPPING(169, "Gesture Button" , RATBAG_BUTTON_TYPE_MIDDLE),
|
||||
BUTTON_PHYS_MAPPING(221, "LedToggle" , RATBAG_BUTTON_TYPE_UNKNOWN),
|
||||
};
|
||||
|
||||
|
||||
@@ -55,9 +55,12 @@ hidpp20_feature_get_name(uint16_t feature)
|
||||
CASE_RETURN_STRING(HIDPP_PAGE_ROOT);
|
||||
CASE_RETURN_STRING(HIDPP_PAGE_FEATURE_SET);
|
||||
CASE_RETURN_STRING(HIDPP_PAGE_DEVICE_INFO);
|
||||
CASE_RETURN_STRING(HIDPP_PAGE_DEVICE_NAME);
|
||||
CASE_RETURN_STRING(HIDPP_PAGE_RESET);
|
||||
CASE_RETURN_STRING(HIDPP_PAGE_BATTERY_LEVEL_STATUS);
|
||||
CASE_RETURN_STRING(HIDPP_PAGE_KBD_REPROGRAMMABLE_KEYS);
|
||||
CASE_RETURN_STRING(HIDPP_PAGE_SPECIAL_KEYS_BUTTONS);
|
||||
CASE_RETURN_STRING(HIDPP_PAGE_WIRELESS_DEVICE_STATUS);
|
||||
CASE_RETURN_STRING(HIDPP_PAGE_MOUSE_POINTER_BASIC);
|
||||
CASE_RETURN_STRING(HIDPP_PAGE_ADJUSTABLE_DPI);
|
||||
CASE_RETURN_STRING(HIDPP_PAGE_ADJUSTABLE_REPORT_RATE);
|
||||
@@ -189,7 +192,9 @@ out_err:
|
||||
int
|
||||
hidpp20_request_command(struct hidpp20_device *device, union hidpp20_message *msg)
|
||||
{
|
||||
return hidpp20_request_command_allow_error(device, msg, false);
|
||||
int ret = hidpp20_request_command_allow_error(device, msg, false);
|
||||
|
||||
return ret > 0 ? -EPROTO : ret;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@@ -1040,7 +1045,7 @@ int hidpp20_special_key_mouse_get_controls(struct hidpp20_device *device,
|
||||
{
|
||||
uint8_t feature_index;
|
||||
struct hidpp20_control_id *c_list, *control;
|
||||
uint8_t num_controls;
|
||||
uint8_t num_controls, real_num_controls = 0;
|
||||
unsigned i;
|
||||
int rc;
|
||||
|
||||
@@ -1060,22 +1065,30 @@ int hidpp20_special_key_mouse_get_controls(struct hidpp20_device *device,
|
||||
return 0;
|
||||
}
|
||||
|
||||
hidpp_log_debug(&device->base, "device has %d buttons\n", num_controls);
|
||||
|
||||
c_list = zalloc(num_controls * sizeof(struct hidpp20_control_id));
|
||||
|
||||
for (i = 0; i < num_controls; i++) {
|
||||
control = &c_list[i];
|
||||
control = &c_list[real_num_controls];
|
||||
control->index = i;
|
||||
rc = hidpp20_special_keys_buttons_get_info(device,
|
||||
feature_index,
|
||||
control);
|
||||
if (rc)
|
||||
goto err;
|
||||
if (rc) {
|
||||
hidpp_log_error(&device->base,
|
||||
"error getting button info for control %d, ignoring\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = hidpp20_special_keys_buttons_get_reporting(device,
|
||||
feature_index,
|
||||
control);
|
||||
if (rc)
|
||||
goto err;
|
||||
if (rc) {
|
||||
hidpp_log_error(&device->base,
|
||||
"error getting button reporting for control %d, ignoring\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
hidpp_log_raw(&device->base,
|
||||
"control %d: cid: '%s' (%d) tid: '%s' (%d) flags: 0x%02x pos: %d group: %d gmask: 0x%02x raw_XY: %s\n"
|
||||
@@ -1095,13 +1108,11 @@ int hidpp20_special_key_mouse_get_controls(struct hidpp20_device *device,
|
||||
control->reporting.divert ? "yes" : "no",
|
||||
hidpp20_1b04_get_logical_mapping_name(control->reporting.remapped),
|
||||
control->reporting.remapped);
|
||||
}
|
||||
|
||||
*controls_list = c_list;
|
||||
return num_controls;
|
||||
err:
|
||||
free(c_list);
|
||||
return rc;
|
||||
real_num_controls++;
|
||||
}
|
||||
*controls_list = realloc(c_list, real_num_controls * sizeof(struct hidpp20_control_id));
|
||||
return real_num_controls;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -2362,7 +2373,7 @@ hidpp20_onboard_profiles_parse(struct hidpp20_device *device,
|
||||
profiles->sector_size,
|
||||
data);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
return rc; // ignore_clang_sa_mem_leak
|
||||
|
||||
crc_valid = hidpp20_onboard_profiles_is_sector_valid(device,
|
||||
profiles->sector_size,
|
||||
|
||||
@@ -100,6 +100,18 @@ int hidpp20_root_get_protocol_version(struct hidpp20_device *dev,
|
||||
|
||||
#define HIDPP_PAGE_DEVICE_INFO 0x0003
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0x0005: Device Name */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#define HIDPP_PAGE_DEVICE_NAME 0x0005
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0x0020: Reset */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#define HIDPP_PAGE_RESET 0x0020
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0x1000: Battery level status */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@@ -316,6 +328,12 @@ const char *hidpp20_1b04_get_logical_mapping_name(uint16_t value);
|
||||
enum ratbag_button_type hidpp20_1b04_get_physical_mapping(uint16_t value);
|
||||
const char *hidpp20_1b04_get_physical_mapping_name(uint16_t value);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0x1d4b: Wireless Device Status */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#define HIDPP_PAGE_WIRELESS_DEVICE_STATUS 0x1d4b
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0x2200: Mouse Pointer Basic Optical Sensors */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@@ -195,7 +195,7 @@ lur_receiver_enumerate(struct lur_receiver *lur,
|
||||
dev->present = false;
|
||||
|
||||
for (i = 0; i < MAX_DEVICES; i++) {
|
||||
_cleanup_hidpp10_device_destroy_ struct hidpp10_device *d;
|
||||
_cleanup_hidpp10_device_destroy_ struct hidpp10_device *d = NULL;
|
||||
size_t name_size = 64;
|
||||
char name[name_size];
|
||||
uint8_t interval, type;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "libratbag.h"
|
||||
#include "libratbag-private.h"
|
||||
@@ -47,6 +48,7 @@ enum driver {
|
||||
ETEKCITY,
|
||||
GSKILL,
|
||||
LOGITECH_G300,
|
||||
LOGITECH_G600,
|
||||
STEELSERIES,
|
||||
};
|
||||
|
||||
@@ -71,6 +73,8 @@ struct data_steelseries {
|
||||
struct dpi_list *dpi_list;
|
||||
struct dpi_range *dpi_range;
|
||||
int macro_length;
|
||||
int mono_led;
|
||||
int short_button;
|
||||
};
|
||||
|
||||
struct ratbag_device_data {
|
||||
@@ -174,6 +178,8 @@ init_data_steelseries(struct ratbag *ratbag,
|
||||
data->steelseries.led_count = -1;
|
||||
data->steelseries.dpi_list = NULL;
|
||||
data->steelseries.dpi_range = NULL;
|
||||
data->steelseries.mono_led = 0;
|
||||
data->steelseries.short_button = 0;
|
||||
|
||||
num = g_key_file_get_integer(keyfile, group, "Buttons", &error);
|
||||
if (num != 0 || !error)
|
||||
@@ -210,6 +216,20 @@ init_data_steelseries(struct ratbag *ratbag,
|
||||
data->steelseries.macro_length = num;
|
||||
if (error)
|
||||
g_error_free(error);
|
||||
|
||||
error = NULL;
|
||||
num = g_key_file_get_integer(keyfile, group, "MonoLed", &error);
|
||||
if (num > 0 || !error)
|
||||
data->steelseries.mono_led = num;
|
||||
if (error)
|
||||
g_error_free(error);
|
||||
|
||||
error = NULL;
|
||||
num = g_key_file_get_integer(keyfile, group, "ShortButton", &error);
|
||||
if (num > 0 || !error)
|
||||
data->steelseries.short_button = num;
|
||||
if (error)
|
||||
g_error_free(error);
|
||||
}
|
||||
|
||||
static const struct driver_map {
|
||||
@@ -225,6 +245,7 @@ static const struct driver_map {
|
||||
{ ETEKCITY, "etekcity", NULL},
|
||||
{ GSKILL, "gskill", NULL },
|
||||
{ LOGITECH_G300, "logitech_g300", NULL},
|
||||
{ LOGITECH_G600, "logitech_g600", NULL},
|
||||
{ STEELSERIES, "steelseries", init_data_steelseries },
|
||||
};
|
||||
|
||||
@@ -388,7 +409,7 @@ file_data_matches(struct ratbag *ratbag,
|
||||
data->refcount = 1;
|
||||
data->name = g_key_file_get_string(keyfile, GROUP_DEVICE, "Name", NULL);
|
||||
if (!data->name) {
|
||||
return false;
|
||||
return false; // ignore_clang_sa_mem_leak
|
||||
}
|
||||
|
||||
data->driver = g_key_file_get_string(keyfile, GROUP_DEVICE, "Driver", NULL);
|
||||
@@ -599,3 +620,19 @@ ratbag_device_data_steelseries_get_macro_length(const struct ratbag_device_data
|
||||
|
||||
return data->steelseries.macro_length;
|
||||
}
|
||||
|
||||
int
|
||||
ratbag_device_data_steelseries_get_mono_led(const struct ratbag_device_data *data)
|
||||
{
|
||||
assert(data->drivertype == STEELSERIES);
|
||||
|
||||
return data->steelseries.mono_led;
|
||||
}
|
||||
|
||||
int
|
||||
ratbag_device_data_steelseries_get_short_button(const struct ratbag_device_data *data)
|
||||
{
|
||||
assert(data->drivertype == STEELSERIES);
|
||||
|
||||
return data->steelseries.short_button;
|
||||
}
|
||||
|
||||
@@ -110,3 +110,9 @@ ratbag_device_data_steelseries_get_dpi_range(const struct ratbag_device_data *da
|
||||
|
||||
int
|
||||
ratbag_device_data_steelseries_get_macro_length(const struct ratbag_device_data *data);
|
||||
|
||||
int
|
||||
ratbag_device_data_steelseries_get_mono_led(const struct ratbag_device_data *data);
|
||||
|
||||
int
|
||||
ratbag_device_data_steelseries_get_short_button(const struct ratbag_device_data *data);
|
||||
|
||||
@@ -1223,7 +1223,7 @@ static int
|
||||
ratbag_hidraw_parse_report_descriptor(struct ratbag_device *device)
|
||||
{
|
||||
int rc, desc_size = 0;
|
||||
struct ratbag_hidraw *hidraw = &device->hidraw;
|
||||
struct ratbag_hidraw *hidraw = &device->hidraw[0];
|
||||
struct hidraw_report_descriptor report_desc = {0};
|
||||
unsigned int i, j;
|
||||
unsigned int usage_page, usage;
|
||||
@@ -1291,7 +1291,7 @@ ratbag_hidraw_parse_report_descriptor(struct ratbag_device *device)
|
||||
}
|
||||
|
||||
static int
|
||||
ratbag_open_hidraw_node(struct ratbag_device *device, struct udev_device *hidraw_udev)
|
||||
ratbag_open_hidraw_node(struct ratbag_device *device, struct udev_device *hidraw_udev, int idx)
|
||||
{
|
||||
struct hidraw_devinfo info;
|
||||
struct ratbag_device *tmp_device;
|
||||
@@ -1300,15 +1300,17 @@ ratbag_open_hidraw_node(struct ratbag_device *device, struct udev_device *hidraw
|
||||
const char *sysname;
|
||||
size_t reports_size;
|
||||
|
||||
device->hidraw.fd = -1;
|
||||
assert(idx >= 0 && idx < MAX_HIDRAW);
|
||||
|
||||
device->hidraw[idx].fd = -1;
|
||||
|
||||
sysname = udev_device_get_sysname(hidraw_udev);
|
||||
if (!strneq("hidraw", sysname, 6))
|
||||
return -ENODEV;
|
||||
|
||||
list_for_each(tmp_device, &device->ratbag->devices, link) {
|
||||
if (tmp_device->hidraw.sysname &&
|
||||
streq(tmp_device->hidraw.sysname, sysname)) {
|
||||
if (tmp_device->hidraw[idx].sysname &&
|
||||
streq(tmp_device->hidraw[idx].sysname, sysname)) {
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
@@ -1339,7 +1341,7 @@ ratbag_open_hidraw_node(struct ratbag_device *device, struct udev_device *hidraw
|
||||
device->name,
|
||||
udev_device_get_devnode(hidraw_udev));
|
||||
|
||||
device->hidraw.fd = fd;
|
||||
device->hidraw[idx].fd = fd;
|
||||
|
||||
/* parse first to count the number of reports */
|
||||
res = ratbag_hidraw_parse_report_descriptor(device);
|
||||
@@ -1348,19 +1350,19 @@ ratbag_open_hidraw_node(struct ratbag_device *device, struct udev_device *hidraw
|
||||
"Error while parsing the report descriptor: '%s' (%d)\n",
|
||||
strerror(-res),
|
||||
res);
|
||||
device->hidraw.fd = -1;
|
||||
device->hidraw[idx].fd = -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (device->hidraw.num_reports)
|
||||
reports_size = device->hidraw.num_reports * sizeof(struct ratbag_hid_report);
|
||||
if (device->hidraw[idx].num_reports)
|
||||
reports_size = device->hidraw[idx].num_reports * sizeof(struct ratbag_hid_report);
|
||||
else
|
||||
reports_size = sizeof(struct ratbag_hid_report);
|
||||
|
||||
device->hidraw.reports = zalloc(reports_size);
|
||||
device->hidraw[idx].reports = zalloc(reports_size);
|
||||
ratbag_hidraw_parse_report_descriptor(device);
|
||||
|
||||
device->hidraw.sysname = strdup_safe(sysname);
|
||||
device->hidraw[idx].sysname = strdup_safe(sysname);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
@@ -1372,17 +1374,18 @@ err:
|
||||
static int
|
||||
ratbag_find_hidraw_node(struct ratbag_device *device,
|
||||
int (*match)(struct ratbag_device *device),
|
||||
int use_usb_parent)
|
||||
int use_usb_parent,
|
||||
int match_index, int hidraw_index)
|
||||
{
|
||||
struct ratbag *ratbag = device->ratbag;
|
||||
struct udev_enumerate *e;
|
||||
_cleanup_(udev_enumerate_unrefp) struct udev_enumerate *e = NULL;
|
||||
struct udev_list_entry *entry;
|
||||
const char *path;
|
||||
struct udev_device *hid_udev;
|
||||
struct udev_device *parent_udev;
|
||||
struct udev *udev = ratbag->udev;
|
||||
int rc = -ENODEV;
|
||||
int matched;
|
||||
int matched, endpoint_index = 0;
|
||||
|
||||
assert(match);
|
||||
|
||||
@@ -1414,29 +1417,30 @@ ratbag_find_hidraw_node(struct ratbag_device *device,
|
||||
if (!udev_device)
|
||||
continue;
|
||||
|
||||
rc = ratbag_open_hidraw_node(device, udev_device);
|
||||
if (match_index > 0 && match_index != endpoint_index++)
|
||||
continue;
|
||||
|
||||
rc = ratbag_open_hidraw_node(device, udev_device, hidraw_index);
|
||||
if (rc)
|
||||
goto skip;
|
||||
|
||||
|
||||
matched = match(device);
|
||||
rc = matched ? 0 : -ENODEV;
|
||||
if (matched == 1)
|
||||
goto out;
|
||||
return rc;
|
||||
|
||||
skip:
|
||||
ratbag_close_hidraw(device);
|
||||
ratbag_close_hidraw_index(device, hidraw_index);
|
||||
}
|
||||
|
||||
out:
|
||||
udev_enumerate_unref(e);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ratbag_find_hidraw(struct ratbag_device *device, int (*match)(struct ratbag_device *device))
|
||||
{
|
||||
return ratbag_find_hidraw_node(device, match, true);
|
||||
return ratbag_find_hidraw_node(device, match, true, -1, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1448,7 +1452,13 @@ hidraw_match_all(struct ratbag_device *device)
|
||||
int
|
||||
ratbag_open_hidraw(struct ratbag_device *device)
|
||||
{
|
||||
return ratbag_find_hidraw_node(device, hidraw_match_all, false);
|
||||
return ratbag_find_hidraw_node(device, hidraw_match_all, false, -1, 0);
|
||||
}
|
||||
|
||||
int
|
||||
ratbag_open_hidraw_index(struct ratbag_device *device, int endpoint_index, int hidraw_index)
|
||||
{
|
||||
return ratbag_find_hidraw_node(device, hidraw_match_all, true, endpoint_index, hidraw_index);
|
||||
}
|
||||
|
||||
static struct ratbag_hid_report *
|
||||
@@ -1457,15 +1467,15 @@ ratbag_hidraw_get_report(struct ratbag_device *device, unsigned int report_id)
|
||||
unsigned i;
|
||||
|
||||
if (report_id == 0) {
|
||||
if (device->hidraw.reports[0].report_id == report_id)
|
||||
return &device->hidraw.reports[0];
|
||||
if (device->hidraw[0].reports[0].report_id == report_id)
|
||||
return &device->hidraw[0].reports[0];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < device->hidraw.num_reports; i++) {
|
||||
if (device->hidraw.reports[i].report_id == report_id)
|
||||
return &device->hidraw.reports[i];
|
||||
for (i = 0; i < device->hidraw[0].num_reports; i++) {
|
||||
if (device->hidraw[0].reports[i].report_id == report_id)
|
||||
return &device->hidraw[0].reports[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -1507,20 +1517,28 @@ ratbag_hidraw_get_usage(struct ratbag_device *device, unsigned int report_id)
|
||||
void
|
||||
ratbag_close_hidraw(struct ratbag_device *device)
|
||||
{
|
||||
if (device->hidraw.fd < 0)
|
||||
ratbag_close_hidraw_index(device, 0);
|
||||
}
|
||||
|
||||
void
|
||||
ratbag_close_hidraw_index(struct ratbag_device *device, int idx)
|
||||
{
|
||||
assert(idx >= 0 && idx < MAX_HIDRAW);
|
||||
|
||||
if (device->hidraw[idx].fd < 0)
|
||||
return;
|
||||
|
||||
if (device->hidraw.sysname) {
|
||||
free(device->hidraw.sysname);
|
||||
device->hidraw.sysname = NULL;
|
||||
if (device->hidraw[idx].sysname) {
|
||||
free(device->hidraw[idx].sysname);
|
||||
device->hidraw[idx].sysname = NULL;
|
||||
}
|
||||
|
||||
ratbag_close_fd(device, device->hidraw.fd);
|
||||
device->hidraw.fd = -1;
|
||||
ratbag_close_fd(device, device->hidraw[idx].fd);
|
||||
device->hidraw[idx].fd = -1;
|
||||
|
||||
if (device->hidraw.reports) {
|
||||
free(device->hidraw.reports);
|
||||
device->hidraw.reports = NULL;
|
||||
if (device->hidraw[idx].reports) {
|
||||
free(device->hidraw[idx].reports);
|
||||
device->hidraw[idx].reports = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1531,7 +1549,7 @@ ratbag_hidraw_raw_request(struct ratbag_device *device, unsigned char reportnum,
|
||||
uint8_t tmp_buf[HID_MAX_BUFFER_SIZE];
|
||||
int rc;
|
||||
|
||||
if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf || device->hidraw.fd < 0)
|
||||
if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf || device->hidraw[0].fd < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (rtype != HID_FEATURE_REPORT)
|
||||
@@ -1542,7 +1560,7 @@ ratbag_hidraw_raw_request(struct ratbag_device *device, unsigned char reportnum,
|
||||
memset(tmp_buf, 0, len);
|
||||
tmp_buf[0] = reportnum;
|
||||
|
||||
rc = ioctl(device->hidraw.fd, HIDIOCGFEATURE(len), tmp_buf);
|
||||
rc = ioctl(device->hidraw[0].fd, HIDIOCGFEATURE(len), tmp_buf);
|
||||
if (rc < 0)
|
||||
return -errno;
|
||||
|
||||
@@ -1554,7 +1572,7 @@ ratbag_hidraw_raw_request(struct ratbag_device *device, unsigned char reportnum,
|
||||
buf[0] = reportnum;
|
||||
|
||||
log_buf_raw(device->ratbag, "feature set: ", buf, len);
|
||||
rc = ioctl(device->hidraw.fd, HIDIOCSFEATURE(len), buf);
|
||||
rc = ioctl(device->hidraw[0].fd, HIDIOCSFEATURE(len), buf);
|
||||
if (rc < 0)
|
||||
return -errno;
|
||||
|
||||
@@ -1569,12 +1587,12 @@ ratbag_hidraw_output_report(struct ratbag_device *device, uint8_t *buf, size_t l
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf || device->hidraw.fd < 0)
|
||||
if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf || device->hidraw[0].fd < 0)
|
||||
return -EINVAL;
|
||||
|
||||
log_buf_raw(device->ratbag, "output report: ", buf, len);
|
||||
|
||||
rc = write(device->hidraw.fd, buf, len);
|
||||
rc = write(device->hidraw[0].fd, buf, len);
|
||||
|
||||
if (rc < 0)
|
||||
return -errno;
|
||||
@@ -1587,14 +1605,22 @@ ratbag_hidraw_output_report(struct ratbag_device *device, uint8_t *buf, size_t l
|
||||
|
||||
int
|
||||
ratbag_hidraw_read_input_report(struct ratbag_device *device, uint8_t *buf, size_t len)
|
||||
{
|
||||
return ratbag_hidraw_read_input_report_index(device, buf, len, 0);
|
||||
}
|
||||
|
||||
int
|
||||
ratbag_hidraw_read_input_report_index(struct ratbag_device *device, uint8_t *buf, size_t len, int hidrawno)
|
||||
{
|
||||
int rc;
|
||||
struct pollfd fds;
|
||||
|
||||
if (len < 1 || !buf || device->hidraw.fd < 0)
|
||||
assert(hidrawno >= 0 && hidrawno < MAX_HIDRAW);
|
||||
|
||||
if (len < 1 || !buf || device->hidraw[hidrawno].fd < 0)
|
||||
return -EINVAL;
|
||||
|
||||
fds.fd = device->hidraw.fd;
|
||||
fds.fd = device->hidraw[hidrawno].fd;
|
||||
fds.events = POLLIN;
|
||||
|
||||
rc = poll(&fds, 1, 1000);
|
||||
@@ -1604,7 +1630,7 @@ ratbag_hidraw_read_input_report(struct ratbag_device *device, uint8_t *buf, size
|
||||
if (rc == 0)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
rc = read(device->hidraw.fd, buf, len);
|
||||
rc = read(device->hidraw[hidrawno].fd, buf, len);
|
||||
|
||||
if (rc > 0)
|
||||
log_buf_raw(device->ratbag, "input report: ", buf, rc);
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#define HID_INPUT_REPORT 0
|
||||
#define HID_OUTPUT_REPORT 1
|
||||
#define HID_FEATURE_REPORT 2
|
||||
#define MAX_HIDRAW 2
|
||||
|
||||
struct ratbag_hid_report {
|
||||
unsigned int report_id;
|
||||
@@ -55,6 +56,18 @@ struct ratbag_hidraw {
|
||||
*/
|
||||
int ratbag_open_hidraw(struct ratbag_device *device);
|
||||
|
||||
/**
|
||||
* Open a hidraw device associated with the device by its enumeration order to
|
||||
* a specific internal hidraw index.
|
||||
*
|
||||
* @param device the ratbag device
|
||||
* @param enumeration index of the endpoint
|
||||
* @param interal index of hidraw array
|
||||
*
|
||||
* @return 0 on success or a negative errno on error
|
||||
*/
|
||||
int ratbag_open_hidraw_index(struct ratbag_device *device, int endpoint_index, int hidraw_index);
|
||||
|
||||
/**
|
||||
* Find and open the hidraw device associated with the device by using the
|
||||
* given matching function.
|
||||
@@ -75,6 +88,14 @@ ratbag_find_hidraw(struct ratbag_device *device,
|
||||
*/
|
||||
void ratbag_close_hidraw(struct ratbag_device *device);
|
||||
|
||||
/**
|
||||
* Close a hidraw device associated with the device by the internal index.
|
||||
*
|
||||
* @param device the ratbag device
|
||||
* @param interal index of hidraw array
|
||||
*/
|
||||
void ratbag_close_hidraw_index(struct ratbag_device *device, int idx);
|
||||
|
||||
/**
|
||||
* Send report request to device
|
||||
*
|
||||
@@ -115,6 +136,19 @@ int ratbag_hidraw_output_report(struct ratbag_device *device, uint8_t *buf, size
|
||||
*/
|
||||
int ratbag_hidraw_read_input_report(struct ratbag_device *device, uint8_t *buf, size_t len);
|
||||
|
||||
/**
|
||||
* Read an input report from the device from a specific hidraw index
|
||||
*
|
||||
* @param device the ratbag device
|
||||
* @param[out] buf resulting raw data
|
||||
* @param len length of buf
|
||||
* @param interal index of hidraw array
|
||||
*
|
||||
* @return count of data transfered, or a negative errno on error
|
||||
*/
|
||||
int ratbag_hidraw_read_input_report_index(struct ratbag_device *device, uint8_t *buf, size_t len, int hidrawno);
|
||||
|
||||
|
||||
/**
|
||||
* Tells if a given device has the specified report ID.
|
||||
*
|
||||
|
||||
@@ -129,7 +129,7 @@ struct ratbag_device {
|
||||
void *userdata;
|
||||
|
||||
struct udev_device *udev_device;
|
||||
struct ratbag_hidraw hidraw;
|
||||
struct ratbag_hidraw hidraw[MAX_HIDRAW];
|
||||
int refcount;
|
||||
struct input_id ids;
|
||||
struct ratbag_driver *driver;
|
||||
@@ -262,7 +262,7 @@ struct ratbag_resolution {
|
||||
unsigned int dpi_y; /**< y resolution in dpi */
|
||||
unsigned int hz; /**< report rate in Hz */
|
||||
|
||||
unsigned int rates[5];
|
||||
unsigned int rates[8];
|
||||
size_t nrates;
|
||||
|
||||
bool is_active;
|
||||
@@ -603,6 +603,7 @@ struct ratbag_driver etekcity_driver;
|
||||
struct ratbag_driver hidpp20_driver;
|
||||
struct ratbag_driver hidpp10_driver;
|
||||
struct ratbag_driver logitech_g300_driver;
|
||||
struct ratbag_driver logitech_g600_driver;
|
||||
struct ratbag_driver roccat_driver;
|
||||
struct ratbag_driver gskill_driver;
|
||||
struct ratbag_driver steelseries_driver;
|
||||
|
||||
@@ -583,6 +583,7 @@ ratbag_create_context(const struct ratbag_interface *interface,
|
||||
ratbag_register_driver(ratbag, &hidpp20_driver);
|
||||
ratbag_register_driver(ratbag, &hidpp10_driver);
|
||||
ratbag_register_driver(ratbag, &logitech_g300_driver);
|
||||
ratbag_register_driver(ratbag, &logitech_g600_driver);
|
||||
ratbag_register_driver(ratbag, &roccat_driver);
|
||||
ratbag_register_driver(ratbag, &gskill_driver);
|
||||
ratbag_register_driver(ratbag, &steelseries_driver);
|
||||
@@ -649,7 +650,7 @@ ratbag_create_led(struct ratbag_profile *profile, unsigned int index)
|
||||
return led;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT bool
|
||||
ratbag_profile_has_capability(const struct ratbag_profile *profile,
|
||||
enum ratbag_profile_capability cap)
|
||||
{
|
||||
@@ -831,16 +832,16 @@ ratbag_profile_set_enabled(struct ratbag_profile *profile, bool enabled)
|
||||
return RATBAG_SUCCESS;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT bool
|
||||
ratbag_profile_is_active(struct ratbag_profile *profile)
|
||||
{
|
||||
return profile->is_active;
|
||||
return !!profile->is_active;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT bool
|
||||
ratbag_profile_is_enabled(const struct ratbag_profile *profile)
|
||||
{
|
||||
return profile->is_enabled;
|
||||
return !!profile->is_enabled;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT unsigned int
|
||||
@@ -892,7 +893,7 @@ ratbag_device_unset_capability(struct ratbag_device *device,
|
||||
long_clear_bit(device->capabilities, cap);
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT bool
|
||||
ratbag_device_has_capability(const struct ratbag_device *device,
|
||||
enum ratbag_device_capability cap)
|
||||
{
|
||||
@@ -1001,7 +1002,7 @@ ratbag_device_commit(struct ratbag_device *device)
|
||||
|
||||
list_for_each(resolution, &profile->resolutions, link)
|
||||
resolution->dirty = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
return RATBAG_SUCCESS;
|
||||
@@ -1083,7 +1084,7 @@ ratbag_resolution_unref(struct ratbag_resolution *resolution)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT bool
|
||||
ratbag_resolution_has_capability(struct ratbag_resolution *resolution,
|
||||
enum ratbag_resolution_capability cap)
|
||||
{
|
||||
@@ -1226,10 +1227,10 @@ ratbag_resolution_get_report_rate_list(struct ratbag_resolution *resolution,
|
||||
return resolution->nrates;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT bool
|
||||
ratbag_resolution_is_active(const struct ratbag_resolution *resolution)
|
||||
{
|
||||
return resolution->is_active;
|
||||
return !!resolution->is_active;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
@@ -1248,10 +1249,10 @@ ratbag_resolution_set_active(struct ratbag_resolution *resolution)
|
||||
}
|
||||
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT bool
|
||||
ratbag_resolution_is_default(const struct ratbag_resolution *resolution)
|
||||
{
|
||||
return resolution->is_default;
|
||||
return !!resolution->is_default;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
@@ -1314,7 +1315,7 @@ ratbag_button_get_action_type(struct ratbag_button *button)
|
||||
return button->action.type;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT bool
|
||||
ratbag_button_has_action_type(struct ratbag_button *button,
|
||||
enum ratbag_button_action_type action_type)
|
||||
{
|
||||
@@ -1544,7 +1545,7 @@ ratbag_led_get_type(struct ratbag_led *led)
|
||||
return led->type;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT bool
|
||||
ratbag_led_has_mode(struct ratbag_led *led,
|
||||
enum ratbag_led_mode mode)
|
||||
{
|
||||
@@ -1553,7 +1554,7 @@ ratbag_led_has_mode(struct ratbag_led *led,
|
||||
if (mode == RATBAG_LED_OFF)
|
||||
return 1;
|
||||
|
||||
return (led->modes & (1 << mode));
|
||||
return !!(led->modes & (1 << mode));
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT struct ratbag_color
|
||||
@@ -1681,6 +1682,7 @@ ratbag_profile_set_name(struct ratbag_profile *profile,
|
||||
free(profile->name);
|
||||
|
||||
profile->name = name_copy;
|
||||
profile->dirty = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -452,7 +452,7 @@ ratbag_device_get_svg_name(const struct ratbag_device* device);
|
||||
* @retval 1 The device has the capability
|
||||
* @retval 0 The device does not have the capability
|
||||
*/
|
||||
int
|
||||
bool
|
||||
ratbag_device_has_capability(const struct ratbag_device *device,
|
||||
enum ratbag_device_capability cap);
|
||||
|
||||
@@ -540,7 +540,7 @@ ratbag_profile_unref(struct ratbag_profile *profile);
|
||||
*
|
||||
* @return non-zero if the capability is available, zero otherwise.
|
||||
*/
|
||||
int
|
||||
bool
|
||||
ratbag_profile_has_capability(const struct ratbag_profile *profile,
|
||||
enum ratbag_profile_capability cap);
|
||||
|
||||
@@ -655,7 +655,7 @@ ratbag_device_get_profile(struct ratbag_device *device, unsigned int index);
|
||||
*
|
||||
* @return non-zero if the profile is currently active, zero otherwise
|
||||
*/
|
||||
int
|
||||
bool
|
||||
ratbag_profile_is_active(struct ratbag_profile *profile);
|
||||
|
||||
/**
|
||||
@@ -771,7 +771,7 @@ ratbag_resolution_get_user_data(const struct ratbag_resolution *resolution);
|
||||
*
|
||||
* @return non-zero if the capability is available, zero otherwise.
|
||||
*/
|
||||
int
|
||||
bool
|
||||
ratbag_resolution_has_capability(struct ratbag_resolution *resolution,
|
||||
enum ratbag_resolution_capability cap);
|
||||
|
||||
@@ -988,7 +988,7 @@ ratbag_resolution_set_active(struct ratbag_resolution *resolution);
|
||||
* @return Non-zero if the resolution mode is the active one, zero
|
||||
* otherwise.
|
||||
*/
|
||||
int
|
||||
bool
|
||||
ratbag_resolution_is_active(const struct ratbag_resolution *resolution);
|
||||
|
||||
/**
|
||||
@@ -1023,7 +1023,7 @@ ratbag_resolution_set_default(struct ratbag_resolution *resolution);
|
||||
* @return Non-zero if the resolution mode is the default one, zero
|
||||
* otherwise.
|
||||
*/
|
||||
int
|
||||
bool
|
||||
ratbag_resolution_is_default(const struct ratbag_resolution *resolution);
|
||||
|
||||
/**
|
||||
@@ -1117,7 +1117,7 @@ ratbag_button_get_action_type(struct ratbag_button *button);
|
||||
*
|
||||
* @return non-zero if the action type is supported, zero otherwise.
|
||||
*/
|
||||
int
|
||||
bool
|
||||
ratbag_button_has_action_type(struct ratbag_button *button,
|
||||
enum ratbag_button_action_type action_type);
|
||||
|
||||
@@ -1218,7 +1218,7 @@ ratbag_led_get_type(struct ratbag_led *led);
|
||||
*
|
||||
* @see ratbag_led_set_mode
|
||||
*/
|
||||
int
|
||||
bool
|
||||
ratbag_led_has_mode(struct ratbag_led *led,
|
||||
enum ratbag_led_mode mode);
|
||||
|
||||
|
||||
@@ -135,6 +135,7 @@ static inline void reset_errno(int *saved_errno)
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev*, udev_unref);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_device*, udev_device_unref);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_enumerate*, udev_enumerate_unref);
|
||||
|
||||
/*
|
||||
* ELEMENTSOF() - number of array elements
|
||||
|
||||
99
tools/check_scan_build.py
Executable file
@@ -0,0 +1,99 @@
|
||||
#!/bin/env python3
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
|
||||
import bs4
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
class Bug(object):
|
||||
def __init__(self):
|
||||
self.line_number = None
|
||||
self.cfile = None
|
||||
self.sa_type = None
|
||||
self.sa_descr = None
|
||||
|
||||
|
||||
def main(argv):
|
||||
if len(argv) < 2:
|
||||
print(f'usage {argv[0]} PATH')
|
||||
sys.exit(1)
|
||||
|
||||
scanbuild_path = argv[1]
|
||||
|
||||
ignored = []
|
||||
bugs = []
|
||||
|
||||
line_re = re.compile(r'line (\d+), column (\d+)')
|
||||
|
||||
for root, dirs, files in os.walk(scanbuild_path):
|
||||
for filename in files:
|
||||
if not filename.startswith('report'):
|
||||
continue
|
||||
|
||||
with open(os.path.join(root, filename)) as f:
|
||||
soup = bs4.BeautifulSoup(f, 'html.parser')
|
||||
|
||||
# the first table is the summary
|
||||
summary = soup.table
|
||||
bug = Bug()
|
||||
|
||||
# iterate over the table
|
||||
for tr in summary('tr'):
|
||||
if 'File:' in tr.contents[0].string:
|
||||
bug.cfile = os.path.abspath(tr.contents[1].string)
|
||||
else:
|
||||
bug.sa_type = tr.contents[0].string.rstrip(':').lower()
|
||||
for s in tr.contents[1].strings:
|
||||
# retrieve the line number and the description
|
||||
m = line_re.match(s)
|
||||
if m is None:
|
||||
bug.sa_descr = s
|
||||
else:
|
||||
bug.line_number = int(m.group(1))
|
||||
|
||||
# retrieve the html line corresponding to the code
|
||||
code = soup.find('td', id=f'LN{bug.line_number}').parent
|
||||
|
||||
# fetching any comments in this line
|
||||
try:
|
||||
comments = code.find('span', class_='comment').string
|
||||
except AttributeError:
|
||||
# no comments on the line
|
||||
bugs.append(bug)
|
||||
else:
|
||||
if 'ignore_clang_sa_' in comments:
|
||||
ignored.append(bug)
|
||||
else:
|
||||
bugs.append(bug)
|
||||
|
||||
if len(ignored) > 0:
|
||||
print(f'{len(ignored)} bugs are ignored:')
|
||||
for b in ignored:
|
||||
print(f' {b.sa_type}: {b.sa_descr} at {b.cfile}:{b.line_number}')
|
||||
|
||||
if len(bugs) > 0:
|
||||
print()
|
||||
|
||||
if len(bugs) > 0:
|
||||
print(f'ERROR: {len(bugs)} bugs found:')
|
||||
for b in bugs:
|
||||
print(f' * {b.sa_type.upper()}: {b.sa_descr} at {b.cfile}:{b.line_number}')
|
||||
sys.exit(1)
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <liblur.h>
|
||||
#include <libratbag-util.h>
|
||||
|
||||
@@ -30,7 +30,7 @@ import sys
|
||||
|
||||
|
||||
def print_ratbagctl(ratbagctl_path, ratbagd_path, version_string):
|
||||
with open(ratbagctl_path, 'r') as ratbagctl, open(ratbagd_path, 'r') as ratbagd:
|
||||
with open(ratbagctl_path, 'r', encoding='utf-8') as ratbagctl, open(ratbagd_path, 'r', encoding='utf-8') as ratbagd:
|
||||
for l in ratbagctl.readlines():
|
||||
if l.startswith("from ratbagd import "):
|
||||
headers = True
|
||||
@@ -53,7 +53,7 @@ def main(argv):
|
||||
parser.add_argument("--version", action="store", default="git_master")
|
||||
ns = parser.parse_args(sys.argv[1:])
|
||||
if ns.output:
|
||||
ns.output_file = open(ns.output, 'w')
|
||||
ns.output_file = open(ns.output, 'w', encoding='utf-8')
|
||||
st = os.stat(ns.output)
|
||||
os.chmod(ns.output, st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
|
||||
sys.stdout = ns.output_file
|
||||
@@ -63,5 +63,6 @@ def main(argv):
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1:])
|
||||
|
||||
@@ -27,6 +27,8 @@ import sys
|
||||
|
||||
from evdev import ecodes
|
||||
|
||||
LIBRATBAG_DATA_DIR = "@LIBRATBAG_DATA_DIR@"
|
||||
|
||||
|
||||
# Deferred translations, see https://docs.python.org/3/library/gettext.html#deferred-translations
|
||||
def N_(x):
|
||||
@@ -53,29 +55,34 @@ class MetaRatbag(type):
|
||||
|
||||
|
||||
class RatbagErrorCode(metaclass=MetaRatbag):
|
||||
RATBAG_SUCCESS = libratbag.RATBAG_SUCCESS
|
||||
SUCCESS = libratbag.RATBAG_SUCCESS
|
||||
|
||||
"""An error occured on the device. Either the device is not a libratbag
|
||||
device or communication with the device failed."""
|
||||
RATBAG_ERROR_DEVICE = libratbag.RATBAG_ERROR_DEVICE
|
||||
DEVICE = libratbag.RATBAG_ERROR_DEVICE
|
||||
|
||||
"""Insufficient capabilities. This error occurs when a requested change is
|
||||
beyond the device's capabilities."""
|
||||
RATBAG_ERROR_CAPABILITY = libratbag.RATBAG_ERROR_CAPABILITY
|
||||
CAPABILITY = libratbag.RATBAG_ERROR_CAPABILITY
|
||||
|
||||
"""Invalid value or value range. The provided value or value range is
|
||||
outside of the legal or supported range."""
|
||||
RATBAG_ERROR_VALUE = libratbag.RATBAG_ERROR_VALUE
|
||||
VALUE = libratbag.RATBAG_ERROR_VALUE
|
||||
|
||||
"""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 = libratbag.RATBAG_ERROR_SYSTEM
|
||||
SYSTEM = libratbag.RATBAG_ERROR_SYSTEM
|
||||
|
||||
"""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 = libratbag.RATBAG_ERROR_IMPLEMENTATION
|
||||
IMPLEMENTATION = libratbag.RATBAG_ERROR_IMPLEMENTATION
|
||||
|
||||
|
||||
class RatbagdUnavailable(Exception):
|
||||
"""Signals DBus is unavailable or the ratbagd daemon is not available."""
|
||||
pass
|
||||
|
||||
|
||||
class RatbagError(Exception):
|
||||
@@ -84,37 +91,37 @@ class RatbagError(Exception):
|
||||
|
||||
|
||||
class RatbagErrorDevice(RatbagError):
|
||||
"""An exception corresponding to RatbagErrorCode.RATBAG_ERROR_DEVICE."""
|
||||
"""An exception corresponding to RatbagErrorCode.DEVICE."""
|
||||
pass
|
||||
|
||||
|
||||
class RatbagErrorCapability(RatbagError):
|
||||
"""An exception corresponding to RatbagErrorCode.RATBAG_ERROR_CAPABILITY."""
|
||||
"""An exception corresponding to RatbagErrorCode.CAPABILITY."""
|
||||
pass
|
||||
|
||||
|
||||
class RatbagErrorValue(RatbagError):
|
||||
"""An exception corresponding to RatbagErrorCode.RATBAG_ERROR_Value."""
|
||||
"""An exception corresponding to RatbagErrorCode.VALUE."""
|
||||
pass
|
||||
|
||||
|
||||
class RatbagErrorSystem(RatbagError):
|
||||
"""An exception corresponding to RatbagErrorCode.RATBAG_ERROR_System."""
|
||||
"""An exception corresponding to RatbagErrorCode.SYSTEM."""
|
||||
pass
|
||||
|
||||
|
||||
class RatbagErrorImplementation(RatbagError):
|
||||
"""An exception corresponding to RatbagErrorCode.RATBAG_ERROR_IMPLEMENTATION."""
|
||||
"""An exception corresponding to RatbagErrorCode.IMPLEMENTATION."""
|
||||
pass
|
||||
|
||||
|
||||
"""A table mapping RatbagErrorCode values to RatbagError* exceptions."""
|
||||
EXCEPTION_TABLE = {
|
||||
RatbagErrorCode.RATBAG_ERROR_DEVICE: RatbagErrorDevice,
|
||||
RatbagErrorCode.RATBAG_ERROR_CAPABILITY: RatbagErrorCapability,
|
||||
RatbagErrorCode.RATBAG_ERROR_VALUE: RatbagErrorValue,
|
||||
RatbagErrorCode.RATBAG_ERROR_SYSTEM: RatbagErrorSystem,
|
||||
RatbagErrorCode.RATBAG_ERROR_IMPLEMENTATION: RatbagErrorImplementation
|
||||
RatbagErrorCode.DEVICE: RatbagErrorDevice,
|
||||
RatbagErrorCode.CAPABILITY: RatbagErrorCapability,
|
||||
RatbagErrorCode.VALUE: RatbagErrorValue,
|
||||
RatbagErrorCode.SYSTEM: RatbagErrorSystem,
|
||||
RatbagErrorCode.IMPLEMENTATION: RatbagErrorImplementation
|
||||
}
|
||||
|
||||
|
||||
@@ -126,6 +133,7 @@ class Ratbagd(object):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
os.environ['LIBRATBAG_DATA_DIR'] = LIBRATBAG_DATA_DIR
|
||||
self._ratbag = libratbag.ratbag_create_context(libratbag.interface, None)
|
||||
self._devices = {}
|
||||
self._devices_initialized = False
|
||||
@@ -180,6 +188,9 @@ class Ratbagd(object):
|
||||
|
||||
def __getitem__(self, id):
|
||||
"""Returns the requested device, or None."""
|
||||
if id.startswith("event"):
|
||||
id = "/dev/input/{}".format(id)
|
||||
|
||||
if id not in self._devices.keys():
|
||||
try:
|
||||
dev = RatbagdDevice(self._ratbag, id)
|
||||
@@ -281,25 +292,33 @@ class RatbagdDevice(metaclass=MetaRatbag):
|
||||
|
||||
@param theme The theme from which to retrieve the SVG, as str
|
||||
"""
|
||||
return os.path.join(theme, libratbag.ratbag_device_get_svg_name(self._device))
|
||||
svg = libratbag.ratbag_device_get_svg_name(self._device)
|
||||
if svg is None:
|
||||
return ''
|
||||
|
||||
def commit(self, callback=None):
|
||||
return os.path.join(LIBRATBAG_DATA_DIR, theme, svg)
|
||||
|
||||
def get_svg_fd(self, theme):
|
||||
"""Returns a File-like object to the SVG for the given theme, or
|
||||
raises FileNotFoundError if the file is not available.
|
||||
|
||||
The theme must be one of org.freedesktop.ratbag1.Manager.Themes. The
|
||||
theme 'default' is guaranteed to be available (but the file itself
|
||||
may not be).
|
||||
|
||||
@param theme The theme from which to retrieve the SVG, as str
|
||||
"""
|
||||
return open(self.get_svg(theme))
|
||||
|
||||
def commit(self):
|
||||
"""Commits all changes made to the device.
|
||||
|
||||
This is an async call to DBus and this method does not return
|
||||
anything. Any success or failure code is reported to the callback
|
||||
provided when ratbagd finishes writing to the device. Note that upon
|
||||
failure, the device is automatically resynchronized by ratbagd and no
|
||||
further interaction is required by the client; clients can thus treat a
|
||||
commit as being always successful.
|
||||
|
||||
@param callback The function to call with the result of the commit, as
|
||||
a function that takes the return value of the Commit
|
||||
method.
|
||||
This is implemented asynchronously inside ratbagd. Hence, we just call
|
||||
this method and always succeed. Any failure is handled inside ratbagd
|
||||
by emitting the Resync signal, which automatically resynchronizes the
|
||||
device. No further interaction is required by the client.
|
||||
"""
|
||||
r = libratbag.ratbag_device_commit(self._device)
|
||||
if callback is not None:
|
||||
callback(r)
|
||||
return libratbag.ratbag_device_commit(self._device)
|
||||
|
||||
|
||||
class RatbagdProfile(metaclass=MetaRatbag):
|
||||
@@ -6,7 +6,7 @@ ratbagctl \- inspect and modify configurable mice
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The
|
||||
.I ratbagctl
|
||||
.B ratbagctl
|
||||
tool queries or changes a device's settings.
|
||||
.PP
|
||||
This tool usually needs ratbagd to be running.
|
||||
@@ -18,12 +18,13 @@ Show program's version number and exit.
|
||||
.B \-\-verbose, \-v
|
||||
Print debugging output. Multiple -v options increase the verbosity. For example,
|
||||
.B \-vvv
|
||||
will show the protocol output.
|
||||
will show the protocol output.
|
||||
.TP 8
|
||||
.B \-\-nocommit
|
||||
Do not immediately write the settings to the mouse. This allows to set
|
||||
multiple parameters in a script, and the last call to ratbagctl will write
|
||||
them all.
|
||||
multiple parameters in a script, and the last call to
|
||||
.B ratbagctl
|
||||
will write them all.
|
||||
.TP 8
|
||||
.B \-\-help, \-h
|
||||
Print the help.
|
||||
|
||||
@@ -30,6 +30,7 @@ import time
|
||||
import toolbox
|
||||
import signal
|
||||
import sys
|
||||
from ratbagctl import RatbagErrorCapability # NOQA
|
||||
|
||||
|
||||
def main(argv):
|
||||
@@ -64,10 +65,13 @@ def main(argv):
|
||||
parser.print_help()
|
||||
return
|
||||
else:
|
||||
f(ratbagd, cmd)
|
||||
# give time for ratbagd to receive async requests before
|
||||
# we try to terminate it
|
||||
time.sleep(0.5)
|
||||
try:
|
||||
f(ratbagd, cmd)
|
||||
# give time for ratbagd to receive async requests before
|
||||
# we try to terminate it
|
||||
time.sleep(0.5)
|
||||
except RatbagErrorCapability as e:
|
||||
print("Error: {}".format(e), file=sys.stderr)
|
||||
finally:
|
||||
try:
|
||||
if cmd.keepalive:
|
||||
|
||||
@@ -26,8 +26,10 @@
|
||||
import evdev
|
||||
import sys
|
||||
import argparse
|
||||
import re
|
||||
|
||||
from ratbagd import Ratbagd, RatbagdDevice, RatbagdProfile, RatbagdMacro, RatbagdResolution, RatbagdButton, RatbagdLed, RatbagdUnavailable, RatbagError, RatbagErrorCode, RatbagErrorCapability # NOQA
|
||||
|
||||
from ratbagd import Ratbagd, RatbagdDevice, RatbagdProfile, RatbagdMacro, RatbagdResolution, RatbagdButton, RatbagdLed, RatbagdDBusUnavailable, RatbagError, RatbagErrorCode, RatbagErrorCapability # NOQA
|
||||
|
||||
button_specials_strmap = {
|
||||
RatbagdButton.ACTION_SPECIAL_UNKNOWN: "unknown",
|
||||
@@ -266,8 +268,18 @@ def print_device(d, level):
|
||||
RatbagdDevice.CAP_LED: "led"}
|
||||
capabilities = [caps[c] for c in d.capabilities]
|
||||
|
||||
svg_name = 'unknown'
|
||||
try:
|
||||
with d.get_svg_fd('gnome') as fd:
|
||||
svg = fd.read()
|
||||
match = re.search('sodipodi:docname=".*"\n', svg)
|
||||
if match:
|
||||
svg_name = match.group(0).split('"')[1]
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
print(" " * level + "{} - {}".format(d.id, d.name))
|
||||
print(" " * level + " SVG: {}".format(d.get_svg('gnome')))
|
||||
print(" " * level + " SVG: {}".format(svg_name))
|
||||
print(" " * level + " Capabilities: {}".format(", ".join(capabilities)))
|
||||
print(" " * level + " Number of Buttons: {}".format(len(p.buttons)))
|
||||
print(" " * level + " Number of Leds: {}".format(len(p.leds)))
|
||||
@@ -367,12 +379,17 @@ def func_button_get(r, args):
|
||||
|
||||
def func_button_action_set_button(r, args):
|
||||
b, p, d = find_button(r, args)
|
||||
if not d.CAP_BUTTON in d.capabilities:
|
||||
raise RatbagErrorCapability("assigning a button is not supported on this device")
|
||||
b.mapping = args.target_button
|
||||
commit(d, args)
|
||||
|
||||
|
||||
def func_button_action_set_special(r, args):
|
||||
b, p, d = find_button(r, args)
|
||||
if not d.CAP_BUTTON in d.capabilities:
|
||||
raise RatbagErrorCapability("assigning a button is not supported on this device")
|
||||
|
||||
try:
|
||||
special = args.target_special
|
||||
except AttributeError:
|
||||
@@ -384,6 +401,9 @@ def func_button_action_set_special(r, args):
|
||||
|
||||
def func_button_action_set_macro(r, args):
|
||||
b, p, d = find_button(r, args)
|
||||
if not d.CAP_BUTTON_MACROS in d.capabilities:
|
||||
raise RatbagErrorCapability("assigning a macro is not supported on this device")
|
||||
|
||||
macro_keys = args.target_macro
|
||||
macro = RatbagdMacro()
|
||||
for s in macro_keys:
|
||||
@@ -602,15 +622,10 @@ link = 'link'
|
||||
################################################################################
|
||||
|
||||
|
||||
def commit_cb(status):
|
||||
if not status == RatbagErrorCode.RATBAG_SUCCESS:
|
||||
print("Could not commit changes to the device")
|
||||
|
||||
|
||||
def commit(device, args):
|
||||
if args.nocommit:
|
||||
return
|
||||
device.commit(commit_cb)
|
||||
device.commit()
|
||||
|
||||
|
||||
def color(string):
|
||||
@@ -651,6 +666,7 @@ def dpi(string):
|
||||
else:
|
||||
return (int_x, int_y)
|
||||
|
||||
|
||||
# note: 'eventX' is assumed at the end of each command
|
||||
parser_def = [
|
||||
{
|
||||
@@ -1408,6 +1424,7 @@ class RatbagParserLink(RatbagParser):
|
||||
dest = self.get_dest()
|
||||
print(" {:<36}Use {}for '{} Commands'".format(prefix + self.dest + " ...", prefix, dest.group))
|
||||
|
||||
|
||||
classes = {
|
||||
switch: RatbagParserSwitch,
|
||||
set: RatbagParserSet,
|
||||
@@ -1506,8 +1523,8 @@ def open_ratbagd(ratbagd_process=None, verbose=0):
|
||||
try:
|
||||
r = Ratbagd()
|
||||
r.verbose = verbose
|
||||
except RatbagdDBusUnavailable:
|
||||
print("Unable to connect to ratbagd over dbus")
|
||||
except RatbagdUnavailable:
|
||||
print("Unable to connect to ratbagd")
|
||||
return None
|
||||
|
||||
if ratbagd_process is not None:
|
||||
@@ -1540,7 +1557,11 @@ def main(argv):
|
||||
parser.print_help()
|
||||
return
|
||||
else:
|
||||
f(r, cmd)
|
||||
try:
|
||||
f(r, cmd)
|
||||
except RatbagErrorCapability as e:
|
||||
print("Error: {}".format(e), file=sys.stderr)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1:])
|
||||
|
||||
151
tools/ratbagd.py
@@ -36,32 +36,32 @@ def N_(x):
|
||||
|
||||
|
||||
class RatbagErrorCode(IntEnum):
|
||||
RATBAG_SUCCESS = 0
|
||||
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
|
||||
DEVICE = -1000
|
||||
|
||||
"""Insufficient capabilities. This error occurs when a requested change is
|
||||
beyond the device's capabilities."""
|
||||
RATBAG_ERROR_CAPABILITY = -1001
|
||||
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
|
||||
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
|
||||
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
|
||||
IMPLEMENTATION = -1004
|
||||
|
||||
|
||||
class RatbagdDBusUnavailable(Exception):
|
||||
class RatbagdUnavailable(Exception):
|
||||
"""Signals DBus is unavailable or the ratbagd daemon is not available."""
|
||||
pass
|
||||
|
||||
@@ -77,37 +77,37 @@ class RatbagError(Exception):
|
||||
|
||||
|
||||
class RatbagErrorDevice(RatbagError):
|
||||
"""An exception corresponding to RatbagErrorCode.RATBAG_ERROR_DEVICE."""
|
||||
"""An exception corresponding to RatbagErrorCode.DEVICE."""
|
||||
pass
|
||||
|
||||
|
||||
class RatbagErrorCapability(RatbagError):
|
||||
"""An exception corresponding to RatbagErrorCode.RATBAG_ERROR_CAPABILITY."""
|
||||
"""An exception corresponding to RatbagErrorCode.CAPABILITY."""
|
||||
pass
|
||||
|
||||
|
||||
class RatbagErrorValue(RatbagError):
|
||||
"""An exception corresponding to RatbagErrorCode.RATBAG_ERROR_Value."""
|
||||
"""An exception corresponding to RatbagErrorCode.VALUE."""
|
||||
pass
|
||||
|
||||
|
||||
class RatbagErrorSystem(RatbagError):
|
||||
"""An exception corresponding to RatbagErrorCode.RATBAG_ERROR_System."""
|
||||
"""An exception corresponding to RatbagErrorCode.SYSTEM."""
|
||||
pass
|
||||
|
||||
|
||||
class RatbagErrorImplementation(RatbagError):
|
||||
"""An exception corresponding to RatbagErrorCode.RATBAG_ERROR_IMPLEMENTATION."""
|
||||
"""An exception corresponding to RatbagErrorCode.IMPLEMENTATION."""
|
||||
pass
|
||||
|
||||
|
||||
"""A table mapping RatbagErrorCode values to RatbagError* exceptions."""
|
||||
EXCEPTION_TABLE = {
|
||||
RatbagErrorCode.RATBAG_ERROR_DEVICE: RatbagErrorDevice,
|
||||
RatbagErrorCode.RATBAG_ERROR_CAPABILITY: RatbagErrorCapability,
|
||||
RatbagErrorCode.RATBAG_ERROR_VALUE: RatbagErrorValue,
|
||||
RatbagErrorCode.RATBAG_ERROR_SYSTEM: RatbagErrorSystem,
|
||||
RatbagErrorCode.RATBAG_ERROR_IMPLEMENTATION: RatbagErrorImplementation
|
||||
RatbagErrorCode.DEVICE: RatbagErrorDevice,
|
||||
RatbagErrorCode.CAPABILITY: RatbagErrorCapability,
|
||||
RatbagErrorCode.VALUE: RatbagErrorValue,
|
||||
RatbagErrorCode.SYSTEM: RatbagErrorSystem,
|
||||
RatbagErrorCode.IMPLEMENTATION: RatbagErrorImplementation
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ class _RatbagdDBus(GObject.GObject):
|
||||
try:
|
||||
_RatbagdDBus._dbus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None)
|
||||
except GLib.Error as e:
|
||||
raise RatbagdDBusUnavailable(e.message)
|
||||
raise RatbagdUnavailable(e.message)
|
||||
|
||||
ratbag1 = "org.freedesktop.ratbag1"
|
||||
if os.environ.get('RATBAGCTL_DEVEL'):
|
||||
@@ -142,10 +142,10 @@ class _RatbagdDBus(GObject.GObject):
|
||||
self._interface,
|
||||
None)
|
||||
except GLib.Error as e:
|
||||
raise RatbagdDBusUnavailable(e.message)
|
||||
raise RatbagdUnavailable(e.message)
|
||||
|
||||
if self._proxy.get_name_owner() is None:
|
||||
raise RatbagdDBusUnavailable("No one currently owns {}".format(ratbag1))
|
||||
raise RatbagdUnavailable("No one currently owns {}".format(ratbag1))
|
||||
|
||||
self._proxy.connect("g-properties-changed", self._on_properties_changed)
|
||||
|
||||
@@ -186,27 +186,6 @@ class _RatbagdDBus(GObject.GObject):
|
||||
# update
|
||||
self._proxy.set_cached_property(property, val)
|
||||
|
||||
def _dbus_call_async(self, method, type, *value, callback):
|
||||
# The callback handler to unwrap the data
|
||||
def callback_handler(obj, result, user_callback):
|
||||
try:
|
||||
res = obj.call_finish(result)
|
||||
res = res.unpack()[0] # Result is always a tuple
|
||||
user_callback(res)
|
||||
except GLib.Error as e:
|
||||
# Unrecognized error code; print the message to stderr and raise
|
||||
# the GLib.Error.
|
||||
print(e.message, file=sys.stderr)
|
||||
raise
|
||||
|
||||
# Calls a method asynchronously on the bus, using the given method
|
||||
# name, type signature and values. The callback is invoked when the
|
||||
# method finishes
|
||||
val = GLib.Variant("({})".format(type), value)
|
||||
self._proxy.call(method, val,
|
||||
Gio.DBusCallFlags.NO_AUTO_START,
|
||||
500, None, callback_handler, callback)
|
||||
|
||||
def _dbus_call(self, method, type, *value):
|
||||
# Calls a method synchronously on the bus, using the given method name,
|
||||
# type signature and values.
|
||||
@@ -232,6 +211,35 @@ class _RatbagdDBus(GObject.GObject):
|
||||
print(e.message, file=sys.stderr)
|
||||
raise
|
||||
|
||||
def _dbus_call_return_one_fd(self, method, type, *value):
|
||||
# Calls a method synchronously on the bus, using the given method name,
|
||||
# type signature and values.
|
||||
#
|
||||
# It the result is valid, it is returned. Invalid results raise the
|
||||
# appropriate RatbagError* or RatbagdDBus* exception, or GLib.Error if
|
||||
# it is an unexpected exception that probably shouldn't be passed up to
|
||||
# the UI.
|
||||
val = GLib.Variant("({})".format(type), value)
|
||||
try:
|
||||
res = self._proxy.call_with_unix_fd_list_sync(method, val,
|
||||
Gio.DBusCallFlags.NO_AUTO_START,
|
||||
2000, None, None)
|
||||
if res in EXCEPTION_TABLE:
|
||||
raise EXCEPTION_TABLE[res]
|
||||
# Result is a tuple of (GLib.Variant('(h)', (0,)), fd_list),
|
||||
# we return the first file descriptor in that list
|
||||
return res[1].get(0)
|
||||
except GLib.Error as e:
|
||||
if e.code == Gio.DBusError.FILE_NOT_FOUND:
|
||||
raise FileNotFoundError('Failed to open SVG file')
|
||||
elif e.code == Gio.IOErrorEnum.TIMED_OUT:
|
||||
raise RatbagdDBusTimeout(e.message)
|
||||
else:
|
||||
# Unrecognized error code; print the message to stderr and raise
|
||||
# the GLib.Error.
|
||||
print(e.message, file=sys.stderr)
|
||||
raise
|
||||
|
||||
def __eq__(self, other):
|
||||
return other and self._object_path == other._object_path
|
||||
|
||||
@@ -241,7 +249,7 @@ class Ratbagd(_RatbagdDBus):
|
||||
through ratbagd; actual interaction with the devices is via the
|
||||
RatbagdDevice, RatbagdProfile, RatbagdResolution and RatbagdButton objects.
|
||||
|
||||
Throws RatbagdDBusUnavailable when the DBus service is not available.
|
||||
Throws RatbagdUnavailable when the DBus service is not available.
|
||||
"""
|
||||
|
||||
__gsignals__ = {
|
||||
@@ -249,12 +257,18 @@ class Ratbagd(_RatbagdDBus):
|
||||
(GObject.SignalFlags.RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)),
|
||||
"device-removed":
|
||||
(GObject.SignalFlags.RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)),
|
||||
"daemon-disappeared":
|
||||
(GObject.SignalFlags.RUN_FIRST, None, ()),
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
_RatbagdDBus.__init__(self, "Manager", None)
|
||||
result = self._get_dbus_property("Devices")
|
||||
result = self._get_dbus_property("Devices") or []
|
||||
self._devices = [RatbagdDevice(objpath) for objpath in result]
|
||||
self._proxy.connect("notify::g-name-owner", self._on_name_owner_changed)
|
||||
|
||||
def _on_name_owner_changed(self, *kwargs):
|
||||
self.emit("daemon-disappeared")
|
||||
|
||||
def _on_properties_changed(self, proxy, changed_props, invalidated_props):
|
||||
if "Devices" in changed_props.keys():
|
||||
@@ -286,7 +300,7 @@ class Ratbagd(_RatbagdDBus):
|
||||
def themes(self):
|
||||
"""A list of theme names. The theme 'default' is guaranteed to be
|
||||
available."""
|
||||
return self._get_dbus_property("Themes")
|
||||
return self._get_dbus_property("Themes") or []
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
@@ -321,7 +335,7 @@ class RatbagdDevice(_RatbagdDBus):
|
||||
|
||||
# FIXME: if we start adding and removing objects from this list,
|
||||
# things will break!
|
||||
result = self._get_dbus_property("Profiles")
|
||||
result = self._get_dbus_property("Profiles") or []
|
||||
self._profiles = [RatbagdProfile(objpath) for objpath in result]
|
||||
for profile in self._profiles:
|
||||
profile.connect("notify::is-active", self._on_active_profile_changed)
|
||||
@@ -343,7 +357,7 @@ class RatbagdDevice(_RatbagdDBus):
|
||||
if RatbagdDevice.CAP_SWITCHABLE_RESOLUTION is in device.capabilities:
|
||||
do something
|
||||
"""
|
||||
return self._get_dbus_property("Capabilities")
|
||||
return self._get_dbus_property("Capabilities") or []
|
||||
|
||||
@GObject.Property
|
||||
def name(self):
|
||||
@@ -367,6 +381,19 @@ class RatbagdDevice(_RatbagdDBus):
|
||||
print("No active profile. Please report this bug to the libratbag developers", file=sys.stderr)
|
||||
return self._profiles[0]
|
||||
|
||||
def get_svg_fd(self, theme):
|
||||
"""Returns a File-like object to the SVG for the given theme, or
|
||||
raises FileNotFoundError if the file is not available.
|
||||
|
||||
The theme must be one of org.freedesktop.ratbag1.Manager.Themes. The
|
||||
theme 'default' is guaranteed to be available (but the file itself
|
||||
may not be).
|
||||
|
||||
@param theme The theme from which to retrieve the SVG, as str
|
||||
"""
|
||||
fd = self._dbus_call_return_one_fd("GetSvgFd", "s", theme)
|
||||
return os.fdopen(fd)
|
||||
|
||||
def get_svg(self, theme):
|
||||
"""Gets the full path to the SVG for the given theme, or the empty
|
||||
string if none is available.
|
||||
@@ -378,21 +405,15 @@ class RatbagdDevice(_RatbagdDBus):
|
||||
"""
|
||||
return self._dbus_call("GetSvg", "s", theme)
|
||||
|
||||
def commit(self, callback):
|
||||
def commit(self):
|
||||
"""Commits all changes made to the device.
|
||||
|
||||
This is an async call to DBus and this method does not return
|
||||
anything. Any success or failure code is reported to the callback
|
||||
provided when ratbagd finishes writing to the device. Note that upon
|
||||
failure, the device is automatically resynchronized by ratbagd and no
|
||||
further interaction is required by the client; clients can thus treat a
|
||||
commit as being always successful.
|
||||
|
||||
@param callback The function to call with the result of the commit, as
|
||||
a function that takes the return value of the Commit
|
||||
method.
|
||||
This is implemented asynchronously inside ratbagd. Hence, we just call
|
||||
this method and always succeed. Any failure is handled inside ratbagd
|
||||
by emitting the Resync signal, which automatically resynchronizes the
|
||||
device. No further interaction is required by the client.
|
||||
"""
|
||||
self._dbus_call_async("Commit", "", callback=callback)
|
||||
self._dbus_call("Commit", "")
|
||||
for profile in self._profiles:
|
||||
if profile.dirty:
|
||||
profile._dirty = False
|
||||
@@ -411,15 +432,15 @@ class RatbagdProfile(_RatbagdDBus):
|
||||
|
||||
# FIXME: if we start adding and removing objects from any of these
|
||||
# lists, things will break!
|
||||
result = self._get_dbus_property("Resolutions")
|
||||
result = self._get_dbus_property("Resolutions") or []
|
||||
self._resolutions = [RatbagdResolution(objpath) for objpath in result]
|
||||
self._subscribe_dirty(self._resolutions)
|
||||
|
||||
result = self._get_dbus_property("Buttons")
|
||||
result = self._get_dbus_property("Buttons") or []
|
||||
self._buttons = [RatbagdButton(objpath) for objpath in result]
|
||||
self._subscribe_dirty(self._buttons)
|
||||
|
||||
result = self._get_dbus_property("Leds")
|
||||
result = self._get_dbus_property("Leds") or []
|
||||
self._leds = [RatbagdLed(objpath) for objpath in result]
|
||||
self._subscribe_dirty(self._leds)
|
||||
|
||||
@@ -448,7 +469,7 @@ class RatbagdProfile(_RatbagdDBus):
|
||||
if RatbagdProfile.CAP_WRITABLE_NAME is in profile.capabilities:
|
||||
do something
|
||||
"""
|
||||
return self._get_dbus_property("Capabilities")
|
||||
return self._get_dbus_property("Capabilities") or []
|
||||
|
||||
@GObject.Property
|
||||
def name(self):
|
||||
@@ -565,7 +586,7 @@ class RatbagdResolution(_RatbagdDBus):
|
||||
if RatbagdResolution.CAP_SEPARATE_XY_RESOLUTION is in resolution.capabilities:
|
||||
do something
|
||||
"""
|
||||
return self._get_dbus_property("Capabilities")
|
||||
return self._get_dbus_property("Capabilities") or []
|
||||
|
||||
@GObject.Property
|
||||
def resolution(self):
|
||||
@@ -596,12 +617,12 @@ class RatbagdResolution(_RatbagdDBus):
|
||||
@GObject.Property
|
||||
def resolutions(self):
|
||||
"""The list of supported DPI values"""
|
||||
return self._get_dbus_property("Resolutions")
|
||||
return self._get_dbus_property("Resolutions") or []
|
||||
|
||||
@GObject.Property
|
||||
def report_rates(self):
|
||||
"""The list of supported report rates"""
|
||||
return self._get_dbus_property("ReportRates")
|
||||
return self._get_dbus_property("ReportRates") or []
|
||||
|
||||
@GObject.Property
|
||||
def is_active(self):
|
||||
|
||||
@@ -28,17 +28,22 @@ udev_device_from_path(struct udev *udev, const char *path)
|
||||
{
|
||||
struct udev_device *udev_device;
|
||||
const char *event_node_prefix = "/dev/input/event";
|
||||
_cleanup_(freep) char *path_canonical = NULL;
|
||||
|
||||
if (strneq(path, event_node_prefix, strlen(event_node_prefix))) {
|
||||
if ((path_canonical = canonicalize_file_name(path)) == NULL) {
|
||||
error("Failed to canonicalize path '%s': %s\n", path, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
if (strneq(path_canonical, event_node_prefix, strlen(event_node_prefix))) {
|
||||
struct stat st;
|
||||
if (stat(path, &st) == -1) {
|
||||
if (stat(path_canonical, &st) == -1) {
|
||||
error("Failed to stat '%s': %s\n", path, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
udev_device = udev_device_new_from_devnum(udev, 'c', st.st_rdev);
|
||||
|
||||
} else {
|
||||
udev_device = udev_device_new_from_syspath(udev, path);
|
||||
udev_device = udev_device_new_from_syspath(udev, path_canonical);
|
||||
}
|
||||
if (!udev_device) {
|
||||
error("Can't open '%s': %s\n", path, strerror(errno));
|
||||
|
||||
@@ -61,6 +61,8 @@ def start_ratbagd(verbosity=0):
|
||||
from gi.repository import Gio
|
||||
import time
|
||||
|
||||
os.makedirs(DBUS_CONF_DIR, exist_ok=True)
|
||||
|
||||
# first copy the policy for the ratbagd daemon to be allowed to run
|
||||
shutil.copy(os.path.join('@MESON_BUILD_ROOT@', DBUS_CONF_NAME),
|
||||
DBUS_CONF_PATH)
|
||||
@@ -73,6 +75,8 @@ def start_ratbagd(verbosity=0):
|
||||
args.append('--verbose=raw')
|
||||
elif verbosity >= 2:
|
||||
args.append('--verbose')
|
||||
elif verbosity == 0:
|
||||
args.append('--quiet')
|
||||
|
||||
ratbagd_process = subprocess.Popen(args, shell=False, stdout=sys.stdout, stderr=sys.stderr)
|
||||
|
||||
|
||||