1
0
forked from drath/libratbag

Compare commits

..

65 Commits

Author SHA1 Message Date
Peter Hutterer
549a6c47b8 libratbag 0.9.904
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2019-01-24 13:38:26 +10:00
Đặng Đoàn Đức Trung
400451efe1 Change G102/203's symlink to G-Pro (#605)
* Change G102/203 symlink to G-Pro

* Fix the symbolic link breaking
2019-01-22 19:29:43 +01:00
Zachary
2ee88948f3 data: added Logitech G603 svg (#600)
* data: added Logitech G603 svg

* data: added Logitech G603 svg

* data: added Logitech G603 svg

* data: updated Logitech G603 svg

I fixed an issue with the right and left click buttons missing and the middle button being on the incorrect layer. I also removed the logo on the mouse as I was having some issues in Inkscape due to my unfamiliarity with the software. I figured properly configured buttons is good enough for the time being.
2019-01-12 14:06:14 +01:00
Jente Hidskes
ace60f76da data/gnome/logitech-g-pro-wireless: don't use Logitech LED logo
We don't want this for copyright reasons.
2019-01-10 08:52:18 +10:00
Daniele Laudani
451af331b9 Logitech G402 support (#602)
This brings initial support for the Logitech G402, as discussed in #471.
I used the G502 svg and modified it, without changing the graphics. The two mice are aesthetically similar.

* Added G402 device file
* Added G402 svg file
* Add G402 files to build

[bentiss] squashed the 3 patches as one
2019-01-08 16:16:20 +01:00
Peter Hutterer
b87a770970 data: add MX Anywhere 2S 2019-01-07 10:19:12 +01:00
Benjamin Tissoires
e59ef319b0 hidpp20: non-rgb leds: switch back to HW control once configured
As mentioned in the code:
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

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2019-01-07 10:39:55 +10:00
Benjamin Tissoires
8a1487f6f4 hidpp20: use macros for key+modifiers
Since a0830a8aaa, we can re-add the simple
keybindings capabilities. It's time the HID++ 2.0 devices get this.

This used to be working with the KEY API, but this has been dropped in
favor of the macro one.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2019-01-02 15:57:36 +10:00
Justin Gottula
44d36d2bf0 tools: canonicalize path first in udev_device_from_path (#592)
* tools: canonicalize path first in udev_device_from_path

This fixes a problem in which running ratbag-command with the path to a
device node symlink (e.g. /dev/logi-g502 -> /dev/input/event4), such as
one created by a udev rule, would not work correctly, due to the code
failing to resolve the symlink prior to checking for the presence of the
"/dev/input/event" prefix.

This resulted in nonsensical error messages (shown below) and the
curious inability to run ratbag-command successfully with anything but
the actual raw path to the device node itself (e.g. /dev/input/event4
would work fine, but /dev/logi-g502 would not, despite both being valid
ways of getting to the same device node).

    Error: Can't open '/dev/logi-g502': Success
    Error: Device '/dev/logi-g502' is not supported

Note that this same problem also prevented the usage of autogenerated
symlinks by udev, i.e. '/dev/input/by-id/' and '/dev/input/by-path/'.

* Update tools/shared.c

Co-Authored-By: jgottula <justin@jgottula.com>
2018-12-24 19:04:04 +01:00
Peter Hutterer
635865efa5 hidpp20: if the button is remapped, use that
A non-zero value for the remapped field means the button is mapped to that
button.

"diverted" means to decouple it from normal HID reports and report it via
HID++ only. In our case here, we "map" it, which is different.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-12-21 15:53:10 +01:00
Peter Hutterer
38949013f7 circleci: check for missing .device or .svg files
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-12-20 06:55:33 +01:00
Peter Hutterer
e1879818b4 meson.build: add missing mx master.svg
Missing from cf9a3e48b7

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-12-20 06:55:33 +01:00
Peter Hutterer
9b2614109f tools: sync ratbagd.py from Piper - drop async commit
ratbagd now implements commit as normal always-successful call with a
potential Resync signal later if something failed on the device.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-12-20 10:34:19 +10:00
Haochen Tong
abe99fec6a data: add device file and SVG for MX Anywhere 2 2018-12-20 10:14:54 +10:00
Haochen Tong
21936db58b hidpp20: remove redundant rc check
Protocol error code is already handled in hidpp20_request_command.
2018-12-20 10:14:54 +10:00
Haochen Tong
74f01f3de4 hidpp-generic: add physical mapping for button 169
This is the "Gesture Button" found on MX Anywhere2.
2018-12-19 23:12:04 +01:00
Haochen Tong
53ba4d975d hidpp20: add 3 new feature constants
Add HIDPP_PAGE_RESET, HIDPP_PAGE_DEVICE_NAME, and
HIDPP_PAGE_WIRELESS_DEVICE_STATUS. These feature names are found in the
"features.xml" of an LogiOptions installation. Probably not very useful
for now.
2018-12-19 23:12:04 +01:00
Haochen Tong
97306ddd5a hidpp20: ignore error on single button when enumerating special keys
The MX Anywhere 2 mouse has a problematic special key (index=7). When
trying to get the reporting value of this key, the device returns an
"invalid argument" error. [1]

To avoid giving up all good information about other keys, ignore error
(and the cause) when enumerating special keys.

[1] https://github.com/libratbag/libratbag/issues/558#issuecomment-439732655
2018-12-19 23:12:04 +01:00
Peter Hutterer
16e052d846 tools: print a nice error when we don't have the required capabilities
Fixes #583

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-12-19 10:15:09 +01:00
Peter Hutterer
1586913fc7 tools: don't allow setting macros where not supported
Fixes #585

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-12-19 10:15:09 +01:00
Peter Hutterer
cf9a3e48b7 gnome: symlink the mx master to our existing mx master 2 SVG
Those two devices look identical

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-12-19 09:21:36 +01:00
Peter Hutterer
ec835e2e82 data: rename the MX master svg to drop the underscore
More consistent with the rest of the files

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-12-19 09:21:36 +01:00
Peter Hutterer
b86211204c tools: make ratbagctl bold in the man page
And a double-space to single-space change snuck in as well

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-12-19 11:51:52 +10:00
Lukas Werling
1d6995be72 Add Logitech MX Master 2S 2018-12-18 16:15:28 +10:00
Aleksandar Trifunovic
536576fe8b meson: conditional check to avoid use of depricated features after Meson v0.48.0 2018-12-17 18:04:37 +00:00
Peter Hutterer
b514f49b08 tools: sync ratbagd from Piper
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-12-13 11:58:49 +10:00
Aleksandar Trifunovic
46a466ffe1 Fix Logitech G Pro commit 2018-12-13 08:23:30 +10:00
Aleksandar Trifunovic
15f1667fa4 Add Logitech G Pro Wireless 2018-12-13 08:23:30 +10:00
Peter Hutterer
284c13b2fe ratbagd: update all properties before sending out Resync
Fixes #528

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-12-11 11:09:14 +10:00
Peter Hutterer
e9bb4f98ae ratbagd: make Commit() truly asynchronous
Schedule the actual operation as a callback to handle at the end of the event
loop and return success. The Resync signal will handle the rest.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-12-11 11:08:56 +10:00
Peter Hutterer
45b8d792cc meson.build: add the new device files to meson.build
A few of the device files didn't get installed, let's add them to the list.
This reshuffles the list a bit because the easiest way to make sure all files
are included is to run git ls-files, so let's stick to that.

Fixes #552

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-12-11 11:08:11 +10:00
Peter Hutterer
b93dfcfda4 data: add helper functions for checking list contents
Easier to print the lists instead of just failing

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-12-11 11:08:11 +10:00
Peter Hutterer
3ffdc8daa0 Revert "Add Logitech G Pro wired configuration (#555)"
This wasn't added to the meson.build file so the test didn't run on it. And
the test fails. Issues found include:

- DPIRange and DPIList must not be in the Device section
- Only one of those two, not both
- The svg file was in the 'default' theme rather than in gnome

This needs to be fixed first, not sure how this would've worked at all.

This reverts commit 2371960a1d.
2018-12-04 16:34:02 +10:00
Peter Hutterer
e38bc7a760 ratbagd: set up a simple exit-on-idle
ratbagd is not something that needs stay around forever just because we
configured a mouse once. We have DBus activation and we don't store anything
anyway, so we might as well exit after a period of inactivity (20 min).

There's a slight race condition where if something comes in at exactly the
20min mark, we may shut down anyway and the messages get lost. This is too
narrow to worry about.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-11-28 09:33:16 +01:00
Peter Hutterer
2dca516afa data: check for missing buttons
The Logitech G502 had a wrong button ID so it doesn't show up. We have a
correctly named leader and path though so let's add that to the checks.

https://github.com/libratbag/piper/issues/240

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-11-28 09:18:50 +01:00
Peter Hutterer
b489ac871d data: fix the Logitech G502 button 10 label
Fixes https://github.com/libratbag/piper/issues/240

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-11-28 09:18:50 +01:00
Peter Hutterer
50fb898138 roccat: set the dpi list
Turns out this driver never got updated for the 'new' DPI list provided by
libratbag and thus broke with bacdab2596 when we
enforced that DPI list.

Set a fixed DPI list based on the hardcoded values we use elsewhere in this
driver.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-11-28 09:08:24 +01:00
Peter Hutterer
c676fcefb1 README: minor improvements (#565)
Notable: parts of the instructions have been punted to the wiki now where it's
faster to edit and be verbose about the specific instructions.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-11-27 10:55:24 +10:00
Peter Hutterer
bb4dd2aae0 data: fix Logitech g600 button 6/7 assignment (#564)
Fixes #550

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-11-27 08:03:51 +10:00
Benjamin Tissoires
9b11340e91 Revert "circle CI: switch to ubuntu 18.10"
This reverts commit 874d7eccb8.

Looks like 18.10 fails at every pipeline build, so better
punting this for later.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2018-11-26 09:38:11 +01:00
Peter Hutterer
3cd5a1f986 hidpp20: if a command returns with error, return a neg errno
I'm pretty sure all callers rely on this command to return either 0 or a
negative errno. There's a quirky occasion where if we get a HID error (a
positive number) during hidpp20_special_keys_buttons_get_reporting, that
number eventually ends up as the 'num_controls' value in
hidpp20_special_key_mouse_get_controls().

Since the only time we care about HID++ errors is during
hidpp20_root_get_protocol_version, let's just always return -EPROTO on HID++
errors.

Fixes #558

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-11-26 09:27:35 +01:00
Peter Hutterer
874d7eccb8 circle CI: switch to ubuntu 18.10
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-11-26 09:25:08 +01:00
Erol Gorancic
44c4b901e2 Steelseries Rival 600 Support.
- New svg and device file. Updated meson.build.
- New device version (version 3).
- Refactored led cycle to be general for v2 and v3.
- New defines for v3.
2018-11-26 01:27:17 +00:00
mike391
2371960a1d Add Logitech G Pro wired configuration (#555) 2018-11-26 11:25:17 +10:00
Mateusz Maćkowski
874aa8e63e Add support for Logitech G502 HERO (#559)
* Add support for Logitech G502 HERO
2018-11-26 11:24:41 +10:00
Peter Hutterer
1225f421c0 circle CI: switch fedora latest to fedora 28
Some change in F29 breaks the CI runs, so lets switch back to what we had
before so we can merge patches.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-11-26 11:17:25 +10:00
Peter Hutterer
5f0f5d2843 driver-hidpp10: force the single profile to be active
If we can successfully read a profile but hidpp10_get_current_profile() fails
we end up with one profile, but not set to active. Fix this by always forcing
the single profile to be active.

Fixes #526
2018-11-26 11:11:42 +10:00
Peter Hutterer
1d464767e1 tools: fix error code names in ratbagd.py documentation 2018-09-27 09:44:05 +10:00
Peter Hutterer
9551dddbb8 tools: handle NULL svgs in ratbag-command
Showed up in #526
https://github.com/libratbag/libratbag/issues/526#issuecomment-420016451
2018-09-27 09:39:44 +10:00
Peter Hutterer
563c274705 tools: remove the unnecessary prefix from the error code enum
It's already encoded as part of the enum, no need to have it again for the
value
2018-09-26 13:17:36 +02:00
jit26
71ed64a843 Add Logitech G PowerPlay wireless configuration
Tested with a Logitech G903, should also work with a Logitech G703.
May also work with other Logitech mice that work with a G900 receiver.
2018-09-24 17:14:54 +01:00
Timofey Titovets
efb3efc828 Update Logitech G900 wireless config - add G903
Signed-off-by: Timofey Titovets <timofey.titovets@synesis.ru>
2018-09-18 14:51:11 +10:00
Timofey Titovets
982e6cc7fe Add Logitech G903 wired configuration
Signed-off-by: Timofey Titovets <timofey.titovets@synesis.ru>
2018-09-18 14:51:11 +10:00
Peter Hutterer
44dc754e31 meson.build: add hacks to be able to run coverity
Taken from libinput, we need to define a few gcc7 types that coverity doesn't
know about. To submit a coverity build, run meson with -Dcoverity=true

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-09-14 11:04:59 +02:00
Peter Hutterer
18887e4c86 meson_options: use a consistent style
Move the closing ) up to match the other options
2018-09-14 11:04:59 +02:00
Peter Hutterer
46d5fae2e5 tools: ratbagc - allow for the device to be just 'event7'
ratbagctl requires 'eventX' as argument, but ratbag-command requires
/dev/input/eventX. That's not smart, let's do better.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-09-14 10:23:11 +10:00
Peter Hutterer
4b31945e1d tools: change the exception to just RatbagdUnavailable
ratbag-command has an 'except RatbagdDBusUnavailable' line despite that class
never being defined. That's ok because we'll never throw it in this case but
it's still confusing (to flake8). So let's change the class name to something
more generic and define it in ratbagc.py

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-09-14 10:23:11 +10:00
Peter Hutterer
7e685f5196 tools: fix flake8 warnings about missing double empty lines 2018-09-13 10:51:15 +10:00
Andreas Heider
050db150f6 Add device match for MX Master 2018-09-10 17:54:03 +10:00
Peter Hutterer
a3de0e1ff7 ratbagd: provide a decent error message when the bus name is taken
sd-bus returns EEXISTS which is "File exists" and way too confusing. Let's
print out a decent error message for that case.

Relater #535
2018-09-10 04:15:01 +01:00
Peter Hutterer
acc0066f08 meson.build: add comments and tidy up a bit
Add some comments to make it slightly more obvious how the tools are being put
together.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-09-06 13:33:58 +02:00
Peter Hutterer
eb9f98e58d tools: ratbagc - set the LIBRATBAG_DATA_DIR environment before context start
This way we use the data files from the source directory, not the installed
ones.

Fixes #530

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-09-06 13:33:58 +02:00
Peter Hutterer
6d996bf1aa tools: add get_svg_fd() to ratbagc
Missing from 6000688c30

Fixes #31

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-09-06 13:33:58 +02:00
Peter Hutterer
34fbfe105c tools: return the full svg path for ratbagc get_svg()
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-09-06 13:33:58 +02:00
Peter Hutterer
dfeac1bcbc tools: generate ratbagc.py from configuration_data()
No functional changes, this is prep work only

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-09-06 13:33:58 +02:00
52 changed files with 3756 additions and 262 deletions

View File

@@ -7,6 +7,16 @@ hardware-specific and kernel-specific quirks.
libratbag exports the devices over a DBus daemon called **ratbagd**, see the
[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:

View File

@@ -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
@@ -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:

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -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])

View 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

View File

@@ -0,0 +1,5 @@
[Device]
Name=Logitech MX Anywhere 2S
DeviceMatch=usb:046d:406a
Driver=hidpp20
Svg=logitech-mx-anywhere2.svg

View 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

View File

@@ -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

View 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

View 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

View 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

View 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

View File

@@ -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

View File

@@ -0,0 +1,6 @@
# Logitech G903 over USB
[Device]
Name=Logitech G903
DeviceMatch=usb:046d:c086
Driver=hidpp20
Svg=logitech-g900.svg

View 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

View 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

View File

@@ -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.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))

View 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

View 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

View File

@@ -1 +1 @@
logitech-g303.svg
logitech-g-pro.svg

View 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

View File

@@ -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

View File

@@ -292,16 +292,16 @@
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#babdb6;stroke-width:1.00157475;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 317.54607,570.04977 v -14.86768 c 0,-3.32226 -2.53923,-3.17407 -10.93958,-3.17407 -8.40035,0 -10.75737,-0.17634 -10.75737,3.17407 v 14.99268 c 0,0.8228 0.29258,1.29021 0.94502,1.28789 l 19.59359,-0.0698 c 0.59119,-0.002 1.15834,-0.75189 1.15834,-1.34309 z"
id="button6"
id="button7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sszsssss" />
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#babdb6;stroke-width:1.00157475;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 296.79395,573.25201 c -0.65244,0 -0.94531,0.46626 -0.94531,1.28906 v 13.6836 c 0.125,3.125 1.04518,4.18009 3.82812,4.92578 1.12947,0.30264 3.08418,0.75 6.92969,0.75 3.81789,0 6.10173,-0.5475 7.0957,-0.8125 2.12312,-0.56604 3.84375,-1.86328 3.84375,-4.48828 v -13.9336 c 0,-1.00605 -0.19935,-1.34375 -1.1582,-1.34375 z"
id="button7"
id="button6"
inkscape:connector-curvature="0" />
<g
id="button7_display"
id="button6_display"
transform="translate(9.375)">
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#babdb6;stroke-width:1.00157475;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
@@ -831,7 +831,7 @@
y="204.89717" />
</g>
<g
id="button6-path"
id="button7-path"
transform="translate(9.3749998)">
<path
id="path2125"
@@ -848,14 +848,14 @@
style="display:inline;opacity:1;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:9.99999905;stroke-opacity:1;paint-order:normal" />
<rect
style="text-align:start;opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:9.99999905;stroke-opacity:1;paint-order:normal"
id="button6-leader"
id="button7-leader"
width="1"
height="1"
x="473.625"
y="235.11517" />
</g>
<g
id="button7-path"
id="button6-path"
transform="translate(9.3749998)">
<path
id="path2127"
@@ -872,7 +872,7 @@
y="181.92424" />
<rect
style="text-align:start;opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:9.99999905;stroke-opacity:1;paint-order:normal"
id="button7-leader"
id="button6-leader"
width="1"
height="1"
x="473.625"

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 95 KiB

View 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

View 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

View File

@@ -0,0 +1 @@
logitech-mx-anywhere2.svg

View 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

View File

@@ -0,0 +1 @@
logitech-mx-master-2s.svg

View 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

View File

@@ -1,5 +1,5 @@
project('libratbag', 'c', 'cpp',
version : '0.9.903',
version : '0.9.904',
license : 'MIT/Expat',
default_options : [ 'c_std=gnu99', 'warning_level=2' ],
meson_version : '>= 0.40.0')
@@ -46,6 +46,25 @@ 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')
@@ -243,41 +262,54 @@ 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-g102-g203.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-g600.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',
)
@@ -291,24 +323,34 @@ 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',
)
@@ -501,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'],
@@ -527,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,
@@ -578,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')

View File

@@ -31,12 +31,15 @@ option('dbus-group',
option('systemd',
type : 'boolean',
value : true,
description : 'Build systemd unit files'
)
description : 'Build systemd unit files')
option('logind-provider',
type : 'combo',
choices: [ 'elogind', 'systemd'],
value : 'systemd',
description : 'Which logind provider to use'
)
description : 'Which logind provider to use')
option('coverity',
type: 'boolean',
value: false,
description: 'Enable coverity build fixes, see meson.build for details [default=false]')

View File

@@ -433,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);
}

View File

@@ -256,20 +256,25 @@ static int ratbagd_device_get_profiles(sd_bus *bus,
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,
void *userdata,
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);
CHECK_CALL(sd_bus_reply_method_return(m, "u", 0));
@@ -438,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",

View File

@@ -360,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);
}

View File

@@ -788,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);
}

View File

@@ -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)
{

View File

@@ -489,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)
@@ -502,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;
@@ -524,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);
}
@@ -568,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);
}

View File

@@ -100,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);
@@ -115,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);
@@ -130,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);
@@ -145,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);
@@ -208,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;
@@ -216,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);

View File

@@ -696,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);

View File

@@ -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;
}
@@ -1123,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)

View File

@@ -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)

View File

@@ -63,6 +63,13 @@
#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
@@ -91,6 +98,20 @@ struct steelseries_led_cycle {
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)
{
@@ -124,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;
@@ -136,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;
@@ -155,10 +183,13 @@ steelseries_get_firmware_version(struct ratbag_device *device)
uint8_t buf[STEELSERIES_REPORT_SIZE] = {0};
int ret;
if (device_version == 1)
return 0;
if (device_version == 2)
buf[0] = STEELSERIES_ID_FIRMWARE;
else if (device_version == 3)
buf[0] = STEELSERIES_ID_FIRMWARE_PROTOCOL3;
else
return -ENOTSUP;
buf[0] = STEELSERIES_ID_FIRMWARE;
msleep(10);
ret = ratbag_hidraw_output_report(device, buf, buf_len);
if (ret < 0)
@@ -187,10 +218,13 @@ steelseries_read_settings(struct ratbag_device *device)
int ret;
unsigned int active_resolution;
if (device_version == 1)
return 0;
if (device_version == 2)
buf[0] = STEELSERIES_ID_SETTTINGS;
else if (device_version == 3)
buf[0] = STEELSERIES_ID_SETTTINGS_PROTOCOL3;
else
return -ENOTSUP;
buf[0] = STEELSERIES_ID_SETTTINGS;
msleep(10);
ret = ratbag_hidraw_output_report(device, buf, buf_len);
if (ret < 0)
@@ -200,19 +234,28 @@ steelseries_read_settings(struct ratbag_device *device)
if (ret < 0)
return ret;
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;
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;
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];
}
}
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;
}
}
}
@@ -375,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);
@@ -404,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);
@@ -423,6 +480,7 @@ steelseries_write_buttons(struct ratbag_profile *profile)
{
struct ratbag_device *device = profile->device;
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)
@@ -523,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;
@@ -598,53 +661,61 @@ create_cycle(struct steelseries_led_cycle *cycle)
}
static void
construct_cycle_buffer(struct steelseries_led_cycle *cycle, uint8_t *buf, uint8_t buf_size)
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] = STEELSERIES_ID_LED;
buf[2] = cycle->led_id;
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[19] = 0x01;
buf[spec->repeat_idx] = 0x01;
buf[23] = cycle->trigger_buttons;
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 to 28,29,30 */
buf[28] = point->color.red;
buf[29] = point->color.green;
buf[30] = point->color.blue;
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[31 + npoints*4] = point->color.red;
buf[32 + npoints*4] = point->color.green;
buf[33 + npoints*4] = point->color.blue;
buf[34 + npoints*4] = point->pos;
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[27] = npoints;
buf[spec->point_count_idx] = npoints;
/* this seems to be the minimum allowed */
duration = max(buf[27] * 330, cycle->duration);
duration = max(buf[spec->point_count_idx] * 330, cycle->duration);
hidpp_set_unaligned_le_u16(&buf[3], 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};
@@ -663,13 +734,18 @@ steelseries_write_led_v2(struct ratbag_led *led)
switch(led->mode) {
case RATBAG_LED_OFF:
cycle.repeat = false;
point[0].color = black;
point[0].pos = 0x00;
list_append(&cycle.points, &point[0].link);
break;
case RATBAG_LED_ON:
cycle.repeat = false;
point[0].color = led->color;
point[0].pos = 0x00;
list_append(&cycle.points, &point[0].link);
break;
@@ -713,16 +789,54 @@ steelseries_write_led_v2(struct ratbag_led *led)
return -EINVAL;
}
construct_cycle_buffer(&cycle, buf, sizeof(buf));
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)
{
@@ -733,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;
}
@@ -748,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);

