absolute_axes.html 8.81 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
<!-- HTML header for doxygen 1.8.8-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <!-- For Mobile Devices -->
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
        <meta name="generator" content="Doxygen 1.8.13"/>
        <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
        <title>libinput: Absolute axes</title>
        <!--<link href="tabs.css" rel="stylesheet" type="text/css"/>-->
        <script type="text/javascript" src="dynsections.js"></script>
        <script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
</script><script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js"></script>
        <link href="doxygen.css" rel="stylesheet" type="text/css" />
        <link href="bootstrap.css" rel="stylesheet" type="text/css"/>
<link href="customdoxygen.css" rel="stylesheet" type="text/css"/>
<link href="libinputdoxygen.css" rel="stylesheet" type="text/css"/>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
        <script type="text/javascript" src="doxy-boot.js"></script>
    </head>
    <body>
        <nav class="navbar navbar-default" role="navigation">
            <div class="container">
                <div class="navbar-header">
                    <a class="navbar-brand">libinput 1.7.0</a>
                </div>
            </div>
        </nav>
        <div id="top"><!-- do not remove this div, it is closed by doxygen! -->
            <div class="content" id="content">
                <div class="container">
                    <div class="row">
                        <div class="col-sm-12 panel panel-default" style="padding-bottom: 15px;">
                            <div style="margin-bottom: 15px;">
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('',false,false,'search.php','Search');
});
</script>
<div id="main-nav"></div>
<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="touchscreens.html">Touchscreens</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Absolute axes </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>Devices with absolute axes are those that send positioning data for an axis in a device-specific coordinate range, defined by a minimum and a maximum value.</p>
<p>Compare this to relative devices (e.g. a mouse) that can only detect directional data, not positional data.</p>
<p>libinput supports three types of devices with absolute axes:</p>
<ul>
<li>multi-touch screens</li>
<li>single-touch screens</li>
<li><a class="el" href="tablet-support.html">graphics tablets</a></li>
</ul>
<p>Touchpads are technically absolute devices but libinput converts the axis values to directional motion and posts events as relative events. Touchpads do not count as absolute devices in libinput.</p>
<p>For all absolute devices in libinput, the default unit for x/y coordinates is in mm off the top left corner on the device, or more specifically off the device's sensor. If the device is physically rotated from its natural position and this rotation was communicated to libinput (e.g. <a class="el" href="group__config.html#ga9bbdef04c07804ce7c121133c04d4edf">by setting the device left-handed</a>), the coordinate origin is the top left corner of in the current rotation.</p>
<h1><a class="anchor" id="absolute_axes_handling"></a>
Handling of absolute coordinates</h1>
<p>In most use-cases, absolute input devices are mapped to a single screen. For direct input devices such as touchscreens the aspect ratio of the screen and the device match. Mapping the input device position to the output position is thus a simple mapping between two coordinates. libinput provides the API for this with</p>
<ul>
<li><a class="el" href="group__event__pointer.html#ga26fa3d0b2bcc7f0a7939b84dc8207021" title="Return the current absolute x coordinate of the pointer event, transformed to screen coordinates...">libinput_event_pointer_get_absolute_x_transformed()</a> for pointer events</li>
<li><a class="el" href="group__event__touch.html#gadd04ccc3a7b4564e5aca3c8592f090fe" title="Return the current absolute x coordinate of the touch event, transformed to screen coordinates...">libinput_event_touch_get_x_transformed()</a> for touch events</li>
</ul>
<p>libinput's API only provides the call to map into a single coordinate range. If the coordinate range has an offset, the compositor is responsible for applying that offset after the mapping. For example, if the device is mapped to the right of two outputs, add the output offset to the transformed coordinate.</p>
<h1><a class="anchor" id="absolute_axes_nores"></a>
Devices without x/y resolution</h1>
<p>An absolute device that does not provide a valid resolution is considered buggy and must be fixed in the kernel. Some touchpad devices do not provide resolution, those devices are correctly handled within libinput (touchpads are not absolute devices, as mentioned above).</p>
<h1><a class="anchor" id="calibration"></a>
Calibration of absolute devices</h1>
<p>Absolute devices may require calibration to map precisely into the output range required. This is done by setting a transformation matrix, see <a class="el" href="group__config.html#ga09a798f58cc601edd2797780096e9804" title="Apply the 3x3 transformation matrix to absolute device coordinates. ">libinput_device_config_calibration_set_matrix()</a> which is applied to each input coordinate.</p>
<p class="formulaDsp">
\[ \begin{pmatrix} cos\theta &amp; -sin\theta &amp; xoff \\ sin\theta &amp; cos\theta &amp; yoff \\ 0 &amp; 0 &amp; 1 \end{pmatrix} \begin{pmatrix} x \\ y \\ 1 \end{pmatrix} \]
</p>
<p>\(\theta\) is the rotation angle. The offsets \(xoff\) and \(yoff\) are specified in device dimensions, i.e. a value of 1 equals one device width or height. Note that rotation applies to the device's origin, rotation usually requires an offset to move the coordinates back into the original range.</p>
<p>The most common matrices are:</p>
<ul>
<li>90 degree clockwise: \( \begin{pmatrix} 0 &amp; -1 &amp; 1 \\ 1 &amp; 0 &amp; 0 \\ 0 &amp; 0 &amp; 1 \end{pmatrix} \)</li>
<li>180 degree clockwise: \( \begin{pmatrix} -1 &amp; 0 &amp; 1 \\ 0 &amp; -1 &amp; 1 \\ 0 &amp; 0 &amp; 1 \end{pmatrix} \)</li>
<li>270 degree clockwise: \( \begin{pmatrix} 0 &amp; 1 &amp; 0 \\ -1 &amp; 0 &amp; 1 \\ 0 &amp; 0 &amp; 1 \end{pmatrix} \)</li>
<li>reflection along y axis: \( \begin{pmatrix} -1 &amp; 0 &amp; 1 \\ 1 &amp; 0 &amp; 0 \\ 0 &amp; 0 &amp; 1 \end{pmatrix} \)</li>
</ul>
<p>See Wikipedia's <a href="http://en.wikipedia.org/wiki/Transformation_matrix">Transformation Matrix article</a> for more information on the matrix maths. See <a class="el" href="group__config.html#ga3d9f1b9be10e804e170c4ea455bd1f1b" title="Return the default calibration matrix for this device. ">libinput_device_config_calibration_get_default_matrix()</a> for how these matrices must be supplied to libinput.</p>
<p>Once applied, any x and y axis value has the calibration applied before it is made available to the caller. libinput does not provide access to the raw coordinates before the calibration is applied.</p>
<h1><a class="anchor" id="absolute_axes_nonorm"></a>
Why x/y coordinates are not normalized</h1>
<p>x/y are not given in <a class="el" href="motion_normalization.html">normalized coordinates</a> ([0..1]) for one simple reason: the aspect ratio of virtually all current devices is something other than 1:1. A normalized axes thus is only useful to determine that the stylus is e.g. at 78% from the left, 34% from the top of the device. Without knowing the per-axis resolution, these numbers are meaningless. Worse, calculation based on previous coordinates is simply wrong: a movement from 0/0 to 50%/50% is not a 45% degree line.</p>
<p>This could be alleviated by providing resolution and information about the aspect ratio to the caller. Which shifts processing and likely errors into the caller for little benefit. Providing the x/y axes in mm from the outset removes these errors. </p>
</div></div><!-- contents -->
<!-- HTML footer for doxygen 1.8.8-->
<!-- start footer part -->
</div>
</div>
</div>
</div>
</div>
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
</body>
</html>