diff --git a/doc/Makefile.am b/doc/Makefile.am
index 58ae2161..efd4d857 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -14,6 +14,7 @@ header_files = \
$(srcdir)/clickpad-softbuttons.dox \
$(srcdir)/device-configuration-via-udev.dox \
$(srcdir)/faqs.dox \
+ $(srcdir)/gestures.dox \
$(srcdir)/normalization-of-relative-motion.dox \
$(srcdir)/palm-detection.dox \
$(srcdir)/scrolling.dox \
@@ -33,8 +34,11 @@ diagram_files = \
$(srcdir)/svg/button-scrolling.svg \
$(srcdir)/svg/edge-scrolling.svg \
$(srcdir)/svg/palm-detection.svg \
+ $(srcdir)/svg/pinch-gestures.svg \
+ $(srcdir)/svg/swipe-gestures.svg \
$(srcdir)/svg/tap-n-drag.svg \
$(srcdir)/svg/top-software-buttons.svg \
+ $(srcdir)/svg/touchscreen-gestures.svg \
$(srcdir)/svg/twofinger-scrolling.svg
html/index.html: libinput.doxygen $(header_files) $(diagram_files)
diff --git a/doc/gestures.dox b/doc/gestures.dox
new file mode 100644
index 00000000..a8cef36d
--- /dev/null
+++ b/doc/gestures.dox
@@ -0,0 +1,91 @@
+/**
+@page gestures Gestures
+
+libinput supports basic gestures on touchpads and other indirect input
+devices. Two types of gestures are supported: @ref gestures_pinch and @ref
+gestures_swipe. Support for gestures depends on the hardware device, most
+touchpads support both gestures and any device that may send gesture events
+has the @ref LIBINPUT_DEVICE_CAP_GESTURE capability set.
+
+Note that libinput **does not** support gestures on touchscreens, see
+@ref gestures_touchscreens.
+
+@section gestures_lifetime Lifetime of a gesture
+
+A gesture's lifetime has three distinct stages: begin, update and end, each
+with their own event types. Begin is sent when the fingers are first set
+down or libinput decides that the gesture begins. For @ref gestures_pinch
+this sets the initial scale. Any events changing properties of the gesture
+are sent as update events. On termination of the gesture, an end event is
+sent.
+
+A gesture includes the finger count (see
+libinput_event_gesture_get_finger_count()) and that finger count remains the
+same for the lifetime of a gesture. Thus, if a user puts down a fourth
+finger during a three-finger swipe gesture, libinput will end
+the three-finger gesture and, if applicable, start a four-finger swipe
+gesture. A caller may decide that those gestures are semantically identical
+and continue the two gestures as one single gesture.
+
+@see LIBINPUT_EVENT_GESTURE_PINCH_BEGIN
+@see LIBINPUT_EVENT_GESTURE_PINCH_UPDATE
+@see LIBINPUT_EVENT_GESTURE_PINCH_END
+@see LIBINPUT_EVENT_GESTURE_PINCH_BEGIN
+@see LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE
+@see LIBINPUT_EVENT_GESTURE_SWIPE_END
+
+@section gestures_pinch Pinch gestures
+
+Pinch gestures are executed when two or more fingers are located on the
+touchpad and are either changing the relative distance to each other
+(pinching) or are changing the relative angle (rotate). Pinch gestures may
+change both rotation and distance at the same time. For such gestures,
+libinput calculates a logical center for the gestures and provides the
+caller with the delta x/y coordinates of that center, the relative angle of
+the fingers compared to the previous event, and the absolute scale compared
+to the initial finger position.
+
+@image html pinch-gestures.svg "The pinch and rotate gestures"
+
+The illustration above shows a basic pinch in the left image and a rotate in
+the right angle. Not shown is a movement of the logical center if the
+fingers move unevenly. Such a movement is supported by libinput, it is
+merely left out of the illustration.
+
+Note that while position and angle is relative to the previous event, the
+scale is always absolute and a multiplier of the initial finger position's
+scale.
+
+@section gestures_swipe Swipe gestures
+
+Swipe gestures are executed when three or more fingers are moved
+synchronously in the same direction. libinput provides x and y coordinates
+in the gesture and thus allows swipe gestures in any direction, including
+the tracing of complex paths. It is up to the caller to interpret the
+gesture into an action or limit a gesture to specific directions only.
+
+@image html swipe-gestures.svg "The swipe gestures"
+
+The illustration above shows a vertical three-finger swipe. The coordinates
+provided during the gesture are the movements of the logical center.
+
+@section gestures_touchscreens Touchscreen gestures
+
+Touchscreen gestures are **not** interpreted by libinput. Rather, any touch
+point is passed to the caller and any interpretation of gestures is up to
+the caller or, eventually, the X or Wayland client.
+
+Interpreting gestures on a touchscreen requires context that libinput does
+not have, such as the location of windows and other virtual objects on the
+screen as well as the context of those virtual objects:
+
+@image html touchscreen-gestures.svg "Context-sensitivity of touchscreen gestures"
+
+In this example, the finger movements are identical but in the left case
+both fingers are located within the same window, thus suggesting an attemp
+to zoom. In the right case both fingers are located on a window border,
+thus suggesting a window movement. libinput only has knowledge of the finger
+coordinates (and even then only in device coordinates, not in screen
+coordinates) and thus cannot differentiate the two.
+
+*/
diff --git a/doc/svg/pinch-gestures.svg b/doc/svg/pinch-gestures.svg
new file mode 100644
index 00000000..4dca4cf4
--- /dev/null
+++ b/doc/svg/pinch-gestures.svg
@@ -0,0 +1,612 @@
+
+
+
+
diff --git a/doc/svg/swipe-gestures.svg b/doc/svg/swipe-gestures.svg
new file mode 100644
index 00000000..a88f646b
--- /dev/null
+++ b/doc/svg/swipe-gestures.svg
@@ -0,0 +1,512 @@
+
+
+
+
diff --git a/doc/svg/touchscreen-gestures.svg b/doc/svg/touchscreen-gestures.svg
new file mode 100644
index 00000000..8452c7e0
--- /dev/null
+++ b/doc/svg/touchscreen-gestures.svg
@@ -0,0 +1,440 @@
+
+
+
+
diff --git a/src/libinput.h b/src/libinput.h
index d23f8fdb..3595fd1d 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -955,6 +955,8 @@ libinput_event_touch_get_base_event(struct libinput_event_touch *event);
* LIBINPUT_EVENT_GESTURE_FOO_UPDATE type until a
* LIBINPUT_EVENT_GESTURE_FOO_END is generated which signals the end of the
* gesture.
+ *
+ * See @ref gestures for more information on gesture handling.
*/
/**