View File

@@ -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),
};

View File

@@ -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

View File

@@ -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 */
/* -------------------------------------------------------------------------- */

View File

@@ -63,5 +63,6 @@ def main(argv):
except AttributeError:
pass
if __name__ == "__main__":
main(sys.argv[1:])

View File

@@ -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):

View File

@@ -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.

View File

@@ -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:

View File

@@ -28,7 +28,8 @@ import sys
import argparse
import re
from ratbagd import Ratbagd, RatbagdDevice, RatbagdProfile, RatbagdMacro, RatbagdResolution, RatbagdButton, RatbagdLed, RatbagdDBusUnavailable, RatbagError, RatbagErrorCode, RatbagErrorCapability # NOQA
from ratbagd import Ratbagd, RatbagdDevice, RatbagdProfile, RatbagdMacro, RatbagdResolution, RatbagdButton, RatbagdLed, RatbagdUnavailable, RatbagError, RatbagErrorCode, RatbagErrorCapability # NOQA
button_specials_strmap = {
RatbagdButton.ACTION_SPECIAL_UNKNOWN: "unknown",
@@ -378,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:
@@ -395,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:
@@ -613,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):
@@ -662,6 +666,7 @@ def dpi(string):
else:
return (int_x, int_y)
# note: 'eventX' is assumed at the end of each command
parser_def = [
{
@@ -1419,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,
@@ -1517,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:
@@ -1551,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:])

View File

@@ -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.
@@ -270,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__ = {
@@ -278,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") 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():
@@ -420,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

View File

@@ -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));