mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-06-19 11:18:23 +02:00
Merge branch 'master' into tablet-support
This commit is contained in:
commit
99aa1f5dc3
47 changed files with 2977 additions and 228 deletions
79
CODING_STYLE
Normal file
79
CODING_STYLE
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
- Indentation in tabs, 8 characters wide, spaces after the tabs where
|
||||
vertical alignment is required (see below)
|
||||
|
||||
- Max line width 80ch, do not break up printed strings though
|
||||
|
||||
- Break up long lines at logical groupings, one line for each logical group
|
||||
|
||||
int a = somelongname() +
|
||||
someotherlongname();
|
||||
|
||||
if (a < 0 &&
|
||||
(b > 20 & d < 10) &&
|
||||
d != 0.0)
|
||||
|
||||
|
||||
somelongfunctioncall(arg1,
|
||||
arg2,
|
||||
arg3);
|
||||
|
||||
- Function declarations: return type on separate line, {} on separate line,
|
||||
arguments broken up as above.
|
||||
|
||||
static inline int
|
||||
foobar(int a, int b)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
somenamethatiswaytoolong(int a,
|
||||
int b,
|
||||
int c)
|
||||
{
|
||||
}
|
||||
|
||||
- /* comments only */, no // comments
|
||||
|
||||
- variable_name, not VariableName or variableName. same for functions.
|
||||
|
||||
- no typedefs of structs, enums, unions
|
||||
|
||||
- if it generates a compiler warning, it needs to be fixed
|
||||
- if it generates a static checker warning, it needs to be fixed or
|
||||
commented
|
||||
|
||||
- declare variables at the top, try to keep them as local as possible.
|
||||
Exception: if the same variable is re-used in multiple blocks, declare it
|
||||
at the top.
|
||||
|
||||
int a;
|
||||
int c;
|
||||
|
||||
if (foo) {
|
||||
int b;
|
||||
|
||||
c = get_value();
|
||||
usevalue(c);
|
||||
}
|
||||
|
||||
if (bar) {
|
||||
c = get_value();
|
||||
useit(c);
|
||||
}
|
||||
|
||||
- public functions MUST be doxygen-commented, use doxygen's @foo rather than
|
||||
\foo notation
|
||||
|
||||
- include "config.h" comes first, followed by system headers, followed by
|
||||
external library headers, followed by internal headers.
|
||||
sort alphabetically where it makes sense (specifically system headers)
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libevdev/libevdev.h>
|
||||
|
||||
#include "libinput-private.h"
|
||||
10
COPYING
10
COPYING
|
|
@ -4,7 +4,7 @@ Copyright © 2010-2012 Intel Corporation
|
|||
Copyright © 2010-2011 Benjamin Franzke
|
||||
Copyright © 2011-2012 Collabora, Ltd.
|
||||
Copyright © 2013-2014 Jonas Ådahl
|
||||
Copyright © 2013-2014 Red Hat, Inc.
|
||||
Copyright © 2013-2015 Red Hat, Inc.
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
|
|
@ -23,3 +23,11 @@ CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
OF THIS SOFTWARE.
|
||||
|
||||
libinput ships a copy of the GPL-licensed Linux kernel's linux/input.h
|
||||
header file. [1] This does not make libinput GPL.
|
||||
This copy is provided to provide consistent behavior regardless which kernel
|
||||
version libinput is compiled against. The header is used during compilation
|
||||
only, libinput does not link against GPL libraries.
|
||||
|
||||
[1] http://cgit.freedesktop.org/wayland/libinput/tree/include/linux/input.h
|
||||
|
|
|
|||
64
README.txt
64
README.txt
|
|
@ -9,22 +9,78 @@ applications that need to directly deal with input devices.
|
|||
It provides device detection, device handling, input device event processing
|
||||
and abstraction so minimize the amount of custom input code the user of
|
||||
libinput need to provide the common set of functionality that users expect.
|
||||
|
||||
Input event processing includes scaling touch coordinates, generating
|
||||
pointer events from touchpads, pointer acceleration, etc.
|
||||
|
||||
libinput originates from weston, the Wayland reference compositor.
|
||||
libinput originates from
|
||||
[weston](http://cgit.freedesktop.org/wayland/weston/), the Wayland reference
|
||||
compositor.
|
||||
|
||||
Architecture
|
||||
------------
|
||||
|
||||
libinput is not used directly by applications, rather it is used by the
|
||||
xf86-input-libinput X.Org driver or wayland compositors. The typical
|
||||
software stack for a system running Wayland is:
|
||||
|
||||
@dotfile libinput-stack-wayland.gv
|
||||
|
||||
Where the Wayland compositor may be Weston, mutter, KWin, etc. Note that
|
||||
Wayland encourages the use of toolkits, so the Wayland client (your
|
||||
application) does not usually talk directly to the compositor but rather
|
||||
employs a toolkit (e.g. GTK) to do so.
|
||||
|
||||
The simplified software stack for a system running X.Org is:
|
||||
|
||||
@dotfile libinput-stack-xorg.gv
|
||||
|
||||
Again, on a modern system the application does not usually talk directly to
|
||||
the X server using Xlib but rather employs a toolkit to do so.
|
||||
|
||||
Source code
|
||||
-----------
|
||||
|
||||
The source code of libinput can be found at:
|
||||
http://cgit.freedesktop.org/wayland/libinput
|
||||
|
||||
For more information, visit:
|
||||
For a list of current and past releases visit:
|
||||
http://www.freedesktop.org/wiki/Software/libinput/
|
||||
|
||||
Reporting Bugs
|
||||
--------------
|
||||
|
||||
Bugs can be filed in the libinput component of Wayland:
|
||||
https://bugs.freedesktop.org/enter_bug.cgi?product=Wayland&component=libinput
|
||||
|
||||
Online API documentation:
|
||||
Where possible, please provide an
|
||||
[evemu](http://www.freedesktop.org/wiki/Evemu/) recording of the input
|
||||
device and/or the event sequence in question.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
Developer API documentation:
|
||||
http://wayland.freedesktop.org/libinput/doc/latest/modules.html
|
||||
|
||||
High-level documentation about libinput's features:
|
||||
http://wayland.freedesktop.org/libinput/doc/latest/pages.html
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
libinput is licensed under the MIT license.
|
||||
|
||||
> Permission to use, copy, modify, distribute, and sell this software and its
|
||||
> documentation for any purpose is hereby granted without fee, provided that
|
||||
> the above copyright notice appear in all copies and that both that copyright
|
||||
> notice and this permission notice appear in supporting documentation, and
|
||||
> that the name of the copyright holders not be used in advertising or
|
||||
> publicity pertaining to distribution of the software without specific,
|
||||
> written prior permission. The copyright holders make no representations
|
||||
> about the suitability of this software for any purpose. It is provided "as
|
||||
> is" without express or implied warranty.
|
||||
|
||||
See the [COPYING](http://cgit.freedesktop.org/wayland/libinput/tree/COPYING)
|
||||
file for the full license information.
|
||||
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
AC_PREREQ([2.64])
|
||||
|
||||
m4_define([libinput_major_version], [0])
|
||||
m4_define([libinput_minor_version], [15])
|
||||
m4_define([libinput_minor_version], [17])
|
||||
m4_define([libinput_micro_version], [0])
|
||||
m4_define([libinput_version],
|
||||
[libinput_major_version.libinput_minor_version.libinput_micro_version])
|
||||
|
|
@ -31,7 +31,7 @@ AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz])
|
|||
# b) If interfaces have been changed or added, but binary compatibility has
|
||||
# been preserved, change to C+1:0:A+1
|
||||
# c) If the interface is the same as the previous version, change to C:R+1:A
|
||||
LIBINPUT_LT_VERSION=12:0:2
|
||||
LIBINPUT_LT_VERSION=12:2:2
|
||||
AC_SUBST(LIBINPUT_LT_VERSION)
|
||||
|
||||
AM_SILENT_RULES([yes])
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ header_files = \
|
|||
$(srcdir)/absolute-axes.dox \
|
||||
$(srcdir)/clickpad-softbuttons.dox \
|
||||
$(srcdir)/device-configuration-via-udev.dox \
|
||||
$(srcdir)/faqs.dox \
|
||||
$(srcdir)/normalization-of-relative-motion.dox \
|
||||
$(srcdir)/palm-detection.dox \
|
||||
$(srcdir)/scrolling.dox \
|
||||
|
|
@ -25,9 +26,16 @@ header_files = \
|
|||
diagram_files = \
|
||||
$(srcdir)/dot/seats-sketch.gv \
|
||||
$(srcdir)/dot/seats-sketch-libinput.gv \
|
||||
$(srcdir)/dot/libinput-stack-wayland.gv \
|
||||
$(srcdir)/dot/libinput-stack-xorg.gv \
|
||||
$(srcdir)/dot/libinput-stack-gnome.gv \
|
||||
$(srcdir)/svg/software-buttons.svg \
|
||||
$(srcdir)/svg/clickfinger.svg \
|
||||
$(srcdir)/svg/button-scrolling.svg \
|
||||
$(srcdir)/svg/edge-scrolling.svg \
|
||||
$(srcdir)/svg/palm-detection.svg \
|
||||
$(srcdir)/svg/tap-n-drag.svg \
|
||||
$(srcdir)/svg/top-software-buttons.svg \
|
||||
$(srcdir)/svg/twofinger-scrolling.svg
|
||||
|
||||
html/index.html: libinput.doxygen $(header_files) $(diagram_files)
|
||||
|
|
|
|||
|
|
@ -24,15 +24,6 @@ is split in the middle to generate left or right button events on click. The
|
|||
height of the button area depends on the hardware but is usually around
|
||||
10mm.
|
||||
|
||||
@dot
|
||||
digraph G {
|
||||
clickpad [
|
||||
shape = "record";
|
||||
label = "{\nMain\nArea\n\n|{LEFT|RIGHT}}";
|
||||
]
|
||||
}
|
||||
@enddot
|
||||
|
||||
Left, right and middle button events can be triggered as follows:
|
||||
- if a finger is in the main area or the left button area, a click generates
|
||||
left button events.
|
||||
|
|
@ -40,6 +31,8 @@ Left, right and middle button events can be triggered as follows:
|
|||
- if there is a finger in both the left and right button area, a click
|
||||
generates middle button events.
|
||||
|
||||
@image html software-buttons.svg "Left, right and middle-button click with software button areas"
|
||||
|
||||
If fingers are down in the main area in addition to fingers in the
|
||||
left or right button area, those fingers are are ignored.
|
||||
A release event always releases the buttons logically down, regardless of
|
||||
|
|
@ -69,9 +62,18 @@ three fingers are held down on the touchpad when a physical click is
|
|||
generated. The location of the fingers does not matter and there are no
|
||||
software-defined button areas.
|
||||
|
||||
The Xorg synaptics driver uses 30% of the touchpad dimensions as threshold,
|
||||
libinput does not have this restriction. If two fingers are on the pad
|
||||
while clicking, that is a two-finger click.
|
||||
@image html clickfinger.svg "One, two and three-finger click with Clickfinger behavior"
|
||||
|
||||
On some touchpads, libinput imposes a limit on how the fingers may be placed
|
||||
on the touchpad. In the most common use-case this allows for a user to
|
||||
trigger a click with the thumb while leaving the pointer-moving finger on
|
||||
the touchpad.
|
||||
|
||||
@image html clickfinger-distance.svg "Illustration of the distance detection algorithm"
|
||||
|
||||
In the illustration above the red area marks the proximity area around the
|
||||
first finger. Since the thumb is outside of that area libinput considers the
|
||||
click a single-finger click rather than a two-finger click.
|
||||
|
||||
Clickfinger configuration can be enabled through the
|
||||
libinput_device_config_click_set_method() call. If clickfingers are
|
||||
|
|
|
|||
30
doc/dot/libinput-stack-gnome.gv
Normal file
30
doc/dot/libinput-stack-gnome.gv
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
digraph stack
|
||||
{
|
||||
compound=true;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
gcc -> gsettings
|
||||
|
||||
xf86libinput -> libinput
|
||||
|
||||
subgraph cluster0 {
|
||||
label="X.Org";
|
||||
xf86libinput [label="xf86-input-libinput"];
|
||||
xserver [label="X Server"];
|
||||
xserver -> xf86libinput;
|
||||
}
|
||||
|
||||
gcc [label="gnome-control-center"];
|
||||
|
||||
subgraph cluster3 {
|
||||
gsettings
|
||||
}
|
||||
|
||||
gsd [label="gnome-settings-daemon"];
|
||||
|
||||
gsd -> gsettings
|
||||
gsd -> xserver
|
||||
}
|
||||
17
doc/dot/libinput-stack-wayland.gv
Normal file
17
doc/dot/libinput-stack-wayland.gv
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
digraph stack
|
||||
{
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
kernel [label="Kernel"];
|
||||
|
||||
libinput;
|
||||
compositor [label="Wayland Compositor"];
|
||||
client [label="Wayland Client"];
|
||||
|
||||
kernel -> libinput
|
||||
libinput -> compositor
|
||||
compositor -> client
|
||||
}
|
||||
19
doc/dot/libinput-stack-xorg.gv
Normal file
19
doc/dot/libinput-stack-xorg.gv
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
digraph stack
|
||||
{
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
kernel [label="Kernel"];
|
||||
|
||||
libinput;
|
||||
xf86libinput [label="xf86-input-libinput"];
|
||||
xserver [label="X Server"];
|
||||
client [label="X11 client"];
|
||||
|
||||
kernel -> libinput
|
||||
libinput -> xf86libinput
|
||||
xf86libinput -> xserver
|
||||
xserver -> client
|
||||
}
|
||||
51
doc/faqs.dox
Normal file
51
doc/faqs.dox
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
@page faq FAQs - Frequently Asked Questions
|
||||
|
||||
Frequently asked questions about libinput.
|
||||
|
||||
@section faq_kinetic_scrolling Kinetic scrolling does not work
|
||||
|
||||
The X.Org synaptics driver implemented kinetic scrolling in the driver. It
|
||||
measures the scroll speed and once the finger leaves the touchpad the driver
|
||||
keeps sending scroll events for a predetermined time. This effectively
|
||||
provides for kinetic scrolling without client support but triggers an
|
||||
unfixable [bug](https://bugs.freedesktop.org/show_bug.cgi?id=38909): the
|
||||
client cannot know that the events are from a kinetic scroll source. Scroll
|
||||
events in X are always sent to the current cursor position, a movement of the
|
||||
cursor after lifting the finger will send the kinetic scroll events to the
|
||||
new client, something the user does not usually expect. A key event during
|
||||
the kinetic scroll procedure causes side-effects such as triggering zoom.
|
||||
|
||||
libinput does not implement kinetic scrolling for touchpads. Instead it
|
||||
provides the libinput_event_pointer_get_axis_source() function that enables
|
||||
callers to implement kinetic scrolling on a per-widget basis, see @ref
|
||||
scroll_sources.
|
||||
|
||||
@section faq_gpl Is libinput GPL-licensed?
|
||||
|
||||
No, libinput is MIT licensed. The Linux kernel header file linux/input.h in
|
||||
libinput's tree is provded to ensure the same behavior regardless of which
|
||||
kernel version libinput is built on. It does not make libinput GPL-licensed.
|
||||
|
||||
@section faq_config_options Where is the configuration stored?
|
||||
|
||||
libinput does not store configuration options, it is up to the caller to
|
||||
manage these and decide which configuration option to apply to each device.
|
||||
This must be done at startup, after a resume and whenever a new device is
|
||||
detected.
|
||||
|
||||
In a GNOME X.Org stack a user would usually toggle an option in
|
||||
the gnome-control-center which adjusts a gsettings entry. That change is
|
||||
picked up by gnome-settings-daemon and applied to the device by adjusting
|
||||
input device properties that the xf86-input-libinput driver provides.
|
||||
The input device property changes map to the respective libinput
|
||||
configuration options.
|
||||
|
||||
@dotfile libinput-stack-gnome.gv
|
||||
|
||||
This has an effect on the availability of configuration options: if an
|
||||
option is not exposed by the intermediary, it cannot be configured by the
|
||||
client. Also some configuration options that are provided by the
|
||||
intermediary may not be libinput-specific configuration options.
|
||||
|
||||
*/
|
||||
|
|
@ -74,8 +74,9 @@ Notable behaviors of libinput's disable-while-typing feature:
|
|||
- Some keys do not trigger the timeout, specifically some modifier keys
|
||||
(Ctrl, Alt, Shift, and Fn). Actions such as Ctrl + click thus stay
|
||||
responsive.
|
||||
- Touches started while the touchpad is disabled do not control the cursor,
|
||||
it is thus possible to rest the palm on the touchpad while typing.
|
||||
- Touches started while typing do not control the cursor even after typing
|
||||
has stopped, it is thus possible to rest the palm on the touchpad while
|
||||
typing.
|
||||
- Physical buttons work even while the touchpad is disabled. This includes
|
||||
software-emulated buttons.
|
||||
|
||||
|
|
|
|||
|
|
@ -63,4 +63,23 @@ the motion events. Cross-device scrolling is not supported but
|
|||
for one exception: libinput's @ref t440_support enables the use of the middle
|
||||
button for button scrolling (even when the touchpad is disabled).
|
||||
|
||||
@section scroll_sources Scroll sources
|
||||
|
||||
libinput provides a pointer axis *source* for each scroll event. The
|
||||
source can be obtained with the libinput_event_pointer_get_axis_source()
|
||||
function and is one of **wheel**, **finger**, or **continuous**. The source
|
||||
information lets a caller decide when to implement kinetic scrolling.
|
||||
Usually, a caller will process events of source wheel as they come in.
|
||||
For events of source finger a caller should calculate the velocity of the
|
||||
scroll motion and upon finger release start a kinetic scrolling motion (i.e.
|
||||
continue executing a scroll according to some friction factor).
|
||||
libinput expects the caller to be in charge of widget handling, the source
|
||||
information is thus enough to provide kinetic scrolling on a per-widget
|
||||
basis. A caller should cancel kinetic scrolling when the pointer leaves the
|
||||
current widget or when a key is pressed.
|
||||
|
||||
See the libinput_event_pointer_get_axis_source() for details on the
|
||||
behavior of each scroll source.
|
||||
|
||||
See also http://who-t.blogspot.com.au/2015/03/libinput-scroll-sources.html
|
||||
*/
|
||||
|
|
|
|||
106
doc/svg/clickfinger-distance.svg
Normal file
106
doc/svg/clickfinger-distance.svg
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
<?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="89.829216mm"
|
||||
height="59.06765mm"
|
||||
viewBox="0 0 318.2925 209.29482"
|
||||
id="svg4184"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="clickfinger-distance.svg">
|
||||
<defs
|
||||
id="defs4186" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4"
|
||||
inkscape:cx="235.68795"
|
||||
inkscape:cy="163.39995"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata4189">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-257.99662,-299.41313)">
|
||||
<rect
|
||||
width="313.09872"
|
||||
height="167.89594"
|
||||
x="260.59351"
|
||||
y="302.01001"
|
||||
id="rect2858-0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.19376326;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<rect
|
||||
style="opacity:0.92000002;fill:#7b0000;fill-opacity:0.2983426;stroke:#000000;stroke-width:1.00100005;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4788"
|
||||
width="188.57143"
|
||||
height="79.285713"
|
||||
x="355"
|
||||
y="309.50507" />
|
||||
<g
|
||||
transform="matrix(0.79657897,0.11742288,-0.14814182,0.631399,276.6631,-158.96703)"
|
||||
id="g3663-9-5">
|
||||
<path
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z"
|
||||
id="path2820-6-6"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z"
|
||||
id="path2824-1-1"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z"
|
||||
id="path2824-7-1-4"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00100005;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path2824-1-1-3"
|
||||
d="m 353.70196,495.15765 c -24.01774,-7.29937 -29.0012,-10.10221 -30.51977,-10.54973 -10.67294,-3.14527 -18.27051,-5.54063 -23.77758,-13.4704 -5.50707,-7.92977 -5.34967,-20.78347 8.87612,-26.31604 14.2258,-5.53257 39.34351,8.79597 60.13061,16.16341 20.7871,7.36744 33.04563,11.44545 39.33422,13.87551 -8.10022,18.05041 -7.22129,21.15857 -10.11054,33.34117 -0.0481,0.20261 -17.87459,-5.12433 -43.93306,-13.04392 z"
|
||||
sodipodi:nodetypes="sszzzcss" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
id="path2824-7-1-4-3"
|
||||
d="m 324.44991,483.39364 c -10.67294,-1.94747 -17.88441,-5.64478 -21.62691,-8.75386 -8.11652,-9.03765 -6.31775,-15.03428 -3.3272,-13.99784 8.90495,-0.9097 30.20384,9.01528 33.86042,10.17935 -5.80268,11.37909 -1.08919,13.70271 -8.90631,12.57235 z"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.9 KiB |
207
doc/svg/clickfinger.svg
Normal file
207
doc/svg/clickfinger.svg
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
<?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"
|
||||
width="1084.4291"
|
||||
height="218.18733"
|
||||
id="svg2"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="clickfinger.svg">
|
||||
<metadata
|
||||
id="metadata4314">
|
||||
<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>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
id="namedview4312"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.81739538"
|
||||
inkscape:cx="347.81182"
|
||||
inkscape:cy="125.36322"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:snap-page="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0">
|
||||
<sodipodi:guide
|
||||
position="563.61797,339.58481"
|
||||
orientation="0,1"
|
||||
id="guide4473" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs4" />
|
||||
<g
|
||||
id="g4405"
|
||||
transform="matrix(0.81023703,0,0,0.6422249,-2.3181067e-6,0.47063383)">
|
||||
<rect
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:7.20000076;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="rect2858-0"
|
||||
y="3.6000037"
|
||||
x="3.6000032"
|
||||
height="261.42856"
|
||||
width="386.42856" />
|
||||
<g
|
||||
id="g3663-9-5"
|
||||
transform="matrix(0.98314313,0.18283763,-0.18283763,0.98314313,-4.7772181,-625.20496)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path2820-6-6"
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path2824-1-1"
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
id="path2824-7-1-4"
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g4394"
|
||||
transform="matrix(0.81023703,0,0,0.6422249,-2.3181067e-6,0.47063383)">
|
||||
<rect
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:7.20000076;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="rect2858"
|
||||
y="3.6000218"
|
||||
x="475.52567"
|
||||
height="261.42856"
|
||||
width="386.42856" />
|
||||
<g
|
||||
id="g3663"
|
||||
transform="matrix(0.98196551,0.12493315,-0.14261338,1.1209308,508.26203,-717.12108)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.94553083px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path2820"
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.00189106;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path2824"
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
id="path2824-7"
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z" />
|
||||
</g>
|
||||
<g
|
||||
id="g3663-9"
|
||||
transform="matrix(0.98314313,0.18283763,-0.18283763,0.98314313,458.58466,-619.69966)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path2820-6"
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path2824-1"
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
id="path2824-7-1"
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z" />
|
||||
</g>
|
||||
</g>
|
||||
<rect
|
||||
width="313.09872"
|
||||
height="167.89594"
|
||||
x="768.41345"
|
||||
y="2.3120098"
|
||||
id="rect2858-7"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.19376326;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<g
|
||||
transform="matrix(0.79562482,0.08023518,-0.11555064,0.71988967,731.4982,-458.98163)"
|
||||
id="g3663-3">
|
||||
<path
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z"
|
||||
id="path2820-0"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.94553083px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z"
|
||||
id="path2824-9"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.00189106;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z"
|
||||
id="path2824-7-8"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.79657897,0.11742288,-0.14814182,0.631399,697.24775,-392.41517)"
|
||||
id="g3663-9-8">
|
||||
<path
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z"
|
||||
id="path2820-6-7"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z"
|
||||
id="path2824-1-6"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z"
|
||||
id="path2824-7-1-7"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.79562482,0.08023518,-0.11555064,0.71988967,793.15605,-458.77793)"
|
||||
id="g3663-3-0">
|
||||
<path
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z"
|
||||
id="path2820-0-5"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.94553083px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z"
|
||||
id="path2824-9-3"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.00189106;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z"
|
||||
id="path2824-7-8-8"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 16 KiB |
175
doc/svg/software-buttons.svg
Normal file
175
doc/svg/software-buttons.svg
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
<?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"
|
||||
width="1083.7891"
|
||||
height="270.02051"
|
||||
id="svg2"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="software-buttons.svg">
|
||||
<metadata
|
||||
id="metadata4314">
|
||||
<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>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
id="namedview4312"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.57798581"
|
||||
inkscape:cx="1134.9723"
|
||||
inkscape:cy="-71.183873"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:snap-page="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0">
|
||||
<sodipodi:guide
|
||||
position="563.298,391.13313"
|
||||
orientation="0,1"
|
||||
id="guide4473" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs4" />
|
||||
<g
|
||||
id="g4598"
|
||||
transform="translate(-0.31997204,0.28487182)">
|
||||
<rect
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.19376326;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="rect2858-0"
|
||||
y="2.7826459"
|
||||
x="2.9168537"
|
||||
height="167.89594"
|
||||
width="313.09872" />
|
||||
<g
|
||||
id="g3663-9-5"
|
||||
transform="matrix(0.79657897,0.11742288,-0.14814182,0.631399,-118.87011,-352.11563)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path2820-6-6"
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path2824-1-1"
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
id="path2824-7-1-4"
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z" />
|
||||
</g>
|
||||
</g>
|
||||
<rect
|
||||
width="313.09872"
|
||||
height="167.89594"
|
||||
x="384.96854"
|
||||
y="3.0675292"
|
||||
id="rect2858"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.19376326;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<rect
|
||||
width="313.09872"
|
||||
height="167.89594"
|
||||
x="768.09351"
|
||||
y="2.5968816"
|
||||
id="rect2858-7"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.19376326;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<g
|
||||
transform="matrix(0.79657897,0.11742288,-0.14814182,0.631399,665.11943,-345.64117)"
|
||||
id="g3663-9-8">
|
||||
<path
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z"
|
||||
id="path2820-6-7"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z"
|
||||
id="path2824-1-6"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z"
|
||||
id="path2824-7-1-7"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g4656"
|
||||
transform="translate(-0.31997204,0.28487182)">
|
||||
<g
|
||||
id="g4639">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.72135597px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path2820-0-5"
|
||||
d="m 970.15914,263.93369 32.58666,-97.47985 c 0,0 12.2603,-46.32869 38.5506,-33.925 20.7457,9.78778 17.4301,24.72594 16.4399,28.75425 -10.1846,41.43257 -30.105,105.84033 -30.105,105.84033 l -0.428,-0.37827 z"
|
||||
sodipodi:nodetypes="ccssccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.00144271;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path2824-9-3"
|
||||
d="m 987.16367,214.84092 c 8.97014,-26.84686 16.75933,-50.19953 17.30923,-51.89481 3.8651,-11.91483 10.3862,-22.76212 16.5622,-27.54951 6.8496,-5.30946 13.8243,-5.75615 21.9108,-1.40323 3.7999,2.04543 6.0302,3.61208 8.2265,5.77836 2.5214,2.487 3.6881,4.17002 5.1008,7.35828 1.3655,3.08181 1.9391,7.11725 1.5051,10.58923 -0.597,4.77663 -10.2821,40.41668 -20.9931,77.25236 -7.7256,26.56907 -9.371,31.11182 -9.5644,31.10964 -0.1479,-0.002 -55.70067,-1.83937 -56.08626,-2.18017 -0.16723,-0.1478 6.29681,-19.93218 16.02913,-49.06015 z"
|
||||
sodipodi:nodetypes="scsssscsccs" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
id="path2824-7-8-8"
|
||||
d="m 1008.3595,164.57667 c 3.8651,-11.91483 7.6606,-19.35039 13.8366,-24.13778 6.8495,-5.30946 12.0833,-5.57765 20.1698,-1.22474 9.3061,4.73331 12.9905,9.62271 11.9094,19.03362 -6.3459,19.3209 -6.9054,22.12042 -9.2168,26.32727 -0.1479,-0.002 -33.6651,-14.70742 -35.0296,-15.23839 -1.4035,-0.54616 -1.8884,-3.70289 -1.6694,-4.75998 z" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
transform="translate(-386.56163,2.2570367)"
|
||||
id="g4656-3">
|
||||
<g
|
||||
id="g4639-2">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.72135597px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path2820-0-5-6"
|
||||
d="m 970.15914,263.93369 32.58666,-97.47985 c 0,0 12.2603,-46.32869 38.5506,-33.925 20.7457,9.78778 17.4301,24.72594 16.4399,28.75425 -10.1846,41.43257 -30.105,105.84033 -30.105,105.84033 l -0.428,-0.37827 z"
|
||||
sodipodi:nodetypes="ccssccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.00144271;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path2824-9-3-6"
|
||||
d="m 987.16367,214.84092 c 8.97014,-26.84686 16.75933,-50.19953 17.30923,-51.89481 3.8651,-11.91483 10.3862,-22.76212 16.5622,-27.54951 6.8496,-5.30946 13.8243,-5.75615 21.9108,-1.40323 3.7999,2.04543 6.0302,3.61208 8.2265,5.77836 2.5214,2.487 3.6881,4.17002 5.1008,7.35828 1.3655,3.08181 1.9391,7.11725 1.5051,10.58923 -0.597,4.77663 -10.2821,40.41668 -20.9931,77.25236 -7.7256,26.56907 -9.371,31.11182 -9.5644,31.10964 -0.1479,-0.002 -55.70067,-1.83937 -56.08626,-2.18017 -0.16723,-0.1478 6.29681,-19.93218 16.02913,-49.06015 z"
|
||||
sodipodi:nodetypes="scsssscsccs" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
id="path2824-7-8-8-4"
|
||||
d="m 1008.3595,164.57667 c 3.8651,-11.91483 7.6606,-19.35039 13.8366,-24.13778 6.8495,-5.30946 12.0833,-5.57765 20.1698,-1.22474 9.3061,4.73331 12.9905,9.62271 11.9094,19.03362 -6.3459,19.3209 -6.9054,22.12042 -9.2168,26.32727 -0.1479,-0.002 -33.6651,-14.70742 -35.0296,-15.23839 -1.4035,-0.54616 -1.8884,-3.70289 -1.6694,-4.75998 z" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
810
doc/svg/tap-n-drag.svg
Normal file
810
doc/svg/tap-n-drag.svg
Normal file
|
|
@ -0,0 +1,810 @@
|
|||
<?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"
|
||||
width="753.05255"
|
||||
height="737.14532"
|
||||
id="svg2"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="tap-n-drag.svg">
|
||||
<metadata
|
||||
id="metadata4314">
|
||||
<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>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
id="namedview4312"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.57798582"
|
||||
inkscape:cx="926.00645"
|
||||
inkscape:cy="627.63785"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:snap-page="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0">
|
||||
<sodipodi:guide
|
||||
position="600.67806,858.83692"
|
||||
orientation="0,1"
|
||||
id="guide4473" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker6136"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path6138" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker6132"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6134"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker6111"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Lend">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path6113" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker5983"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path5985"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker5979"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5981"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5429"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5414"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(0.4,0,0,0.4,4,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker5963"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5965"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker5954"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5956"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker5950"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path5952"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker5935"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5937"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker5931"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path5933"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker5873"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path5875"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker5869"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lstart">
|
||||
<path
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path5871"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker5772"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path5774"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker5743"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path5745"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker5739"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lstart">
|
||||
<path
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path5741"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker5682"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path5684"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker5678"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5680"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker5674"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path5676"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker5668"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5670"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lend"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5411"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5408"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
</defs>
|
||||
<g
|
||||
id="g6226"
|
||||
transform="translate(5.049491e-5,0)">
|
||||
<rect
|
||||
transform="matrix(1,0,-0.3959173,0.91828617,0,0)"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.41992331;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="rect2858-0"
|
||||
y="2.7099617"
|
||||
x="77.243813"
|
||||
height="182.83618"
|
||||
width="313.09872" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:0.2983426;fill-rule:nonzero;stroke:none;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path5690"
|
||||
d="m 187.13717,141.62175 c -7.23616,-20.04776 -13.54188,-37.48106 -14.01271,-38.74063 -3.30915,-8.852639 -3.7924,-18.06951 -1.22734,-23.40863 2.84478,-5.921356 8.47454,-8.88606 17.68557,-9.313448 4.32826,-0.20083 7.07051,-0.09252 10.1144,0.399498 3.49454,0.564856 5.4048,1.155131 8.35172,2.580712 2.84854,1.377989 5.55537,3.650555 7.10286,5.96335 2.12899,3.181858 13.60803,28.938928 24.88164,55.830298 8.13151,19.39637 18.05518,43.64654 17.89104,43.71977 -0.12552,0.056 -56.74536,-0.47345 -57.25799,-0.53541 -0.22232,-0.0269 -5.6782,-14.74433 -13.52919,-36.49551 z" />
|
||||
<g
|
||||
id="g3663-9-5"
|
||||
transform="matrix(0.79657897,0.11742288,-0.14814182,0.631399,28.295757,-432.54234)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path2820-6-6"
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path2824-1-1"
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
id="path2824-7-1-4"
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z" />
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5672"
|
||||
d="m 166.69233,71.697127 0,37.313633"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker5682);marker-end:url(#marker5674)" />
|
||||
</g>
|
||||
<g
|
||||
id="g5747"
|
||||
transform="translate(37.060081,-0.29412562)">
|
||||
<rect
|
||||
width="313.09872"
|
||||
height="182.83618"
|
||||
x="400.31058"
|
||||
y="3.0302601"
|
||||
id="rect5718"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.41992331;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
transform="matrix(1,0,-0.3959173,0.91828617,0,0)" />
|
||||
<path
|
||||
d="m 510.07714,141.91588 c -7.23616,-20.04776 -13.54188,-37.48106 -14.01271,-38.74063 -3.30915,-8.852643 -3.7924,-18.069514 -1.22734,-23.408634 2.84478,-5.921356 8.47454,-8.88606 17.68557,-9.313448 4.32826,-0.20083 7.07051,-0.09252 10.1144,0.399498 3.49454,0.564856 5.4048,1.155131 8.35172,2.580712 2.84854,1.377989 5.55537,3.650555 7.10286,5.96335 2.12899,3.181858 13.60803,28.938932 24.88164,55.830302 8.13151,19.39637 18.05518,43.64654 17.89104,43.71977 -0.12552,0.056 -56.74536,-0.47345 -57.25799,-0.53541 -0.22232,-0.0269 -5.6782,-14.74433 -13.52919,-36.49551 z"
|
||||
id="path5720"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:0.2983426;fill-rule:nonzero;stroke:none;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
transform="matrix(0.79717939,0.09917984,-0.14825348,0.53330368,349.25624,-338.55557)"
|
||||
id="g5722">
|
||||
<path
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z"
|
||||
id="path5724"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z"
|
||||
id="path5726"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z"
|
||||
id="path5728"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker5743)"
|
||||
d="m 489.6323,71.991253 0,37.313637"
|
||||
id="path5730"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
<g
|
||||
id="g6193"
|
||||
transform="translate(-719.99994,240)">
|
||||
<rect
|
||||
width="313.09872"
|
||||
height="182.83618"
|
||||
x="1157.2438"
|
||||
y="2.7099617"
|
||||
id="rect6064"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.41992331;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
transform="matrix(1,0,-0.3959173,0.91828617,0,0)" />
|
||||
<path
|
||||
d="m 1204.1322,161.80782 c -7.2362,-20.04776 -13.5419,-37.48106 -14.0127,-38.74063 -3.3092,-8.85264 -3.7925,-18.06951 -1.2274,-23.40863 2.8448,-5.921356 8.4746,-8.88606 17.6856,-9.313448 4.3282,-0.20083 7.0705,-0.09252 10.1144,0.399498 3.4945,0.564856 5.4048,1.155131 8.3517,2.580712 2.8485,1.377989 5.5554,3.650555 7.1029,5.96335 2.129,3.181858 13.608,28.938928 24.8816,55.830298 8.1315,19.39637 18.0552,43.64654 17.891,43.71977 -0.1255,0.056 -56.7453,-0.47345 -57.258,-0.53541 -0.2223,-0.0269 -5.6781,-14.74433 -13.5291,-36.49551 z"
|
||||
id="path6066"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:0.2983426;fill-rule:nonzero;stroke:none;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
transform="matrix(0.79717939,0.09917984,-0.14825348,0.53330368,1043.3113,-318.66363)"
|
||||
id="g6068">
|
||||
<path
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z"
|
||||
id="path6070"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z"
|
||||
id="path6072"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z"
|
||||
id="path6074"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker6136)"
|
||||
d="m 1360.3559,35.196081 -121.004,62.192402"
|
||||
id="path6076"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:0.2983426;fill-rule:nonzero;stroke:none;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path6080"
|
||||
d="m 1204.1322,161.80782 c -7.2362,-20.04776 -13.5419,-37.48106 -14.0127,-38.74063 -3.3092,-8.85264 -3.7925,-18.06951 -1.2274,-23.40863 2.8448,-5.921356 8.4746,-8.88606 17.6856,-9.313448 4.3282,-0.20083 7.0705,-0.09252 10.1144,0.399498 3.4945,0.564856 5.4048,1.155131 8.3517,2.580712 2.8485,1.377989 5.5554,3.650555 7.1029,5.96335 2.129,3.181858 13.608,28.938928 24.8816,55.830298 8.1315,19.39637 18.0552,43.64654 17.891,43.71977 -0.1255,0.056 -56.7453,-0.47345 -57.258,-0.53541 -0.2223,-0.0269 -5.6781,-14.74433 -13.5291,-36.49551 z" />
|
||||
<g
|
||||
id="g6082"
|
||||
transform="matrix(0.79717939,0.09917984,-0.14825348,0.53330368,1043.3113,-318.66363)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path6084"
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path6086"
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
id="path6088"
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z" />
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6092"
|
||||
d="M 1238.5753,97.34219 C 1220.4088,41.977511 1322.8368,-6.8249094 1359.1699,33.833528"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 2;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker5983)" />
|
||||
<g
|
||||
transform="translate(397.06003,-0.29412562)"
|
||||
id="g5801">
|
||||
<g
|
||||
id="g5776">
|
||||
<rect
|
||||
transform="matrix(1,0,-0.3959173,0.91828617,0,0)"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.41992331;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="rect5758"
|
||||
y="3.0302601"
|
||||
x="400.31058"
|
||||
height="182.83618"
|
||||
width="313.09872" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:0.2983426;fill-rule:nonzero;stroke:none;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path5760"
|
||||
d="m 447.07213,162.10195 c -7.23616,-20.04776 -13.54188,-37.48106 -14.01271,-38.74063 -3.30915,-8.85264 -3.7924,-18.06951 -1.22734,-23.408634 2.84478,-5.921356 8.47454,-8.88606 17.68557,-9.313448 4.32826,-0.20083 7.07051,-0.09252 10.1144,0.399498 3.49454,0.564856 5.4048,1.155131 8.35172,2.580712 2.84854,1.377989 5.55537,3.650555 7.10286,5.96335 2.12899,3.181862 13.60803,28.938932 24.88164,55.830302 8.13151,19.39637 18.05518,43.64654 17.89104,43.71977 -0.12552,0.056 -56.74536,-0.47345 -57.25799,-0.53541 -0.22232,-0.0269 -5.6782,-14.74433 -13.52919,-36.49551 z" />
|
||||
<g
|
||||
id="g5762"
|
||||
transform="matrix(0.79717939,0.09917984,-0.14825348,0.53330368,286.25123,-318.3695)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path5764"
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path5766"
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
id="path5768"
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z" />
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5770"
|
||||
d="M 534.17392,70.357054 482.29191,97.682609"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker5772)" />
|
||||
</g>
|
||||
<g
|
||||
id="g5785">
|
||||
<path
|
||||
d="m 447.07213,162.10195 c -7.23616,-20.04776 -13.54188,-37.48106 -14.01271,-38.74063 -3.30915,-8.85264 -3.7924,-18.06951 -1.22734,-23.408634 2.84478,-5.921356 8.47454,-8.88606 17.68557,-9.313448 4.32826,-0.20083 7.07051,-0.09252 10.1144,0.399498 3.49454,0.564856 5.4048,1.155131 8.35172,2.580712 2.84854,1.377989 5.55537,3.650555 7.10286,5.96335 2.12899,3.181862 13.60803,28.938932 24.88164,55.830302 8.13151,19.39637 18.05518,43.64654 17.89104,43.71977 -0.12552,0.056 -56.74536,-0.47345 -57.25799,-0.53541 -0.22232,-0.0269 -5.6782,-14.74433 -13.52919,-36.49551 z"
|
||||
id="path5789"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:0.2983426;fill-rule:nonzero;stroke:none;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
transform="matrix(0.79717939,0.09917984,-0.14825348,0.53330368,286.25123,-318.3695)"
|
||||
id="g5791">
|
||||
<path
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z"
|
||||
id="path5793"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z"
|
||||
id="path5795"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z"
|
||||
id="path5797"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker5950)"
|
||||
d="M 534.17392,70.357054 482.29191,97.682609"
|
||||
id="path5799"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g6251"
|
||||
transform="translate(-2.4752545e-5,40)">
|
||||
<g
|
||||
id="g6042"
|
||||
transform="translate(-1042.9399,459.70587)">
|
||||
<rect
|
||||
width="313.09872"
|
||||
height="182.83618"
|
||||
x="1120.3105"
|
||||
y="3.0302601"
|
||||
id="rect6044"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.41992331;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
transform="matrix(1,0,-0.3959173,0.91828617,0,0)" />
|
||||
<path
|
||||
d="m 1167.0721,162.10195 c -7.2361,-20.04776 -13.5418,-37.48106 -14.0127,-38.74063 -3.3091,-8.85264 -3.7924,-18.06951 -1.2273,-23.408634 2.8448,-5.921356 8.4745,-8.88606 17.6856,-9.313448 4.3282,-0.20083 7.0705,-0.09252 10.1144,0.399498 3.4945,0.564856 5.4048,1.155131 8.3517,2.580712 2.8485,1.377989 5.5553,3.650555 7.1028,5.96335 2.129,3.181862 13.6081,28.938932 24.8817,55.830302 8.1315,19.39637 18.0552,43.64654 17.891,43.71977 -0.1255,0.056 -56.7453,-0.47345 -57.258,-0.53541 -0.2223,-0.0269 -5.6782,-14.74433 -13.5292,-36.49551 z"
|
||||
id="path6046"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:0.2983426;fill-rule:nonzero;stroke:none;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
transform="matrix(0.79657897,0.11742288,-0.14814182,0.631399,1011.2357,-412.24821)"
|
||||
id="g6048">
|
||||
<path
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z"
|
||||
id="path6050"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z"
|
||||
id="path6052"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z"
|
||||
id="path6054"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker5935)"
|
||||
d="m 1149.6323,91.991253 0,37.313637"
|
||||
id="path6056"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(360.00008,460)"
|
||||
id="g6235">
|
||||
<rect
|
||||
transform="matrix(1,0,-0.3959173,0.91828617,0,0)"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.41992331;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="rect6237"
|
||||
y="2.7099617"
|
||||
x="77.243813"
|
||||
height="182.83618"
|
||||
width="313.09872" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:0.2983426;fill-rule:nonzero;stroke:none;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path6239"
|
||||
d="m 187.13717,141.62175 c -7.23616,-20.04776 -13.54188,-37.48106 -14.01271,-38.74063 -3.30915,-8.852639 -3.7924,-18.06951 -1.22734,-23.40863 2.84478,-5.921356 8.47454,-8.88606 17.68557,-9.313448 4.32826,-0.20083 7.07051,-0.09252 10.1144,0.399498 3.49454,0.564856 5.4048,1.155131 8.35172,2.580712 2.84854,1.377989 5.55537,3.650555 7.10286,5.96335 2.12899,3.181858 13.60803,28.938928 24.88164,55.830298 8.13151,19.39637 18.05518,43.64654 17.89104,43.71977 -0.12552,0.056 -56.74536,-0.47345 -57.25799,-0.53541 -0.22232,-0.0269 -5.6782,-14.74433 -13.52919,-36.49551 z" />
|
||||
<g
|
||||
id="g6241"
|
||||
transform="matrix(0.79657897,0.11742288,-0.14814182,0.631399,28.295757,-432.54234)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path6243"
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 l -0.71428,0 -71.07143,12.14286 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path6245"
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
id="path6247"
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z" />
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6249"
|
||||
d="m 166.69233,71.697127 0,37.313633"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker5682);marker-end:url(#marker5674)" />
|
||||
</g>
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="138.85577"
|
||||
y="212.46516"
|
||||
id="text6269"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6271"
|
||||
x="138.85577"
|
||||
y="212.46516"
|
||||
style="font-size:22.5px">a) Tap</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text6273"
|
||||
y="212.46516"
|
||||
x="462.85577"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:22.5px"
|
||||
y="212.46516"
|
||||
x="462.85577"
|
||||
id="tspan6275"
|
||||
sodipodi:role="line">b) Hold down</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text6277"
|
||||
y="472.46515"
|
||||
x="136.85577"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:22.5px"
|
||||
y="472.46515"
|
||||
x="136.85577"
|
||||
id="tspan6279"
|
||||
sodipodi:role="line">c) Move</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="378.85577"
|
||||
y="472.46515"
|
||||
id="text6281"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6283"
|
||||
x="378.85577"
|
||||
y="472.46515"
|
||||
style="font-size:22.5px">d) Reset finger, move (optional)</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text6285"
|
||||
y="732.46515"
|
||||
x="436.85577"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:22.5px"
|
||||
y="732.46515"
|
||||
x="436.85577"
|
||||
id="tspan6287"
|
||||
sodipodi:role="line">f) Tap to end (optional)</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="122.85577"
|
||||
y="732.46515"
|
||||
id="text6289"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6291"
|
||||
x="122.85577"
|
||||
y="732.46515"
|
||||
style="font-size:22.5px">e) Release</tspan></text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 46 KiB |
213
doc/svg/top-software-buttons.svg
Normal file
213
doc/svg/top-software-buttons.svg
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
<?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"
|
||||
width="956.69696"
|
||||
height="207.31395"
|
||||
id="svg2"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="top-software-buttons.svg">
|
||||
<metadata
|
||||
id="metadata4314">
|
||||
<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>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1136"
|
||||
id="namedview4312"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.1559716"
|
||||
inkscape:cx="527.43768"
|
||||
inkscape:cy="31.469935"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:snap-page="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0">
|
||||
<sodipodi:guide
|
||||
position="126.62171,304.81443"
|
||||
orientation="0,1"
|
||||
id="guide4473" />
|
||||
<sodipodi:guide
|
||||
position="-59.334811,222.84675"
|
||||
orientation="1,0"
|
||||
id="guide4774" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs4" />
|
||||
<g
|
||||
id="g4776"
|
||||
transform="translate(0,33.753604)">
|
||||
<rect
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#222222;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.26503992;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="rect2858-0"
|
||||
y="-28.093496"
|
||||
x="2.63252"
|
||||
height="199.02132"
|
||||
width="271.43192" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4718"
|
||||
d="m 12.201667,-12.062569 97.876283,0.09937"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1.42133546;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.77900552" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1.42133546;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.77900552"
|
||||
d="m 166.20167,-12.062569 97.87628,0.09937"
|
||||
id="path4768"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4772"
|
||||
d="m 117.44622,-11.972768 41.59554,0"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.5999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.6, 5.2;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
id="g4800"
|
||||
transform="translate(340,33.753604)">
|
||||
<rect
|
||||
width="271.43192"
|
||||
height="199.02132"
|
||||
x="2.63252"
|
||||
y="-28.093496"
|
||||
id="rect4802"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#222222;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.26503992;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1.42133546;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.77900552"
|
||||
d="m 12.201667,-12.062569 97.876283,0.09937"
|
||||
id="path4804"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4806"
|
||||
d="m 166.20167,-12.062569 97.87628,0.09937"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1.42133546;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.77900552" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.5999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.6, 5.2;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 117.44622,-11.972768 41.59554,0"
|
||||
id="path4808"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g4835"
|
||||
transform="matrix(0.73822306,-0.67455668,0.67455668,0.73822306,537.11787,65.759499)"
|
||||
inkscape:transform-center-x="-34.439004"
|
||||
inkscape:transform-center-y="45.87469">
|
||||
<path
|
||||
d="M 65.88204,110.10383 39.621684,21.31208 c 0,0 -15.199155,-40.682325 13.783835,-43.694695 22.870506,-2.377059 28.308474,10.4407 29.693939,13.9424019 C 97.349439,27.575979 124.86389,110.86612 124.86389,110.86612 l -0.56898,-0.0839 -58.41287,-0.67842 z"
|
||||
id="path2820-6-6"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.72135597px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 53.156605,65.10762 C 45.92045,40.655669 39.614727,19.392552 39.143896,17.856259 35.834749,7.0588289 35.351503,-4.1828468 37.916556,-10.69489 c 2.844782,-7.222187 8.474545,-10.838191 17.685579,-11.35947 4.328257,-0.244949 7.070506,-0.112842 10.114398,0.487262 3.49454,0.688946 5.404793,1.408896 8.351719,3.147655 2.848538,1.680712 5.555366,4.452526 7.10286,7.273407 2.128991,3.8808629 13.608031,35.296377 24.881638,68.09537 8.13151,23.65746 18.05518,53.235016 17.89104,53.324326 -0.12552,0.0683 -56.745362,-0.57745 -57.257993,-0.65302 -0.222317,-0.0328 -5.678201,-17.983442 -13.529192,-44.51302 z"
|
||||
id="path2824-1-1"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.00144271;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 43.316663,17.257819 C 40.007515,6.4603886 39.107932,-0.92832907 41.672985,-7.4403722 c 2.844782,-7.2221878 7.10625,-9.8851248 16.317283,-10.4064038 10.448053,-0.80798 16.246136,1.144839 20.520953,8.7461155 5.300002,17.54581 6.371244,19.9188585 6.742033,24.1763215 -0.125516,0.06829 -36.465311,4.743495 -37.907409,4.984858 -1.48335,0.248267 -3.63121,-1.903 -4.029182,-2.8027 z"
|
||||
id="path2824-7-1-4"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(680,33.753604)"
|
||||
id="g4810">
|
||||
<rect
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#222222;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5.26503992;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="rect4812"
|
||||
y="-28.093496"
|
||||
x="2.63252"
|
||||
height="199.02132"
|
||||
width="271.43192" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4814"
|
||||
d="m 12.201667,-12.062569 97.876283,0.09937"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1.42133546;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.77900552" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:1.42133546;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.77900552"
|
||||
d="m 166.20167,-12.062569 97.87628,0.09937"
|
||||
id="path4816"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4818"
|
||||
d="m 117.44622,-11.972768 41.59554,0"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.5999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.6, 5.2;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
id="g4835-3"
|
||||
transform="matrix(0.85372372,-0.52072624,0.52072624,0.85372372,770.03163,57.741757)">
|
||||
<path
|
||||
d="M 65.88204,110.10383 39.621684,21.31208 c 0,0 -15.199155,-40.682325 13.783835,-43.694695 22.870506,-2.377059 28.308474,10.4407 29.693939,13.9424019 C 97.349439,27.575979 124.86389,110.86612 124.86389,110.86612 l -0.56898,-0.0839 -58.41287,-0.67842 z"
|
||||
id="path2820-6-6-7"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.72135597px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 53.156605,65.10762 C 45.92045,40.655669 39.614727,19.392552 39.143896,17.856259 35.834749,7.0588289 35.351503,-4.1828468 37.916556,-10.69489 c 2.844782,-7.222187 8.474545,-10.838191 17.685579,-11.35947 4.328257,-0.244949 7.070506,-0.112842 10.114398,0.487262 3.49454,0.688946 5.404793,1.408896 8.351719,3.147655 2.848538,1.680712 5.555366,4.452526 7.10286,7.273407 2.128991,3.8808629 13.608031,35.296377 24.881638,68.09537 8.13151,23.65746 18.05518,53.235016 17.89104,53.324326 -0.12552,0.0683 -56.745362,-0.57745 -57.257993,-0.65302 -0.222317,-0.0328 -5.678201,-17.983442 -13.529192,-44.51302 z"
|
||||
id="path2824-1-1-7"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.00144271;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 43.316663,17.257819 C 40.007515,6.4603886 39.107932,-0.92832907 41.672985,-7.4403722 c 2.844782,-7.2221878 7.10625,-9.8851248 16.317283,-10.4064038 10.448053,-0.80798 16.246136,1.144839 20.520953,8.7461155 5.300002,17.54581 6.371244,19.9188585 6.742033,24.1763215 -0.125516,0.06829 -36.465311,4.743495 -37.907409,4.984858 -1.48335,0.248267 -3.63121,-1.903 -4.029182,-2.8027 z"
|
||||
id="path2824-7-1-4-9"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g4835-0"
|
||||
transform="matrix(0.78868314,-0.61479989,0.61479989,0.78868314,7.9549192,61.170364)"
|
||||
inkscape:transform-center-x="-31.290987"
|
||||
inkscape:transform-center-y="47.742947">
|
||||
<path
|
||||
d="M 65.88204,110.10383 39.621684,21.31208 c 0,0 -15.199155,-40.682325 13.783835,-43.694695 22.870506,-2.377059 28.308474,10.4407 29.693939,13.9424019 C 97.349439,27.575979 124.86389,110.86612 124.86389,110.86612 l -0.56898,-0.0839 -58.41287,-0.67842 z"
|
||||
id="path2820-6-6-1"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.72135597px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 53.156605,65.10762 C 45.92045,40.655669 39.614727,19.392552 39.143896,17.856259 35.834749,7.0588289 35.351503,-4.1828468 37.916556,-10.69489 c 2.844782,-7.222187 8.474545,-10.838191 17.685579,-11.35947 4.328257,-0.244949 7.070506,-0.112842 10.114398,0.487262 3.49454,0.688946 5.404793,1.408896 8.351719,3.147655 2.848538,1.680712 5.555366,4.452526 7.10286,7.273407 2.128991,3.8808629 13.608031,35.296377 24.881638,68.09537 8.13151,23.65746 18.05518,53.235016 17.89104,53.324326 -0.12552,0.0683 -56.745362,-0.57745 -57.257993,-0.65302 -0.222317,-0.0328 -5.678201,-17.983442 -13.529192,-44.51302 z"
|
||||
id="path2824-1-1-0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.00144271;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 43.316663,17.257819 C 40.007515,6.4603886 39.107932,-0.92832907 41.672985,-7.4403722 c 2.844782,-7.2221878 7.10625,-9.8851248 16.317283,-10.4064038 10.448053,-0.80798 16.246136,1.144839 20.520953,8.7461155 5.300002,17.54581 6.371244,19.9188585 6.742033,24.1763215 -0.125516,0.06829 -36.465311,4.743495 -37.907409,4.984858 -1.48335,0.248267 -3.63121,-1.903 -4.029182,-2.8027 z"
|
||||
id="path2824-7-1-4-0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92000002;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 13 KiB |
|
|
@ -11,21 +11,10 @@ laptops had a separate set of physical buttons for the
|
|||
<a href="http://en.wikipedia.org/wiki/Pointing_stick">trackstick</a>. This
|
||||
series removed these buttons, relying on a software emulation of the top
|
||||
section of the touchpad. This is visually marked on the trackpad itself,
|
||||
approximately like this:
|
||||
and clicks can be triggered by pressing the touchpad down with a finger in
|
||||
the respective area:
|
||||
|
||||
@dot
|
||||
digraph G {
|
||||
subgraph cluster_0 {
|
||||
margin="0";
|
||||
|
||||
clickpad [
|
||||
shape = "record";
|
||||
color = "none";
|
||||
label = "{{LLLLLLLLLL|MMMMM|RRRRRRRRR}|\n\n\n\n\n\n\n\n|{LLLLLLLL| |RRRRRRRR}}";
|
||||
]
|
||||
}
|
||||
}
|
||||
@enddot
|
||||
@image html top-software-buttons.svg "Left, right and middle-button click with top software button areas"
|
||||
|
||||
This page only covers the top software buttons, the bottom button behavior
|
||||
is covered in @ref clickpad_softbuttons "Clickpad software buttons".
|
||||
|
|
@ -36,36 +25,77 @@ property.
|
|||
|
||||
@section t440_support_btn_size Size of the buttons
|
||||
|
||||
The size of the buttons matches the visual markings on this touchpad.
|
||||
The width of the left and right buttons is approximately 42% of the
|
||||
touchpad's width, the middle button is centered and assigned 16% of the
|
||||
touchpad width.
|
||||
|
||||
The line of the buttons is 5mm from the top edge of the touchpad,
|
||||
measurements of button presses showed that the size of the buttons needs to
|
||||
be approximately 10mm high to work reliable (especially when using the
|
||||
thumb to press the button).
|
||||
|
||||
The width of the left and right buttons is approximately 42% of the
|
||||
touchpad's width, the middle button is centered and should be assigned
|
||||
approximately 16% of the touchpad width.
|
||||
|
||||
@section t440_support_btn_behavior Button behavior
|
||||
|
||||
Movement in the top button area does not generate pointer movement. These
|
||||
buttons are not replacement buttons for the bottom button area but have
|
||||
their own behavior.
|
||||
Semantically attached to the trackstick device, libinput re-routes events
|
||||
from these buttons to appear through the trackstick device. The top button
|
||||
areas work even if the touchpad is disabled but will be disabled when the
|
||||
trackstick device is disabled.
|
||||
their own behavior. Semantically attached to the trackstick device, libinput
|
||||
re-routes events from these buttons to appear through the trackstick device.
|
||||
|
||||
If the finger starts inside the top area and moves outside the button area
|
||||
the finger is treated as dead and must be lifted to generate future buttons.
|
||||
Likewise, movement into the top button area does not trigger button events, a click
|
||||
has to start inside this area to take effect.
|
||||
@dot
|
||||
digraph top_button_routing
|
||||
{
|
||||
rankdir="LR";
|
||||
node [shape="box";]
|
||||
|
||||
trackstick [label="trackstick kernel device"];
|
||||
touchpad [label="touchpad kernel device"];
|
||||
|
||||
subgraph cluster0 {
|
||||
bgcolor = floralwhite
|
||||
label = "libinput"
|
||||
|
||||
libinput_ts [label="trackstick libinput_device"
|
||||
style=filled
|
||||
fillcolor=white];
|
||||
libinput_tp [label="touchpad libinput_device"
|
||||
style=filled
|
||||
fillcolor=white];
|
||||
|
||||
libinput_tp -> libinput_ts [constraint=false
|
||||
color="red4"];
|
||||
}
|
||||
|
||||
trackstick -> libinput_ts [arrowhead="none"]
|
||||
touchpad -> libinput_tp [color="red4"]
|
||||
|
||||
events_tp [label="other touchpad events"];
|
||||
events_topbutton [label="top sofware button events"];
|
||||
|
||||
libinput_tp -> events_tp [arrowhead="none"]
|
||||
libinput_ts -> events_topbutton [color="red4"]
|
||||
}
|
||||
@enddot
|
||||
|
||||
|
||||
The top button areas work even if the touchpad is disabled but will be
|
||||
disabled when the trackstick device is disabled. If the finger starts inside
|
||||
the top area and moves outside the button area the finger is treated as dead
|
||||
and must be lifted to generate future buttons. Likewise, movement into the
|
||||
top button area does not trigger button events, a click has to start inside
|
||||
this area to take effect.
|
||||
|
||||
@section t440_support_identification Kernel support
|
||||
|
||||
The firmware on touchpads providing top software buttons is buggy and
|
||||
announces wrong ranges. <a href="https://lkml.org/lkml/2014/3/7/722">Kernel
|
||||
patches</a> are required; these fixes are available in kernels
|
||||
3.14.1, 3.15 and later but each touchpad needs a separate fix.
|
||||
The firmware on the first generation of touchpads providing top software
|
||||
buttons is buggy and announces wrong ranges.
|
||||
<a href="https://lkml.org/lkml/2014/3/7/722">Kernel patches</a> are required;
|
||||
these fixes are available in kernels 3.14.1, 3.15 and later but each
|
||||
touchpad needs a separate fix.
|
||||
|
||||
The October 2014 refresh of these laptops do not have this firmware bug
|
||||
anymore and should work without per-device patches, though
|
||||
<a href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=02e07492cdfae9c86e3bd21c0beec88dbcc1e9e8">this kernel commit</a> is required.
|
||||
|
||||
For a complete list of supported touchpads check <a
|
||||
href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/input/mouse/synaptics.c">the
|
||||
|
|
|
|||
|
|
@ -27,15 +27,22 @@ libinput_device_config_tap_set_enabled() for details.
|
|||
|
||||
libinput also supports "tap-and-drag" where a tap immediately followed by a
|
||||
finger down and that finger being held down emulates a button press. Moving
|
||||
the finger around can thus drag the selected item on the screen. Lifting the
|
||||
finger and putting it back down immediately (i.e. within the timeout) will
|
||||
continue the dragging process, so that multiple touchpad-widths of distance
|
||||
can be covered easily. If two-fingers are supported by the hardware, a
|
||||
second finger can be used to drag while the first is held in-place.
|
||||
the finger around can thus drag the selected item on the screen.
|
||||
|
||||
An alternative method to end a drag process is to tap immediately after
|
||||
lifting the finger. The full sequence is thus: tap, finger down, drag,
|
||||
finger up, tap.
|
||||
@image html tap-n-drag.svg "Tap-and-drag process"
|
||||
|
||||
The above diagram explains the process, a tap (a) followed by a finger held
|
||||
down (b) starts the drag process and logically holds the left mouse button
|
||||
down. A movement of the finger (c) will drag the selected item until the
|
||||
finger is relased (e). If needed, the finger's position can be reset by
|
||||
lifting and quickly setting it down again on the touchpad (d). This will be
|
||||
interpreted as continuing move and is especially useful on small touchpads
|
||||
or with slow pointer acceleration.
|
||||
The release of the mouse buttons after the finger release (e) is triggered
|
||||
by a timeout. To release the button immediately, simply tap again (f).
|
||||
|
||||
If two fingers are supported by the hardware, a second finger can be used to
|
||||
drag while the first is held in-place.
|
||||
|
||||
@section tap_constraints Constraints while tapping
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2014 Red Hat, Inc.
|
||||
* Copyright © 2014-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
|
|
@ -20,6 +20,8 @@
|
|||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "evdev.h"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2014 Red Hat, Inc.
|
||||
* Copyright © 2014-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
|
|
@ -20,6 +20,8 @@
|
|||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
|
@ -392,7 +394,7 @@ tp_button_handle_event(struct tp_dispatch *tp,
|
|||
enum button_event event,
|
||||
uint64_t time)
|
||||
{
|
||||
struct libinput *libinput = tp->device->base.seat->libinput;
|
||||
struct libinput *libinput = tp_libinput_context(tp);
|
||||
enum button_state current = t->button.state;
|
||||
|
||||
switch(t->button.state) {
|
||||
|
|
@ -478,7 +480,7 @@ tp_process_button(struct tp_dispatch *tp,
|
|||
const struct input_event *e,
|
||||
uint64_t time)
|
||||
{
|
||||
struct libinput *libinput = tp->device->base.seat->libinput;
|
||||
struct libinput *libinput = tp_libinput_context(tp);
|
||||
uint32_t mask = 1 << (e->code - BTN_LEFT);
|
||||
|
||||
/* Ignore other buttons on clickpads */
|
||||
|
|
@ -680,7 +682,7 @@ int
|
|||
tp_init_buttons(struct tp_dispatch *tp,
|
||||
struct evdev_device *device)
|
||||
{
|
||||
struct libinput *libinput = tp->device->base.seat->libinput;
|
||||
struct libinput *libinput = tp_libinput_context(tp);
|
||||
struct tp_touch *t;
|
||||
int width, height;
|
||||
double diagonal;
|
||||
|
|
@ -731,7 +733,7 @@ tp_init_buttons(struct tp_dispatch *tp,
|
|||
tp_for_each_touch(tp, t) {
|
||||
t->button.state = BUTTON_STATE_NONE;
|
||||
libinput_timer_init(&t->button.timer,
|
||||
tp->device->base.seat->libinput,
|
||||
tp_libinput_context(tp),
|
||||
tp_button_handle_timeout, t);
|
||||
}
|
||||
|
||||
|
|
@ -782,6 +784,104 @@ tp_post_physical_buttons(struct tp_dispatch *tp, uint64_t time)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
tp_check_clickfinger_distance(struct tp_dispatch *tp,
|
||||
struct tp_touch *t1,
|
||||
struct tp_touch *t2)
|
||||
{
|
||||
double x, y;
|
||||
|
||||
if (!t1 || !t2)
|
||||
return 0;
|
||||
|
||||
x = abs(t1->point.x - t2->point.x);
|
||||
y = abs(t1->point.y - t2->point.y);
|
||||
|
||||
/* no resolution, so let's assume they're close enough together */
|
||||
if (tp->device->abs.fake_resolution) {
|
||||
int w, h;
|
||||
|
||||
/* Use a maximum of 30% of the touchpad width or height if
|
||||
* we dont' have resolution. */
|
||||
w = tp->device->abs.absinfo_x->maximum -
|
||||
tp->device->abs.absinfo_x->minimum;
|
||||
h = tp->device->abs.absinfo_y->maximum -
|
||||
tp->device->abs.absinfo_y->minimum;
|
||||
|
||||
return (x < w * 0.3 && y < h * 0.3) ? 1 : 0;
|
||||
} else {
|
||||
/* maximum spread is 40mm horiz, 20mm vert. Anything wider than that
|
||||
* is probably a gesture. The y spread is small so we ignore clicks
|
||||
* with thumbs at the bottom of the touchpad while the pointer
|
||||
* moving finger is still on the pad */
|
||||
|
||||
x /= tp->device->abs.absinfo_x->resolution;
|
||||
y /= tp->device->abs.absinfo_y->resolution;
|
||||
|
||||
return (x < 40 && y < 20) ? 1 : 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
tp_clickfinger_set_button(struct tp_dispatch *tp)
|
||||
{
|
||||
uint32_t button;
|
||||
unsigned int nfingers = tp->nfingers_down;
|
||||
struct tp_touch *t;
|
||||
struct tp_touch *first = NULL,
|
||||
*second = NULL,
|
||||
*third = NULL;
|
||||
uint32_t close_touches = 0;
|
||||
|
||||
if (nfingers < 2 || nfingers > 3)
|
||||
goto out;
|
||||
|
||||
/* two or three fingers down on the touchpad. Check for distance
|
||||
* between the fingers. */
|
||||
tp_for_each_touch(tp, t) {
|
||||
if (t->state != TOUCH_BEGIN && t->state != TOUCH_UPDATE)
|
||||
continue;
|
||||
|
||||
if (!first)
|
||||
first = t;
|
||||
else if (!second)
|
||||
second = t;
|
||||
else if (!third) {
|
||||
third = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!first || !second) {
|
||||
nfingers = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
close_touches |= tp_check_clickfinger_distance(tp, first, second) << 0;
|
||||
close_touches |= tp_check_clickfinger_distance(tp, second, third) << 1;
|
||||
close_touches |= tp_check_clickfinger_distance(tp, first, third) << 2;
|
||||
|
||||
switch(__builtin_popcount(close_touches)) {
|
||||
case 0: nfingers = 1; break;
|
||||
case 1: nfingers = 2; break;
|
||||
default: nfingers = 3; break;
|
||||
}
|
||||
|
||||
out:
|
||||
switch (nfingers) {
|
||||
case 0:
|
||||
case 1: button = BTN_LEFT; break;
|
||||
case 2: button = BTN_RIGHT; break;
|
||||
case 3: button = BTN_MIDDLE; break;
|
||||
default:
|
||||
button = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
static int
|
||||
tp_notify_clickpadbutton(struct tp_dispatch *tp,
|
||||
uint64_t time,
|
||||
|
|
@ -816,14 +916,7 @@ tp_notify_clickpadbutton(struct tp_dispatch *tp,
|
|||
*/
|
||||
if (tp->buttons.click_method == LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER &&
|
||||
state == LIBINPUT_BUTTON_STATE_PRESSED) {
|
||||
switch (tp->nfingers_down) {
|
||||
case 0:
|
||||
case 1: button = BTN_LEFT; break;
|
||||
case 2: button = BTN_RIGHT; break;
|
||||
case 3: button = BTN_MIDDLE; break;
|
||||
default:
|
||||
button = 0;
|
||||
}
|
||||
button = tp_clickfinger_set_button(tp);
|
||||
tp->buttons.active = button;
|
||||
|
||||
if (!button)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2014 Red Hat, Inc.
|
||||
* Copyright © 2014-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
|
|
@ -20,6 +20,8 @@
|
|||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
|
@ -121,7 +123,7 @@ tp_edge_scroll_handle_none(struct tp_dispatch *tp,
|
|||
struct tp_touch *t,
|
||||
enum scroll_event event)
|
||||
{
|
||||
struct libinput *libinput = tp->device->base.seat->libinput;
|
||||
struct libinput *libinput = tp_libinput_context(tp);
|
||||
|
||||
switch (event) {
|
||||
case SCROLL_EVENT_TOUCH:
|
||||
|
|
@ -149,7 +151,7 @@ tp_edge_scroll_handle_edge_new(struct tp_dispatch *tp,
|
|||
struct tp_touch *t,
|
||||
enum scroll_event event)
|
||||
{
|
||||
struct libinput *libinput = tp->device->base.seat->libinput;
|
||||
struct libinput *libinput = tp_libinput_context(tp);
|
||||
|
||||
switch (event) {
|
||||
case SCROLL_EVENT_TOUCH:
|
||||
|
|
@ -178,7 +180,7 @@ tp_edge_scroll_handle_edge(struct tp_dispatch *tp,
|
|||
struct tp_touch *t,
|
||||
enum scroll_event event)
|
||||
{
|
||||
struct libinput *libinput = tp->device->base.seat->libinput;
|
||||
struct libinput *libinput = tp_libinput_context(tp);
|
||||
|
||||
switch (event) {
|
||||
case SCROLL_EVENT_TOUCH:
|
||||
|
|
@ -209,7 +211,7 @@ tp_edge_scroll_handle_area(struct tp_dispatch *tp,
|
|||
struct tp_touch *t,
|
||||
enum scroll_event event)
|
||||
{
|
||||
struct libinput *libinput = tp->device->base.seat->libinput;
|
||||
struct libinput *libinput = tp_libinput_context(tp);
|
||||
|
||||
switch (event) {
|
||||
case SCROLL_EVENT_TOUCH:
|
||||
|
|
@ -232,7 +234,7 @@ tp_edge_scroll_handle_event(struct tp_dispatch *tp,
|
|||
struct tp_touch *t,
|
||||
enum scroll_event event)
|
||||
{
|
||||
struct libinput *libinput = tp->device->base.seat->libinput;
|
||||
struct libinput *libinput = tp_libinput_context(tp);
|
||||
enum tp_edge_scroll_touch_state current = t->scroll.edge_state;
|
||||
|
||||
switch (current) {
|
||||
|
|
@ -301,7 +303,7 @@ tp_edge_scroll_init(struct tp_dispatch *tp, struct evdev_device *device)
|
|||
tp_for_each_touch(tp, t) {
|
||||
t->scroll.direction = -1;
|
||||
libinput_timer_init(&t->scroll.timer,
|
||||
device->base.seat->libinput,
|
||||
tp_libinput_context(tp),
|
||||
tp_edge_scroll_handle_timeout, t);
|
||||
}
|
||||
|
||||
|
|
@ -361,6 +363,9 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
|
|||
if (!t->dirty)
|
||||
continue;
|
||||
|
||||
if (t->palm.state != PALM_NONE)
|
||||
continue;
|
||||
|
||||
switch (t->scroll.edge) {
|
||||
case EDGE_NONE:
|
||||
if (t->scroll.direction != -1) {
|
||||
|
|
@ -438,6 +443,10 @@ tp_edge_scroll_stop_events(struct tp_dispatch *tp, uint64_t time)
|
|||
&zero,
|
||||
&zero_discrete);
|
||||
t->scroll.direction = -1;
|
||||
/* reset touch to area state, avoids loading the
|
||||
* state machine with special case handling */
|
||||
t->scroll.edge = EDGE_NONE;
|
||||
t->scroll.edge_state = EDGE_SCROLL_TOUCH_STATE_AREA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2013 Red Hat, Inc.
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
#define CASE_RETURN_STRING(a) case a: return #a
|
||||
|
||||
#define DEFAULT_TAP_TIMEOUT_PERIOD 180
|
||||
#define DEFAULT_DRAG_TIMEOUT_PERIOD 500
|
||||
#define DEFAULT_DRAG_TIMEOUT_PERIOD 300
|
||||
#define DEFAULT_TAP_MOVE_THRESHOLD TP_MM_TO_DPI_NORMALIZED(3)
|
||||
|
||||
enum tap_event {
|
||||
|
|
@ -147,7 +147,7 @@ tp_tap_idle_handle_event(struct tp_dispatch *tp,
|
|||
struct tp_touch *t,
|
||||
enum tap_event event, uint64_t time)
|
||||
{
|
||||
struct libinput *libinput = tp->device->base.seat->libinput;
|
||||
struct libinput *libinput = tp_libinput_context(tp);
|
||||
|
||||
switch (event) {
|
||||
case TAP_EVENT_TOUCH:
|
||||
|
|
@ -223,7 +223,7 @@ tp_tap_tapped_handle_event(struct tp_dispatch *tp,
|
|||
struct tp_touch *t,
|
||||
enum tap_event event, uint64_t time)
|
||||
{
|
||||
struct libinput *libinput = tp->device->base.seat->libinput;
|
||||
struct libinput *libinput = tp_libinput_context(tp);
|
||||
|
||||
switch (event) {
|
||||
case TAP_EVENT_MOTION:
|
||||
|
|
@ -483,7 +483,7 @@ tp_tap_multitap_handle_event(struct tp_dispatch *tp,
|
|||
struct tp_touch *t,
|
||||
enum tap_event event, uint64_t time)
|
||||
{
|
||||
struct libinput *libinput = tp->device->base.seat->libinput;
|
||||
struct libinput *libinput = tp_libinput_context(tp);
|
||||
|
||||
switch (event) {
|
||||
case TAP_EVENT_RELEASE:
|
||||
|
|
@ -576,7 +576,7 @@ tp_tap_handle_event(struct tp_dispatch *tp,
|
|||
enum tap_event event,
|
||||
uint64_t time)
|
||||
{
|
||||
struct libinput *libinput = tp->device->base.seat->libinput;
|
||||
struct libinput *libinput = tp_libinput_context(tp);
|
||||
enum tp_tap_state current;
|
||||
|
||||
current = tp->tap.state;
|
||||
|
|
@ -857,7 +857,7 @@ tp_init_tap(struct tp_dispatch *tp)
|
|||
tp->tap.enabled = tp_tap_default(tp->device);
|
||||
|
||||
libinput_timer_init(&tp->tap.timer,
|
||||
tp->device->base.seat->libinput,
|
||||
tp_libinput_context(tp),
|
||||
tp_tap_handle_timeout, tp);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2014 Red Hat, Inc.
|
||||
* Copyright © 2014-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
|
|
@ -237,6 +237,7 @@ tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
t->state = TOUCH_END;
|
||||
t->pinned.is_pinned = false;
|
||||
t->millis = time;
|
||||
t->palm.time = 0;
|
||||
assert(tp->nfingers_down >= 1);
|
||||
tp->nfingers_down--;
|
||||
tp->queued |= TOUCHPAD_EVENT_MOTION;
|
||||
|
|
@ -310,6 +311,7 @@ tp_process_absolute(struct tp_dispatch *tp,
|
|||
tp_new_touch(tp, t, time);
|
||||
else
|
||||
tp_end_sequence(tp, t, time);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -475,12 +477,45 @@ tp_palm_tap_is_palm(struct tp_dispatch *tp, struct tp_touch *t)
|
|||
|
||||
/* We're inside the left/right palm edge and in the northern half of
|
||||
* the touchpad - this tap is a palm */
|
||||
if (t->point.y < tp->palm.vert_center)
|
||||
if (t->point.y < tp->palm.vert_center) {
|
||||
log_debug(tp_libinput_context(tp),
|
||||
"palm: palm-tap detected\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
tp_palm_detect_dwt(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
{
|
||||
if (tp->dwt.keyboard_active &&
|
||||
t->state == TOUCH_BEGIN) {
|
||||
t->palm.state = PALM_TYPING;
|
||||
t->palm.time = time;
|
||||
t->palm.first = t->point;
|
||||
return 1;
|
||||
} else if (!tp->dwt.keyboard_active &&
|
||||
t->state == TOUCH_UPDATE &&
|
||||
t->palm.state == PALM_TYPING)
|
||||
{
|
||||
/* If a touch has started before the first or after the last
|
||||
key press, release it on timeout. Benefit: a palm rested
|
||||
while typing on the touchpad will be ignored, but a touch
|
||||
started once we stop typing will be able to control the
|
||||
pointer (alas not tap, etc.).
|
||||
*/
|
||||
if (t->palm.time == 0 ||
|
||||
t->palm.time > tp->dwt.keyboard_last_press_time) {
|
||||
t->palm.state = PALM_NONE;
|
||||
log_debug(tp_libinput_context(tp),
|
||||
"palm: touch released, timeout after typing\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
{
|
||||
|
|
@ -489,13 +524,8 @@ tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
struct device_float_coords delta;
|
||||
int dirs;
|
||||
|
||||
if (tp->sendevents.keyboard_active &&
|
||||
t->state == TOUCH_BEGIN) {
|
||||
t->palm.state = PALM_TYPING;
|
||||
t->palm.time = time;
|
||||
t->palm.first = t->point;
|
||||
return;
|
||||
}
|
||||
if (tp_palm_detect_dwt(tp, t, time))
|
||||
goto out;
|
||||
|
||||
/* If labelled a touch as palm, we unlabel as palm when
|
||||
we move out of the palm edge zone within the timeout, provided
|
||||
|
|
@ -509,6 +539,8 @@ tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
tp_normalize_delta(tp, delta));
|
||||
if ((dirs & DIRECTIONS) && !(dirs & ~DIRECTIONS)) {
|
||||
t->palm.state = PALM_NONE;
|
||||
log_debug(tp_libinput_context(tp),
|
||||
"palm: touch released, out of edge zone\n");
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
@ -530,6 +562,11 @@ tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
t->palm.state = PALM_EDGE;
|
||||
t->palm.time = time;
|
||||
t->palm.first = t->point;
|
||||
|
||||
out:
|
||||
log_debug(tp_libinput_context(tp),
|
||||
"palm: palm detected (%s)\n",
|
||||
t->palm.state == PALM_EDGE ? "edge" : "typing");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -717,7 +754,7 @@ tp_post_events(struct tp_dispatch *tp, uint64_t time)
|
|||
|
||||
if (filter_motion ||
|
||||
tp->sendevents.trackpoint_active ||
|
||||
tp->sendevents.keyboard_active) {
|
||||
tp->dwt.keyboard_active) {
|
||||
tp_edge_scroll_stop_events(tp, time);
|
||||
tp_gesture_stop(tp, time);
|
||||
return;
|
||||
|
|
@ -767,15 +804,15 @@ static void
|
|||
tp_remove_sendevents(struct tp_dispatch *tp)
|
||||
{
|
||||
libinput_timer_cancel(&tp->sendevents.trackpoint_timer);
|
||||
libinput_timer_cancel(&tp->sendevents.keyboard_timer);
|
||||
libinput_timer_cancel(&tp->dwt.keyboard_timer);
|
||||
|
||||
if (tp->buttons.trackpoint)
|
||||
libinput_device_remove_event_listener(
|
||||
&tp->sendevents.trackpoint_listener);
|
||||
|
||||
if (tp->sendevents.keyboard)
|
||||
if (tp->dwt.keyboard)
|
||||
libinput_device_remove_event_listener(
|
||||
&tp->sendevents.keyboard_listener);
|
||||
&tp->dwt.keyboard_listener);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -810,7 +847,7 @@ tp_release_fake_touches(struct tp_dispatch *tp)
|
|||
static void
|
||||
tp_clear_state(struct tp_dispatch *tp)
|
||||
{
|
||||
uint64_t now = libinput_now(tp->device->base.seat->libinput);
|
||||
uint64_t now = libinput_now(tp_libinput_context(tp));
|
||||
struct tp_touch *t;
|
||||
|
||||
/* Unroll the touchpad state.
|
||||
|
|
@ -912,7 +949,41 @@ tp_keyboard_timeout(uint64_t now, void *data)
|
|||
struct tp_dispatch *tp = data;
|
||||
|
||||
tp_tap_resume(tp, now);
|
||||
tp->sendevents.keyboard_active = false;
|
||||
|
||||
tp->dwt.keyboard_active = false;
|
||||
|
||||
log_debug(tp_libinput_context(tp), "palm: keyboard timeout\n");
|
||||
}
|
||||
|
||||
static inline bool
|
||||
tp_key_ignore_for_dwt(unsigned int keycode)
|
||||
{
|
||||
switch (keycode) {
|
||||
/* Ignore modifiers to be responsive to ctrl-click, alt-tab, etc. */
|
||||
case KEY_LEFTCTRL:
|
||||
case KEY_RIGHTCTRL:
|
||||
case KEY_LEFTALT:
|
||||
case KEY_RIGHTALT:
|
||||
case KEY_LEFTSHIFT:
|
||||
case KEY_RIGHTSHIFT:
|
||||
case KEY_FN:
|
||||
case KEY_CAPSLOCK:
|
||||
case KEY_TAB:
|
||||
case KEY_COMPOSE:
|
||||
case KEY_RIGHTMETA:
|
||||
case KEY_LEFTMETA:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Ignore keys not part of the "typewriter set", i.e. F-keys,
|
||||
* multimedia keys, numpad, etc.
|
||||
*/
|
||||
if (keycode >= KEY_F1)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -934,42 +1005,61 @@ tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
|
|||
|
||||
/* modifier keys don't trigger disable-while-typing so things like
|
||||
* ctrl+zoom or ctrl+click are possible */
|
||||
switch (libinput_event_keyboard_get_key(kbdev)) {
|
||||
case KEY_LEFTCTRL:
|
||||
case KEY_RIGHTCTRL:
|
||||
case KEY_LEFTALT:
|
||||
case KEY_RIGHTALT:
|
||||
case KEY_LEFTSHIFT:
|
||||
case KEY_RIGHTSHIFT:
|
||||
case KEY_FN:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (tp_key_ignore_for_dwt(libinput_event_keyboard_get_key(kbdev)))
|
||||
return;
|
||||
|
||||
if (!tp->sendevents.keyboard_active) {
|
||||
if (!tp->dwt.keyboard_active) {
|
||||
tp_edge_scroll_stop_events(tp, time);
|
||||
tp_gesture_stop(tp, time);
|
||||
tp_tap_suspend(tp, time);
|
||||
tp->sendevents.keyboard_active = true;
|
||||
tp->dwt.keyboard_active = true;
|
||||
timeout = DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_1;
|
||||
} else {
|
||||
timeout = DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2;
|
||||
}
|
||||
|
||||
libinput_timer_set(&tp->sendevents.keyboard_timer,
|
||||
tp->dwt.keyboard_last_press_time = time;
|
||||
libinput_timer_set(&tp->dwt.keyboard_timer,
|
||||
time + timeout);
|
||||
}
|
||||
|
||||
static bool
|
||||
tp_want_dwt(struct evdev_device *touchpad,
|
||||
struct evdev_device *keyboard)
|
||||
{
|
||||
unsigned int bus_tp = libevdev_get_id_bustype(touchpad->evdev),
|
||||
bus_kbd = libevdev_get_id_bustype(keyboard->evdev);
|
||||
|
||||
if (bus_tp == BUS_BLUETOOTH || bus_kbd == BUS_BLUETOOTH)
|
||||
return false;
|
||||
|
||||
/* evemu will set the right bus type */
|
||||
if (bus_tp == BUS_VIRTUAL || bus_kbd == BUS_VIRTUAL)
|
||||
return false;
|
||||
|
||||
/* If the touchpad is on serio, the keyboard is too, so ignore any
|
||||
other devices */
|
||||
if (bus_tp == BUS_I8042 && bus_kbd != bus_tp)
|
||||
return false;
|
||||
|
||||
/* Wacom makes touchpads, but not internal ones */
|
||||
if (libevdev_get_id_vendor(touchpad->evdev) == VENDOR_ID_WACOM)
|
||||
return false;
|
||||
|
||||
/* everything else we don't really know, so we have to assume
|
||||
they go together */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
tp_interface_device_added(struct evdev_device *device,
|
||||
struct evdev_device *added_device)
|
||||
{
|
||||
struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
|
||||
unsigned int bus_tp = libevdev_get_id_bustype(device->evdev),
|
||||
bus_trp = libevdev_get_id_bustype(added_device->evdev),
|
||||
bus_kbd = libevdev_get_id_bustype(added_device->evdev);
|
||||
bool tp_is_internal, trp_is_internal, kbd_is_internal;
|
||||
bus_trp = libevdev_get_id_bustype(added_device->evdev);
|
||||
bool tp_is_internal, trp_is_internal;
|
||||
|
||||
tp_is_internal = bus_tp != BUS_USB && bus_tp != BUS_BLUETOOTH;
|
||||
trp_is_internal = bus_trp != BUS_USB && bus_trp != BUS_BLUETOOTH;
|
||||
|
|
@ -985,16 +1075,19 @@ tp_interface_device_added(struct evdev_device *device,
|
|||
tp_trackpoint_event, tp);
|
||||
}
|
||||
|
||||
/* FIXME: detect external keyboard better */
|
||||
kbd_is_internal = bus_tp != BUS_BLUETOOTH &&
|
||||
bus_kbd == bus_tp;
|
||||
if (tp_is_internal && kbd_is_internal &&
|
||||
tp->sendevents.keyboard == NULL) {
|
||||
if (added_device->tags & EVDEV_TAG_KEYBOARD &&
|
||||
tp->dwt.keyboard == NULL &&
|
||||
tp_want_dwt(device, added_device)) {
|
||||
log_debug(tp_libinput_context(tp),
|
||||
"palm: dwt activated with %s<->%s\n",
|
||||
device->devname,
|
||||
added_device->devname);
|
||||
|
||||
libinput_device_add_event_listener(&added_device->base,
|
||||
&tp->sendevents.keyboard_listener,
|
||||
&tp->dwt.keyboard_listener,
|
||||
tp_keyboard_event, tp);
|
||||
tp->sendevents.keyboard = added_device;
|
||||
tp->sendevents.keyboard_active = false;
|
||||
tp->dwt.keyboard = added_device;
|
||||
tp->dwt.keyboard_active = false;
|
||||
}
|
||||
|
||||
if (tp->sendevents.current_mode !=
|
||||
|
|
@ -1023,10 +1116,10 @@ tp_interface_device_removed(struct evdev_device *device,
|
|||
tp->buttons.trackpoint = NULL;
|
||||
}
|
||||
|
||||
if (removed_device == tp->sendevents.keyboard) {
|
||||
if (removed_device == tp->dwt.keyboard) {
|
||||
libinput_device_remove_event_listener(
|
||||
&tp->sendevents.keyboard_listener);
|
||||
tp->sendevents.keyboard = NULL;
|
||||
&tp->dwt.keyboard_listener);
|
||||
tp->dwt.keyboard = NULL;
|
||||
}
|
||||
|
||||
if (tp->sendevents.current_mode !=
|
||||
|
|
@ -1044,9 +1137,9 @@ tp_interface_device_removed(struct evdev_device *device,
|
|||
tp_resume(tp, device);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_interface_tag_device(struct evdev_device *device,
|
||||
struct udev_device *udev_device)
|
||||
void
|
||||
evdev_tag_touchpad(struct evdev_device *device,
|
||||
struct udev_device *udev_device)
|
||||
{
|
||||
int bustype;
|
||||
|
||||
|
|
@ -1076,7 +1169,6 @@ static struct evdev_dispatch_interface tp_interface = {
|
|||
tp_interface_device_removed,
|
||||
tp_interface_device_removed, /* device_suspended, treat as remove */
|
||||
tp_interface_device_added, /* device_resumed, treat as add */
|
||||
tp_interface_tag_device,
|
||||
NULL, /* post_added */
|
||||
};
|
||||
|
||||
|
|
@ -1182,7 +1274,7 @@ tp_init_accel(struct tp_dispatch *tp, double diagonal)
|
|||
* and y resolution, so that a circle on the
|
||||
* touchpad does not turn into an elipse on the screen.
|
||||
*/
|
||||
if (res_x > 1 && res_y > 1) {
|
||||
if (!tp->device->abs.fake_resolution) {
|
||||
tp->accel.x_scale_coeff = (DEFAULT_MOUSE_DPI/25.4) / res_x;
|
||||
tp->accel.y_scale_coeff = (DEFAULT_MOUSE_DPI/25.4) / res_y;
|
||||
} else {
|
||||
|
|
@ -1231,7 +1323,7 @@ tp_scroll_config_scroll_method_set_method(struct libinput_device *device,
|
|||
{
|
||||
struct evdev_device *evdev = (struct evdev_device*)device;
|
||||
struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
|
||||
uint64_t time = libinput_now(device->seat->libinput);
|
||||
uint64_t time = libinput_now(tp_libinput_context(tp));
|
||||
|
||||
if (method == tp->scroll.method)
|
||||
return LIBINPUT_CONFIG_STATUS_SUCCESS;
|
||||
|
|
@ -1297,6 +1389,7 @@ tp_init_palmdetect(struct tp_dispatch *tp,
|
|||
struct evdev_device *device)
|
||||
{
|
||||
int width, height;
|
||||
unsigned int vendor_id;
|
||||
|
||||
tp->palm.right_edge = INT_MAX;
|
||||
tp->palm.left_edge = INT_MIN;
|
||||
|
|
@ -1307,8 +1400,13 @@ tp_init_palmdetect(struct tp_dispatch *tp,
|
|||
height = abs(device->abs.absinfo_y->maximum -
|
||||
device->abs.absinfo_y->minimum);
|
||||
|
||||
/* Apple touchpads are always big enough to warrant palm detection */
|
||||
if (evdev_device_get_id_vendor(device) != VENDOR_ID_APPLE) {
|
||||
vendor_id = evdev_device_get_id_vendor(device);
|
||||
|
||||
/* Wacom doesn't have internal touchpads,
|
||||
* Apple touchpads are always big enough to warrant palm detection */
|
||||
if (vendor_id == VENDOR_ID_WACOM) {
|
||||
return 0;
|
||||
} else if (vendor_id != VENDOR_ID_APPLE) {
|
||||
/* We don't know how big the touchpad is */
|
||||
if (device->abs.absinfo_x->resolution == 1)
|
||||
return 0;
|
||||
|
|
@ -1332,15 +1430,39 @@ tp_init_sendevents(struct tp_dispatch *tp,
|
|||
struct evdev_device *device)
|
||||
{
|
||||
libinput_timer_init(&tp->sendevents.trackpoint_timer,
|
||||
tp->device->base.seat->libinput,
|
||||
tp_libinput_context(tp),
|
||||
tp_trackpoint_timeout, tp);
|
||||
|
||||
libinput_timer_init(&tp->sendevents.keyboard_timer,
|
||||
tp->device->base.seat->libinput,
|
||||
libinput_timer_init(&tp->dwt.keyboard_timer,
|
||||
tp_libinput_context(tp),
|
||||
tp_keyboard_timeout, tp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tp_sanity_check(struct tp_dispatch *tp,
|
||||
struct evdev_device *device)
|
||||
{
|
||||
struct libevdev *evdev = device->evdev;
|
||||
struct libinput *libinput = tp_libinput_context(tp);
|
||||
|
||||
if (!libevdev_has_event_code(evdev, EV_ABS, ABS_X))
|
||||
goto error;
|
||||
|
||||
if (!libevdev_has_event_code(evdev, EV_KEY, BTN_TOUCH))
|
||||
goto error;
|
||||
|
||||
if (!libevdev_has_event_code(evdev, EV_KEY, BTN_TOOL_FINGER))
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
log_bug_kernel(libinput,
|
||||
"device %s failed touchpad sanity checks\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
tp_init(struct tp_dispatch *tp,
|
||||
struct evdev_device *device)
|
||||
|
|
@ -1351,6 +1473,9 @@ tp_init(struct tp_dispatch *tp,
|
|||
tp->base.interface = &tp_interface;
|
||||
tp->device = device;
|
||||
|
||||
if (tp_sanity_check(tp, device) != 0)
|
||||
return -1;
|
||||
|
||||
if (tp_init_slots(tp, device) != 0)
|
||||
return -1;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2014 Red Hat, Inc.
|
||||
* Copyright © 2014-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
|
|
@ -32,8 +32,6 @@
|
|||
#define TOUCHPAD_HISTORY_LENGTH 4
|
||||
#define TOUCHPAD_MIN_SAMPLES 4
|
||||
|
||||
#define VENDOR_ID_APPLE 0x5ac
|
||||
|
||||
/* Convert mm to a distance normalized to DEFAULT_MOUSE_DPI */
|
||||
#define TP_MM_TO_DPI_NORMALIZED(mm) (DEFAULT_MOUSE_DPI/25.4 * mm)
|
||||
|
||||
|
|
@ -282,17 +280,27 @@ struct tp_dispatch {
|
|||
bool trackpoint_active;
|
||||
struct libinput_event_listener trackpoint_listener;
|
||||
struct libinput_timer trackpoint_timer;
|
||||
} sendevents;
|
||||
|
||||
struct {
|
||||
bool keyboard_active;
|
||||
struct libinput_event_listener keyboard_listener;
|
||||
struct libinput_timer keyboard_timer;
|
||||
struct evdev_device *keyboard;
|
||||
} sendevents;
|
||||
|
||||
uint64_t keyboard_last_press_time;
|
||||
} dwt;
|
||||
};
|
||||
|
||||
#define tp_for_each_touch(_tp, _t) \
|
||||
for (unsigned int _i = 0; _i < (_tp)->ntouches && (_t = &(_tp)->touches[_i]); _i++)
|
||||
|
||||
static inline struct libinput*
|
||||
tp_libinput_context(struct tp_dispatch *tp)
|
||||
{
|
||||
return tp->device->base.seat->libinput;
|
||||
}
|
||||
|
||||
static inline struct normalized_coords
|
||||
tp_normalize_delta(struct tp_dispatch *tp, struct device_float_coords delta)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1029,7 +1029,6 @@ static struct evdev_dispatch_interface tablet_interface = {
|
|||
NULL, /* device_removed */
|
||||
NULL, /* device_suspended */
|
||||
NULL, /* device_resumed */
|
||||
NULL, /* tag_device */
|
||||
tablet_check_initial_proximity,
|
||||
};
|
||||
|
||||
|
|
|
|||
84
src/evdev.c
84
src/evdev.c
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
* Copyright © 2013 Jonas Ådahl
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
|
|
@ -59,6 +60,7 @@ enum evdev_device_udev_tags {
|
|||
EVDEV_UDEV_TAG_JOYSTICK = (1 << 6),
|
||||
EVDEV_UDEV_TAG_ACCELEROMETER = (1 << 7),
|
||||
EVDEV_UDEV_TAG_BUTTONSET = (1 << 8),
|
||||
EVDEV_UDEV_TAG_POINTINGSTICK = (1 << 9),
|
||||
};
|
||||
|
||||
struct evdev_udev_tag_match {
|
||||
|
|
@ -77,6 +79,7 @@ static const struct evdev_udev_tag_match evdev_udev_tag_matches[] = {
|
|||
{"ID_INPUT_TABLET_PAD", EVDEV_UDEV_TAG_BUTTONSET},
|
||||
{"ID_INPUT_JOYSTICK", EVDEV_UDEV_TAG_JOYSTICK},
|
||||
{"ID_INPUT_ACCELEROMETER", EVDEV_UDEV_TAG_ACCELEROMETER},
|
||||
{"ID_INPUT_POINTINGSTICK", EVDEV_UDEV_TAG_POINTINGSTICK},
|
||||
|
||||
/* sentinel value */
|
||||
{ 0 },
|
||||
|
|
@ -439,6 +442,7 @@ evdev_button_scroll_button(struct evdev_device *device,
|
|||
if (is_press) {
|
||||
libinput_timer_set(&device->scroll.timer,
|
||||
time + DEFAULT_MIDDLE_BUTTON_SCROLL_TIMEOUT);
|
||||
device->scroll.button_down_time = time;
|
||||
} else {
|
||||
libinput_timer_cancel(&device->scroll.timer);
|
||||
if (device->scroll.button_scroll_active) {
|
||||
|
|
@ -448,7 +452,8 @@ evdev_button_scroll_button(struct evdev_device *device,
|
|||
} else {
|
||||
/* If the button is released quickly enough emit the
|
||||
* button press/release events. */
|
||||
evdev_pointer_notify_physical_button(device, time,
|
||||
evdev_pointer_notify_physical_button(device,
|
||||
device->scroll.button_down_time,
|
||||
device->scroll.button,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
evdev_pointer_notify_physical_button(device, time,
|
||||
|
|
@ -719,20 +724,40 @@ evdev_tag_external_mouse(struct evdev_device *device,
|
|||
int bustype;
|
||||
|
||||
bustype = libevdev_get_id_bustype(device->evdev);
|
||||
if (bustype == BUS_USB || bustype == BUS_BLUETOOTH) {
|
||||
if (device->seat_caps & EVDEV_DEVICE_POINTER)
|
||||
device->tags |= EVDEV_TAG_EXTERNAL_MOUSE;
|
||||
}
|
||||
if (bustype == BUS_USB || bustype == BUS_BLUETOOTH)
|
||||
device->tags |= EVDEV_TAG_EXTERNAL_MOUSE;
|
||||
}
|
||||
|
||||
static void
|
||||
evdev_tag_trackpoint(struct evdev_device *device,
|
||||
struct udev_device *udev_device)
|
||||
{
|
||||
if (libevdev_has_property(device->evdev, INPUT_PROP_POINTING_STICK))
|
||||
if (libevdev_has_property(device->evdev,
|
||||
INPUT_PROP_POINTING_STICK) ||
|
||||
udev_device_get_property_value(udev_device,
|
||||
"ID_INPUT_POINTINGSTICK"))
|
||||
device->tags |= EVDEV_TAG_TRACKPOINT;
|
||||
}
|
||||
|
||||
static void
|
||||
evdev_tag_keyboard(struct evdev_device *device,
|
||||
struct udev_device *udev_device)
|
||||
{
|
||||
int code;
|
||||
|
||||
if (!libevdev_has_event_type(device->evdev, EV_KEY))
|
||||
return;
|
||||
|
||||
for (code = KEY_Q; code <= KEY_P; code++) {
|
||||
if (!libevdev_has_event_code(device->evdev,
|
||||
EV_KEY,
|
||||
code))
|
||||
return;
|
||||
}
|
||||
|
||||
device->tags |= EVDEV_TAG_KEYBOARD;
|
||||
}
|
||||
|
||||
static void
|
||||
fallback_process(struct evdev_dispatch *dispatch,
|
||||
struct evdev_device *device,
|
||||
|
|
@ -825,14 +850,6 @@ fallback_destroy(struct evdev_dispatch *dispatch)
|
|||
free(dispatch);
|
||||
}
|
||||
|
||||
static void
|
||||
fallback_tag_device(struct evdev_device *device,
|
||||
struct udev_device *udev_device)
|
||||
{
|
||||
evdev_tag_external_mouse(device, udev_device);
|
||||
evdev_tag_trackpoint(device, udev_device);
|
||||
}
|
||||
|
||||
static int
|
||||
evdev_calibration_has_matrix(struct libinput_device *libinput_device)
|
||||
{
|
||||
|
|
@ -883,7 +900,6 @@ struct evdev_dispatch_interface fallback_interface = {
|
|||
NULL, /* device_removed */
|
||||
NULL, /* device_suspended */
|
||||
NULL, /* device_resumed */
|
||||
fallback_tag_device,
|
||||
NULL, /* post_added */
|
||||
};
|
||||
|
||||
|
|
@ -1045,7 +1061,7 @@ evdev_scroll_get_default_method(struct libinput_device *device)
|
|||
{
|
||||
struct evdev_device *evdev = (struct evdev_device *)device;
|
||||
|
||||
if (libevdev_has_property(evdev->evdev, INPUT_PROP_POINTING_STICK))
|
||||
if (evdev->tags & EVDEV_TAG_TRACKPOINT)
|
||||
return LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
|
||||
|
||||
/* Mice without a scroll wheel but with middle button have on-button
|
||||
|
|
@ -1085,14 +1101,7 @@ evdev_scroll_get_default_button(struct libinput_device *device)
|
|||
{
|
||||
struct evdev_device *evdev = (struct evdev_device *)device;
|
||||
|
||||
if (libevdev_has_property(evdev->evdev, INPUT_PROP_POINTING_STICK))
|
||||
return BTN_MIDDLE;
|
||||
|
||||
/* A device that defaults to button scrolling defaults
|
||||
to BTN_MIDDLE */
|
||||
if (evdev_scroll_get_default_method(device) ==
|
||||
LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN &&
|
||||
libevdev_has_event_code(evdev->evdev, EV_KEY, BTN_MIDDLE))
|
||||
if( libevdev_has_event_code(evdev->evdev, EV_KEY, BTN_MIDDLE))
|
||||
return BTN_MIDDLE;
|
||||
|
||||
return 0;
|
||||
|
|
@ -1412,14 +1421,6 @@ evdev_need_mtdev(struct evdev_device *device)
|
|||
!libevdev_has_event_code(evdev, EV_ABS, ABS_MT_SLOT));
|
||||
}
|
||||
|
||||
static void
|
||||
evdev_tag_device(struct evdev_device *device)
|
||||
{
|
||||
if (device->dispatch->interface->tag_device)
|
||||
device->dispatch->interface->tag_device(device,
|
||||
device->udev_device);
|
||||
}
|
||||
|
||||
static inline int
|
||||
evdev_read_wheel_click_prop(struct evdev_device *device)
|
||||
{
|
||||
|
|
@ -1480,7 +1481,7 @@ evdev_read_dpi_prop(struct evdev_device *device)
|
|||
* POINTINGSTICK_CONST_ACCEL value to compensate for sensitivity
|
||||
* differences between models, we translate this to a fake dpi.
|
||||
*/
|
||||
if (libevdev_has_property(device->evdev, INPUT_PROP_POINTING_STICK))
|
||||
if (device->tags & EVDEV_TAG_TRACKPOINT)
|
||||
return evdev_get_trackpoint_dpi(device);
|
||||
|
||||
mouse_dpi = udev_device_get_property_value(device->udev_device,
|
||||
|
|
@ -1820,13 +1821,14 @@ evdev_configure_device(struct evdev_device *device)
|
|||
}
|
||||
|
||||
log_info(libinput,
|
||||
"input device '%s', %s is tagged by udev as:%s%s%s%s%s%s%s%s\n",
|
||||
"input device '%s', %s is tagged by udev as:%s%s%s%s%s%s%s%s%s\n",
|
||||
device->devname, devnode,
|
||||
udev_tags & EVDEV_UDEV_TAG_KEYBOARD ? " Keyboard" : "",
|
||||
udev_tags & EVDEV_UDEV_TAG_MOUSE ? " Mouse" : "",
|
||||
udev_tags & EVDEV_UDEV_TAG_TOUCHPAD ? " Touchpad" : "",
|
||||
udev_tags & EVDEV_UDEV_TAG_TOUCHSCREEN ? " Touchscreen" : "",
|
||||
udev_tags & EVDEV_UDEV_TAG_TABLET ? " Tablet" : "",
|
||||
udev_tags & EVDEV_UDEV_TAG_POINTINGSTICK ? " Pointingstick" : "",
|
||||
udev_tags & EVDEV_UDEV_TAG_JOYSTICK ? " Joystick" : "",
|
||||
udev_tags & EVDEV_UDEV_TAG_ACCELEROMETER ? " Accelerometer" : "",
|
||||
udev_tags & EVDEV_UDEV_TAG_BUTTONSET ? " Buttonset" : "");
|
||||
|
|
@ -1897,10 +1899,13 @@ evdev_configure_device(struct evdev_device *device)
|
|||
log_info(libinput,
|
||||
"input device '%s', %s is a touchpad\n",
|
||||
device->devname, devnode);
|
||||
|
||||
evdev_tag_touchpad(device, device->udev_device);
|
||||
return device->dispatch == NULL ? -1 : 0;
|
||||
}
|
||||
|
||||
if (udev_tags & EVDEV_UDEV_TAG_MOUSE) {
|
||||
if (udev_tags & EVDEV_UDEV_TAG_MOUSE ||
|
||||
udev_tags & EVDEV_UDEV_TAG_POINTINGSTICK) {
|
||||
if (libevdev_has_event_code(evdev, EV_REL, REL_X) &&
|
||||
libevdev_has_event_code(evdev, EV_REL, REL_Y) &&
|
||||
evdev_device_init_pointer_acceleration(
|
||||
|
|
@ -1920,6 +1925,9 @@ evdev_configure_device(struct evdev_device *device)
|
|||
device->scroll.natural_scrolling_enabled = true;
|
||||
/* want button scrolling config option */
|
||||
device->scroll.want_button = 1;
|
||||
|
||||
evdev_tag_external_mouse(device, device->udev_device);
|
||||
evdev_tag_trackpoint(device, device->udev_device);
|
||||
}
|
||||
|
||||
if (udev_tags & EVDEV_UDEV_TAG_KEYBOARD) {
|
||||
|
|
@ -1934,6 +1942,8 @@ evdev_configure_device(struct evdev_device *device)
|
|||
device->scroll.natural_scrolling_enabled = true;
|
||||
device->seat_caps |= EVDEV_DEVICE_POINTER;
|
||||
}
|
||||
|
||||
evdev_tag_keyboard(device, device->udev_device);
|
||||
}
|
||||
|
||||
if (udev_tags & EVDEV_UDEV_TAG_TOUCHSCREEN) {
|
||||
|
|
@ -2089,7 +2099,6 @@ evdev_device_create(struct libinput_seat *seat,
|
|||
device->scroll.direction = 0;
|
||||
device->scroll.wheel_click_angle =
|
||||
evdev_read_wheel_click_prop(device);
|
||||
device->dpi = evdev_read_dpi_prop(device);
|
||||
device->model = evdev_read_model(device);
|
||||
/* at most 5 SYN_DROPPED log-messages per 30s */
|
||||
ratelimit_init(&device->syn_drop_limit, 30ULL * 1000, 5);
|
||||
|
|
@ -2101,6 +2110,8 @@ evdev_device_create(struct libinput_seat *seat,
|
|||
if (evdev_configure_device(device) == -1)
|
||||
goto err;
|
||||
|
||||
device->dpi = evdev_read_dpi_prop(device);
|
||||
|
||||
if (device->seat_caps == 0) {
|
||||
unhandled_device = 1;
|
||||
goto err;
|
||||
|
|
@ -2122,7 +2133,6 @@ evdev_device_create(struct libinput_seat *seat,
|
|||
|
||||
list_insert(seat->devices_list.prev, &device->base.link);
|
||||
|
||||
evdev_tag_device(device);
|
||||
evdev_notify_added_device(device);
|
||||
|
||||
return device;
|
||||
|
|
|
|||
12
src/evdev.h
12
src/evdev.h
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright © 2011, 2012 Intel Corporation
|
||||
* Copyright © 2013 Jonas Ådahl
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
|
|
@ -69,6 +70,7 @@ enum evdev_device_tags {
|
|||
EVDEV_TAG_INTERNAL_TOUCHPAD = (1 << 1),
|
||||
EVDEV_TAG_TRACKPOINT = (1 << 2),
|
||||
EVDEV_TAG_TOUCHPAD_TRACKPOINT = (1 << 3),
|
||||
EVDEV_TAG_KEYBOARD = (1 << 4),
|
||||
};
|
||||
|
||||
enum evdev_middlebutton_state {
|
||||
|
|
@ -149,6 +151,8 @@ struct evdev_device {
|
|||
/* Currently enabled method, button */
|
||||
enum libinput_config_scroll_method method;
|
||||
uint32_t button;
|
||||
uint64_t button_down_time;
|
||||
|
||||
/* set during device init, used at runtime to delay changes
|
||||
* until all buttons are up */
|
||||
enum libinput_config_scroll_method want_method;
|
||||
|
|
@ -254,10 +258,6 @@ struct evdev_dispatch_interface {
|
|||
void (*device_resumed)(struct evdev_device *device,
|
||||
struct evdev_device *resumed_device);
|
||||
|
||||
/* Tag device with one of EVDEV_TAG */
|
||||
void (*tag_device)(struct evdev_device *device,
|
||||
struct udev_device *udev_device);
|
||||
|
||||
/* Called immediately after the LIBINPUT_EVENT_DEVICE_ADDED event
|
||||
* was sent */
|
||||
void (*post_added)(struct evdev_device *device,
|
||||
|
|
@ -298,6 +298,10 @@ evdev_mt_touchpad_create(struct evdev_device *device);
|
|||
struct evdev_dispatch *
|
||||
evdev_tablet_create(struct evdev_device *device);
|
||||
|
||||
void
|
||||
evdev_tag_touchpad(struct evdev_device *device,
|
||||
struct udev_device *udev_device);
|
||||
|
||||
void
|
||||
evdev_device_led_update(struct evdev_device *device, enum libinput_led leds);
|
||||
|
||||
|
|
|
|||
52
src/filter.c
52
src/filter.c
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright © 2006-2009 Simon Thum
|
||||
* Copyright © 2012 Jonas Ådahl
|
||||
* Copyright © 2014-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
|
|
@ -77,7 +78,7 @@ filter_get_speed(struct motion_filter *filter)
|
|||
*/
|
||||
|
||||
#define MAX_VELOCITY_DIFF 1.0 /* units/ms */
|
||||
#define MOTION_TIMEOUT 300 /* (ms) */
|
||||
#define MOTION_TIMEOUT 1000 /* (ms) */
|
||||
#define NUM_POINTER_TRACKERS 16
|
||||
|
||||
struct pointer_tracker {
|
||||
|
|
@ -143,6 +144,24 @@ calculate_tracker_velocity(struct pointer_tracker *tracker, uint64_t time)
|
|||
return normalized_length(tracker->delta) / tdelta; /* units/ms */
|
||||
}
|
||||
|
||||
static inline double
|
||||
calculate_velocity_after_timeout(struct pointer_tracker *tracker)
|
||||
{
|
||||
/* First movement after timeout needs special handling.
|
||||
*
|
||||
* When we trigger the timeout, the last event is too far in the
|
||||
* past to use it for velocity calculation across multiple tracker
|
||||
* values.
|
||||
*
|
||||
* Use the motion timeout itself to calculate the speed rather than
|
||||
* the last tracker time. This errs on the side of being too fast
|
||||
* for really slow movements but provides much more useful initial
|
||||
* movement in normal use-cases (pause, move, pause, move)
|
||||
*/
|
||||
return calculate_tracker_velocity(tracker,
|
||||
tracker->time + MOTION_TIMEOUT);
|
||||
}
|
||||
|
||||
static double
|
||||
calculate_velocity(struct pointer_accelerator *accel, uint64_t time)
|
||||
{
|
||||
|
|
@ -162,15 +181,23 @@ calculate_velocity(struct pointer_accelerator *accel, uint64_t time)
|
|||
|
||||
/* Stop if too far away in time */
|
||||
if (time - tracker->time > MOTION_TIMEOUT ||
|
||||
tracker->time > time)
|
||||
tracker->time > time) {
|
||||
if (offset == 1)
|
||||
result = calculate_velocity_after_timeout(tracker);
|
||||
break;
|
||||
}
|
||||
|
||||
velocity = calculate_tracker_velocity(tracker, time);
|
||||
|
||||
/* Stop if direction changed */
|
||||
dir &= tracker->dir;
|
||||
if (dir == 0)
|
||||
if (dir == 0) {
|
||||
/* First movement after dirchange - velocity is that
|
||||
* of the last movement */
|
||||
if (offset == 1)
|
||||
result = velocity;
|
||||
break;
|
||||
|
||||
velocity = calculate_tracker_velocity(tracker, time);
|
||||
}
|
||||
|
||||
if (initial_velocity == 0.0) {
|
||||
result = initial_velocity = velocity;
|
||||
|
|
@ -196,17 +223,20 @@ acceleration_profile(struct pointer_accelerator *accel,
|
|||
|
||||
static double
|
||||
calculate_acceleration(struct pointer_accelerator *accel,
|
||||
void *data, double velocity, uint64_t time)
|
||||
void *data,
|
||||
double velocity,
|
||||
double last_velocity,
|
||||
uint64_t time)
|
||||
{
|
||||
double factor;
|
||||
|
||||
/* Use Simpson's rule to calculate the avarage acceleration between
|
||||
* the previous motion and the most recent. */
|
||||
factor = acceleration_profile(accel, data, velocity, time);
|
||||
factor += acceleration_profile(accel, data, accel->last_velocity, time);
|
||||
factor += acceleration_profile(accel, data, last_velocity, time);
|
||||
factor += 4.0 *
|
||||
acceleration_profile(accel, data,
|
||||
(accel->last_velocity + velocity) / 2,
|
||||
(last_velocity + velocity) / 2,
|
||||
time);
|
||||
|
||||
factor = factor / 6.0;
|
||||
|
|
@ -227,7 +257,11 @@ accelerator_filter(struct motion_filter *filter,
|
|||
|
||||
feed_trackers(accel, unaccelerated, time);
|
||||
velocity = calculate_velocity(accel, time);
|
||||
accel_value = calculate_acceleration(accel, data, velocity, time);
|
||||
accel_value = calculate_acceleration(accel,
|
||||
data,
|
||||
velocity,
|
||||
accel->last_velocity,
|
||||
time);
|
||||
|
||||
accelerated.x = accel_value * unaccelerated->x;
|
||||
accelerated.y = accel_value * unaccelerated->y;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2012 Jonas Ådahl
|
||||
* Copyright © 2014-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2013 Jonas Ådahl
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright © 2008-2011 Kristian Høgsberg
|
||||
* Copyright © 2011 Intel Corporation
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2008 Kristian Høgsberg
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
|
|
@ -25,11 +26,16 @@
|
|||
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "libinput.h"
|
||||
|
||||
#define VENDOR_ID_APPLE 0x5ac
|
||||
#define VENDOR_ID_WACOM 0x56a
|
||||
|
||||
void
|
||||
set_logging_enabled(int enabled);
|
||||
|
||||
|
|
@ -250,6 +256,38 @@ matrix_to_farray6(const struct matrix *m, float out[6])
|
|||
out[5] = m->val[1][2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple wrapper for asprintf that ensures the passed in-pointer is set
|
||||
* to NULL upon error.
|
||||
* The standard asprintf() call does not guarantee the passed in pointer
|
||||
* will be NULL'ed upon failure, whereas this wrapper does.
|
||||
*
|
||||
* @param strp pointer to set to newly allocated string.
|
||||
* This pointer should be passed to free() to release when done.
|
||||
* @param fmt the format string to use for printing.
|
||||
* @return The number of bytes printed (excluding the null byte terminator)
|
||||
* upon success or -1 upon failure. In the case of failure the pointer is set
|
||||
* to NULL.
|
||||
*/
|
||||
static inline int
|
||||
xasprintf(char **strp, const char *fmt, ...)
|
||||
LIBINPUT_ATTRIBUTE_PRINTF(2, 3);
|
||||
|
||||
static inline int
|
||||
xasprintf(char **strp, const char *fmt, ...)
|
||||
{
|
||||
int rc = 0;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
rc = vasprintf(strp, fmt, args);
|
||||
va_end(args);
|
||||
if ((rc == -1) && strp)
|
||||
*strp = NULL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
enum ratelimit_state {
|
||||
RATELIMIT_EXCEEDED,
|
||||
RATELIMIT_THRESHOLD,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2013 Jonas Ådahl
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2013 Jonas Ådahl
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2013 Red Hat, Inc.
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2014 Red Hat, Inc.
|
||||
* Copyright © 2014-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
|
|
@ -20,6 +20,8 @@
|
|||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2013 Intel Corporation
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ START_TEST(device_sendevents_config_touchpad)
|
|||
expected = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
|
||||
|
||||
/* The wacom devices in the test suite are external */
|
||||
if (libevdev_get_id_vendor(dev->evdev) != 0x56a) /* wacom */
|
||||
if (libevdev_get_id_vendor(dev->evdev) != VENDOR_ID_WACOM)
|
||||
expected |=
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
|
||||
|
||||
|
|
|
|||
|
|
@ -84,8 +84,10 @@ litest_backtrace_get_lineno(const char *executable,
|
|||
char *s;
|
||||
unsigned int i;
|
||||
|
||||
if (!cwd[0])
|
||||
getcwd(cwd, sizeof(cwd));
|
||||
if (!cwd[0]) {
|
||||
if (getcwd(cwd, sizeof(cwd)) == NULL)
|
||||
cwd[0] = 0; /* contents otherwise undefined. */
|
||||
}
|
||||
|
||||
sprintf (buffer,
|
||||
ADDR2LINE " -C -e %s -i %lx",
|
||||
|
|
@ -383,7 +385,17 @@ static struct list all_tests;
|
|||
static void
|
||||
litest_reload_udev_rules(void)
|
||||
{
|
||||
system("udevadm control --reload-rules");
|
||||
int ret = system("udevadm control --reload-rules");
|
||||
if (ret == -1) {
|
||||
litest_abort_msg("Failed to execute: udevadm");
|
||||
} else if (WIFEXITED(ret)) {
|
||||
if (WEXITSTATUS(ret))
|
||||
litest_abort_msg("udevadm failed with %d",
|
||||
WEXITSTATUS(ret));
|
||||
} else if (WIFSIGNALED(ret)) {
|
||||
litest_abort_msg("udevadm terminated with signal %d",
|
||||
WTERMSIG(ret));
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -648,6 +660,7 @@ _litest_add_ranged_for_device(const char *name,
|
|||
{
|
||||
struct suite *s;
|
||||
struct litest_test_device **dev = devices;
|
||||
bool device_filtered = false;
|
||||
|
||||
assert(type < LITEST_NO_DEVICE);
|
||||
|
||||
|
|
@ -662,8 +675,10 @@ _litest_add_ranged_for_device(const char *name,
|
|||
s = get_suite(name);
|
||||
for (; *dev; dev++) {
|
||||
if (filter_device &&
|
||||
fnmatch(filter_device, (*dev)->shortname, 0) != 0)
|
||||
fnmatch(filter_device, (*dev)->shortname, 0) != 0) {
|
||||
device_filtered = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*dev)->type == type) {
|
||||
litest_add_tcase_for_device(s,
|
||||
|
|
@ -675,7 +690,9 @@ _litest_add_ranged_for_device(const char *name,
|
|||
}
|
||||
}
|
||||
|
||||
litest_abort_msg("Invalid test device type");
|
||||
/* only abort if no filter was set, that's a bug */
|
||||
if (!device_filtered)
|
||||
litest_abort_msg("Invalid test device type");
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -879,7 +896,7 @@ litest_init_udev_rules(struct litest_test_device *dev)
|
|||
ck_abort_msg("Failed to create udev rules directory (%s)\n",
|
||||
strerror(errno));
|
||||
|
||||
rc = asprintf(&path,
|
||||
rc = xasprintf(&path,
|
||||
"%s/%s%s.rules",
|
||||
UDEV_RULES_D,
|
||||
UDEV_RULE_PREFIX,
|
||||
|
|
@ -985,6 +1002,32 @@ litest_restore_log_handler(struct libinput *libinput)
|
|||
libinput_log_set_handler(libinput, litest_log_handler);
|
||||
}
|
||||
|
||||
static inline void
|
||||
litest_wait_for_udev(int fd)
|
||||
{
|
||||
struct udev *udev;
|
||||
struct udev_device *device;
|
||||
struct stat st;
|
||||
int loop_count = 0;
|
||||
|
||||
litest_assert_int_ge(fstat(fd, &st), 0);
|
||||
|
||||
udev = udev_new();
|
||||
device = udev_device_new_from_devnum(udev, 'c', st.st_rdev);
|
||||
litest_assert_ptr_notnull(device);
|
||||
while (device && !udev_device_get_property_value(device, "ID_INPUT")) {
|
||||
loop_count++;
|
||||
litest_assert_int_lt(loop_count, 300);
|
||||
|
||||
udev_device_unref(device);
|
||||
msleep(2);
|
||||
device = udev_device_new_from_devnum(udev, 'c', st.st_rdev);
|
||||
}
|
||||
|
||||
udev_device_unref(device);
|
||||
udev_unref(udev);
|
||||
}
|
||||
|
||||
struct litest_device *
|
||||
litest_add_device_with_overrides(struct libinput *libinput,
|
||||
enum litest_device_type which,
|
||||
|
|
@ -1012,6 +1055,8 @@ litest_add_device_with_overrides(struct libinput *libinput,
|
|||
rc = libevdev_new_from_fd(fd, &d->evdev);
|
||||
litest_assert_int_eq(rc, 0);
|
||||
|
||||
litest_wait_for_udev(fd);
|
||||
|
||||
d->libinput = libinput;
|
||||
d->libinput_device = libinput_path_add_device(d->libinput, path);
|
||||
litest_assert(d->libinput_device != NULL);
|
||||
|
|
@ -1097,6 +1142,11 @@ litest_delete_device(struct litest_device *d)
|
|||
free(d->private);
|
||||
memset(d,0, sizeof(*d));
|
||||
free(d);
|
||||
|
||||
/* zzz so udev can catch up with things, so we don't accidentally open
|
||||
* an old device in the next test and then get all upset when things blow
|
||||
* up */
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -2115,6 +2165,18 @@ litest_timeout_middlebutton(void)
|
|||
msleep(70);
|
||||
}
|
||||
|
||||
void
|
||||
litest_timeout_dwt_short(void)
|
||||
{
|
||||
msleep(220);
|
||||
}
|
||||
|
||||
void
|
||||
litest_timeout_dwt_long(void)
|
||||
{
|
||||
msleep(520);
|
||||
}
|
||||
|
||||
void
|
||||
litest_push_event_frame(struct litest_device *dev)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -416,6 +416,8 @@ void litest_timeout_buttonscroll(void);
|
|||
void litest_timeout_edgescroll(void);
|
||||
void litest_timeout_finger_switch(void);
|
||||
void litest_timeout_middlebutton(void);
|
||||
void litest_timeout_dwt_short(void);
|
||||
void litest_timeout_dwt_long(void);
|
||||
|
||||
void litest_push_event_frame(struct litest_device *dev);
|
||||
void litest_pop_event_frame(struct litest_device *dev);
|
||||
|
|
|
|||
|
|
@ -586,7 +586,8 @@ START_TEST(touch_initial_state)
|
|||
{
|
||||
struct litest_device *dev;
|
||||
struct libinput *libinput1, *libinput2;
|
||||
struct libinput_event *ev1, *ev2;
|
||||
struct libinput_event *ev1 = NULL;
|
||||
struct libinput_event *ev2 = NULL;
|
||||
struct libinput_event_touch *t1, *t2;
|
||||
struct libinput_device *device1, *device2;
|
||||
int axis = _i; /* looped test */
|
||||
|
|
|
|||
504
test/touchpad.c
504
test/touchpad.c
|
|
@ -1808,6 +1808,51 @@ START_TEST(touchpad_2fg_clickfinger)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_2fg_clickfinger_distance)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
|
||||
libinput_device_config_click_set_method(dev->libinput_device,
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 90, 50);
|
||||
litest_touch_down(dev, 1, 10, 50);
|
||||
litest_event(dev, EV_KEY, BTN_LEFT, 1);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
litest_event(dev, EV_KEY, BTN_LEFT, 0);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
litest_touch_up(dev, 0);
|
||||
litest_touch_up(dev, 1);
|
||||
|
||||
litest_assert_button_event(li,
|
||||
BTN_LEFT,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
litest_assert_button_event(li,
|
||||
BTN_LEFT,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_touch_down(dev, 0, 50, 5);
|
||||
litest_touch_down(dev, 1, 50, 95);
|
||||
litest_event(dev, EV_KEY, BTN_LEFT, 1);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
litest_event(dev, EV_KEY, BTN_LEFT, 0);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
litest_touch_up(dev, 0);
|
||||
litest_touch_up(dev, 1);
|
||||
|
||||
litest_assert_button_event(li,
|
||||
BTN_LEFT,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
litest_assert_button_event(li,
|
||||
BTN_LEFT,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_clickfinger_to_area_method)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
|
|
@ -2636,7 +2681,7 @@ START_TEST(clickpad_topsoftbuttons_clickfinger)
|
|||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_touch_down(dev, 0, 90, 5);
|
||||
litest_touch_down(dev, 1, 10, 5);
|
||||
litest_touch_down(dev, 1, 80, 5);
|
||||
litest_event(dev, EV_KEY, BTN_LEFT, 1);
|
||||
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||
litest_event(dev, EV_KEY, BTN_LEFT, 0);
|
||||
|
|
@ -2959,7 +3004,7 @@ START_TEST(touchpad_edge_scroll)
|
|||
litest_touch_up(dev, 0);
|
||||
|
||||
libinput_dispatch(li);
|
||||
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 10);
|
||||
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 4);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_touch_down(dev, 0, 99, 80);
|
||||
|
|
@ -2967,7 +3012,7 @@ START_TEST(touchpad_edge_scroll)
|
|||
litest_touch_up(dev, 0);
|
||||
|
||||
libinput_dispatch(li);
|
||||
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -10);
|
||||
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -4);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_touch_down(dev, 0, 20, 99);
|
||||
|
|
@ -2975,7 +3020,7 @@ START_TEST(touchpad_edge_scroll)
|
|||
litest_touch_up(dev, 0);
|
||||
|
||||
libinput_dispatch(li);
|
||||
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 10);
|
||||
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 4);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_touch_down(dev, 0, 70, 99);
|
||||
|
|
@ -2983,7 +3028,7 @@ START_TEST(touchpad_edge_scroll)
|
|||
litest_touch_up(dev, 0);
|
||||
|
||||
libinput_dispatch(li);
|
||||
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -10);
|
||||
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -4);
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
END_TEST
|
||||
|
|
@ -3065,7 +3110,7 @@ START_TEST(touchpad_edge_scroll_no_motion)
|
|||
litest_touch_up(dev, 0);
|
||||
libinput_dispatch(li);
|
||||
|
||||
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 5);
|
||||
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 4);
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
END_TEST
|
||||
|
|
@ -3198,9 +3243,13 @@ static int
|
|||
touchpad_has_palm_detect_size(struct litest_device *dev)
|
||||
{
|
||||
double width, height;
|
||||
unsigned int vendor;
|
||||
int rc;
|
||||
|
||||
if (libinput_device_get_id_vendor(dev->libinput_device) == 0x5ac) /* Apple */
|
||||
vendor = libinput_device_get_id_vendor(dev->libinput_device);
|
||||
if (vendor == VENDOR_ID_WACOM)
|
||||
return 0;
|
||||
if (vendor == VENDOR_ID_APPLE)
|
||||
return 1;
|
||||
|
||||
rc = libinput_device_get_size(dev->libinput_device, &width, &height);
|
||||
|
|
@ -4590,6 +4639,434 @@ START_TEST(touchpad_initial_state)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
static inline bool
|
||||
has_disable_while_typing(struct litest_device *device)
|
||||
{
|
||||
if (libevdev_get_id_vendor(device->evdev) == VENDOR_ID_WACOM)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
START_TEST(touchpad_dwt)
|
||||
{
|
||||
struct litest_device *touchpad = litest_current_device();
|
||||
struct litest_device *keyboard;
|
||||
struct libinput *li = touchpad->libinput;
|
||||
|
||||
if (!has_disable_while_typing(touchpad))
|
||||
return;
|
||||
|
||||
keyboard = litest_add_device(li, LITEST_KEYBOARD);
|
||||
libinput_device_config_tap_set_enabled(touchpad->libinput_device,
|
||||
LIBINPUT_CONFIG_TAP_DISABLED);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_keyboard_key(keyboard, KEY_A, true);
|
||||
litest_keyboard_key(keyboard, KEY_A, false);
|
||||
libinput_dispatch(li);
|
||||
litest_touch_down(touchpad, 0, 50, 50);
|
||||
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
|
||||
litest_touch_up(touchpad, 0);
|
||||
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
|
||||
/* within timeout - no events */
|
||||
litest_touch_down(touchpad, 0, 50, 50);
|
||||
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
|
||||
litest_touch_up(touchpad, 0);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_timeout_dwt_short();
|
||||
libinput_dispatch(li);
|
||||
|
||||
/* after timeout - motion events*/
|
||||
litest_touch_down(touchpad, 0, 50, 50);
|
||||
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
|
||||
litest_touch_up(touchpad, 0);
|
||||
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
|
||||
|
||||
litest_delete_device(keyboard);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_dwt_enable_touch)
|
||||
{
|
||||
struct litest_device *touchpad = litest_current_device();
|
||||
struct litest_device *keyboard;
|
||||
struct libinput *li = touchpad->libinput;
|
||||
|
||||
if (!has_disable_while_typing(touchpad))
|
||||
return;
|
||||
|
||||
keyboard = litest_add_device(li, LITEST_KEYBOARD);
|
||||
libinput_device_config_tap_set_enabled(touchpad->libinput_device,
|
||||
LIBINPUT_CONFIG_TAP_DISABLED);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_keyboard_key(keyboard, KEY_A, true);
|
||||
litest_keyboard_key(keyboard, KEY_A, false);
|
||||
libinput_dispatch(li);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
|
||||
/* finger down after last key event, but
|
||||
we're still within timeout - no events */
|
||||
msleep(10);
|
||||
litest_touch_down(touchpad, 0, 50, 50);
|
||||
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_timeout_dwt_short();
|
||||
libinput_dispatch(li);
|
||||
|
||||
/* same touch after timeout - motion events*/
|
||||
litest_touch_move_to(touchpad, 0, 70, 50, 50, 50, 10, 1);
|
||||
litest_touch_up(touchpad, 0);
|
||||
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
|
||||
|
||||
litest_delete_device(keyboard);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_dwt_touch_hold)
|
||||
{
|
||||
struct litest_device *touchpad = litest_current_device();
|
||||
struct litest_device *keyboard;
|
||||
struct libinput *li = touchpad->libinput;
|
||||
|
||||
if (!has_disable_while_typing(touchpad))
|
||||
return;
|
||||
|
||||
keyboard = litest_add_device(li, LITEST_KEYBOARD);
|
||||
libinput_device_config_tap_set_enabled(touchpad->libinput_device,
|
||||
LIBINPUT_CONFIG_TAP_DISABLED);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_keyboard_key(keyboard, KEY_A, true);
|
||||
msleep(1); /* make sure touch starts after key press */
|
||||
litest_touch_down(touchpad, 0, 50, 50);
|
||||
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5, 1);
|
||||
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
|
||||
/* touch still down - no events */
|
||||
litest_keyboard_key(keyboard, KEY_A, false);
|
||||
libinput_dispatch(li);
|
||||
litest_touch_move_to(touchpad, 0, 70, 50, 30, 50, 5, 1);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
|
||||
/* touch still down - no events */
|
||||
litest_timeout_dwt_short();
|
||||
libinput_dispatch(li);
|
||||
litest_touch_move_to(touchpad, 0, 30, 50, 50, 50, 5, 1);
|
||||
litest_touch_up(touchpad, 0);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
|
||||
|
||||
litest_delete_device(keyboard);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_dwt_key_hold)
|
||||
{
|
||||
struct litest_device *touchpad = litest_current_device();
|
||||
struct litest_device *keyboard;
|
||||
struct libinput *li = touchpad->libinput;
|
||||
|
||||
if (!has_disable_while_typing(touchpad))
|
||||
return;
|
||||
|
||||
keyboard = litest_add_device(li, LITEST_KEYBOARD);
|
||||
libinput_device_config_tap_set_enabled(touchpad->libinput_device,
|
||||
LIBINPUT_CONFIG_TAP_DISABLED);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_keyboard_key(keyboard, KEY_A, true);
|
||||
libinput_dispatch(li);
|
||||
litest_touch_down(touchpad, 0, 50, 50);
|
||||
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5, 1);
|
||||
litest_touch_up(touchpad, 0);
|
||||
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
litest_keyboard_key(keyboard, KEY_A, false);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
|
||||
litest_delete_device(keyboard);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_dwt_type)
|
||||
{
|
||||
struct litest_device *touchpad = litest_current_device();
|
||||
struct litest_device *keyboard;
|
||||
struct libinput *li = touchpad->libinput;
|
||||
int i;
|
||||
|
||||
if (!has_disable_while_typing(touchpad))
|
||||
return;
|
||||
|
||||
keyboard = litest_add_device(li, LITEST_KEYBOARD);
|
||||
libinput_device_config_tap_set_enabled(touchpad->libinput_device,
|
||||
LIBINPUT_CONFIG_TAP_DISABLED);
|
||||
litest_drain_events(li);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
litest_keyboard_key(keyboard, KEY_A, true);
|
||||
litest_keyboard_key(keyboard, KEY_A, false);
|
||||
libinput_dispatch(li);
|
||||
}
|
||||
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
|
||||
litest_touch_down(touchpad, 0, 50, 50);
|
||||
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5, 1);
|
||||
litest_touch_up(touchpad, 0);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_timeout_dwt_long();
|
||||
libinput_dispatch(li);
|
||||
litest_touch_down(touchpad, 0, 50, 50);
|
||||
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5, 1);
|
||||
litest_touch_up(touchpad, 0);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
|
||||
|
||||
litest_delete_device(keyboard);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_dwt_type_short_timeout)
|
||||
{
|
||||
struct litest_device *touchpad = litest_current_device();
|
||||
struct litest_device *keyboard;
|
||||
struct libinput *li = touchpad->libinput;
|
||||
int i;
|
||||
|
||||
if (!has_disable_while_typing(touchpad))
|
||||
return;
|
||||
|
||||
keyboard = litest_add_device(li, LITEST_KEYBOARD);
|
||||
libinput_device_config_tap_set_enabled(touchpad->libinput_device,
|
||||
LIBINPUT_CONFIG_TAP_DISABLED);
|
||||
litest_drain_events(li);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
litest_keyboard_key(keyboard, KEY_A, true);
|
||||
litest_keyboard_key(keyboard, KEY_A, false);
|
||||
libinput_dispatch(li);
|
||||
}
|
||||
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
|
||||
litest_touch_down(touchpad, 0, 50, 50);
|
||||
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5, 1);
|
||||
litest_touch_up(touchpad, 0);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_timeout_dwt_short();
|
||||
libinput_dispatch(li);
|
||||
litest_touch_down(touchpad, 0, 50, 50);
|
||||
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5, 1);
|
||||
litest_touch_up(touchpad, 0);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_delete_device(keyboard);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_dwt_tap)
|
||||
{
|
||||
struct litest_device *touchpad = litest_current_device();
|
||||
struct litest_device *keyboard;
|
||||
struct libinput *li = touchpad->libinput;
|
||||
|
||||
if (!has_disable_while_typing(touchpad))
|
||||
return;
|
||||
|
||||
keyboard = litest_add_device(li, LITEST_KEYBOARD);
|
||||
libinput_device_config_tap_set_enabled(touchpad->libinput_device,
|
||||
LIBINPUT_CONFIG_TAP_ENABLED);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_keyboard_key(keyboard, KEY_A, true);
|
||||
libinput_dispatch(li);
|
||||
litest_touch_down(touchpad, 0, 50, 50);
|
||||
litest_touch_up(touchpad, 0);
|
||||
|
||||
litest_keyboard_key(keyboard, KEY_A, false);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
|
||||
litest_timeout_dwt_short();
|
||||
litest_touch_down(touchpad, 0, 50, 50);
|
||||
litest_touch_up(touchpad, 0);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_BUTTON);
|
||||
|
||||
litest_delete_device(keyboard);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_dwt_tap_drag)
|
||||
{
|
||||
struct litest_device *touchpad = litest_current_device();
|
||||
struct litest_device *keyboard;
|
||||
struct libinput *li = touchpad->libinput;
|
||||
|
||||
if (!has_disable_while_typing(touchpad))
|
||||
return;
|
||||
|
||||
keyboard = litest_add_device(li, LITEST_KEYBOARD);
|
||||
libinput_device_config_tap_set_enabled(touchpad->libinput_device,
|
||||
LIBINPUT_CONFIG_TAP_ENABLED);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_keyboard_key(keyboard, KEY_A, true);
|
||||
libinput_dispatch(li);
|
||||
msleep(1); /* make sure touch starts after key press */
|
||||
litest_touch_down(touchpad, 0, 50, 50);
|
||||
litest_touch_up(touchpad, 0);
|
||||
litest_touch_down(touchpad, 0, 50, 50);
|
||||
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5, 1);
|
||||
|
||||
litest_keyboard_key(keyboard, KEY_A, false);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
|
||||
litest_timeout_dwt_short();
|
||||
libinput_dispatch(li);
|
||||
litest_touch_move_to(touchpad, 0, 70, 50, 50, 50, 5, 1);
|
||||
litest_touch_up(touchpad, 0);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
|
||||
|
||||
litest_delete_device(keyboard);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_dwt_click)
|
||||
{
|
||||
struct litest_device *touchpad = litest_current_device();
|
||||
struct litest_device *keyboard;
|
||||
struct libinput *li = touchpad->libinput;
|
||||
|
||||
if (!has_disable_while_typing(touchpad))
|
||||
return;
|
||||
|
||||
keyboard = litest_add_device(li, LITEST_KEYBOARD);
|
||||
libinput_device_config_tap_set_enabled(touchpad->libinput_device,
|
||||
LIBINPUT_CONFIG_TAP_DISABLED);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_keyboard_key(keyboard, KEY_A, true);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
|
||||
litest_touch_down(touchpad, 0, 50, 50);
|
||||
litest_button_click(touchpad, BTN_LEFT, true);
|
||||
litest_button_click(touchpad, BTN_LEFT, false);
|
||||
libinput_dispatch(li);
|
||||
litest_touch_up(touchpad, 0);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_BUTTON);
|
||||
|
||||
litest_keyboard_key(keyboard, KEY_A, false);
|
||||
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
|
||||
litest_delete_device(keyboard);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_dwt_edge_scroll)
|
||||
{
|
||||
struct litest_device *touchpad = litest_current_device();
|
||||
struct litest_device *keyboard;
|
||||
struct libinput *li = touchpad->libinput;
|
||||
|
||||
if (!has_disable_while_typing(touchpad))
|
||||
return;
|
||||
|
||||
enable_edge_scroll(touchpad);
|
||||
|
||||
keyboard = litest_add_device(li, LITEST_KEYBOARD);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_keyboard_key(keyboard, KEY_A, true);
|
||||
litest_keyboard_key(keyboard, KEY_A, false);
|
||||
litest_keyboard_key(keyboard, KEY_A, true);
|
||||
litest_keyboard_key(keyboard, KEY_A, false);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
|
||||
litest_touch_down(touchpad, 0, 99, 20);
|
||||
libinput_dispatch(li);
|
||||
litest_timeout_edgescroll();
|
||||
libinput_dispatch(li);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
/* edge scroll timeout is 300ms atm, make sure we don't accidentally
|
||||
exit the DWT timeout */
|
||||
litest_keyboard_key(keyboard, KEY_A, true);
|
||||
litest_keyboard_key(keyboard, KEY_A, false);
|
||||
libinput_dispatch(li);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
|
||||
litest_touch_move_to(touchpad, 0, 99, 20, 99, 80, 60, 10);
|
||||
libinput_dispatch(li);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_touch_move_to(touchpad, 0, 99, 80, 99, 20, 60, 10);
|
||||
litest_touch_up(touchpad, 0);
|
||||
libinput_dispatch(li);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
litest_delete_device(keyboard);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_dwt_edge_scroll_interrupt)
|
||||
{
|
||||
struct litest_device *touchpad = litest_current_device();
|
||||
struct litest_device *keyboard;
|
||||
struct libinput *li = touchpad->libinput;
|
||||
struct libinput_event_pointer *stop_event;
|
||||
|
||||
if (!has_disable_while_typing(touchpad))
|
||||
return;
|
||||
|
||||
enable_edge_scroll(touchpad);
|
||||
|
||||
keyboard = litest_add_device(li, LITEST_KEYBOARD);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(touchpad, 0, 99, 20);
|
||||
libinput_dispatch(li);
|
||||
litest_timeout_edgescroll();
|
||||
litest_touch_move_to(touchpad, 0, 99, 20, 99, 30, 10, 10);
|
||||
libinput_dispatch(li);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
|
||||
|
||||
litest_keyboard_key(keyboard, KEY_A, true);
|
||||
litest_keyboard_key(keyboard, KEY_A, false);
|
||||
litest_keyboard_key(keyboard, KEY_A, true);
|
||||
litest_keyboard_key(keyboard, KEY_A, false);
|
||||
|
||||
/* scroll stop event */
|
||||
litest_wait_for_event(li);
|
||||
stop_event = litest_is_axis_event(libinput_get_event(li),
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
|
||||
LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
|
||||
libinput_event_destroy(libinput_event_pointer_get_base_event(stop_event));
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
|
||||
|
||||
litest_timeout_dwt_long();
|
||||
|
||||
/* Known bad behavior: a touch starting to edge-scroll before dwt
|
||||
* kicks in will stop to scroll but be recognized as normal
|
||||
* pointer-moving touch once the timeout expires. We'll fix that
|
||||
* when we need to.
|
||||
*/
|
||||
litest_touch_move_to(touchpad, 0, 99, 30, 99, 80, 10, 5);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
|
||||
|
||||
litest_delete_device(keyboard);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void
|
||||
litest_setup_tests(void)
|
||||
{
|
||||
|
|
@ -4652,6 +5129,7 @@ litest_setup_tests(void)
|
|||
litest_add("touchpad:clickfinger", touchpad_1fg_clickfinger, LITEST_CLICKPAD, LITEST_ANY);
|
||||
litest_add("touchpad:clickfinger", touchpad_1fg_clickfinger_no_touch, LITEST_CLICKPAD, LITEST_ANY);
|
||||
litest_add("touchpad:clickfinger", touchpad_2fg_clickfinger, LITEST_CLICKPAD, LITEST_ANY);
|
||||
litest_add("touchpad:clickfinger", touchpad_2fg_clickfinger_distance, LITEST_CLICKPAD, LITEST_ANY);
|
||||
litest_add("touchpad:clickfinger", touchpad_clickfinger_to_area_method, LITEST_CLICKPAD, LITEST_ANY);
|
||||
litest_add("touchpad:clickfinger",
|
||||
touchpad_clickfinger_to_area_method_while_down, LITEST_CLICKPAD, LITEST_ANY);
|
||||
|
|
@ -4738,4 +5216,16 @@ litest_setup_tests(void)
|
|||
litest_add_for_device("touchpad:trackpoint", touchpad_trackpoint_no_trackpoint, LITEST_SYNAPTICS_TRACKPOINT_BUTTONS);
|
||||
|
||||
litest_add_ranged("touchpad:state", touchpad_initial_state, LITEST_TOUCHPAD, LITEST_ANY, &axis_range);
|
||||
|
||||
litest_add("touchpad:dwt", touchpad_dwt, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add("touchpad:dwt", touchpad_dwt_enable_touch, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add("touchpad:dwt", touchpad_dwt_touch_hold, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add("touchpad:dwt", touchpad_dwt_key_hold, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add("touchpad:dwt", touchpad_dwt_type, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add("touchpad:dwt", touchpad_dwt_type_short_timeout, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add("touchpad:dwt", touchpad_dwt_tap, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add("touchpad:dwt", touchpad_dwt_tap_drag, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add("touchpad:dwt", touchpad_dwt_click, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add("touchpad:dwt", touchpad_dwt_edge_scroll, LITEST_TOUCHPAD, LITEST_CLICKPAD);
|
||||
litest_add("touchpad:dwt", touchpad_dwt_edge_scroll_interrupt, LITEST_TOUCHPAD, LITEST_CLICKPAD);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,15 +35,34 @@ START_TEST(trackpoint_middlebutton)
|
|||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_pointer *ptrev;
|
||||
uint64_t ptime, rtime;
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
/* A quick middle button click should get reported normally */
|
||||
litest_button_click(dev, BTN_MIDDLE, 1);
|
||||
msleep(2);
|
||||
litest_button_click(dev, BTN_MIDDLE, 0);
|
||||
|
||||
litest_assert_button_event(li, BTN_MIDDLE, 1);
|
||||
litest_assert_button_event(li, BTN_MIDDLE, 0);
|
||||
litest_wait_for_event(li);
|
||||
|
||||
event = libinput_get_event(li);
|
||||
ptrev = litest_is_button_event(event,
|
||||
BTN_MIDDLE,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
ptime = libinput_event_pointer_get_time(ptrev);
|
||||
libinput_event_destroy(event);
|
||||
|
||||
event = libinput_get_event(li);
|
||||
ptrev = litest_is_button_event(event,
|
||||
BTN_MIDDLE,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
rtime = libinput_event_pointer_get_time(ptrev);
|
||||
libinput_event_destroy(event);
|
||||
|
||||
ck_assert_int_lt(ptime, rtime);
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ libshared_la_CFLAGS = $(LIBEVDEV_CFLAGS)
|
|||
libshared_la_LIBADD = $(LIBEVDEV_LIBS)
|
||||
|
||||
event_debug_SOURCES = event-debug.c
|
||||
event_debug_LDADD = ../src/libinput.la libshared.la $(LIBUDEV_LIBS)
|
||||
event_debug_LDADD = ../src/libinput.la libshared.la $(LIBUDEV_LIBS) $(LIBEVDEV_LIBS)
|
||||
event_debug_LDFLAGS = -no-install
|
||||
event_debug_CFLAGS = $(LIBUDEV_CFLAGS)
|
||||
event_debug_CFLAGS = $(LIBUDEV_CFLAGS) $(LIBEVDEV_CFLAGS)
|
||||
|
||||
ptraccel_debug_SOURCES = ptraccel-debug.c
|
||||
ptraccel_debug_LDADD = ../src/libfilter.la
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <sys/ioctl.h>
|
||||
|
||||
#include <libinput.h>
|
||||
#include <libevdev/libevdev.h>
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
|
|
@ -205,11 +206,17 @@ print_key_event(struct libinput_event *ev)
|
|||
{
|
||||
struct libinput_event_keyboard *k = libinput_event_get_keyboard_event(ev);
|
||||
enum libinput_key_state state;
|
||||
uint32_t key;
|
||||
const char *keyname;
|
||||
|
||||
print_event_time(libinput_event_keyboard_get_time(k));
|
||||
state = libinput_event_keyboard_get_key_state(k);
|
||||
printf("%d %s\n",
|
||||
libinput_event_keyboard_get_key(k),
|
||||
|
||||
key = libinput_event_keyboard_get_key(k);
|
||||
keyname = libevdev_event_code_get_name(EV_KEY, key);
|
||||
printf("%s (%d) %s\n",
|
||||
keyname ? keyname : "???",
|
||||
key,
|
||||
state == LIBINPUT_KEY_STATE_PRESSED ? "pressed" : "released");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -120,17 +120,17 @@ calibration_default(struct libinput_device *device)
|
|||
float calibration[6];
|
||||
|
||||
if (!libinput_device_config_calibration_has_matrix(device)) {
|
||||
asprintf(&str, "n/a");
|
||||
xasprintf(&str, "n/a");
|
||||
return str;
|
||||
}
|
||||
|
||||
if (libinput_device_config_calibration_get_default_matrix(device,
|
||||
calibration) == 0) {
|
||||
asprintf(&str, "identity matrix");
|
||||
xasprintf(&str, "identity matrix");
|
||||
return str;
|
||||
}
|
||||
|
||||
asprintf(&str,
|
||||
xasprintf(&str,
|
||||
"%.2f %.2f %.2f %.2f %.2f %.2f",
|
||||
calibration[0],
|
||||
calibration[1],
|
||||
|
|
@ -150,13 +150,13 @@ scroll_defaults(struct libinput_device *device)
|
|||
|
||||
scroll_methods = libinput_device_config_scroll_get_methods(device);
|
||||
if (scroll_methods == LIBINPUT_CONFIG_SCROLL_NO_SCROLL) {
|
||||
asprintf(&str, "none");
|
||||
xasprintf(&str, "none");
|
||||
return str;
|
||||
}
|
||||
|
||||
method = libinput_device_config_scroll_get_default_method(device);
|
||||
|
||||
asprintf(&str,
|
||||
xasprintf(&str,
|
||||
"%s%s%s%s%s%s",
|
||||
(method == LIBINPUT_CONFIG_SCROLL_2FG) ? "*" : "",
|
||||
(scroll_methods & LIBINPUT_CONFIG_SCROLL_2FG) ? "two-finger " : "",
|
||||
|
|
@ -176,12 +176,12 @@ click_defaults(struct libinput_device *device)
|
|||
|
||||
click_methods = libinput_device_config_click_get_methods(device);
|
||||
if (click_methods == LIBINPUT_CONFIG_CLICK_METHOD_NONE) {
|
||||
asprintf(&str, "none");
|
||||
xasprintf(&str, "none");
|
||||
return str;
|
||||
}
|
||||
|
||||
method = libinput_device_config_click_get_default_method(device);
|
||||
asprintf(&str,
|
||||
xasprintf(&str,
|
||||
"%s%s%s%s",
|
||||
(method == LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) ? "*" : "",
|
||||
(click_methods & LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) ? "button-areas " : "",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue