├── .gitignore ├── COPYING ├── CREDITS ├── Makefile.am ├── Makefile.in ├── README.md ├── RELEASE.md ├── aclocal.m4 ├── compile ├── config.guess ├── config.h.in ├── config.sub ├── configure ├── configure.ac ├── debian ├── README.Debian ├── changelog ├── compat ├── control ├── copyright ├── dirs └── rules ├── depcomp ├── driver ├── mprops.c └── mtrack.c ├── include ├── button.h ├── capabilities.h ├── common.h ├── gestures.h ├── hwstate.h ├── mconfig.h ├── mprops.h ├── mtouch.h ├── mtstate.h └── trig.h ├── install-sh ├── ltmain.sh ├── m4 ├── .keep ├── libtool.m4 ├── ltoptions.m4 ├── ltsugar.m4 ├── ltversion.m4 └── lt~obsolete.m4 ├── missing ├── src ├── capabilities.c ├── gestures.c ├── hwstate.c ├── mconfig.c ├── mtouch.c ├── mtstate.c └── trig.c └── tools └── mtrack-test.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.la 2 | *.lo 3 | *.o 4 | *.sw? 5 | .deps 6 | .dirstamp 7 | .libs 8 | Makefile 9 | autom4te.cache 10 | config.h 11 | config.log 12 | config.status 13 | libtool 14 | mtrack-test 15 | stamp-h1 16 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) year name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | This is a copy of the CREDITS file from the xf86-input-multitouch driver. 2 | 3 | --- 4 | 5 | Multitouch X driver (GPL license) 6 | 7 | Copyright (C) 2008 Henrik Rydberg 8 | 9 | This program is free software; you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation; either version 2 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | 23 | --- 24 | 25 | The Multitouch X driver extracts a lot of X knowledge from the 26 | synaptics X driver (MIT license) 27 | 28 | Copyright (C) 1997 C. Scott Ananian 29 | Copyright (C) 1998-2000 Bruce Kalk 30 | Copyright (C) 1999 Henry Davies 31 | Copyright (C) 2001 Stefan Gmeiner 32 | Copyright (C) 2002 Linuxcare Inc. David Kennedy 33 | Copyright (C) 2003 Fred Hucht 34 | Copyright (C) 2003 Neil Brown 35 | Copyright (C) 2003 Jörg Bösner 36 | Copyright (C) 2003 Hartwig Felger 37 | Copyright (C) 2002-2007 Peter Osterlund 38 | Copyright (C) 2004 Arne Schwabe 39 | Copyright (C) 2004 Matthias Ihmig 40 | Copyright (C) 2004 Alexei Gilchrist 41 | Copyright (C) 2006-2007 Christian Thaeter 42 | Copyright (C) 2006 Stefan Bethge 43 | Copyright (C) 2007 Joseph P. Skudlarek 44 | Copyright (C) 2007 Florian Loitsch 45 | Copyright (C) 2008 Fedor P. Goncharov 46 | Copyright (C) 2008-2009 Red Hat, Inc. 47 | 48 | Permission is hereby granted, free of charge, to any person obtaining a copy 49 | of this software and associated documentation files (the "Software"), to deal 50 | in the Software without restriction, including without limitation the rights 51 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 52 | copies of the Software, and to permit persons to whom the Software is 53 | furnished to do so, subject to the following conditions: 54 | 55 | The above copyright notice and this permission notice shall be included in 56 | all copies or substantial portions of the Software. 57 | 58 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 59 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 60 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 61 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 62 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 63 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 64 | THE SOFTWARE. 65 | 66 | --- 67 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SOURCES_COMMON = \ 2 | src/capabilities.c \ 3 | src/gestures.c \ 4 | src/hwstate.c \ 5 | src/mconfig.c \ 6 | src/mtouch.c \ 7 | src/mtstate.c \ 8 | src/trig.c 9 | 10 | @DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la 11 | @DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version 12 | @DRIVER_NAME@_drv_la_SOURCES = $(SOURCES_COMMON) \ 13 | driver/mtrack.c \ 14 | driver/mprops.c 15 | @DRIVER_NAME@_drv_ladir = @inputdir@ 16 | 17 | noinst_PROGRAMS = mtrack-test 18 | mtrack_test_SOURCES = $(SOURCES_COMMON) \ 19 | tools/mtrack-test.c 20 | mtrack_test_CFLAGS = $(AM_CFLAGS) 21 | 22 | ACLOCAL_AMFLAGS = -I m4 23 | AM_CPPFLAGS = -I$(top_srcdir)/include/ \ 24 | -I/usr/include/xorg \ 25 | -I/usr/include/pixman-1 26 | AM_CFLAGS = $(XORG_CFLAGS) 27 | 28 | .PHONY: ChangeLog INSTALL 29 | 30 | INSTALL: 31 | $(INSTALL_CMD) 32 | 33 | ChangeLog: 34 | $(CHANGELOG_CMD) 35 | 36 | dist-hook: ChangeLog INSTALL 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | xf86-input-mtrack 2 | ================= 3 | 4 | An Xorg driver for multitouch trackpads. Supports any trackpad whose kernel 5 | driver uses the slotted multitouch protocol. For more information on the 6 | protocol see the [kernel documentation][1]. 7 | 8 | This driver is compatible with Xorg server versions 1.7 to 1.12. It requires 9 | the [mtdev][4] library to operate. 10 | 11 | License 12 | ------- 13 | 14 | * Copyright (C) 2011 Ryan Bourgeois 15 | * Copyright (C) 2008 Henrik Rydberg 16 | 17 | This software is licensed under the [GPLv2][2] and is a fork of the 18 | [xf86-input-multitouch][3] driver by Henrik Rydberg. 19 | 20 | Building and Installing 21 | ----------------------- 22 | This is a standard autoconf package. So: 23 | 24 | ./configure 25 | make && make install 26 | 27 | It is likely that you will need to change system-dependent paths such as the 28 | xorg module directory. See `configure --help` for options. 29 | 30 | Configuration 31 | ------------- 32 | 33 | The following is a minimal working InputClass section for xorg.conf: 34 | 35 | Section "InputClass" 36 | MatchIsTouchpad "on" 37 | Identifier "Touchpads" 38 | Driver "mtrack" 39 | EndSection 40 | 41 | Configuration options may be defined inside the InputClass section to configure 42 | the driver. Available options and their defaults are as follows. 43 | 44 | **TrackpadDisable** - 45 | Disables trackpad touch input. A value of 0 will enable the trackpad. A value 46 | of 1 will disable tapping and gestures but not movement. A value of 2 will 47 | disable all input. A value of 3 will also disable physical buttons. Integer. 48 | Default is 0. 49 | 50 | **Sensitivity** - 51 | Adjusts the sensitivity (movement speed) of the touchpad. This is a real number 52 | greater than or equal to zero. Default is 1. A value of 0 will disable pointer 53 | movement. 54 | 55 | **FingerHigh** - 56 | Defines the pressure at which a finger is detected as a touch. This is a 57 | percentage represented as an integer. Default is 5. 58 | 59 | **FingerLow** - 60 | Defines the pressure at which a finger is detected as a release. This is a 61 | percentage represented as an integer. Default is 5. 62 | 63 | **IgnoreThumb** - 64 | Whether or not to ignore touches that are determined to be thumbs. Boolean 65 | value. Defaults to false. 66 | 67 | **IgnorePalm** - 68 | Whether or not to ignore touches that are determined to be palms. Boolean 69 | value. Defaults to false. 70 | 71 | **DisableOnThumb** - 72 | Whether or not to disable the entire trackpad when a thumb is touching. Boolean 73 | value. Defaults to false. 74 | 75 | **DisableOnPalm** - 76 | Whether or not to disable the entire trackpad when a palm is touching. Boolean 77 | value. Defaults to false. 78 | 79 | **ThumbRatio** - 80 | The width/length ratio of what's considered a thumb. It is expected that a 81 | thumb is longer than it is wide. This tells the driver how much longer. 82 | Percentage represented by an integer. Defaults to 70. 83 | 84 | **ThumbSize** - 85 | The minimum size of what's considered a thumb. It is expected that a thumb 86 | will be larger than other fingers. This is represented as a percentage of the 87 | maximum touch value and is dependent on the trackpad hardware. Integer value. 88 | Defaults to 25. 89 | 90 | **PalmSize** - 91 | The minimum size of what's considered a palm. Palms are expected to be very 92 | large on the trackpad. This is represented as a percentage of the maximum touch 93 | value and is dependent on the trackpad hardware. Integer value. Defaults to 40. 94 | 95 | **BottomEdge** - 96 | The size of an area at the bottom of the trackpad where new touches are ignored 97 | (fingers traveling into this area from above will still be tracked). This is 98 | represented as a percentage of the total trackpad height. Defaults to 10. 99 | 100 | **ButtonEnable** - 101 | Whether or not to enable the physical buttons on or near the trackpad. Boolean 102 | value. Defaults to true. 103 | 104 | **ButtonIntegrated** - 105 | Whether or not the physical buttons are integrated with the trackpad. If you 106 | have a one-piece trackpad like on newer MacBooks, this should be set to true. 107 | Button emulation depends on this value being correct. Boolean value. Defaults 108 | to true. 109 | 110 | **ButtonMoveEmulate** 111 | Whether or not to count the moving finger when emulating button clicks. Useful to disable if you use two hands on trackpad. Boolean value. Defaults to true. 112 | 113 | **ButtonZonesEnable** - 114 | Whether or not to enable button zones. If button zones are enabled then the 115 | trackpad will be split into one, two, or three vertical zones. Clicking the 116 | integrated button in one of these zones will send the button event for 117 | ClickFinger1, ClickFinger2, or ClickFinger3. The driver will only add zones for 118 | those ClickFinger values that are enabled. So setting ClickFinger1 to 0 and 119 | enabling the other two will create two zones, one for ClickFinger2 and one for 120 | ClickFinger3. Boolean value. Defaults to false. 121 | 122 | **ButtonTouchExpire** - 123 | How long (in ms) to consider a touching finger as part of button emulation. A 124 | value of 0 will not expire touches. Integer value. Defaults to 100. 125 | 126 | **ClickFinger1** - 127 | Which button to emulate when one finger is touching the trackpad during a 128 | click. Integer value. A value of 0 disables one-touch emulation. Defaults to 3. 129 | 130 | **ClickFinger2** - 131 | Which button to emulate when two fingers are touching the trackpad during a 132 | click. Integer value. A value of 0 disabled one-touch emulation. Defaults to 2. 133 | 134 | **ClickFinger3** - 135 | Which button to emulate when three fingers are touching the trackpad during a 136 | click. Integer value. A value of 0 disabled one-touch emulation. Defaults to 0. 137 | 138 | **TapButton1** - 139 | Which button to emulate for one-finger tapping. Integer value. A value of 0 140 | disables one-finger tapping. Defaults to 1. 141 | 142 | **TapButton2** - 143 | Which button to emulate for two-finger tapping. Integer value. A value of 0 144 | disables two-finger tapping. Defaults to 3. 145 | 146 | **TapButton3** - 147 | Which button to emulate for three-finger tapping. Integer value. A value of 0 148 | disables three-finger tapping. Defaults to 2. 149 | 150 | **TapButton4** - 151 | Which button to emulate for four-finger tapping. Integer value. A value of 0 152 | disables three-finger tapping. Defaults to 0. 153 | 154 | **ClickTime** - 155 | When tapping, how much time to hold down the emulated button. Integer value 156 | representing milliseconds. Defaults to 50. 157 | 158 | **MaxTapTime** - 159 | The amount of time to wait for a tap to release before counting it as a move. 160 | Integer value representing milliseconds. Defaults to 120. 161 | 162 | **MaxTapMove** - 163 | How far a touch is allowed to move before counting it is no longer considered a 164 | tap. Integer value. Defaults to 400. 165 | 166 | **GestureClickTime** - 167 | When a gesture triggers a click, how much time to hold down the emulated button. 168 | Integer value representing milliseconds. Defaults to 10. 169 | 170 | **GestureWaitTime** - 171 | Touches are allowed to transition from one gesture to another. For example, you 172 | may go from scrolling to swiping without releasing your fingers from the pad. 173 | This value is the amount of time you must be performing the new gesture before 174 | it is triggered. This prevents accidental touches from triggering other 175 | gestures. Integer value representing milliseconds. Defaults to 100. 176 | 177 | **ScrollDistance** - 178 | For two finger scrolling. How far you must move your fingers before a button 179 | click is triggered. Integer value. Defaults to 150. 180 | 181 | **ScrollUpButton** - 182 | For two finger scrolling. The button that is triggered by scrolling up. Integer 183 | value. A value of 0 disables scrolling up. Defaults to 4. 184 | 185 | **ScrollDownButton** - 186 | For two finger scrolling. The button that is triggered by scrolling down. 187 | Integer value. A value of 0 disables scrolling down. Defaults to 5. 188 | 189 | **ScrollLeftButton** - 190 | For two finger scrolling. The button that is triggered by scrolling left. 191 | Integer value. A value of 0 disables scrolling left. Defaults to 6. 192 | 193 | **ScrollRightButton** - 194 | For two finger scrolling. The button that is triggered by scrolling right. 195 | Integer value. A value of 0 disables scrolling right. Defaults to 7. 196 | 197 | **SwipeDistance** - 198 | For three finger swiping. How far you must move your fingers before a button 199 | click is triggered. Integer value. Defaults to 700. 200 | 201 | **SwipeUpButton** - 202 | For three finger swiping. The button that is triggered by swiping up. Integer 203 | value. A value of 0 disables swiping up. Defaults to 8. 204 | 205 | **SwipeDownButton** - 206 | For three finger swiping. The button that is triggered by swiping down. Integer 207 | value. A value of 0 disables swiping down. Defaults to 9. 208 | 209 | **SwipeLeftButton** - 210 | For three finger swiping. The button that is triggered by swiping left. Integer 211 | value. A value of 0 disables swiping left. Defaults to 10. 212 | 213 | **SwipeRightButton** - 214 | For three finger swiping. The button that is triggered by swiping right. Integer 215 | value. A value of 0 disables swiping right. Defaults to 11. 216 | 217 | **Swipe4Distance** - 218 | For four finger swiping. How far you must move your fingers before a button 219 | click is triggered. Integer value. Defaults to 700. 220 | 221 | **Swipe4UpButton** - 222 | For four finger swiping. The button that is triggered by swiping up. Integer 223 | value. A value of 0 disables swiping up. Defaults to 8. 224 | 225 | **Swipe4DownButton** - 226 | For four finger swiping. The button that is triggered by swiping down. Integer 227 | value. A value of 0 disables swiping down. Defaults to 9. 228 | 229 | **Swipe4LeftButton** - 230 | For four finger swiping. The button that is triggered by swiping left. Integer 231 | value. A value of 0 disables swiping left. Defaults to 10. 232 | 233 | **Swipe4RightButton** - 234 | For four finger swiping. The button that is triggered by swiping right. Integer 235 | value. A value of 0 disables swiping right. Defaults to 11. 236 | 237 | **ScaleDistance** - 238 | For pinch scaling. How far you must move your fingers before a button click is 239 | triggered. Integer value. Defaults to 150. 240 | 241 | **ScaleUpButton** - 242 | For pinch scaling. The button that is triggered by scaling up. Integer value. A 243 | value of 0 disables scaling up. Defaults to 12. 244 | 245 | **ScaleDownButton** - 246 | For pinch scaling. The button that is triggered by scaling down. Integer value. 247 | A value of 0 disables scaling down. Defaults to 13. 248 | 249 | **RotateDistance** - 250 | For two finger rotation. How far you must move your fingers before a button 251 | click is triggered. Integer value. Defaults to 150. 252 | 253 | **RotateLeftButton** - 254 | For two finger rotation. The button that is triggered by rotating left. Integer 255 | value. A value of 0 disables rotation left. Defaults to 14. 256 | 257 | **RotateRightButton** - 258 | For two finger rotation. The button that is triggered by rotating right. Integer 259 | value. A value of 0 disables rotation right. Defaults to 15. 260 | 261 | **TapDragEnable** - 262 | Whether or not to enable tap-to-drag functionality. Boolean value. Defaults to 263 | true. 264 | 265 | **TapDragTime** - 266 | The tap-to-drag timeout. This is how long the driver will wait after a single 267 | tap for a movement event before sending the click. Integer value representing 268 | milliseconds. Defaults to 350. 269 | 270 | **TapDragWait** 271 | How long after detecting movement to trigger a button down event. During this 272 | time pointer movement will be disabled. Increase this value if you find you're 273 | draggin when you don't wish it. Integer value representing milliseconds. 274 | Defaults to 40. 275 | 276 | **TapDragDist** 277 | How far the finger is allowed to move during drag wait time. If the finger 278 | moves farther than this distance during the wait time then dragging will be 279 | canceled and pointer movement will resume. Integer value. Defaults to 200. 280 | 281 | **AxisXInvert** 282 | Whether or not to invert the X axis. Boolean value. Defaults to false. 283 | 284 | **AxisYInvert** 285 | Whether or not to invert the Y axis. Boolean value. Defaults to false. 286 | 287 | [1]: http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt "Kernel Multitouch Protocol" 288 | [2]: http://www.gnu.org/licenses/gpl-2.0.html "GNU General Public License, version 2" 289 | [3]: http://bitmath.org/code/multitouch/ "xf86-input-multitouch website" 290 | [4]: http://bitmath.org/code/mtdev/ "mtdev library website" 291 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | ## v0.3.1 2 | * Include a configure script. 3 | * Update the README. 4 | * Add the RELEASE file. 5 | -------------------------------------------------------------------------------- /compile: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Wrapper for compilers which do not understand '-c -o'. 3 | 4 | scriptversion=2012-10-14.11; # UTC 5 | 6 | # Copyright (C) 1999-2014 Free Software Foundation, Inc. 7 | # Written by Tom Tromey . 8 | # 9 | # This program is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2, or (at your option) 12 | # any later version. 13 | # 14 | # This program is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with this program. If not, see . 21 | 22 | # As a special exception to the GNU General Public License, if you 23 | # distribute this file as part of a program that contains a 24 | # configuration script generated by Autoconf, you may include it under 25 | # the same distribution terms that you use for the rest of that program. 26 | 27 | # This file is maintained in Automake, please report 28 | # bugs to or send patches to 29 | # . 30 | 31 | nl=' 32 | ' 33 | 34 | # We need space, tab and new line, in precisely that order. Quoting is 35 | # there to prevent tools from complaining about whitespace usage. 36 | IFS=" "" $nl" 37 | 38 | file_conv= 39 | 40 | # func_file_conv build_file lazy 41 | # Convert a $build file to $host form and store it in $file 42 | # Currently only supports Windows hosts. If the determined conversion 43 | # type is listed in (the comma separated) LAZY, no conversion will 44 | # take place. 45 | func_file_conv () 46 | { 47 | file=$1 48 | case $file in 49 | / | /[!/]*) # absolute file, and not a UNC file 50 | if test -z "$file_conv"; then 51 | # lazily determine how to convert abs files 52 | case `uname -s` in 53 | MINGW*) 54 | file_conv=mingw 55 | ;; 56 | CYGWIN*) 57 | file_conv=cygwin 58 | ;; 59 | *) 60 | file_conv=wine 61 | ;; 62 | esac 63 | fi 64 | case $file_conv/,$2, in 65 | *,$file_conv,*) 66 | ;; 67 | mingw/*) 68 | file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` 69 | ;; 70 | cygwin/*) 71 | file=`cygpath -m "$file" || echo "$file"` 72 | ;; 73 | wine/*) 74 | file=`winepath -w "$file" || echo "$file"` 75 | ;; 76 | esac 77 | ;; 78 | esac 79 | } 80 | 81 | # func_cl_dashL linkdir 82 | # Make cl look for libraries in LINKDIR 83 | func_cl_dashL () 84 | { 85 | func_file_conv "$1" 86 | if test -z "$lib_path"; then 87 | lib_path=$file 88 | else 89 | lib_path="$lib_path;$file" 90 | fi 91 | linker_opts="$linker_opts -LIBPATH:$file" 92 | } 93 | 94 | # func_cl_dashl library 95 | # Do a library search-path lookup for cl 96 | func_cl_dashl () 97 | { 98 | lib=$1 99 | found=no 100 | save_IFS=$IFS 101 | IFS=';' 102 | for dir in $lib_path $LIB 103 | do 104 | IFS=$save_IFS 105 | if $shared && test -f "$dir/$lib.dll.lib"; then 106 | found=yes 107 | lib=$dir/$lib.dll.lib 108 | break 109 | fi 110 | if test -f "$dir/$lib.lib"; then 111 | found=yes 112 | lib=$dir/$lib.lib 113 | break 114 | fi 115 | if test -f "$dir/lib$lib.a"; then 116 | found=yes 117 | lib=$dir/lib$lib.a 118 | break 119 | fi 120 | done 121 | IFS=$save_IFS 122 | 123 | if test "$found" != yes; then 124 | lib=$lib.lib 125 | fi 126 | } 127 | 128 | # func_cl_wrapper cl arg... 129 | # Adjust compile command to suit cl 130 | func_cl_wrapper () 131 | { 132 | # Assume a capable shell 133 | lib_path= 134 | shared=: 135 | linker_opts= 136 | for arg 137 | do 138 | if test -n "$eat"; then 139 | eat= 140 | else 141 | case $1 in 142 | -o) 143 | # configure might choose to run compile as 'compile cc -o foo foo.c'. 144 | eat=1 145 | case $2 in 146 | *.o | *.[oO][bB][jJ]) 147 | func_file_conv "$2" 148 | set x "$@" -Fo"$file" 149 | shift 150 | ;; 151 | *) 152 | func_file_conv "$2" 153 | set x "$@" -Fe"$file" 154 | shift 155 | ;; 156 | esac 157 | ;; 158 | -I) 159 | eat=1 160 | func_file_conv "$2" mingw 161 | set x "$@" -I"$file" 162 | shift 163 | ;; 164 | -I*) 165 | func_file_conv "${1#-I}" mingw 166 | set x "$@" -I"$file" 167 | shift 168 | ;; 169 | -l) 170 | eat=1 171 | func_cl_dashl "$2" 172 | set x "$@" "$lib" 173 | shift 174 | ;; 175 | -l*) 176 | func_cl_dashl "${1#-l}" 177 | set x "$@" "$lib" 178 | shift 179 | ;; 180 | -L) 181 | eat=1 182 | func_cl_dashL "$2" 183 | ;; 184 | -L*) 185 | func_cl_dashL "${1#-L}" 186 | ;; 187 | -static) 188 | shared=false 189 | ;; 190 | -Wl,*) 191 | arg=${1#-Wl,} 192 | save_ifs="$IFS"; IFS=',' 193 | for flag in $arg; do 194 | IFS="$save_ifs" 195 | linker_opts="$linker_opts $flag" 196 | done 197 | IFS="$save_ifs" 198 | ;; 199 | -Xlinker) 200 | eat=1 201 | linker_opts="$linker_opts $2" 202 | ;; 203 | -*) 204 | set x "$@" "$1" 205 | shift 206 | ;; 207 | *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) 208 | func_file_conv "$1" 209 | set x "$@" -Tp"$file" 210 | shift 211 | ;; 212 | *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) 213 | func_file_conv "$1" mingw 214 | set x "$@" "$file" 215 | shift 216 | ;; 217 | *) 218 | set x "$@" "$1" 219 | shift 220 | ;; 221 | esac 222 | fi 223 | shift 224 | done 225 | if test -n "$linker_opts"; then 226 | linker_opts="-link$linker_opts" 227 | fi 228 | exec "$@" $linker_opts 229 | exit 1 230 | } 231 | 232 | eat= 233 | 234 | case $1 in 235 | '') 236 | echo "$0: No command. Try '$0 --help' for more information." 1>&2 237 | exit 1; 238 | ;; 239 | -h | --h*) 240 | cat <<\EOF 241 | Usage: compile [--help] [--version] PROGRAM [ARGS] 242 | 243 | Wrapper for compilers which do not understand '-c -o'. 244 | Remove '-o dest.o' from ARGS, run PROGRAM with the remaining 245 | arguments, and rename the output as expected. 246 | 247 | If you are trying to build a whole package this is not the 248 | right script to run: please start by reading the file 'INSTALL'. 249 | 250 | Report bugs to . 251 | EOF 252 | exit $? 253 | ;; 254 | -v | --v*) 255 | echo "compile $scriptversion" 256 | exit $? 257 | ;; 258 | cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) 259 | func_cl_wrapper "$@" # Doesn't return... 260 | ;; 261 | esac 262 | 263 | ofile= 264 | cfile= 265 | 266 | for arg 267 | do 268 | if test -n "$eat"; then 269 | eat= 270 | else 271 | case $1 in 272 | -o) 273 | # configure might choose to run compile as 'compile cc -o foo foo.c'. 274 | # So we strip '-o arg' only if arg is an object. 275 | eat=1 276 | case $2 in 277 | *.o | *.obj) 278 | ofile=$2 279 | ;; 280 | *) 281 | set x "$@" -o "$2" 282 | shift 283 | ;; 284 | esac 285 | ;; 286 | *.c) 287 | cfile=$1 288 | set x "$@" "$1" 289 | shift 290 | ;; 291 | *) 292 | set x "$@" "$1" 293 | shift 294 | ;; 295 | esac 296 | fi 297 | shift 298 | done 299 | 300 | if test -z "$ofile" || test -z "$cfile"; then 301 | # If no '-o' option was seen then we might have been invoked from a 302 | # pattern rule where we don't need one. That is ok -- this is a 303 | # normal compilation that the losing compiler can handle. If no 304 | # '.c' file was seen then we are probably linking. That is also 305 | # ok. 306 | exec "$@" 307 | fi 308 | 309 | # Name of file we expect compiler to create. 310 | cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` 311 | 312 | # Create the lock directory. 313 | # Note: use '[/\\:.-]' here to ensure that we don't use the same name 314 | # that we are using for the .o file. Also, base the name on the expected 315 | # object file name, since that is what matters with a parallel build. 316 | lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d 317 | while true; do 318 | if mkdir "$lockdir" >/dev/null 2>&1; then 319 | break 320 | fi 321 | sleep 1 322 | done 323 | # FIXME: race condition here if user kills between mkdir and trap. 324 | trap "rmdir '$lockdir'; exit 1" 1 2 15 325 | 326 | # Run the compile. 327 | "$@" 328 | ret=$? 329 | 330 | if test -f "$cofile"; then 331 | test "$cofile" = "$ofile" || mv "$cofile" "$ofile" 332 | elif test -f "${cofile}bj"; then 333 | test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" 334 | fi 335 | 336 | rmdir "$lockdir" 337 | exit $ret 338 | 339 | # Local Variables: 340 | # mode: shell-script 341 | # sh-indentation: 2 342 | # eval: (add-hook 'write-file-hooks 'time-stamp) 343 | # time-stamp-start: "scriptversion=" 344 | # time-stamp-format: "%:y-%02m-%02d.%02H" 345 | # time-stamp-time-zone: "UTC" 346 | # time-stamp-end: "; # UTC" 347 | # End: 348 | -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | /* config.h.in. Generated from configure.ac by autoheader. */ 2 | 3 | /* Enable driver debugging. */ 4 | #undef DEBUG_DRIVER 5 | 6 | /* Enable gesture debugging. */ 7 | #undef DEBUG_GESTURES 8 | 9 | /* Enable multitouch state debugging. */ 10 | #undef DEBUG_MTSTATE 11 | 12 | /* Enable property debugging. */ 13 | #undef DEBUG_PROPS 14 | 15 | /* Define to 1 if you have the header file. */ 16 | #undef HAVE_DLFCN_H 17 | 18 | /* Define to 1 if you have the header file. */ 19 | #undef HAVE_INTTYPES_H 20 | 21 | /* Define to 1 if you have the `m' library (-lm). */ 22 | #undef HAVE_LIBM 23 | 24 | /* Define to 1 if you have the `mtdev' library (-lmtdev). */ 25 | #undef HAVE_LIBMTDEV 26 | 27 | /* Define to 1 if you have the header file. */ 28 | #undef HAVE_MEMORY_H 29 | 30 | /* Define to 1 if you have the header file. */ 31 | #undef HAVE_STDINT_H 32 | 33 | /* Define to 1 if you have the header file. */ 34 | #undef HAVE_STDLIB_H 35 | 36 | /* Define to 1 if you have the header file. */ 37 | #undef HAVE_STRINGS_H 38 | 39 | /* Define to 1 if you have the header file. */ 40 | #undef HAVE_STRING_H 41 | 42 | /* Define to 1 if you have the header file. */ 43 | #undef HAVE_SYS_STAT_H 44 | 45 | /* Define to 1 if you have the header file. */ 46 | #undef HAVE_SYS_TYPES_H 47 | 48 | /* Define to 1 if you have the header file. */ 49 | #undef HAVE_UNISTD_H 50 | 51 | /* Define to the sub-directory in which libtool stores uninstalled libraries. 52 | */ 53 | #undef LT_OBJDIR 54 | 55 | /* Name of package */ 56 | #undef PACKAGE 57 | 58 | /* Define to the address where bug reports for this package should be sent. */ 59 | #undef PACKAGE_BUGREPORT 60 | 61 | /* Define to the full name of this package. */ 62 | #undef PACKAGE_NAME 63 | 64 | /* Define to the full name and version of this package. */ 65 | #undef PACKAGE_STRING 66 | 67 | /* Define to the one symbol short name of this package. */ 68 | #undef PACKAGE_TARNAME 69 | 70 | /* Define to the home page for this package. */ 71 | #undef PACKAGE_URL 72 | 73 | /* Define to the version of this package. */ 74 | #undef PACKAGE_VERSION 75 | 76 | /* Major version of this package */ 77 | #undef PACKAGE_VERSION_MAJOR 78 | 79 | /* Minor version of this package */ 80 | #undef PACKAGE_VERSION_MINOR 81 | 82 | /* Patch version of this package */ 83 | #undef PACKAGE_VERSION_PATCHLEVEL 84 | 85 | /* Define to 1 if you have the ANSI C header files. */ 86 | #undef STDC_HEADERS 87 | 88 | /* Version number of package */ 89 | #undef VERSION 90 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # Initialize Autoconf 2 | AC_PREREQ([2.60]) 3 | AC_INIT([xf86-input-mtrack], 4 | [0.2.0], 5 | [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], 6 | [xf86-input-mtrack]) 7 | AC_CONFIG_MACRO_DIR([m4]) 8 | AC_CONFIG_SRCDIR([Makefile.am]) 9 | AC_CONFIG_HEADERS([config.h]) 10 | AC_CONFIG_AUX_DIR(.) 11 | 12 | # Initialize Automake 13 | AM_INIT_AUTOMAKE([foreign subdir-objects]) 14 | AM_MAINTAINER_MODE 15 | 16 | # Initialize libtool 17 | AC_DISABLE_STATIC 18 | AC_PROG_LIBTOOL 19 | 20 | # Initialize X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS 21 | m4_ifndef([XORG_MACROS_VERSION], 22 | [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])]) 23 | XORG_MACROS_VERSION(1.8) 24 | XORG_DEFAULT_OPTIONS 25 | 26 | # Checks for libraries. 27 | AC_CHECK_LIB([mtdev], [mtdev_open]) 28 | AC_CHECK_LIB([m], [atan2]) 29 | 30 | # Obtain compiler/linker options for the mtrack driver dependencies 31 | PKG_CHECK_MODULES(XORG, [xorg-server >= 1.7] xproto inputproto $REQUIRED_MODULES) 32 | 33 | # Set driver name 34 | DRIVER_NAME=mtrack 35 | AC_SUBST([DRIVER_NAME]) 36 | 37 | # configure option for module install directory 38 | AC_ARG_WITH(xorg-module-dir, AC_HELP_STRING([--with-xorg-module-dir=DIR], 39 | [Default xorg module directory [[default=$libdir/xorg/modules]]]), 40 | [moduledir="$withval"], 41 | [moduledir="$libdir/xorg/modules"]) 42 | inputdir=${moduledir}/input 43 | AC_SUBST(inputdir) 44 | 45 | # configure option to build extra tools 46 | AC_ARG_ENABLE(tools, AC_HELP_STRING([--enable-tools], 47 | [Build extra tools (default: disabled)]), 48 | [ENABLE_TOOLS=yes], 49 | [ENABLE_TOOLS=no]) 50 | AM_CONDITIONAL([BUILD_TOOLS], [test "x$ENABLE_TOOLS" = xyes]) 51 | 52 | # configure option to enable gesture ate debugging 53 | AC_ARG_ENABLE(debug-gestures, AS_HELP_STRING([--enable-debug-gestures], 54 | [Enable gesture debugging (default: disabled)]), 55 | [DEBUG_GESTURES=yes], 56 | [DEBUG_GESTURES=no]) 57 | if test "x$DEBUG_GESTURES" = xyes; then 58 | AC_DEFINE(DEBUG_GESTURES, 1, [Enable gesture debugging.]) 59 | fi 60 | 61 | # configure option to enable multitouch state debugging 62 | AC_ARG_ENABLE(debug-mtstate, AS_HELP_STRING([--enable-debug-mtstate], 63 | [Enable multitouch state debugging (default: disabled)]), 64 | [DEBUG_MTSTATE=yes], 65 | [DEBUG_MTSTATE=no]) 66 | if test "x$DEBUG_MTSTATE" = xyes; then 67 | AC_DEFINE(DEBUG_MTSTATE, 1, [Enable multitouch state debugging.]) 68 | fi 69 | 70 | # configure option to enable property debugging 71 | AC_ARG_ENABLE(debug-props, AS_HELP_STRING([--enable-debug-props], 72 | [Enable property debugging (default: disabled)]), 73 | [DEBUG_PROPS=yes], 74 | [DEBUG_PROPS=no]) 75 | if test "x$DEBUG_PROPS" = xyes; then 76 | AC_DEFINE(DEBUG_PROPS, 1, [Enable property debugging.]) 77 | fi 78 | 79 | # configure option to enable driver debugging 80 | AC_ARG_ENABLE(debug-driver, AS_HELP_STRING([--enable-debug-driver], 81 | [Enable property debugging (default: disabled)]), 82 | [DEBUG_DRIVER=yes], 83 | [DEBUG_DRIVER=no]) 84 | if test "x$DEBUG_DRIVER" = xyes; then 85 | AC_DEFINE(DEBUG_DRIVER, 1, [Enable property debugging.]) 86 | fi 87 | 88 | 89 | # configure option to enable all debugging 90 | AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], 91 | [Enable all debugging (default: disabled)]), 92 | [DEBUG_ALL=$enableval], 93 | [DEBUG_ALL=no]) 94 | if test "x$DEBUG_ALL" = xyes; then 95 | AC_DEFINE(DEBUG_GESTURES, 1, [Enable gesture debugging.]) 96 | AC_DEFINE(DEBUG_MTSTATE, 1, [Enable multitouch state debugging.]) 97 | AC_DEFINE(DEBUG_PROPS, 1, [Enable property debugging.]) 98 | AC_DEFINE(DEBUG_DRIVER, 1, [Enable driver debugging.]) 99 | fi 100 | 101 | # Everything else 102 | AC_PROG_CC 103 | AC_PROG_INSTALL 104 | AC_CONFIG_FILES([Makefile]) 105 | AC_OUTPUT 106 | 107 | -------------------------------------------------------------------------------- /debian/README.Debian: -------------------------------------------------------------------------------- 1 | Xorg Multitouch Trackpad Driver 2 | * Install the Debian package 3 | * Configure xorg.conf 4 | * Restart X 5 | 6 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | xserver-xorg-input-mtrack (0.2.0) unstable; urgency=low 2 | 3 | * Now built via autoconf/automake. 4 | * Fully configurable via XInput. 5 | * Sensitivify now configurable. 6 | * Trackpad can now be disabled on keystroke via an external daemon. 7 | * Four finger tapping/swiping added. 8 | * Button zones added, a new button emulation method. 9 | * Tap-to-drag fixed. 10 | * Three finger tapping responsiveness fixed. 11 | 12 | -- Ryan Bourgeois Thu, 26 May 2011 09:44:43 -0500 13 | 14 | xserver-xorg-input-mtrack (0.1.1) unstable; urgency=low 15 | 16 | * Bugfix release. 17 | * Disabling tapping no longer (wrongly) disables pointer movement. 18 | * Button emulation set to ignore "old" touches. What consitutes an old touch can be adjusted with the ButtonTouchExpire option. 19 | 20 | -- Ryan Bourgeois Thu, 28 Apr 2011 01:14:58 -0500 21 | 22 | xserver-xorg-input-mtrack (0.1.0) unstable; urgency=low 23 | 24 | * Initial release. 25 | 26 | -- Ryan Bourgeois Fri, 15 Apr 2011 14:46:10 -0500 27 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 5 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: xserver-xorg-input-mtrack 2 | Section: misc 3 | Priority: optional 4 | Maintainer: Ryan Bourgeois 5 | Build-Depends: 6 | debhelper (>= 5), 7 | xserver-xorg-dev (>= 2:1.7.6), 8 | libmtdev-dev (>= 1.0.10) 9 | Standards-Version: 3.7.2 10 | Homepage: https://github.com/BlueDragonX/xf86-input-mtrack 11 | 12 | Package: xserver-xorg-input-mtrack 13 | Architecture: any 14 | Depends: ${shlibs:Depends}, ${misc:Depends}, libmtdev1 (>= 1.0) 15 | Description: Xorg Multitouch Trackpad Driver 16 | This X input driver provides gestures support for multitouch touchpads, 17 | with or without an integrated button. 18 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Source URL: https://github.com/BlueDragonX/xf86-input-mtrack 2 | 3 | Upstream Author: Ryan Bourgeois 4 | 5 | Copyright: 6 | Copyright (C) 2008 Henrik Rydberg (rydberg@euromail.se) 7 | Copyright (C) 2011 Ryan Bourgeois (bluedragonx@gmail.com) 8 | 9 | License: 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 2 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software 23 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24 | 25 | Packaging: 26 | Copyright (C) 2008 by Henrik Rydberg 27 | Copyright (C) 2011 by Ryan Bourgeois 28 | released under GPL 2 29 | 30 | -------------------------------------------------------------------------------- /debian/dirs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | 4 | # Uncomment this to turn on verbose mode. 5 | #export DH_VERBOSE=1 6 | 7 | build-arch: 8 | dh_testdir 9 | $(MAKE) 10 | 11 | build-indep: 12 | 13 | build: build-arch build-indep 14 | 15 | install: 16 | dh_testdir 17 | dh_testroot 18 | dh_clean -k 19 | dh_installdirs 20 | $(MAKE) DESTDIR=$(CURDIR)/debian/xserver-xorg-input-mtrack install 21 | 22 | binary-arch: build-arch install 23 | dh_testdir 24 | dh_testroot 25 | dh_link 26 | dh_strip 27 | dh_compress 28 | dh_fixperms 29 | dh_installdeb 30 | dh_shlibdeps 31 | dh_gencontrol 32 | dh_md5sums 33 | dh_builddeb 34 | 35 | binary-indep: build-indep 36 | 37 | binary: binary-arch binary-indep 38 | 39 | clean: 40 | dh_testdir 41 | dh_testroot 42 | $(MAKE) clean 43 | dh_clean 44 | 45 | .PHONY: build-arch build-indep build install binary-arch binary-indep binary clean 46 | 47 | -------------------------------------------------------------------------------- /driver/mprops.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2011 Ryan Bourgeois 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | * 20 | **************************************************************************/ 21 | 22 | #include "mprops.h" 23 | #include "common.h" 24 | #include "mtouch.h" 25 | 26 | #define MAX_INT_VALUES 4 27 | #define MAX_FLOAT_VALUES 4 28 | 29 | #define VALID_BUTTON(x) (x >= 0 && x <= 32) 30 | #define VALID_BOOL(x) (x == 0 || x == 1) 31 | #define VALID_PCNT(x) (x >= 0 && x <= 100) 32 | 33 | struct MProps mprops; 34 | 35 | Atom atom_init_integer(DeviceIntPtr dev, char* name, int nvalues, int* values, int size) { 36 | Atom atom; 37 | int i; 38 | uint8_t uvals8[MAX_INT_VALUES]; 39 | uint16_t uvals16[MAX_INT_VALUES]; 40 | uint32_t uvals32[MAX_INT_VALUES]; 41 | pointer uvals; 42 | nvalues = MINVAL(MAX_INT_VALUES, nvalues); 43 | 44 | switch(size) { 45 | case 8: 46 | for (i = 0; i < nvalues; i++) { 47 | uvals8[i] = values[i]; 48 | } 49 | uvals = uvals8; 50 | break; 51 | case 16: 52 | for (i = 0; i < nvalues; i++) { 53 | uvals16[i] = values[i]; 54 | } 55 | uvals = uvals16; 56 | break; 57 | default: 58 | for (i = 0; i < nvalues; i++) { 59 | uvals32[i] = values[i]; 60 | } 61 | uvals = uvals32; 62 | break; 63 | } 64 | 65 | atom = MakeAtom(name, strlen(name), TRUE); 66 | XIChangeDeviceProperty(dev, atom, XA_INTEGER, size, PropModeReplace, nvalues, uvals, FALSE); 67 | XISetDevicePropertyDeletable(dev, atom, FALSE); 68 | return atom; 69 | } 70 | 71 | Atom atom_init_float(DeviceIntPtr dev, char* name, int nvalues, float* values, Atom float_type) { 72 | Atom atom = MakeAtom(name, strlen(name), TRUE); 73 | XIChangeDeviceProperty(dev, atom, float_type, 32, PropModeReplace, nvalues, values, FALSE); 74 | XISetDevicePropertyDeletable(dev, atom, FALSE); 75 | return atom; 76 | } 77 | 78 | void mprops_init(struct MConfig* cfg, InputInfoPtr local) { 79 | int ivals[MAX_INT_VALUES]; 80 | float fvals[MAX_FLOAT_VALUES]; 81 | 82 | mprops.float_type = XIGetKnownProperty(XATOM_FLOAT); 83 | if (!mprops.float_type) { 84 | mprops.float_type = MakeAtom(XATOM_FLOAT, strlen(XATOM_FLOAT), TRUE); 85 | if (!mprops.float_type) { 86 | xf86Msg(X_ERROR, "mtrack: %s: Failed to init float atom. Property support is disabled.\n", local->name); 87 | return; 88 | } 89 | } 90 | 91 | ivals[0] = cfg->trackpad_disable; 92 | mprops.trackpad_disable = atom_init_integer(local->dev, MTRACK_PROP_TRACKPAD_DISABLE, 1, ivals, 8); 93 | 94 | fvals[0] = (float)cfg->sensitivity; 95 | mprops.sensitivity = atom_init_float(local->dev, MTRACK_PROP_SENSITIVITY, 1, fvals, mprops.float_type); 96 | 97 | ivals[0] = cfg->touch_down; 98 | ivals[1] = cfg->touch_up; 99 | mprops.pressure = atom_init_integer(local->dev, MTRACK_PROP_PRESSURE, 2, ivals, 8); 100 | 101 | ivals[0] = cfg->button_enable; 102 | ivals[1] = cfg->button_integrated; 103 | mprops.button_settings = atom_init_integer(local->dev, MTRACK_PROP_BUTTON_SETTINGS, 2, ivals, 8); 104 | 105 | ivals[0] = cfg->button_zones; 106 | ivals[1] = cfg->button_move; 107 | ivals[2] = cfg->button_expire; 108 | mprops.button_emulate_settings = atom_init_integer(local->dev, MTRACK_PROP_BUTTON_EMULATE_SETTINGS, 3, ivals, 16); 109 | 110 | ivals[0] = cfg->button_1touch; 111 | ivals[1] = cfg->button_2touch; 112 | ivals[2] = cfg->button_3touch; 113 | mprops.button_emulate_values = atom_init_integer(local->dev, MTRACK_PROP_BUTTON_EMULATE_VALUES, 3, ivals, 8); 114 | 115 | ivals[0] = cfg->tap_hold; 116 | ivals[1] = cfg->tap_timeout; 117 | ivals[2] = cfg->tap_dist; 118 | mprops.tap_settings = atom_init_integer(local->dev, MTRACK_PROP_TAP_SETTINGS, 3, ivals, 32); 119 | 120 | ivals[0] = cfg->tap_1touch; 121 | ivals[1] = cfg->tap_2touch; 122 | ivals[2] = cfg->tap_3touch; 123 | ivals[3] = cfg->tap_4touch; 124 | mprops.tap_emulate = atom_init_integer(local->dev, MTRACK_PROP_TAP_EMULATE, 4, ivals, 8); 125 | 126 | ivals[0] = cfg->ignore_thumb; 127 | ivals[1] = cfg->disable_on_thumb; 128 | mprops.thumb_detect = atom_init_integer(local->dev, MTRACK_PROP_THUMB_DETECT, 2, ivals, 8); 129 | 130 | ivals[0] = cfg->thumb_size; 131 | ivals[1] = cfg->thumb_ratio; 132 | mprops.thumb_size = atom_init_integer(local->dev, MTRACK_PROP_THUMB_SIZE, 2, ivals, 32); 133 | 134 | ivals[0] = cfg->ignore_palm; 135 | ivals[1] = cfg->disable_on_palm; 136 | mprops.palm_detect = atom_init_integer(local->dev, MTRACK_PROP_PALM_DETECT, 2, ivals, 8); 137 | 138 | ivals[0] = cfg->palm_size; 139 | mprops.palm_size = atom_init_integer(local->dev, MTRACK_PROP_PALM_SIZE, 1, ivals, 32); 140 | 141 | ivals[0] = cfg->gesture_hold; 142 | ivals[1] = cfg->gesture_wait; 143 | mprops.gesture_settings = atom_init_integer(local->dev, MTRACK_PROP_GESTURE_SETTINGS, 2, ivals, 16); 144 | 145 | ivals[0] = cfg->scroll_dist; 146 | mprops.scroll_dist = atom_init_integer(local->dev, MTRACK_PROP_SCROLL_DIST, 1, ivals, 32); 147 | 148 | ivals[0] = cfg->scroll_up_btn; 149 | ivals[1] = cfg->scroll_dn_btn; 150 | ivals[2] = cfg->scroll_lt_btn; 151 | ivals[3] = cfg->scroll_rt_btn; 152 | mprops.scroll_buttons = atom_init_integer(local->dev, MTRACK_PROP_SCROLL_BUTTONS, 4, ivals, 8); 153 | 154 | ivals[0] = cfg->swipe_dist; 155 | mprops.swipe_dist = atom_init_integer(local->dev, MTRACK_PROP_SWIPE_DIST, 1, ivals, 32); 156 | 157 | ivals[0] = cfg->swipe_up_btn; 158 | ivals[1] = cfg->swipe_dn_btn; 159 | ivals[2] = cfg->swipe_lt_btn; 160 | ivals[3] = cfg->swipe_rt_btn; 161 | mprops.swipe_buttons = atom_init_integer(local->dev, MTRACK_PROP_SWIPE_BUTTONS, 4, ivals, 8); 162 | 163 | ivals[0] = cfg->swipe4_dist; 164 | mprops.swipe4_dist = atom_init_integer(local->dev, MTRACK_PROP_SWIPE4_DIST, 1, ivals, 32); 165 | 166 | ivals[0] = cfg->swipe4_up_btn; 167 | ivals[1] = cfg->swipe4_dn_btn; 168 | ivals[2] = cfg->swipe4_lt_btn; 169 | ivals[3] = cfg->swipe4_rt_btn; 170 | mprops.swipe4_buttons = atom_init_integer(local->dev, MTRACK_PROP_SWIPE4_BUTTONS, 4, ivals, 8); 171 | 172 | ivals[0] = cfg->scale_dist; 173 | mprops.scale_dist = atom_init_integer(local->dev, MTRACK_PROP_SCALE_DIST, 1, ivals, 32); 174 | 175 | ivals[0] = cfg->scale_up_btn; 176 | ivals[1] = cfg->scale_dn_btn; 177 | mprops.scale_buttons = atom_init_integer(local->dev, MTRACK_PROP_SCALE_BUTTONS, 2, ivals, 8); 178 | 179 | ivals[0] = cfg->rotate_dist; 180 | mprops.rotate_dist = atom_init_integer(local->dev, MTRACK_PROP_ROTATE_DIST, 1, ivals, 32); 181 | 182 | ivals[0] = cfg->rotate_lt_btn; 183 | ivals[1] = cfg->rotate_rt_btn; 184 | mprops.rotate_buttons = atom_init_integer(local->dev, MTRACK_PROP_SCALE_BUTTONS, 2, ivals, 8); 185 | 186 | ivals[0] = cfg->drag_enable; 187 | ivals[1] = cfg->drag_timeout; 188 | ivals[2] = cfg->drag_wait; 189 | ivals[3] = cfg->drag_dist; 190 | mprops.drag_settings = atom_init_integer(local->dev, MTRACK_PROP_DRAG_SETTINGS, 4, ivals, 32); 191 | 192 | ivals[0] = cfg->axis_x_invert; 193 | ivals[1] = cfg->axis_y_invert; 194 | mprops.axis_invert = atom_init_integer(local->dev, MTRACK_PROP_AXIS_INVERT, 2, ivals, 8); 195 | } 196 | 197 | int mprops_set_property(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, BOOL checkonly) { 198 | InputInfoPtr local = dev->public.devicePrivate; 199 | struct MConfig* cfg = &((struct MTouch*)local->private)->cfg; 200 | 201 | uint8_t* ivals8; 202 | uint16_t* ivals16; 203 | uint32_t* ivals32; 204 | float* fvals; 205 | 206 | if (property == mprops.trackpad_disable) { 207 | if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER) 208 | return BadMatch; 209 | 210 | ivals8 = (uint8_t*)prop->data; 211 | if (ivals8[0] < 0 || ivals8[0] > 3) 212 | return BadMatch; 213 | 214 | if (!checkonly) { 215 | cfg->trackpad_disable = ivals8[0]; 216 | #ifdef DEBUG_PROPS 217 | if (cfg->trackpad_disable) 218 | xf86Msg(X_INFO, "mtrack: trackpad input disabled\n"); 219 | else 220 | xf86Msg(X_INFO, "mtrack: trackpad input enabled\n"); 221 | #endif 222 | } 223 | } 224 | else if (property == mprops.sensitivity) { 225 | if (prop->size != 1 || prop->format != 32 || prop->type != mprops.float_type) 226 | return BadMatch; 227 | 228 | fvals = (float*)prop->data; 229 | if (fvals[0] < 0) 230 | return BadMatch; 231 | 232 | if (!checkonly) { 233 | cfg->sensitivity = fvals[0]; 234 | #ifdef DEBUG_PROPS 235 | xf86Msg(X_INFO, "mtrack: set sensitivity to %f\n", cfg->sensitivity); 236 | #endif 237 | } 238 | } 239 | else if (property == mprops.pressure) { 240 | if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) 241 | return BadMatch; 242 | 243 | ivals8 = (uint8_t*)prop->data; 244 | if (!VALID_PCNT(ivals8[0]) || !VALID_PCNT(ivals8[1])) 245 | return BadMatch; 246 | 247 | if (!checkonly) { 248 | cfg->touch_down = ivals8[0]; 249 | cfg->touch_up = ivals8[1]; 250 | #ifdef DEBUG_PROPS 251 | xf86Msg(X_INFO, "mtrack: set touch pressure to %d %d\n", 252 | cfg->touch_down, cfg->touch_up); 253 | #endif 254 | } 255 | } 256 | else if (property == mprops.button_settings) { 257 | if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) 258 | return BadMatch; 259 | 260 | ivals8 = (uint8_t*)prop->data; 261 | if (!VALID_BOOL(ivals16[0]) || !VALID_BOOL(ivals16[1])) 262 | return BadMatch; 263 | 264 | if (!checkonly) { 265 | cfg->button_enable = ivals8[0]; 266 | cfg->button_integrated = ivals8[1]; 267 | #ifdef DEBUG_PROPS 268 | xf86Msg(X_INFO, "mtrack: set button settings to %d %d\n", 269 | cfg->button_enable, cfg->button_integrated); 270 | #endif 271 | } 272 | } 273 | else if (property == mprops.button_emulate_settings) { 274 | if (prop->size != 3 || prop->format != 16 || prop->type != XA_INTEGER) 275 | return BadMatch; 276 | 277 | ivals16 = (uint16_t*)prop->data; 278 | if (!VALID_BOOL(ivals16[0]) || !VALID_BOOL(ivals16[1]) || ivals16[2] < 0) 279 | return BadMatch; 280 | 281 | if (!checkonly) { 282 | cfg->button_zones = ivals16[0]; 283 | cfg->button_move = ivals16[1]; 284 | cfg->button_expire = ivals16[2]; 285 | #ifdef DEBUG_PROPS 286 | xf86Msg(X_INFO, "mtrack: set button emulate settings to %d %d %d\n", 287 | cfg->button_zones, cfg->button_move, cfg->button_expire); 288 | #endif 289 | } 290 | } 291 | else if (property == mprops.button_emulate_values) { 292 | if (prop->size != 3 || prop->format != 8 || prop->type != XA_INTEGER) 293 | return BadMatch; 294 | 295 | ivals8 = (uint8_t*)prop->data; 296 | if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2])) 297 | return BadMatch; 298 | 299 | if (!checkonly) { 300 | cfg->button_1touch = ivals8[0]; 301 | cfg->button_2touch = ivals8[1]; 302 | cfg->button_3touch = ivals8[2]; 303 | #ifdef DEBUG_PROPS 304 | xf86Msg(X_INFO, "mtrack: set button emulation to %d %d %s\n", 305 | cfg->button_1touch, cfg->button_2touch, cfg->button_3touch); 306 | #endif 307 | } 308 | } 309 | else if (property == mprops.tap_settings) { 310 | if (prop->size != 3 || prop->format != 32 || prop->type != XA_INTEGER) 311 | return BadMatch; 312 | 313 | ivals32 = (uint32_t*)prop->data; 314 | if (ivals32[0] < 1 || ivals32[1] < 1 || ivals32[2] < 1) 315 | return BadMatch; 316 | 317 | if (!checkonly) { 318 | cfg->tap_hold = ivals32[0]; 319 | cfg->tap_timeout = ivals32[1]; 320 | cfg->tap_dist = ivals32[2]; 321 | #ifdef DEBUG_PROPS 322 | xf86Msg(X_INFO, "mtrack: set tap settings to %d %d %d\n", 323 | cfg->tap_hold, cfg->tap_timeout, cfg->tap_dist); 324 | #endif 325 | } 326 | } 327 | else if (property == mprops.tap_emulate) { 328 | if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) 329 | return BadMatch; 330 | 331 | ivals8 = (uint8_t*)prop->data; 332 | if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) 333 | return BadMatch; 334 | 335 | if (!checkonly) { 336 | cfg->tap_1touch = ivals8[0]; 337 | cfg->tap_2touch = ivals8[1]; 338 | cfg->tap_3touch = ivals8[2]; 339 | cfg->tap_4touch = ivals8[3]; 340 | #ifdef DEBUG_PROPS 341 | xf86Msg(X_INFO, "mtrack: set tap emulation to %d %d %d %d\n", 342 | cfg->tap_1touch, cfg->tap_2touch, cfg->tap_3touch, cfg->tap_4touch); 343 | #endif 344 | } 345 | } 346 | else if (property == mprops.thumb_detect) { 347 | if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) 348 | return BadMatch; 349 | 350 | ivals8 = (uint8_t*)prop->data; 351 | if (!VALID_BOOL(ivals8[0]) || !VALID_BOOL(ivals8[1])) 352 | return BadMatch; 353 | 354 | if (!checkonly) { 355 | cfg->ignore_thumb = ivals8[0]; 356 | cfg->disable_on_thumb = ivals8[1]; 357 | #ifdef DEBUG_PROPS 358 | xf86Msg(X_INFO, "mtrack: set thumb detect to %d %d\n", 359 | cfg->ignore_thumb, cfg->disable_on_thumb); 360 | #endif 361 | } 362 | } 363 | else if (property == mprops.thumb_size) { 364 | if (prop->size != 2 || prop->format != 32 || prop->type != XA_INTEGER) 365 | return BadMatch; 366 | 367 | ivals32 = (uint32_t*)prop->data; 368 | if (ivals32[0] < 0 || !VALID_PCNT(ivals32[1])) 369 | return BadMatch; 370 | 371 | if (!checkonly) { 372 | cfg->thumb_size = ivals32[0]; 373 | cfg->thumb_ratio = ivals32[0]; 374 | #ifdef DEBUG_PROPS 375 | xf86Msg(X_INFO, "mtrack: set thumb size to %d %d\n", 376 | cfg->thumb_size, cfg->thumb_ratio); 377 | #endif 378 | } 379 | } 380 | else if (property == mprops.palm_detect) { 381 | if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) 382 | return BadMatch; 383 | 384 | ivals8 = (uint8_t*)prop->data; 385 | if (!VALID_BOOL(ivals8[0]) || !VALID_BOOL(ivals8[1])) 386 | return BadMatch; 387 | 388 | if (!checkonly) { 389 | cfg->ignore_palm = ivals8[0]; 390 | cfg->disable_on_palm = ivals8[1]; 391 | #ifdef DEBUG_PROPS 392 | xf86Msg(X_INFO, "mtrack: set palm detect to %d %d\n", 393 | cfg->ignore_palm, cfg->disable_on_palm); 394 | #endif 395 | } 396 | } 397 | else if (property == mprops.palm_size) { 398 | if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) 399 | return BadMatch; 400 | 401 | ivals32 = (uint32_t*)prop->data; 402 | if (ivals32[0] < 0) 403 | return BadMatch; 404 | 405 | if (!checkonly) { 406 | cfg->palm_size = ivals32[0]; 407 | #ifdef DEBUG_PROPS 408 | xf86Msg(X_INFO, "mtrack: set palm size to %d\n", 409 | cfg->palm_size); 410 | #endif 411 | } 412 | } 413 | else if (property == mprops.gesture_settings) { 414 | if (prop->size != 2 || prop->format != 16 || prop->type != XA_INTEGER) 415 | return BadMatch; 416 | 417 | ivals16 = (uint16_t*)prop->data; 418 | if (ivals16[0] < 1 || ivals16[1] < 0) 419 | return BadMatch; 420 | 421 | if (!checkonly) { 422 | cfg->gesture_hold = ivals16[0]; 423 | cfg->gesture_wait = ivals16[1]; 424 | #ifdef DEBUG_PROPS 425 | xf86Msg(X_INFO, "mtrack: set gesture settings to %d %d\n", 426 | cfg->gesture_hold, cfg->gesture_wait); 427 | #endif 428 | } 429 | } 430 | else if (property == mprops.scroll_dist) { 431 | if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) 432 | return BadMatch; 433 | 434 | ivals32 = (uint32_t*)prop->data; 435 | if (ivals32[0] < 1) 436 | return BadMatch; 437 | 438 | if (!checkonly) { 439 | cfg->scroll_dist = ivals32[0]; 440 | #ifdef DEBUG_PROPS 441 | xf86Msg(X_INFO, "mtrack: set scroll distance to %d\n", 442 | cfg->scroll_dist); 443 | #endif 444 | } 445 | } 446 | else if (property == mprops.scroll_buttons) { 447 | if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) 448 | return BadMatch; 449 | 450 | ivals8 = (uint8_t*)prop->data; 451 | if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) 452 | return BadMatch; 453 | 454 | if (!checkonly) { 455 | cfg->scroll_up_btn = ivals8[0]; 456 | cfg->scroll_dn_btn = ivals8[1]; 457 | cfg->scroll_lt_btn = ivals8[2]; 458 | cfg->scroll_rt_btn = ivals8[3]; 459 | #ifdef DEBUG_PROPS 460 | xf86Msg(X_INFO, "mtrack: set scroll buttons to %d %d %d %d\n", 461 | cfg->scroll_up_btn, cfg->scroll_dn_btn, cfg->scroll_lt_btn, cfg->scroll_rt_btn); 462 | #endif 463 | } 464 | } 465 | else if (property == mprops.swipe_dist) { 466 | if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) 467 | return BadMatch; 468 | 469 | ivals32 = (uint32_t*)prop->data; 470 | if (ivals32[0] < 1) 471 | return BadMatch; 472 | 473 | if (!checkonly) { 474 | cfg->swipe_dist = ivals32[0]; 475 | #ifdef DEBUG_PROPS 476 | xf86Msg(X_INFO, "mtrack: set swipe distance to %d\n", 477 | cfg->swipe_dist); 478 | #endif 479 | } 480 | } 481 | else if (property == mprops.swipe_buttons) { 482 | if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) 483 | return BadMatch; 484 | 485 | ivals8 = (uint8_t*)prop->data; 486 | if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) 487 | return BadMatch; 488 | 489 | if (!checkonly) { 490 | cfg->swipe_up_btn = ivals8[0]; 491 | cfg->swipe_dn_btn = ivals8[1]; 492 | cfg->swipe_lt_btn = ivals8[2]; 493 | cfg->swipe_rt_btn = ivals8[3]; 494 | #ifdef DEBUG_PROPS 495 | xf86Msg(X_INFO, "mtrack: set swipe buttons to %d %d %d %d\n", 496 | cfg->swipe_up_btn, cfg->swipe_dn_btn, cfg->swipe_lt_btn, cfg->swipe_rt_btn); 497 | #endif 498 | } 499 | } 500 | else if (property == mprops.swipe4_dist) { 501 | if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) 502 | return BadMatch; 503 | 504 | ivals32 = (uint32_t*)prop->data; 505 | if (ivals32[0] < 1) 506 | return BadMatch; 507 | 508 | if (!checkonly) { 509 | cfg->swipe4_dist = ivals32[0]; 510 | #ifdef DEBUG_PROPS 511 | xf86Msg(X_INFO, "mtrack: set swipe4 distance to %d\n", 512 | cfg->swipe4_dist); 513 | #endif 514 | } 515 | } 516 | else if (property == mprops.swipe4_buttons) { 517 | if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) 518 | return BadMatch; 519 | 520 | ivals8 = (uint8_t*)prop->data; 521 | if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) 522 | return BadMatch; 523 | 524 | if (!checkonly) { 525 | cfg->swipe4_up_btn = ivals8[0]; 526 | cfg->swipe4_dn_btn = ivals8[1]; 527 | cfg->swipe4_lt_btn = ivals8[2]; 528 | cfg->swipe4_rt_btn = ivals8[3]; 529 | #ifdef DEBUG_PROPS 530 | xf86Msg(X_INFO, "mtrack: set swipe4 buttons to %d %d %d %d\n", 531 | cfg->swipe4_up_btn, cfg->swipe4_dn_btn, cfg->swipe4_lt_btn, cfg->swipe4_rt_btn); 532 | #endif 533 | } 534 | } 535 | else if (property == mprops.scale_dist) { 536 | if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) 537 | return BadMatch; 538 | 539 | ivals32 = (uint32_t*)prop->data; 540 | if (ivals32[0] < 1) 541 | return BadMatch; 542 | 543 | if (!checkonly) { 544 | cfg->scale_dist = ivals32[0]; 545 | #ifdef DEBUG_PROPS 546 | xf86Msg(X_INFO, "mtrack: set scale distance to %d\n", 547 | cfg->scale_dist); 548 | #endif 549 | } 550 | } 551 | else if (property == mprops.scale_buttons) { 552 | if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) 553 | return BadMatch; 554 | 555 | ivals8 = (uint8_t*)prop->data; 556 | if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) 557 | return BadMatch; 558 | 559 | if (!checkonly) { 560 | cfg->scale_up_btn = ivals8[0]; 561 | cfg->scale_dn_btn = ivals8[1]; 562 | #ifdef DEBUG_PROPS 563 | xf86Msg(X_INFO, "mtrack: set scale buttons to %d %d\n", 564 | cfg->scale_up_btn, cfg->scale_dn_btn); 565 | #endif 566 | } 567 | } 568 | else if (property == mprops.rotate_dist) { 569 | if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) 570 | return BadMatch; 571 | 572 | ivals32 = (uint32_t*)prop->data; 573 | if (ivals32[0] < 1) 574 | return BadMatch; 575 | 576 | if (!checkonly) { 577 | cfg->rotate_dist = ivals32[0]; 578 | #ifdef DEBUG_PROPS 579 | xf86Msg(X_INFO, "mtrack: set rotate distance to %d\n", 580 | cfg->rotate_dist); 581 | #endif 582 | } 583 | } 584 | else if (property == mprops.rotate_buttons) { 585 | if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) 586 | return BadMatch; 587 | 588 | ivals8 = (uint8_t*)prop->data; 589 | if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) 590 | return BadMatch; 591 | 592 | if (!checkonly) { 593 | cfg->rotate_lt_btn = ivals8[0]; 594 | cfg->rotate_rt_btn = ivals8[1]; 595 | #ifdef DEBUG_PROPS 596 | xf86Msg(X_INFO, "mtrack: set rotate buttons to %d %d\n", 597 | cfg->rotate_lt_btn, cfg->rotate_rt_btn); 598 | #endif 599 | } 600 | } 601 | else if (property == mprops.drag_settings) { 602 | if (prop->size != 4 || prop->format != 32 || prop->type != XA_INTEGER) 603 | return BadMatch; 604 | 605 | ivals32 = (uint32_t*)prop->data; 606 | if (!VALID_BOOL(ivals32[0]) || ivals32[1] < 1 || ivals32[2] < 0 || ivals32[3] < 0) 607 | return BadMatch; 608 | 609 | if (!checkonly) { 610 | cfg->drag_enable = ivals32[0]; 611 | cfg->drag_timeout = ivals32[1]; 612 | cfg->drag_wait = ivals32[2]; 613 | cfg->drag_dist = ivals32[3]; 614 | #ifdef DEBUG_PROPS 615 | xf86Msg(X_INFO, "mtrack: set drag settings to %d %d %d %d\n", 616 | cfg->drag_enable, cfg->drag_timeout, cfg->drag_wait, cfg->drag_dist); 617 | #endif 618 | } 619 | } 620 | else if (property == mprops.axis_invert) { 621 | if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) 622 | return BadMatch; 623 | 624 | ivals8 = (uint8_t*)prop->data; 625 | if (!VALID_BOOL(ivals8[0]) || !VALID_BOOL(ivals8[1])) 626 | return BadMatch; 627 | 628 | if (!checkonly) { 629 | cfg->axis_x_invert = ivals8[0]; 630 | cfg->axis_y_invert = ivals8[1]; 631 | #ifdef DEBUG_PROPS 632 | xf86Msg(X_INFO, "mtrack: set axis inversion to %d %d\n", 633 | cfg->axis_x_invert, cfg->axis_y_invert); 634 | #endif 635 | } 636 | } 637 | 638 | return Success; 639 | } 640 | 641 | -------------------------------------------------------------------------------- /driver/mtrack.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2008 Henrik Rydberg 5 | * Copyright (C) 2011 Ryan Bourgeois 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | * 21 | **************************************************************************/ 22 | 23 | #include "mtouch.h" 24 | #include "mprops.h" 25 | 26 | #include 27 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 28 | #include 29 | #include 30 | #endif 31 | 32 | #define TAP_HOLD 100 33 | #define TAP_TIMEOUT 200 34 | #define TAP_THRESHOLD 0.05 35 | #define TICK_TIMEOUT 50 36 | #define SCROLL_THRESHOLD 0.05 37 | #define SWIPE_THRESHOLD 0.15 38 | #define SCALE_THRESHOLD 0.15 39 | #define ROTATE_THRESHOLD 0.15 40 | 41 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12 42 | typedef InputInfoPtr LocalDevicePtr; 43 | #endif 44 | 45 | /* button mapping simplified */ 46 | #define PROPMAP(m, x, y) m[x] = XIGetKnownProperty(y) 47 | 48 | static void pointer_control(DeviceIntPtr dev, PtrCtrl *ctrl) 49 | { 50 | #if DEBUG_DRIVER 51 | xf86Msg(X_INFO, "pointer_control\n"); 52 | #endif 53 | } 54 | 55 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 56 | static void initAxesLabels(Atom map[2]) 57 | { 58 | memset(map, 0, 2 * sizeof(Atom)); 59 | PROPMAP(map, 0, AXIS_LABEL_PROP_REL_X); 60 | PROPMAP(map, 1, AXIS_LABEL_PROP_REL_Y); 61 | } 62 | 63 | static void initButtonLabels(Atom map[DIM_BUTTON]) 64 | { 65 | memset(map, 0, DIM_BUTTON * sizeof(Atom)); 66 | PROPMAP(map, MT_BUTTON_LEFT, BTN_LABEL_PROP_BTN_LEFT); 67 | PROPMAP(map, MT_BUTTON_MIDDLE, BTN_LABEL_PROP_BTN_MIDDLE); 68 | PROPMAP(map, MT_BUTTON_RIGHT, BTN_LABEL_PROP_BTN_RIGHT); 69 | PROPMAP(map, MT_BUTTON_WHEEL_UP, BTN_LABEL_PROP_BTN_WHEEL_UP); 70 | PROPMAP(map, MT_BUTTON_WHEEL_DOWN, BTN_LABEL_PROP_BTN_WHEEL_DOWN); 71 | PROPMAP(map, MT_BUTTON_HWHEEL_LEFT, BTN_LABEL_PROP_BTN_HWHEEL_LEFT); 72 | PROPMAP(map, MT_BUTTON_HWHEEL_RIGHT, BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); 73 | /* how to map swipe buttons? */ 74 | PROPMAP(map, MT_BUTTON_SWIPE_UP, BTN_LABEL_PROP_BTN_0); 75 | PROPMAP(map, MT_BUTTON_SWIPE_DOWN, BTN_LABEL_PROP_BTN_1); 76 | PROPMAP(map, MT_BUTTON_SWIPE_LEFT, BTN_LABEL_PROP_BTN_2); 77 | PROPMAP(map, MT_BUTTON_SWIPE_RIGHT, BTN_LABEL_PROP_BTN_3); 78 | /* how to map scale and rotate? */ 79 | PROPMAP(map, MT_BUTTON_SCALE_DOWN, BTN_LABEL_PROP_BTN_4); 80 | PROPMAP(map, MT_BUTTON_SCALE_UP, BTN_LABEL_PROP_BTN_5); 81 | PROPMAP(map, MT_BUTTON_ROTATE_LEFT, BTN_LABEL_PROP_BTN_6); 82 | PROPMAP(map, MT_BUTTON_ROTATE_RIGHT, BTN_LABEL_PROP_BTN_7); 83 | } 84 | #endif 85 | 86 | static int device_init(DeviceIntPtr dev, LocalDevicePtr local) 87 | { 88 | struct MTouch *mt = local->private; 89 | unsigned char btmap[DIM_BUTTON + 1] = { 90 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 91 | }; 92 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 93 | Atom axes_labels[2], btn_labels[DIM_BUTTON]; 94 | initAxesLabels(axes_labels); 95 | initButtonLabels(btn_labels); 96 | #endif 97 | 98 | local->fd = xf86OpenSerial(local->options); 99 | if (local->fd < 0) { 100 | xf86Msg(X_ERROR, "mtrack: cannot open device\n"); 101 | return !Success; 102 | } 103 | if (mtouch_configure(mt, local->fd)) { 104 | xf86Msg(X_ERROR, "mtrack: cannot configure device\n"); 105 | return !Success; 106 | } 107 | xf86CloseSerial(local->fd); 108 | 109 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3 110 | InitPointerDeviceStruct((DevicePtr)dev, 111 | btmap, DIM_BUTTON, 112 | GetMotionHistory, 113 | pointer_control, 114 | GetMotionHistorySize(), 115 | 2); 116 | #elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 7 117 | InitPointerDeviceStruct((DevicePtr)dev, 118 | btmap, DIM_BUTTON, 119 | pointer_control, 120 | GetMotionHistorySize(), 121 | 2); 122 | #elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 123 | InitPointerDeviceStruct((DevicePtr)dev, 124 | btmap, DIM_BUTTON, btn_labels, 125 | pointer_control, 126 | GetMotionHistorySize(), 127 | 2, axes_labels); 128 | #else 129 | #error "Unsupported ABI_XINPUT_VERSION" 130 | #endif 131 | 132 | xf86InitValuatorAxisStruct(dev, 0, 133 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 134 | axes_labels[0], 135 | #endif 136 | mt->caps.abs[MTDEV_POSITION_X].minimum, 137 | mt->caps.abs[MTDEV_POSITION_X].maximum, 138 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12 139 | 1, 0, 1, Absolute); 140 | #else 141 | 1, 0, 1); 142 | #endif 143 | xf86InitValuatorDefaults(dev, 0); 144 | xf86InitValuatorAxisStruct(dev, 1, 145 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 146 | axes_labels[1], 147 | #endif 148 | mt->caps.abs[MTDEV_POSITION_Y].minimum, 149 | mt->caps.abs[MTDEV_POSITION_Y].maximum, 150 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12 151 | 1, 0, 1, Absolute); 152 | #else 153 | 1, 0, 1); 154 | #endif 155 | xf86InitValuatorDefaults(dev, 1); 156 | mprops_init(&mt->cfg, local); 157 | XIRegisterPropertyHandler(dev, mprops_set_property, NULL, NULL); 158 | 159 | return Success; 160 | } 161 | 162 | static int device_on(LocalDevicePtr local) 163 | { 164 | struct MTouch *mt = local->private; 165 | local->fd = xf86OpenSerial(local->options); 166 | if (local->fd < 0) { 167 | xf86Msg(X_ERROR, "mtrack: cannot open device\n"); 168 | return !Success; 169 | } 170 | if (mtouch_open(mt, local->fd)) { 171 | xf86Msg(X_ERROR, "mtrack: cannot grab device\n"); 172 | return !Success; 173 | } 174 | xf86AddEnabledDevice(local); 175 | return Success; 176 | } 177 | 178 | static int device_off(LocalDevicePtr local) 179 | { 180 | struct MTouch *mt = local->private; 181 | xf86RemoveEnabledDevice(local); 182 | if (mtouch_close(mt)) 183 | xf86Msg(X_WARNING, "mtrack: cannot ungrab device\n"); 184 | xf86CloseSerial(local->fd); 185 | return Success; 186 | } 187 | 188 | static int device_close(LocalDevicePtr local) 189 | { 190 | return Success; 191 | } 192 | 193 | static void handle_gestures(LocalDevicePtr local, 194 | const struct Gestures* gs) 195 | { 196 | static bitmask_t buttons_prev = 0U; 197 | int i; 198 | 199 | for (i = 0; i < 32; i++) { 200 | if (GETBIT(gs->buttons, i) == GETBIT(buttons_prev, i)) 201 | continue; 202 | if (GETBIT(gs->buttons, i)) { 203 | xf86PostButtonEvent(local->dev, FALSE, i+1, 1, 0, 0); 204 | #if DEBUG_DRIVER 205 | xf86Msg(X_INFO, "button %d down\n", i+1); 206 | #endif 207 | } 208 | else { 209 | xf86PostButtonEvent(local->dev, FALSE, i+1, 0, 0, 0); 210 | #if DEBUG_DRIVER 211 | xf86Msg(X_INFO, "button %d up\n", i+1); 212 | #endif 213 | } 214 | } 215 | buttons_prev = gs->buttons; 216 | 217 | if (gs->move_dx != 0 || gs->move_dy != 0) 218 | xf86PostMotionEvent(local->dev, 0, 0, 2, gs->move_dx, gs->move_dy); 219 | } 220 | 221 | /* called for each full received packet from the touchpad */ 222 | static void read_input(LocalDevicePtr local) 223 | { 224 | struct MTouch *mt = local->private; 225 | while (mtouch_read(mt) > 0) 226 | handle_gestures(local, &mt->gs); 227 | if (mtouch_delayed(mt)) 228 | handle_gestures(local, &mt->gs); 229 | } 230 | 231 | static Bool device_control(DeviceIntPtr dev, int mode) 232 | { 233 | LocalDevicePtr local = dev->public.devicePrivate; 234 | switch (mode) { 235 | case DEVICE_INIT: 236 | xf86Msg(X_INFO, "device control: init\n"); 237 | return device_init(dev, local); 238 | case DEVICE_ON: 239 | xf86Msg(X_INFO, "device control: on\n"); 240 | return device_on(local); 241 | case DEVICE_OFF: 242 | xf86Msg(X_INFO, "device control: off\n"); 243 | return device_off(local); 244 | case DEVICE_CLOSE: 245 | xf86Msg(X_INFO, "device control: close\n"); 246 | return device_close(local); 247 | default: 248 | xf86Msg(X_INFO, "device control: default\n"); 249 | return BadValue; 250 | } 251 | } 252 | 253 | 254 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12 255 | static int preinit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) 256 | { 257 | struct MTouch *mt; 258 | 259 | mt = calloc(1, sizeof(*mt)); 260 | if (!mt) 261 | return BadAlloc; 262 | 263 | pInfo->private = mt; 264 | pInfo->type_name = XI_TOUCHPAD; 265 | pInfo->device_control = device_control; 266 | pInfo->read_input = read_input; 267 | pInfo->switch_mode = 0; 268 | 269 | xf86CollectInputOptions(pInfo, NULL); 270 | xf86OptionListReport(pInfo->options); 271 | xf86ProcessCommonOptions(pInfo, pInfo->options); 272 | mconfig_configure(&mt->cfg, pInfo->options); 273 | 274 | return Success; 275 | } 276 | #else 277 | static InputInfoPtr preinit(InputDriverPtr drv, IDevPtr dev, int flags) 278 | { 279 | struct MTouch *mt; 280 | InputInfoPtr local = xf86AllocateInput(drv, 0); 281 | if (!local) 282 | goto error; 283 | mt = calloc(1, sizeof(struct MTouch)); 284 | if (!mt) 285 | goto error; 286 | 287 | local->name = dev->identifier; 288 | local->type_name = XI_TOUCHPAD; 289 | local->device_control = device_control; 290 | local->read_input = read_input; 291 | local->private = mt; 292 | local->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS; 293 | local->conf_idev = dev; 294 | 295 | xf86CollectInputOptions(local, NULL, NULL); 296 | xf86OptionListReport(local->options); 297 | xf86ProcessCommonOptions(local, local->options); 298 | mconfig_configure(&mt->cfg, local->options); 299 | 300 | local->flags |= XI86_CONFIGURED; 301 | error: 302 | return local; 303 | } 304 | #endif 305 | 306 | static void uninit(InputDriverPtr drv, InputInfoPtr local, int flags) 307 | { 308 | free(local->private); 309 | local->private = 0; 310 | xf86DeleteInput(local, 0); 311 | } 312 | 313 | static InputDriverRec MTRACK = { 314 | 1, 315 | "mtrack", 316 | NULL, 317 | preinit, 318 | uninit, 319 | NULL, 320 | 0 321 | }; 322 | 323 | static XF86ModuleVersionInfo moduleVersion = { 324 | "mtrack", 325 | MODULEVENDORSTRING, 326 | MODINFOSTRING1, 327 | MODINFOSTRING2, 328 | XORG_VERSION_CURRENT, 329 | 0, 1, 0, 330 | ABI_CLASS_XINPUT, 331 | ABI_XINPUT_VERSION, 332 | MOD_CLASS_XINPUT, 333 | {0, 0, 0, 0} 334 | }; 335 | 336 | static pointer setup(pointer module, pointer options, int *errmaj, int *errmin) 337 | { 338 | xf86AddInputDriver(&MTRACK, module, 0); 339 | return module; 340 | } 341 | 342 | _X_EXPORT XF86ModuleData mtrackModuleData = {&moduleVersion, &setup, NULL }; 343 | -------------------------------------------------------------------------------- /include/button.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2008 Henrik Rydberg 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | * 20 | **************************************************************************/ 21 | 22 | #ifndef BUTTON_H 23 | #define BUTTON_H 24 | 25 | #define DIM_BUTTON 15 26 | 27 | #define MT_BUTTON_LEFT 0 28 | #define MT_BUTTON_MIDDLE 1 29 | #define MT_BUTTON_RIGHT 2 30 | #define MT_BUTTON_WHEEL_UP 3 31 | #define MT_BUTTON_WHEEL_DOWN 4 32 | #define MT_BUTTON_HWHEEL_LEFT 5 33 | #define MT_BUTTON_HWHEEL_RIGHT 6 34 | #define MT_BUTTON_SWIPE_UP 7 35 | #define MT_BUTTON_SWIPE_DOWN 8 36 | #define MT_BUTTON_SWIPE_LEFT 9 37 | #define MT_BUTTON_SWIPE_RIGHT 10 38 | #define MT_BUTTON_SCALE_DOWN 11 39 | #define MT_BUTTON_SCALE_UP 12 40 | #define MT_BUTTON_ROTATE_LEFT 13 41 | #define MT_BUTTON_ROTATE_RIGHT 14 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /include/capabilities.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2008 Henrik Rydberg 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | * 20 | **************************************************************************/ 21 | 22 | #ifndef CAPABILITIES_H 23 | #define CAPABILITIES_H 24 | 25 | #include "common.h" 26 | #include "button.h" 27 | 28 | struct Capabilities { 29 | struct input_id devid; 30 | char devname[32]; 31 | int has_left, has_middle, has_right; 32 | int has_mtdata, has_ibt; 33 | int has_slot; 34 | int has_abs[MT_ABS_SIZE]; 35 | struct input_absinfo slot; 36 | struct input_absinfo abs[MT_ABS_SIZE]; 37 | }; 38 | 39 | int read_capabilities(struct Capabilities *cap, int fd); 40 | int get_cap_xsize(const struct Capabilities *cap); 41 | int get_cap_ysize(const struct Capabilities *cap); 42 | int get_cap_wsize(const struct Capabilities *cap); 43 | 44 | int get_cap_xmid(const struct Capabilities *cap); 45 | int get_cap_ymid(const struct Capabilities *cap); 46 | 47 | int get_cap_xflip(const struct Capabilities *cap, int x); 48 | int get_cap_yflip(const struct Capabilities *cap, int y); 49 | 50 | void output_capabilities(const struct Capabilities *cap); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /include/common.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2008 Henrik Rydberg 5 | * Copyright (C) 2011 Ryan Bourgeois 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | * 21 | **************************************************************************/ 22 | 23 | #ifndef COMMON_H 24 | #define COMMON_H 25 | 26 | #ifdef HAVE_CONFIG_H 27 | #include "config.h" 28 | #endif 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #define DIM_FINGER 32 40 | #define DIM_TOUCHES 32 41 | 42 | /* year-proof millisecond event time */ 43 | typedef __u64 mstime_t; 44 | 45 | /* all bit masks have this type */ 46 | typedef unsigned int bitmask_t; 47 | 48 | #define BITMASK(x) (1U << (x)) 49 | #define BITONES(x) (BITMASK(x) - 1U) 50 | #define GETBIT(m, x) (((m) >> (x)) & 1U) 51 | #define SETBIT(m, x) (m |= BITMASK(x)) 52 | #define CLEARBIT(m, x) (m &= ~BITMASK(x)) 53 | #define MODBIT(m, x, b) ((b) ? SETBIT(m, x) : CLEARBIT(m, x)) 54 | 55 | #define ABSVAL(x) ((x) < 0 ? -1*(x) : (x)) 56 | #define MINVAL(x, y) ((x) < (y) ? (x) : (y)) 57 | #define MAXVAL(x, y) ((x) > (y) ? (x) : (y)) 58 | #define MODVAL(x, y) ((x) - ((int)((x) / (y))) * (y)) 59 | #define SQRVAL(x) ((x) * (x)) 60 | #define CLAMPVAL(x, min, max) MAXVAL(MINVAL(x, max), min) 61 | 62 | /* Retrieve the current time and place it in tv. 63 | */ 64 | static inline void microtime(struct timeval* tv) 65 | { 66 | gettimeofday(tv, NULL); 67 | } 68 | 69 | /* Copy one time value to another. 70 | */ 71 | static inline void timercp(struct timeval* dest, const struct timeval* src) 72 | { 73 | memcpy(dest, src, sizeof(struct timeval)); 74 | } 75 | 76 | /* Convert a timeval to milliseconds since the epoch. Truncates additional 77 | * timer resolution effectively rounding down. 78 | */ 79 | static inline mstime_t timertoms(const struct timeval* tv) 80 | { 81 | return (mstime_t)(tv->tv_sec*1000) + (mstime_t)(tv->tv_usec/1000); 82 | } 83 | 84 | /* Convert a value in milliseconds to a timeval and place the value in tv. 85 | */ 86 | static inline void timerfromms(struct timeval* tv, const mstime_t ms) 87 | { 88 | tv->tv_sec = (time_t)(ms/1000); 89 | tv->tv_usec = (suseconds_t)((ms%1000)*1000); 90 | } 91 | 92 | /* Convert a timeval to microseconds. 93 | */ 94 | static inline suseconds_t timertomicro(const struct timeval* tv) 95 | { 96 | return tv->tv_sec * 1000000 + tv->tv_usec; 97 | } 98 | 99 | /* Add milliseconds to a timeval and place the resulting value in dest. 100 | */ 101 | static inline void timeraddms(const struct timeval* a, const mstime_t b, struct timeval* dest) 102 | { 103 | struct timeval tv; 104 | timerfromms(&tv, b); 105 | timeradd(a, &tv, dest); 106 | } 107 | 108 | /* Clamp value to 15 bits. 109 | */ 110 | static inline int clamp15(int x) 111 | { 112 | return x < -32767 ? -32767 : x > 32767 ? 32767 : x; 113 | } 114 | 115 | /* Absolute scale is assumed to fit in 15 bits. 116 | */ 117 | static inline int dist2(int dx, int dy) 118 | { 119 | dx = clamp15(dx); 120 | dy = clamp15(dy); 121 | return dx * dx + dy * dy; 122 | } 123 | 124 | /* Count number of bits (Sean Eron Andersson's Bit Hacks). 125 | */ 126 | static inline int bitcount(unsigned v) 127 | { 128 | v -= ((v>>1) & 0x55555555); 129 | v = (v&0x33333333) + ((v>>2) & 0x33333333); 130 | return (((v + (v>>4)) & 0xF0F0F0F) * 0x1010101) >> 24; 131 | } 132 | 133 | /* Return index of first bit [0-31], -1 on zero\ 134 | */ 135 | #define firstbit(v) (__builtin_ffs(v) - 1) 136 | 137 | /* Boost-style foreach bit. 138 | */ 139 | #define foreach_bit(i, m) \ 140 | for (i = firstbit(m); i >= 0; i = firstbit((m) & (~0U << i + 1))) 141 | 142 | /* Robust system ioctl calls. 143 | */ 144 | #define SYSCALL(call) while (((call) == -1) && (errno == EINTR)) 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /include/gestures.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2008 Henrik Rydberg 5 | * Copyright (C) 2011 Ryan Bourgeois 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | * 21 | **************************************************************************/ 22 | 23 | #ifndef GESTURES_H 24 | #define GESTURES_H 25 | 26 | #include "common.h" 27 | #include "mconfig.h" 28 | #include "hwstate.h" 29 | #include "mtstate.h" 30 | 31 | struct MTouch; 32 | 33 | #define GS_TAP 0 34 | #define GS_BUTTON 1 35 | 36 | #define GS_NONE 0 37 | #define GS_MOVE 1 38 | #define GS_SCROLL 2 39 | #define GS_SWIPE 3 40 | #define GS_SCALE 4 41 | #define GS_ROTATE 5 42 | #define GS_DRAG_READY 6 43 | #define GS_DRAG_WAIT 7 44 | #define GS_DRAG_ACTIVE 8 45 | 46 | struct Gestures { 47 | /* Taps, physical buttons, and gestures will trigger 48 | * button events. If a bit is set, the button is down. 49 | * If a bit is not set, the button is up. 50 | * Bit 0 is button 1. 51 | */ 52 | bitmask_t buttons; 53 | 54 | /* Pointer movement is tracked here. 55 | */ 56 | int move_dx, move_dy; 57 | 58 | /* Current time and time delta. Updated after each event and after sleeping. 59 | */ 60 | struct timeval time; 61 | struct timeval dt; 62 | 63 | /* Internal state tracking. Not for direct access. 64 | */ 65 | int button_emulate; 66 | int button_delayed; 67 | struct timeval button_delayed_time; 68 | struct timeval button_delayed_delta; 69 | 70 | int tap_touching; 71 | int tap_released; 72 | struct timeval tap_time_down; 73 | 74 | int move_type; 75 | int move_dist; 76 | int move_dir; 77 | int move_drag; 78 | int move_drag_dx; 79 | int move_drag_dy; 80 | double move_speed; 81 | struct timeval move_wait; 82 | struct timeval move_drag_wait; 83 | struct timeval move_drag_expire; 84 | }; 85 | 86 | 87 | void gestures_init(struct MTouch* mt); 88 | void gestures_extract(struct MTouch* mt); 89 | int gestures_delayed(struct MTouch* mt); 90 | 91 | #endif 92 | 93 | -------------------------------------------------------------------------------- /include/hwstate.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2008 Henrik Rydberg 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | * 20 | **************************************************************************/ 21 | 22 | #ifndef HWSTATE_H 23 | #define HWSTATE_H 24 | 25 | #include "common.h" 26 | #include "capabilities.h" 27 | 28 | struct FingerState { 29 | int touch_major, touch_minor; 30 | int width_major, width_minor; 31 | int orientation, pressure; 32 | int position_x, position_y; 33 | int tracking_id; 34 | }; 35 | 36 | struct HWState { 37 | struct FingerState data[DIM_FINGER]; 38 | bitmask_t used; 39 | bitmask_t slot; 40 | bitmask_t button; 41 | int max_x, max_y; 42 | struct timeval evtime; 43 | }; 44 | 45 | void hwstate_init(struct HWState *s, 46 | const struct Capabilities *caps); 47 | int hwstate_modify(struct HWState *s, 48 | struct mtdev *dev, int fd, 49 | const struct Capabilities *caps); 50 | void hwstate_output(const struct HWState *s); 51 | 52 | int find_finger(const struct HWState *s, int tracking_id); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /include/mconfig.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2011 Ryan Bourgeois 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | * 20 | **************************************************************************/ 21 | 22 | #ifndef MCONFIG_H 23 | #define MCONFIG_H 24 | 25 | #include "capabilities.h" 26 | 27 | #define DEFAULT_TRACKPAD_DISABLE 0 28 | #define DEFAULT_TOUCH_DOWN 5 29 | #define DEFAULT_TOUCH_UP 5 30 | #define DEFAULT_IGNORE_THUMB 0 31 | #define DEFAULT_IGNORE_PALM 0 32 | #define DEFAULT_DISABLE_ON_THUMB 0 33 | #define DEFAULT_DISABLE_ON_PALM 0 34 | #define DEFAULT_THUMB_RATIO 70 35 | #define DEFAULT_THUMB_SIZE 25 36 | #define DEFAULT_PALM_SIZE 40 37 | #define DEFAULT_BOTTOM_EDGE 10 38 | #define DEFAULT_BUTTON_ENABLE 1 39 | #define DEFAULT_BUTTON_INTEGRATED 1 40 | #define DEFAULT_BUTTON_ZONES 0 41 | #define DEFAULT_BUTTON_1TOUCH 3 42 | #define DEFAULT_BUTTON_2TOUCH 2 43 | #define DEFAULT_BUTTON_3TOUCH 0 44 | #define DEFAULT_BUTTON_MOVE 1 45 | #define DEFAULT_BUTTON_EXPIRE 100 46 | #define DEFAULT_TAP_1TOUCH 1 47 | #define DEFAULT_TAP_2TOUCH 3 48 | #define DEFAULT_TAP_3TOUCH 2 49 | #define DEFAULT_TAP_4TOUCH 0 50 | #define DEFAULT_TAP_TIMEOUT 120 51 | #define DEFAULT_TAP_HOLD 50 52 | #define DEFAULT_TAP_DIST 400 53 | #define DEFAULT_GESTURE_HOLD 10 54 | #define DEFAULT_GESTURE_WAIT 100 55 | #define DEFAULT_SCROLL_DIST 150 56 | #define DEFAULT_SCROLL_UP_BTN 4 57 | #define DEFAULT_SCROLL_DN_BTN 5 58 | #define DEFAULT_SCROLL_LT_BTN 6 59 | #define DEFAULT_SCROLL_RT_BTN 7 60 | #define DEFAULT_SWIPE_DIST 700 61 | #define DEFAULT_SWIPE_UP_BTN 8 62 | #define DEFAULT_SWIPE_DN_BTN 9 63 | #define DEFAULT_SWIPE_LT_BTN 10 64 | #define DEFAULT_SWIPE_RT_BTN 11 65 | #define DEFAULT_SWIPE4_DIST 700 66 | #define DEFAULT_SWIPE4_UP_BTN 0 67 | #define DEFAULT_SWIPE4_DN_BTN 0 68 | #define DEFAULT_SWIPE4_LT_BTN 0 69 | #define DEFAULT_SWIPE4_RT_BTN 0 70 | #define DEFAULT_SCALE_DIST 150 71 | #define DEFAULT_SCALE_UP_BTN 12 72 | #define DEFAULT_SCALE_DN_BTN 13 73 | #define DEFAULT_ROTATE_DIST 150 74 | #define DEFAULT_ROTATE_LT_BTN 14 75 | #define DEFAULT_ROTATE_RT_BTN 15 76 | #define DEFAULT_DRAG_ENABLE 1 77 | #define DEFAULT_DRAG_TIMEOUT 350 78 | #define DEFAULT_DRAG_WAIT 40 79 | #define DEFAULT_DRAG_DIST 200 80 | #define DEFAULT_AXIS_X_INVERT 0 81 | #define DEFAULT_AXIS_Y_INVERT 0 82 | #define DEFAULT_SENSITIVITY 1.0 83 | 84 | #define MCFG_NONE 0 85 | #define MCFG_SCALE 1 86 | #define MCFG_SIZE 2 87 | #define MCFG_PRESSURE 3 88 | 89 | struct MConfig { 90 | /* Used by MTState */ 91 | 92 | // Set by caps. 93 | int touch_type; // How to determine touch? 0 for none, 1 for scale, 2 for size, 3 for pressure 94 | int touch_minor; // Does the touchpad report touches as ellipses? 0 or 1 95 | int touch_min; // Minimum touch value. 96 | int touch_max; // Maximum touch value. 97 | int pad_width; // Width of the touchpad. 98 | int pad_height; // Height of the touchpad. 99 | 100 | // Set by config. 101 | int touch_down; // When is a finger touching? 0 - 100 (percentage) 102 | int touch_up; // When is a finger released? 0 - 100 (percentage) 103 | int ignore_thumb; // Whether or not to ignore thumbs. 0 or 1 104 | int ignore_palm; // Whether or not to ignore palms. 0 or 1 105 | int disable_on_thumb; // Disable the touchpad if thumb detected. 0 or 1 106 | int disable_on_palm; // Disable the touchpad if palm detected. 0 or 1 107 | int thumb_ratio; // Ratio of width to length that makes a touch a thumb. 0 - 100 108 | int thumb_size; // Minimum touch size for a thumb. 0 - 100 109 | int palm_size; // Minimum touch size for a palm. 0 - 100 110 | int bottom_edge; // Percent of bottom of trackpad to ignore for new touches. 0 - 100 111 | int axis_x_invert; // Whether or not to invert the x axis. 0 or 1. 112 | int axis_y_invert; // Whether or not to invert the y axis. 0 or 1. 113 | 114 | /* Used by Gestures */ 115 | 116 | // Set by config. 117 | int trackpad_disable; // Disable the trackpad? 0 or 1 118 | int button_enable; // Enable physical buttons? 0 or 1 119 | int button_integrated; // Is the button under the touchpad? 0 or 1 120 | int button_expire; // How long to consider a touch for button emulation. >= 0 121 | int button_zones; // Use button zones for emulation? 122 | int button_1touch; // What button to emulate when one finger is on the 123 | // pad or the first zone is clicked? 0 to 32 124 | int button_2touch; // What button to emulate when two fingers are on the 125 | // pad or the second zone is clicked? 0 to 32 126 | int button_3touch; // What button to emulate when three fingers are on the 127 | // pad or the third zone is clicked? 0 to 32 128 | int button_move; // Whether or not to count the moving touch towards button 129 | // emulation. 130 | int tap_1touch; // What button to emulate for one touch taps? 0 to 32 131 | int tap_2touch; // What button to emulate for two touch taps? 0 to 32 132 | int tap_3touch; // What button to emulate for three touch taps? 0 to 32 133 | int tap_4touch; // What button to emulate for four touch taps? 0 to 32 134 | int tap_timeout; // Window for touches when counting for the button. > 0 135 | int tap_hold; // How long to "hold down" the emulated button on tap. > 0 136 | int tap_dist; // How far to allow a touch to move before it's a moving touch. > 0 137 | int gesture_hold; // How long to "hold down" the emulated button for gestures. > 0 138 | int gesture_wait; // How long after a gesture to wait before movement is allowed. >= 0 139 | int scroll_dist; // Distance needed to trigger a button. >= 0, 0 disables 140 | int scroll_up_btn; // Button to use for scroll up. >= 0, 0 is none 141 | int scroll_dn_btn; // Button to use for scroll down. >= 0, 0 is none 142 | int scroll_lt_btn; // Button to use for scroll left. >= 0, 0 is none 143 | int scroll_rt_btn; // Button to use for scroll right. >= 0, 0 is none 144 | int swipe_dist; // Distance needed to trigger a button. >= 0, 0 disables 145 | int swipe_up_btn; // Button to use for swipe up. >= 0, 0 is none 146 | int swipe_dn_btn; // Button to use for swipe down. >= 0, 0 is none 147 | int swipe_lt_btn; // Button to use for swipe left. >= 0, 0 is none 148 | int swipe_rt_btn; // Button to use for swipe right. >= 0, 0 is none 149 | int swipe4_dist; // Distance needed to trigger a button. >= 0, 0 disables 150 | int swipe4_up_btn; // Button to use for four finger swipe up. >= 0, 0 is none 151 | int swipe4_dn_btn; // Button to use for four finger swipe down. >= 0, 0 is none 152 | int swipe4_lt_btn; // Button to use for four finger swipe left. >= 0, 0 is none 153 | int swipe4_rt_btn; // Button to use for four finger swipe right. >= 0, 0 is none 154 | int scale_dist; // Distance needed to trigger a button. >= 0, 0 disables 155 | int scale_up_btn; // Button to use for scale up. >= 0, 0 is none 156 | int scale_dn_btn; // Button to use for scale down. >= 0, 0 is none 157 | int rotate_dist; // Distance needed to trigger a button. >= 0, 0 disables 158 | int rotate_lt_btn; // Button to use for rotate left. >= 0, 0 is none 159 | int rotate_rt_btn; // Button to use for rotate right. >= 0, 0 is none 160 | int drag_enable; // Enable tap-to-drag? 0 or 1 161 | int drag_timeout; // How long to wait for a move after tapping? > 0 162 | int drag_wait; // How long to wait before triggering button down? >= 0 163 | int drag_dist; // How far is the finger allowed to move during wait time? >= 0 164 | double sensitivity; // Mouse movement multiplier. >= 0 165 | }; 166 | 167 | /* Load the MConfig struct with its defaults. 168 | */ 169 | void mconfig_defaults(struct MConfig* cfg); 170 | 171 | /* Initialize the MConfig struct. 172 | */ 173 | void mconfig_init(struct MConfig* cfg, 174 | const struct Capabilities* caps); 175 | 176 | void mconfig_configure(struct MConfig* cfg, 177 | pointer opts); 178 | 179 | #endif 180 | 181 | -------------------------------------------------------------------------------- /include/mprops.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2011 Ryan Bourgeois 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | * 20 | **************************************************************************/ 21 | 22 | #ifndef MTRACK_PROPS_H 23 | #define MTRACK_PROPS_H 24 | 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "mconfig.h" 34 | 35 | #ifndef XATOM_FLOAT 36 | #define XATOM_FLOAT "FLOAT" 37 | #endif 38 | 39 | // int, 1 value 40 | #define MTRACK_PROP_TRACKPAD_DISABLE "Trackpad Disable Input" 41 | // float, 1 value 42 | #define MTRACK_PROP_SENSITIVITY "Trackpad Sensitivity" 43 | // int, 2 values - finger low, finger high 44 | #define MTRACK_PROP_PRESSURE "Trackpad Touch Pressure" 45 | // int, 2 values - enable buttons, has integrated button 46 | #define MTRACK_PROP_BUTTON_SETTINGS "Trackpad Button Settings" 47 | // int, 3 values - enable button zones, button move emulation, emulation touch expiration 48 | #define MTRACK_PROP_BUTTON_EMULATE_SETTINGS "Trackpad Button Emulation Settings" 49 | // int, 3 values - button to emulate with 1 touch, 2 touches, 3 touches 50 | #define MTRACK_PROP_BUTTON_EMULATE_VALUES "Trackpad Button Emulation Values" 51 | // int, 3 values - click time, touch timeout, invalidate distance 52 | #define MTRACK_PROP_TAP_SETTINGS "Trackpad Tap Settings" 53 | // int, 3 values - 1 touch button, 2 touch button, 3 touch button, 4 touch button 54 | #define MTRACK_PROP_TAP_EMULATE "Trackpad Tap Button Emulation" 55 | // int, 2 values - ignore thumb touches, disable trackpad on thumb touches 56 | #define MTRACK_PROP_THUMB_DETECT "Trackpad Thumb Detection" 57 | // int, 2 values - size, width to length ratio 58 | #define MTRACK_PROP_THUMB_SIZE "Trackpad Thumb Size" 59 | // int, 2 values - ignore palm touches, disable trackpad on palm touches 60 | #define MTRACK_PROP_PALM_DETECT "Trackpad Palm Detection" 61 | // int, 1 value - size 62 | #define MTRACK_PROP_PALM_SIZE "Trackpad Palm Size" 63 | // int, 2 value - button hold, wait time 64 | #define MTRACK_PROP_GESTURE_SETTINGS "Trackpad Gesture Settings" 65 | // int, 1 value - distance before a scroll event is triggered 66 | #define MTRACK_PROP_SCROLL_DIST "Trackpad Scroll Distance" 67 | // int, 4 values - up button, down button, left button, right button 68 | #define MTRACK_PROP_SCROLL_BUTTONS "Trackpad Scroll Buttons" 69 | // int, 1 value - distance before a swipe event is triggered 70 | #define MTRACK_PROP_SWIPE_DIST "Trackpad Swipe Distance" 71 | // int, 4 values - up button, down button, left button, right button 72 | #define MTRACK_PROP_SWIPE_BUTTONS "Trackpad Swipe Buttons" 73 | // int, 1 value - distance before a swipe event is triggered 74 | #define MTRACK_PROP_SWIPE4_DIST "Trackpad Swipe4 Distance" 75 | // int, 4 values - up button, down button, left button, right button 76 | #define MTRACK_PROP_SWIPE4_BUTTONS "Trackpad Swipe4 Buttons" 77 | // int, 1 value - distance before a scale event is triggered 78 | #define MTRACK_PROP_SCALE_DIST "Trackpad Scale Distance" 79 | // int, 2 values - up button, down button 80 | #define MTRACK_PROP_SCALE_BUTTONS "Trackpad Scale Buttons" 81 | // int, 1 value - distance before a rotate event is triggered 82 | #define MTRACK_PROP_ROTATE_DIST "Trackpad Rotate Distance" 83 | // int, 2 values - left button, right button 84 | #define MTRACK_PROP_ROTATE_BUTTONS "Trackpad Rotate Buttons" 85 | // int, 4 values - enable, timeout, wait, dist 86 | #define MTRACK_PROP_DRAG_SETTINGS "Trackpad Drag Settings" 87 | // int, 2 values - invert x axis, invert y axis 88 | #define MTRACK_PROP_AXIS_INVERT "Trackpad Axis Inversion" 89 | 90 | struct MProps { 91 | // Properties Config 92 | Atom float_type; 93 | 94 | // Adjustable Properties 95 | Atom api; 96 | Atom trackpad_disable; 97 | Atom sensitivity; 98 | Atom pressure; 99 | Atom button_settings; 100 | Atom button_emulate_settings; 101 | Atom button_emulate_values; 102 | Atom tap_settings; 103 | Atom tap_emulate; 104 | Atom thumb_detect; 105 | Atom thumb_size; 106 | Atom palm_detect; 107 | Atom palm_size; 108 | Atom gesture_settings; 109 | Atom scroll_dist; 110 | Atom scroll_buttons; 111 | Atom swipe_dist; 112 | Atom swipe_buttons; 113 | Atom swipe4_dist; 114 | Atom swipe4_buttons; 115 | Atom scale_dist; 116 | Atom scale_buttons; 117 | Atom rotate_dist; 118 | Atom rotate_buttons; 119 | Atom drag_settings; 120 | Atom axis_invert; 121 | }; 122 | 123 | void mprops_init(struct MConfig* cfg, InputInfoPtr local); 124 | int mprops_set_property(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, BOOL checkonly); 125 | 126 | #endif 127 | 128 | -------------------------------------------------------------------------------- /include/mtouch.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2008 Henrik Rydberg 5 | * Copyright (C) 2011 Ryan Bourgeois 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | * 21 | **************************************************************************/ 22 | 23 | #ifndef MTOUCH_H 24 | #define MTOUCH_H 25 | 26 | #include "common.h" 27 | #include "capabilities.h" 28 | #include "hwstate.h" 29 | #include "mtstate.h" 30 | #include "mconfig.h" 31 | #include "gestures.h" 32 | 33 | struct MTouch { 34 | int fd; 35 | struct mtdev dev; 36 | struct Capabilities caps; 37 | struct HWState hs; 38 | struct MTState state; 39 | struct MConfig cfg; 40 | struct Gestures gs; 41 | }; 42 | 43 | int mtouch_configure(struct MTouch* mt, int fd); 44 | int mtouch_open(struct MTouch* mt, int fd); 45 | int mtouch_close(struct MTouch* mt); 46 | 47 | int mtouch_read(struct MTouch* mt); 48 | int mtouch_delayed(struct MTouch* mt); 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /include/mtstate.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2008 Henrik Rydberg 5 | * Copyright (C) 2011 Ryan Bourgeois 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | * 21 | **************************************************************************/ 22 | 23 | #ifndef MTSTATE_H 24 | #define MTSTATE_H 25 | 26 | #include "common.h" 27 | #include "mconfig.h" 28 | #include "hwstate.h" 29 | #include "capabilities.h" 30 | 31 | #define MT_NEW 0 32 | #define MT_RELEASED 1 33 | #define MT_INVALID 2 34 | #define MT_THUMB 3 35 | #define MT_PALM 4 36 | #define MT_BOTTOM_EDGE 5 37 | 38 | struct Touch { 39 | bitmask_t state; 40 | bitmask_t flags; 41 | double direction; 42 | int tracking_id; 43 | int x, y, dx, dy; 44 | int total_dx, total_dy; 45 | struct timeval down; 46 | }; 47 | 48 | struct MTState { 49 | bitmask_t state; 50 | struct Touch touch[DIM_TOUCHES]; 51 | bitmask_t touch_used; 52 | }; 53 | 54 | /* Initialize an MTState struct. 55 | */ 56 | void mtstate_init(struct MTState* ms); 57 | 58 | /* Extract the MTState from the current hardware state. 59 | */ 60 | void mtstate_extract(struct MTState* ms, 61 | const struct MConfig* cfg, 62 | const struct HWState* hs, 63 | const struct Capabilities* caps); 64 | 65 | #endif 66 | 67 | -------------------------------------------------------------------------------- /include/trig.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2011 Ryan Bourgeois 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | * 20 | **************************************************************************/ 21 | 22 | /* Some bastardized trig functions. These calculations flip the 23 | * Y axis since that axis on touchpads is opposite that of the 24 | * Cartesian system. 25 | */ 26 | 27 | #ifndef MT_TRIG_H 28 | #define MT_TRIG_H 29 | 30 | #define TR_NONE -1 31 | #define TR_DIR_UP 0 32 | #define TR_DIR_RT 2 33 | #define TR_DIR_DN 4 34 | #define TR_DIR_LT 6 35 | 36 | /* Determine the direction of a vector. This uses the slope of the 37 | * vector to approximate the angle, as such it is only accurate at 38 | * increments of 45 degrees. This is sufficient for our uses. 39 | * 40 | * The returned value is 0 <= a < 8 such that the circle is split 41 | * into 45 degree sections. Each whole number lies 45 degrees apart 42 | * and so whole numbers are exact. All fractional parts are 43 | * aproximations. 44 | * 45 | * TR_NONE will be returned if the magnitude of the vector is zero. 46 | */ 47 | double trig_direction(double dx, double dy); 48 | 49 | /* Generalize a direction. Returns TR_NONE, TR_DIR_UP, TR_DIR_RT, 50 | * TR_DIR_DN, or TR_DIR_LT. 51 | */ 52 | int trig_generalize(double dir); 53 | 54 | /* Add two angles. 55 | */ 56 | double trig_angles_add(double a1, double a2); 57 | 58 | /* Subtract two angles. 59 | */ 60 | double trig_angles_sub(double a1, double a2); 61 | 62 | /* Calculate the acute angle between two angles. 63 | */ 64 | double trig_angles_acute(double a1, double a2); 65 | 66 | /* Average a collection of angles. 67 | */ 68 | double trig_angles_avg(double* angles, int len); 69 | 70 | /* Compare two angles. Returns 0 if a1 == a2. Returns < 0 if a1 < a2. 71 | * Returns > 0 if a1 > a2. 72 | */ 73 | int trig_angles_cmp(double a1, double a2); 74 | 75 | #endif 76 | 77 | -------------------------------------------------------------------------------- /install-sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # install - install a program, script, or datafile 3 | 4 | scriptversion=2013-12-25.23; # UTC 5 | 6 | # This originates from X11R5 (mit/util/scripts/install.sh), which was 7 | # later released in X11R6 (xc/config/util/install.sh) with the 8 | # following copyright and license. 9 | # 10 | # Copyright (C) 1994 X Consortium 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to 14 | # deal in the Software without restriction, including without limitation the 15 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16 | # sell copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26 | # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27 | # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | # 29 | # Except as contained in this notice, the name of the X Consortium shall not 30 | # be used in advertising or otherwise to promote the sale, use or other deal- 31 | # ings in this Software without prior written authorization from the X Consor- 32 | # tium. 33 | # 34 | # 35 | # FSF changes to this file are in the public domain. 36 | # 37 | # Calling this script install-sh is preferred over install.sh, to prevent 38 | # 'make' implicit rules from creating a file called install from it 39 | # when there is no Makefile. 40 | # 41 | # This script is compatible with the BSD install script, but was written 42 | # from scratch. 43 | 44 | tab=' ' 45 | nl=' 46 | ' 47 | IFS=" $tab$nl" 48 | 49 | # Set DOITPROG to "echo" to test this script. 50 | 51 | doit=${DOITPROG-} 52 | doit_exec=${doit:-exec} 53 | 54 | # Put in absolute file names if you don't have them in your path; 55 | # or use environment vars. 56 | 57 | chgrpprog=${CHGRPPROG-chgrp} 58 | chmodprog=${CHMODPROG-chmod} 59 | chownprog=${CHOWNPROG-chown} 60 | cmpprog=${CMPPROG-cmp} 61 | cpprog=${CPPROG-cp} 62 | mkdirprog=${MKDIRPROG-mkdir} 63 | mvprog=${MVPROG-mv} 64 | rmprog=${RMPROG-rm} 65 | stripprog=${STRIPPROG-strip} 66 | 67 | posix_mkdir= 68 | 69 | # Desired mode of installed file. 70 | mode=0755 71 | 72 | chgrpcmd= 73 | chmodcmd=$chmodprog 74 | chowncmd= 75 | mvcmd=$mvprog 76 | rmcmd="$rmprog -f" 77 | stripcmd= 78 | 79 | src= 80 | dst= 81 | dir_arg= 82 | dst_arg= 83 | 84 | copy_on_change=false 85 | is_target_a_directory=possibly 86 | 87 | usage="\ 88 | Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 89 | or: $0 [OPTION]... SRCFILES... DIRECTORY 90 | or: $0 [OPTION]... -t DIRECTORY SRCFILES... 91 | or: $0 [OPTION]... -d DIRECTORIES... 92 | 93 | In the 1st form, copy SRCFILE to DSTFILE. 94 | In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 95 | In the 4th, create DIRECTORIES. 96 | 97 | Options: 98 | --help display this help and exit. 99 | --version display version info and exit. 100 | 101 | -c (ignored) 102 | -C install only if different (preserve the last data modification time) 103 | -d create directories instead of installing files. 104 | -g GROUP $chgrpprog installed files to GROUP. 105 | -m MODE $chmodprog installed files to MODE. 106 | -o USER $chownprog installed files to USER. 107 | -s $stripprog installed files. 108 | -t DIRECTORY install into DIRECTORY. 109 | -T report an error if DSTFILE is a directory. 110 | 111 | Environment variables override the default commands: 112 | CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG 113 | RMPROG STRIPPROG 114 | " 115 | 116 | while test $# -ne 0; do 117 | case $1 in 118 | -c) ;; 119 | 120 | -C) copy_on_change=true;; 121 | 122 | -d) dir_arg=true;; 123 | 124 | -g) chgrpcmd="$chgrpprog $2" 125 | shift;; 126 | 127 | --help) echo "$usage"; exit $?;; 128 | 129 | -m) mode=$2 130 | case $mode in 131 | *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) 132 | echo "$0: invalid mode: $mode" >&2 133 | exit 1;; 134 | esac 135 | shift;; 136 | 137 | -o) chowncmd="$chownprog $2" 138 | shift;; 139 | 140 | -s) stripcmd=$stripprog;; 141 | 142 | -t) 143 | is_target_a_directory=always 144 | dst_arg=$2 145 | # Protect names problematic for 'test' and other utilities. 146 | case $dst_arg in 147 | -* | [=\(\)!]) dst_arg=./$dst_arg;; 148 | esac 149 | shift;; 150 | 151 | -T) is_target_a_directory=never;; 152 | 153 | --version) echo "$0 $scriptversion"; exit $?;; 154 | 155 | --) shift 156 | break;; 157 | 158 | -*) echo "$0: invalid option: $1" >&2 159 | exit 1;; 160 | 161 | *) break;; 162 | esac 163 | shift 164 | done 165 | 166 | # We allow the use of options -d and -T together, by making -d 167 | # take the precedence; this is for compatibility with GNU install. 168 | 169 | if test -n "$dir_arg"; then 170 | if test -n "$dst_arg"; then 171 | echo "$0: target directory not allowed when installing a directory." >&2 172 | exit 1 173 | fi 174 | fi 175 | 176 | if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then 177 | # When -d is used, all remaining arguments are directories to create. 178 | # When -t is used, the destination is already specified. 179 | # Otherwise, the last argument is the destination. Remove it from $@. 180 | for arg 181 | do 182 | if test -n "$dst_arg"; then 183 | # $@ is not empty: it contains at least $arg. 184 | set fnord "$@" "$dst_arg" 185 | shift # fnord 186 | fi 187 | shift # arg 188 | dst_arg=$arg 189 | # Protect names problematic for 'test' and other utilities. 190 | case $dst_arg in 191 | -* | [=\(\)!]) dst_arg=./$dst_arg;; 192 | esac 193 | done 194 | fi 195 | 196 | if test $# -eq 0; then 197 | if test -z "$dir_arg"; then 198 | echo "$0: no input file specified." >&2 199 | exit 1 200 | fi 201 | # It's OK to call 'install-sh -d' without argument. 202 | # This can happen when creating conditional directories. 203 | exit 0 204 | fi 205 | 206 | if test -z "$dir_arg"; then 207 | if test $# -gt 1 || test "$is_target_a_directory" = always; then 208 | if test ! -d "$dst_arg"; then 209 | echo "$0: $dst_arg: Is not a directory." >&2 210 | exit 1 211 | fi 212 | fi 213 | fi 214 | 215 | if test -z "$dir_arg"; then 216 | do_exit='(exit $ret); exit $ret' 217 | trap "ret=129; $do_exit" 1 218 | trap "ret=130; $do_exit" 2 219 | trap "ret=141; $do_exit" 13 220 | trap "ret=143; $do_exit" 15 221 | 222 | # Set umask so as not to create temps with too-generous modes. 223 | # However, 'strip' requires both read and write access to temps. 224 | case $mode in 225 | # Optimize common cases. 226 | *644) cp_umask=133;; 227 | *755) cp_umask=22;; 228 | 229 | *[0-7]) 230 | if test -z "$stripcmd"; then 231 | u_plus_rw= 232 | else 233 | u_plus_rw='% 200' 234 | fi 235 | cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 236 | *) 237 | if test -z "$stripcmd"; then 238 | u_plus_rw= 239 | else 240 | u_plus_rw=,u+rw 241 | fi 242 | cp_umask=$mode$u_plus_rw;; 243 | esac 244 | fi 245 | 246 | for src 247 | do 248 | # Protect names problematic for 'test' and other utilities. 249 | case $src in 250 | -* | [=\(\)!]) src=./$src;; 251 | esac 252 | 253 | if test -n "$dir_arg"; then 254 | dst=$src 255 | dstdir=$dst 256 | test -d "$dstdir" 257 | dstdir_status=$? 258 | else 259 | 260 | # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 261 | # might cause directories to be created, which would be especially bad 262 | # if $src (and thus $dsttmp) contains '*'. 263 | if test ! -f "$src" && test ! -d "$src"; then 264 | echo "$0: $src does not exist." >&2 265 | exit 1 266 | fi 267 | 268 | if test -z "$dst_arg"; then 269 | echo "$0: no destination specified." >&2 270 | exit 1 271 | fi 272 | dst=$dst_arg 273 | 274 | # If destination is a directory, append the input filename; won't work 275 | # if double slashes aren't ignored. 276 | if test -d "$dst"; then 277 | if test "$is_target_a_directory" = never; then 278 | echo "$0: $dst_arg: Is a directory" >&2 279 | exit 1 280 | fi 281 | dstdir=$dst 282 | dst=$dstdir/`basename "$src"` 283 | dstdir_status=0 284 | else 285 | dstdir=`dirname "$dst"` 286 | test -d "$dstdir" 287 | dstdir_status=$? 288 | fi 289 | fi 290 | 291 | obsolete_mkdir_used=false 292 | 293 | if test $dstdir_status != 0; then 294 | case $posix_mkdir in 295 | '') 296 | # Create intermediate dirs using mode 755 as modified by the umask. 297 | # This is like FreeBSD 'install' as of 1997-10-28. 298 | umask=`umask` 299 | case $stripcmd.$umask in 300 | # Optimize common cases. 301 | *[2367][2367]) mkdir_umask=$umask;; 302 | .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 303 | 304 | *[0-7]) 305 | mkdir_umask=`expr $umask + 22 \ 306 | - $umask % 100 % 40 + $umask % 20 \ 307 | - $umask % 10 % 4 + $umask % 2 308 | `;; 309 | *) mkdir_umask=$umask,go-w;; 310 | esac 311 | 312 | # With -d, create the new directory with the user-specified mode. 313 | # Otherwise, rely on $mkdir_umask. 314 | if test -n "$dir_arg"; then 315 | mkdir_mode=-m$mode 316 | else 317 | mkdir_mode= 318 | fi 319 | 320 | posix_mkdir=false 321 | case $umask in 322 | *[123567][0-7][0-7]) 323 | # POSIX mkdir -p sets u+wx bits regardless of umask, which 324 | # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 325 | ;; 326 | *) 327 | tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 328 | trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 329 | 330 | if (umask $mkdir_umask && 331 | exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 332 | then 333 | if test -z "$dir_arg" || { 334 | # Check for POSIX incompatibilities with -m. 335 | # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 336 | # other-writable bit of parent directory when it shouldn't. 337 | # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 338 | ls_ld_tmpdir=`ls -ld "$tmpdir"` 339 | case $ls_ld_tmpdir in 340 | d????-?r-*) different_mode=700;; 341 | d????-?--*) different_mode=755;; 342 | *) false;; 343 | esac && 344 | $mkdirprog -m$different_mode -p -- "$tmpdir" && { 345 | ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 346 | test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 347 | } 348 | } 349 | then posix_mkdir=: 350 | fi 351 | rmdir "$tmpdir/d" "$tmpdir" 352 | else 353 | # Remove any dirs left behind by ancient mkdir implementations. 354 | rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 355 | fi 356 | trap '' 0;; 357 | esac;; 358 | esac 359 | 360 | if 361 | $posix_mkdir && ( 362 | umask $mkdir_umask && 363 | $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 364 | ) 365 | then : 366 | else 367 | 368 | # The umask is ridiculous, or mkdir does not conform to POSIX, 369 | # or it failed possibly due to a race condition. Create the 370 | # directory the slow way, step by step, checking for races as we go. 371 | 372 | case $dstdir in 373 | /*) prefix='/';; 374 | [-=\(\)!]*) prefix='./';; 375 | *) prefix='';; 376 | esac 377 | 378 | oIFS=$IFS 379 | IFS=/ 380 | set -f 381 | set fnord $dstdir 382 | shift 383 | set +f 384 | IFS=$oIFS 385 | 386 | prefixes= 387 | 388 | for d 389 | do 390 | test X"$d" = X && continue 391 | 392 | prefix=$prefix$d 393 | if test -d "$prefix"; then 394 | prefixes= 395 | else 396 | if $posix_mkdir; then 397 | (umask=$mkdir_umask && 398 | $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 399 | # Don't fail if two instances are running concurrently. 400 | test -d "$prefix" || exit 1 401 | else 402 | case $prefix in 403 | *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 404 | *) qprefix=$prefix;; 405 | esac 406 | prefixes="$prefixes '$qprefix'" 407 | fi 408 | fi 409 | prefix=$prefix/ 410 | done 411 | 412 | if test -n "$prefixes"; then 413 | # Don't fail if two instances are running concurrently. 414 | (umask $mkdir_umask && 415 | eval "\$doit_exec \$mkdirprog $prefixes") || 416 | test -d "$dstdir" || exit 1 417 | obsolete_mkdir_used=true 418 | fi 419 | fi 420 | fi 421 | 422 | if test -n "$dir_arg"; then 423 | { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 424 | { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 425 | { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 426 | test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 427 | else 428 | 429 | # Make a couple of temp file names in the proper directory. 430 | dsttmp=$dstdir/_inst.$$_ 431 | rmtmp=$dstdir/_rm.$$_ 432 | 433 | # Trap to clean up those temp files at exit. 434 | trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 435 | 436 | # Copy the file name to the temp name. 437 | (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 438 | 439 | # and set any options; do chmod last to preserve setuid bits. 440 | # 441 | # If any of these fail, we abort the whole thing. If we want to 442 | # ignore errors from any of these, just make sure not to ignore 443 | # errors from the above "$doit $cpprog $src $dsttmp" command. 444 | # 445 | { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && 446 | { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && 447 | { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && 448 | { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 449 | 450 | # If -C, don't bother to copy if it wouldn't change the file. 451 | if $copy_on_change && 452 | old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && 453 | new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && 454 | set -f && 455 | set X $old && old=:$2:$4:$5:$6 && 456 | set X $new && new=:$2:$4:$5:$6 && 457 | set +f && 458 | test "$old" = "$new" && 459 | $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 460 | then 461 | rm -f "$dsttmp" 462 | else 463 | # Rename the file to the real destination. 464 | $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || 465 | 466 | # The rename failed, perhaps because mv can't rename something else 467 | # to itself, or perhaps because mv is so ancient that it does not 468 | # support -f. 469 | { 470 | # Now remove or move aside any old file at destination location. 471 | # We try this two ways since rm can't unlink itself on some 472 | # systems and the destination file might be busy for other 473 | # reasons. In this case, the final cleanup might fail but the new 474 | # file should still install successfully. 475 | { 476 | test ! -f "$dst" || 477 | $doit $rmcmd -f "$dst" 2>/dev/null || 478 | { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && 479 | { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } 480 | } || 481 | { echo "$0: cannot unlink or rename $dst" >&2 482 | (exit 1); exit 1 483 | } 484 | } && 485 | 486 | # Now rename the file to the real destination. 487 | $doit $mvcmd "$dsttmp" "$dst" 488 | } 489 | fi || exit 1 490 | 491 | trap '' 0 492 | fi 493 | done 494 | 495 | # Local variables: 496 | # eval: (add-hook 'write-file-hooks 'time-stamp) 497 | # time-stamp-start: "scriptversion=" 498 | # time-stamp-format: "%:y-%02m-%02d.%02H" 499 | # time-stamp-time-zone: "UTC" 500 | # time-stamp-end: "; # UTC" 501 | # End: 502 | -------------------------------------------------------------------------------- /m4/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rynbrd/xf86-input-mtrack/c1301b07d13cbd0b69a069c328f5250f8d87a7f3/m4/.keep -------------------------------------------------------------------------------- /m4/ltoptions.m4: -------------------------------------------------------------------------------- 1 | # Helper functions for option handling. -*- Autoconf -*- 2 | # 3 | # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, 4 | # Inc. 5 | # Written by Gary V. Vaughan, 2004 6 | # 7 | # This file is free software; the Free Software Foundation gives 8 | # unlimited permission to copy and/or distribute it, with or without 9 | # modifications, as long as this notice is preserved. 10 | 11 | # serial 7 ltoptions.m4 12 | 13 | # This is to help aclocal find these macros, as it can't see m4_define. 14 | AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) 15 | 16 | 17 | # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) 18 | # ------------------------------------------ 19 | m4_define([_LT_MANGLE_OPTION], 20 | [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) 21 | 22 | 23 | # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) 24 | # --------------------------------------- 25 | # Set option OPTION-NAME for macro MACRO-NAME, and if there is a 26 | # matching handler defined, dispatch to it. Other OPTION-NAMEs are 27 | # saved as a flag. 28 | m4_define([_LT_SET_OPTION], 29 | [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl 30 | m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), 31 | _LT_MANGLE_DEFUN([$1], [$2]), 32 | [m4_warning([Unknown $1 option `$2'])])[]dnl 33 | ]) 34 | 35 | 36 | # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) 37 | # ------------------------------------------------------------ 38 | # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. 39 | m4_define([_LT_IF_OPTION], 40 | [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) 41 | 42 | 43 | # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) 44 | # ------------------------------------------------------- 45 | # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME 46 | # are set. 47 | m4_define([_LT_UNLESS_OPTIONS], 48 | [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), 49 | [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), 50 | [m4_define([$0_found])])])[]dnl 51 | m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 52 | ])[]dnl 53 | ]) 54 | 55 | 56 | # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) 57 | # ---------------------------------------- 58 | # OPTION-LIST is a space-separated list of Libtool options associated 59 | # with MACRO-NAME. If any OPTION has a matching handler declared with 60 | # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about 61 | # the unknown option and exit. 62 | m4_defun([_LT_SET_OPTIONS], 63 | [# Set options 64 | m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), 65 | [_LT_SET_OPTION([$1], _LT_Option)]) 66 | 67 | m4_if([$1],[LT_INIT],[ 68 | dnl 69 | dnl Simply set some default values (i.e off) if boolean options were not 70 | dnl specified: 71 | _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no 72 | ]) 73 | _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no 74 | ]) 75 | dnl 76 | dnl If no reference was made to various pairs of opposing options, then 77 | dnl we run the default mode handler for the pair. For example, if neither 78 | dnl `shared' nor `disable-shared' was passed, we enable building of shared 79 | dnl archives by default: 80 | _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) 81 | _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) 82 | _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) 83 | _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], 84 | [_LT_ENABLE_FAST_INSTALL]) 85 | ]) 86 | ])# _LT_SET_OPTIONS 87 | 88 | 89 | ## --------------------------------- ## 90 | ## Macros to handle LT_INIT options. ## 91 | ## --------------------------------- ## 92 | 93 | # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) 94 | # ----------------------------------------- 95 | m4_define([_LT_MANGLE_DEFUN], 96 | [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) 97 | 98 | 99 | # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) 100 | # ----------------------------------------------- 101 | m4_define([LT_OPTION_DEFINE], 102 | [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl 103 | ])# LT_OPTION_DEFINE 104 | 105 | 106 | # dlopen 107 | # ------ 108 | LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes 109 | ]) 110 | 111 | AU_DEFUN([AC_LIBTOOL_DLOPEN], 112 | [_LT_SET_OPTION([LT_INIT], [dlopen]) 113 | AC_DIAGNOSE([obsolete], 114 | [$0: Remove this warning and the call to _LT_SET_OPTION when you 115 | put the `dlopen' option into LT_INIT's first parameter.]) 116 | ]) 117 | 118 | dnl aclocal-1.4 backwards compatibility: 119 | dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) 120 | 121 | 122 | # win32-dll 123 | # --------- 124 | # Declare package support for building win32 dll's. 125 | LT_OPTION_DEFINE([LT_INIT], [win32-dll], 126 | [enable_win32_dll=yes 127 | 128 | case $host in 129 | *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) 130 | AC_CHECK_TOOL(AS, as, false) 131 | AC_CHECK_TOOL(DLLTOOL, dlltool, false) 132 | AC_CHECK_TOOL(OBJDUMP, objdump, false) 133 | ;; 134 | esac 135 | 136 | test -z "$AS" && AS=as 137 | _LT_DECL([], [AS], [1], [Assembler program])dnl 138 | 139 | test -z "$DLLTOOL" && DLLTOOL=dlltool 140 | _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl 141 | 142 | test -z "$OBJDUMP" && OBJDUMP=objdump 143 | _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl 144 | ])# win32-dll 145 | 146 | AU_DEFUN([AC_LIBTOOL_WIN32_DLL], 147 | [AC_REQUIRE([AC_CANONICAL_HOST])dnl 148 | _LT_SET_OPTION([LT_INIT], [win32-dll]) 149 | AC_DIAGNOSE([obsolete], 150 | [$0: Remove this warning and the call to _LT_SET_OPTION when you 151 | put the `win32-dll' option into LT_INIT's first parameter.]) 152 | ]) 153 | 154 | dnl aclocal-1.4 backwards compatibility: 155 | dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) 156 | 157 | 158 | # _LT_ENABLE_SHARED([DEFAULT]) 159 | # ---------------------------- 160 | # implement the --enable-shared flag, and supports the `shared' and 161 | # `disable-shared' LT_INIT options. 162 | # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. 163 | m4_define([_LT_ENABLE_SHARED], 164 | [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl 165 | AC_ARG_ENABLE([shared], 166 | [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], 167 | [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], 168 | [p=${PACKAGE-default} 169 | case $enableval in 170 | yes) enable_shared=yes ;; 171 | no) enable_shared=no ;; 172 | *) 173 | enable_shared=no 174 | # Look at the argument we got. We use all the common list separators. 175 | lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," 176 | for pkg in $enableval; do 177 | IFS="$lt_save_ifs" 178 | if test "X$pkg" = "X$p"; then 179 | enable_shared=yes 180 | fi 181 | done 182 | IFS="$lt_save_ifs" 183 | ;; 184 | esac], 185 | [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) 186 | 187 | _LT_DECL([build_libtool_libs], [enable_shared], [0], 188 | [Whether or not to build shared libraries]) 189 | ])# _LT_ENABLE_SHARED 190 | 191 | LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) 192 | LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) 193 | 194 | # Old names: 195 | AC_DEFUN([AC_ENABLE_SHARED], 196 | [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) 197 | ]) 198 | 199 | AC_DEFUN([AC_DISABLE_SHARED], 200 | [_LT_SET_OPTION([LT_INIT], [disable-shared]) 201 | ]) 202 | 203 | AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) 204 | AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) 205 | 206 | dnl aclocal-1.4 backwards compatibility: 207 | dnl AC_DEFUN([AM_ENABLE_SHARED], []) 208 | dnl AC_DEFUN([AM_DISABLE_SHARED], []) 209 | 210 | 211 | 212 | # _LT_ENABLE_STATIC([DEFAULT]) 213 | # ---------------------------- 214 | # implement the --enable-static flag, and support the `static' and 215 | # `disable-static' LT_INIT options. 216 | # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. 217 | m4_define([_LT_ENABLE_STATIC], 218 | [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl 219 | AC_ARG_ENABLE([static], 220 | [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], 221 | [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], 222 | [p=${PACKAGE-default} 223 | case $enableval in 224 | yes) enable_static=yes ;; 225 | no) enable_static=no ;; 226 | *) 227 | enable_static=no 228 | # Look at the argument we got. We use all the common list separators. 229 | lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," 230 | for pkg in $enableval; do 231 | IFS="$lt_save_ifs" 232 | if test "X$pkg" = "X$p"; then 233 | enable_static=yes 234 | fi 235 | done 236 | IFS="$lt_save_ifs" 237 | ;; 238 | esac], 239 | [enable_static=]_LT_ENABLE_STATIC_DEFAULT) 240 | 241 | _LT_DECL([build_old_libs], [enable_static], [0], 242 | [Whether or not to build static libraries]) 243 | ])# _LT_ENABLE_STATIC 244 | 245 | LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) 246 | LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) 247 | 248 | # Old names: 249 | AC_DEFUN([AC_ENABLE_STATIC], 250 | [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) 251 | ]) 252 | 253 | AC_DEFUN([AC_DISABLE_STATIC], 254 | [_LT_SET_OPTION([LT_INIT], [disable-static]) 255 | ]) 256 | 257 | AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) 258 | AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) 259 | 260 | dnl aclocal-1.4 backwards compatibility: 261 | dnl AC_DEFUN([AM_ENABLE_STATIC], []) 262 | dnl AC_DEFUN([AM_DISABLE_STATIC], []) 263 | 264 | 265 | 266 | # _LT_ENABLE_FAST_INSTALL([DEFAULT]) 267 | # ---------------------------------- 268 | # implement the --enable-fast-install flag, and support the `fast-install' 269 | # and `disable-fast-install' LT_INIT options. 270 | # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. 271 | m4_define([_LT_ENABLE_FAST_INSTALL], 272 | [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl 273 | AC_ARG_ENABLE([fast-install], 274 | [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], 275 | [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], 276 | [p=${PACKAGE-default} 277 | case $enableval in 278 | yes) enable_fast_install=yes ;; 279 | no) enable_fast_install=no ;; 280 | *) 281 | enable_fast_install=no 282 | # Look at the argument we got. We use all the common list separators. 283 | lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," 284 | for pkg in $enableval; do 285 | IFS="$lt_save_ifs" 286 | if test "X$pkg" = "X$p"; then 287 | enable_fast_install=yes 288 | fi 289 | done 290 | IFS="$lt_save_ifs" 291 | ;; 292 | esac], 293 | [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) 294 | 295 | _LT_DECL([fast_install], [enable_fast_install], [0], 296 | [Whether or not to optimize for fast installation])dnl 297 | ])# _LT_ENABLE_FAST_INSTALL 298 | 299 | LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) 300 | LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) 301 | 302 | # Old names: 303 | AU_DEFUN([AC_ENABLE_FAST_INSTALL], 304 | [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) 305 | AC_DIAGNOSE([obsolete], 306 | [$0: Remove this warning and the call to _LT_SET_OPTION when you put 307 | the `fast-install' option into LT_INIT's first parameter.]) 308 | ]) 309 | 310 | AU_DEFUN([AC_DISABLE_FAST_INSTALL], 311 | [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) 312 | AC_DIAGNOSE([obsolete], 313 | [$0: Remove this warning and the call to _LT_SET_OPTION when you put 314 | the `disable-fast-install' option into LT_INIT's first parameter.]) 315 | ]) 316 | 317 | dnl aclocal-1.4 backwards compatibility: 318 | dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) 319 | dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) 320 | 321 | 322 | # _LT_WITH_PIC([MODE]) 323 | # -------------------- 324 | # implement the --with-pic flag, and support the `pic-only' and `no-pic' 325 | # LT_INIT options. 326 | # MODE is either `yes' or `no'. If omitted, it defaults to `both'. 327 | m4_define([_LT_WITH_PIC], 328 | [AC_ARG_WITH([pic], 329 | [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], 330 | [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], 331 | [lt_p=${PACKAGE-default} 332 | case $withval in 333 | yes|no) pic_mode=$withval ;; 334 | *) 335 | pic_mode=default 336 | # Look at the argument we got. We use all the common list separators. 337 | lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," 338 | for lt_pkg in $withval; do 339 | IFS="$lt_save_ifs" 340 | if test "X$lt_pkg" = "X$lt_p"; then 341 | pic_mode=yes 342 | fi 343 | done 344 | IFS="$lt_save_ifs" 345 | ;; 346 | esac], 347 | [pic_mode=default]) 348 | 349 | test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) 350 | 351 | _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl 352 | ])# _LT_WITH_PIC 353 | 354 | LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) 355 | LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) 356 | 357 | # Old name: 358 | AU_DEFUN([AC_LIBTOOL_PICMODE], 359 | [_LT_SET_OPTION([LT_INIT], [pic-only]) 360 | AC_DIAGNOSE([obsolete], 361 | [$0: Remove this warning and the call to _LT_SET_OPTION when you 362 | put the `pic-only' option into LT_INIT's first parameter.]) 363 | ]) 364 | 365 | dnl aclocal-1.4 backwards compatibility: 366 | dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) 367 | 368 | ## ----------------- ## 369 | ## LTDL_INIT Options ## 370 | ## ----------------- ## 371 | 372 | m4_define([_LTDL_MODE], []) 373 | LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], 374 | [m4_define([_LTDL_MODE], [nonrecursive])]) 375 | LT_OPTION_DEFINE([LTDL_INIT], [recursive], 376 | [m4_define([_LTDL_MODE], [recursive])]) 377 | LT_OPTION_DEFINE([LTDL_INIT], [subproject], 378 | [m4_define([_LTDL_MODE], [subproject])]) 379 | 380 | m4_define([_LTDL_TYPE], []) 381 | LT_OPTION_DEFINE([LTDL_INIT], [installable], 382 | [m4_define([_LTDL_TYPE], [installable])]) 383 | LT_OPTION_DEFINE([LTDL_INIT], [convenience], 384 | [m4_define([_LTDL_TYPE], [convenience])]) 385 | -------------------------------------------------------------------------------- /m4/ltsugar.m4: -------------------------------------------------------------------------------- 1 | # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- 2 | # 3 | # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. 4 | # Written by Gary V. Vaughan, 2004 5 | # 6 | # This file is free software; the Free Software Foundation gives 7 | # unlimited permission to copy and/or distribute it, with or without 8 | # modifications, as long as this notice is preserved. 9 | 10 | # serial 6 ltsugar.m4 11 | 12 | # This is to help aclocal find these macros, as it can't see m4_define. 13 | AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) 14 | 15 | 16 | # lt_join(SEP, ARG1, [ARG2...]) 17 | # ----------------------------- 18 | # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their 19 | # associated separator. 20 | # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier 21 | # versions in m4sugar had bugs. 22 | m4_define([lt_join], 23 | [m4_if([$#], [1], [], 24 | [$#], [2], [[$2]], 25 | [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) 26 | m4_define([_lt_join], 27 | [m4_if([$#$2], [2], [], 28 | [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) 29 | 30 | 31 | # lt_car(LIST) 32 | # lt_cdr(LIST) 33 | # ------------ 34 | # Manipulate m4 lists. 35 | # These macros are necessary as long as will still need to support 36 | # Autoconf-2.59 which quotes differently. 37 | m4_define([lt_car], [[$1]]) 38 | m4_define([lt_cdr], 39 | [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], 40 | [$#], 1, [], 41 | [m4_dquote(m4_shift($@))])]) 42 | m4_define([lt_unquote], $1) 43 | 44 | 45 | # lt_append(MACRO-NAME, STRING, [SEPARATOR]) 46 | # ------------------------------------------ 47 | # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. 48 | # Note that neither SEPARATOR nor STRING are expanded; they are appended 49 | # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). 50 | # No SEPARATOR is output if MACRO-NAME was previously undefined (different 51 | # than defined and empty). 52 | # 53 | # This macro is needed until we can rely on Autoconf 2.62, since earlier 54 | # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. 55 | m4_define([lt_append], 56 | [m4_define([$1], 57 | m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) 58 | 59 | 60 | 61 | # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) 62 | # ---------------------------------------------------------- 63 | # Produce a SEP delimited list of all paired combinations of elements of 64 | # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list 65 | # has the form PREFIXmINFIXSUFFIXn. 66 | # Needed until we can rely on m4_combine added in Autoconf 2.62. 67 | m4_define([lt_combine], 68 | [m4_if(m4_eval([$# > 3]), [1], 69 | [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl 70 | [[m4_foreach([_Lt_prefix], [$2], 71 | [m4_foreach([_Lt_suffix], 72 | ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, 73 | [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) 74 | 75 | 76 | # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) 77 | # ----------------------------------------------------------------------- 78 | # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited 79 | # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. 80 | m4_define([lt_if_append_uniq], 81 | [m4_ifdef([$1], 82 | [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], 83 | [lt_append([$1], [$2], [$3])$4], 84 | [$5])], 85 | [lt_append([$1], [$2], [$3])$4])]) 86 | 87 | 88 | # lt_dict_add(DICT, KEY, VALUE) 89 | # ----------------------------- 90 | m4_define([lt_dict_add], 91 | [m4_define([$1($2)], [$3])]) 92 | 93 | 94 | # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) 95 | # -------------------------------------------- 96 | m4_define([lt_dict_add_subkey], 97 | [m4_define([$1($2:$3)], [$4])]) 98 | 99 | 100 | # lt_dict_fetch(DICT, KEY, [SUBKEY]) 101 | # ---------------------------------- 102 | m4_define([lt_dict_fetch], 103 | [m4_ifval([$3], 104 | m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), 105 | m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) 106 | 107 | 108 | # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) 109 | # ----------------------------------------------------------------- 110 | m4_define([lt_if_dict_fetch], 111 | [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], 112 | [$5], 113 | [$6])]) 114 | 115 | 116 | # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) 117 | # -------------------------------------------------------------- 118 | m4_define([lt_dict_filter], 119 | [m4_if([$5], [], [], 120 | [lt_join(m4_quote(m4_default([$4], [[, ]])), 121 | lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), 122 | [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl 123 | ]) 124 | -------------------------------------------------------------------------------- /m4/ltversion.m4: -------------------------------------------------------------------------------- 1 | # ltversion.m4 -- version numbers -*- Autoconf -*- 2 | # 3 | # Copyright (C) 2004 Free Software Foundation, Inc. 4 | # Written by Scott James Remnant, 2004 5 | # 6 | # This file is free software; the Free Software Foundation gives 7 | # unlimited permission to copy and/or distribute it, with or without 8 | # modifications, as long as this notice is preserved. 9 | 10 | # @configure_input@ 11 | 12 | # serial 3337 ltversion.m4 13 | # This file is part of GNU Libtool 14 | 15 | m4_define([LT_PACKAGE_VERSION], [2.4.2]) 16 | m4_define([LT_PACKAGE_REVISION], [1.3337]) 17 | 18 | AC_DEFUN([LTVERSION_VERSION], 19 | [macro_version='2.4.2' 20 | macro_revision='1.3337' 21 | _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) 22 | _LT_DECL(, macro_revision, 0) 23 | ]) 24 | -------------------------------------------------------------------------------- /m4/lt~obsolete.m4: -------------------------------------------------------------------------------- 1 | # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- 2 | # 3 | # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. 4 | # Written by Scott James Remnant, 2004. 5 | # 6 | # This file is free software; the Free Software Foundation gives 7 | # unlimited permission to copy and/or distribute it, with or without 8 | # modifications, as long as this notice is preserved. 9 | 10 | # serial 5 lt~obsolete.m4 11 | 12 | # These exist entirely to fool aclocal when bootstrapping libtool. 13 | # 14 | # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) 15 | # which have later been changed to m4_define as they aren't part of the 16 | # exported API, or moved to Autoconf or Automake where they belong. 17 | # 18 | # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN 19 | # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us 20 | # using a macro with the same name in our local m4/libtool.m4 it'll 21 | # pull the old libtool.m4 in (it doesn't see our shiny new m4_define 22 | # and doesn't know about Autoconf macros at all.) 23 | # 24 | # So we provide this file, which has a silly filename so it's always 25 | # included after everything else. This provides aclocal with the 26 | # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything 27 | # because those macros already exist, or will be overwritten later. 28 | # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 29 | # 30 | # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. 31 | # Yes, that means every name once taken will need to remain here until 32 | # we give up compatibility with versions before 1.7, at which point 33 | # we need to keep only those names which we still refer to. 34 | 35 | # This is to help aclocal find these macros, as it can't see m4_define. 36 | AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) 37 | 38 | m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) 39 | m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) 40 | m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) 41 | m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) 42 | m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) 43 | m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) 44 | m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) 45 | m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) 46 | m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) 47 | m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) 48 | m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) 49 | m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) 50 | m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) 51 | m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) 52 | m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) 53 | m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) 54 | m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) 55 | m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) 56 | m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) 57 | m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) 58 | m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) 59 | m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) 60 | m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) 61 | m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) 62 | m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) 63 | m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) 64 | m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) 65 | m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) 66 | m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) 67 | m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) 68 | m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) 69 | m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) 70 | m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) 71 | m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) 72 | m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) 73 | m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) 74 | m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) 75 | m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) 76 | m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) 77 | m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) 78 | m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) 79 | m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) 80 | m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) 81 | m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) 82 | m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) 83 | m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) 84 | m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) 85 | m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) 86 | m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) 87 | m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) 88 | m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) 89 | m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) 90 | m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) 91 | m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) 92 | m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) 93 | m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) 94 | m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) 95 | m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) 96 | m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) 97 | m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) 98 | m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) 99 | -------------------------------------------------------------------------------- /missing: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Common wrapper for a few potentially missing GNU programs. 3 | 4 | scriptversion=2013-10-28.13; # UTC 5 | 6 | # Copyright (C) 1996-2014 Free Software Foundation, Inc. 7 | # Originally written by Fran,cois Pinard , 1996. 8 | 9 | # This program is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2, or (at your option) 12 | # any later version. 13 | 14 | # This program is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | 19 | # You should have received a copy of the GNU General Public License 20 | # along with this program. If not, see . 21 | 22 | # As a special exception to the GNU General Public License, if you 23 | # distribute this file as part of a program that contains a 24 | # configuration script generated by Autoconf, you may include it under 25 | # the same distribution terms that you use for the rest of that program. 26 | 27 | if test $# -eq 0; then 28 | echo 1>&2 "Try '$0 --help' for more information" 29 | exit 1 30 | fi 31 | 32 | case $1 in 33 | 34 | --is-lightweight) 35 | # Used by our autoconf macros to check whether the available missing 36 | # script is modern enough. 37 | exit 0 38 | ;; 39 | 40 | --run) 41 | # Back-compat with the calling convention used by older automake. 42 | shift 43 | ;; 44 | 45 | -h|--h|--he|--hel|--help) 46 | echo "\ 47 | $0 [OPTION]... PROGRAM [ARGUMENT]... 48 | 49 | Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due 50 | to PROGRAM being missing or too old. 51 | 52 | Options: 53 | -h, --help display this help and exit 54 | -v, --version output version information and exit 55 | 56 | Supported PROGRAM values: 57 | aclocal autoconf autoheader autom4te automake makeinfo 58 | bison yacc flex lex help2man 59 | 60 | Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 61 | 'g' are ignored when checking the name. 62 | 63 | Send bug reports to ." 64 | exit $? 65 | ;; 66 | 67 | -v|--v|--ve|--ver|--vers|--versi|--versio|--version) 68 | echo "missing $scriptversion (GNU Automake)" 69 | exit $? 70 | ;; 71 | 72 | -*) 73 | echo 1>&2 "$0: unknown '$1' option" 74 | echo 1>&2 "Try '$0 --help' for more information" 75 | exit 1 76 | ;; 77 | 78 | esac 79 | 80 | # Run the given program, remember its exit status. 81 | "$@"; st=$? 82 | 83 | # If it succeeded, we are done. 84 | test $st -eq 0 && exit 0 85 | 86 | # Also exit now if we it failed (or wasn't found), and '--version' was 87 | # passed; such an option is passed most likely to detect whether the 88 | # program is present and works. 89 | case $2 in --version|--help) exit $st;; esac 90 | 91 | # Exit code 63 means version mismatch. This often happens when the user 92 | # tries to use an ancient version of a tool on a file that requires a 93 | # minimum version. 94 | if test $st -eq 63; then 95 | msg="probably too old" 96 | elif test $st -eq 127; then 97 | # Program was missing. 98 | msg="missing on your system" 99 | else 100 | # Program was found and executed, but failed. Give up. 101 | exit $st 102 | fi 103 | 104 | perl_URL=http://www.perl.org/ 105 | flex_URL=http://flex.sourceforge.net/ 106 | gnu_software_URL=http://www.gnu.org/software 107 | 108 | program_details () 109 | { 110 | case $1 in 111 | aclocal|automake) 112 | echo "The '$1' program is part of the GNU Automake package:" 113 | echo "<$gnu_software_URL/automake>" 114 | echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" 115 | echo "<$gnu_software_URL/autoconf>" 116 | echo "<$gnu_software_URL/m4/>" 117 | echo "<$perl_URL>" 118 | ;; 119 | autoconf|autom4te|autoheader) 120 | echo "The '$1' program is part of the GNU Autoconf package:" 121 | echo "<$gnu_software_URL/autoconf/>" 122 | echo "It also requires GNU m4 and Perl in order to run:" 123 | echo "<$gnu_software_URL/m4/>" 124 | echo "<$perl_URL>" 125 | ;; 126 | esac 127 | } 128 | 129 | give_advice () 130 | { 131 | # Normalize program name to check for. 132 | normalized_program=`echo "$1" | sed ' 133 | s/^gnu-//; t 134 | s/^gnu//; t 135 | s/^g//; t'` 136 | 137 | printf '%s\n' "'$1' is $msg." 138 | 139 | configure_deps="'configure.ac' or m4 files included by 'configure.ac'" 140 | case $normalized_program in 141 | autoconf*) 142 | echo "You should only need it if you modified 'configure.ac'," 143 | echo "or m4 files included by it." 144 | program_details 'autoconf' 145 | ;; 146 | autoheader*) 147 | echo "You should only need it if you modified 'acconfig.h' or" 148 | echo "$configure_deps." 149 | program_details 'autoheader' 150 | ;; 151 | automake*) 152 | echo "You should only need it if you modified 'Makefile.am' or" 153 | echo "$configure_deps." 154 | program_details 'automake' 155 | ;; 156 | aclocal*) 157 | echo "You should only need it if you modified 'acinclude.m4' or" 158 | echo "$configure_deps." 159 | program_details 'aclocal' 160 | ;; 161 | autom4te*) 162 | echo "You might have modified some maintainer files that require" 163 | echo "the 'autom4te' program to be rebuilt." 164 | program_details 'autom4te' 165 | ;; 166 | bison*|yacc*) 167 | echo "You should only need it if you modified a '.y' file." 168 | echo "You may want to install the GNU Bison package:" 169 | echo "<$gnu_software_URL/bison/>" 170 | ;; 171 | lex*|flex*) 172 | echo "You should only need it if you modified a '.l' file." 173 | echo "You may want to install the Fast Lexical Analyzer package:" 174 | echo "<$flex_URL>" 175 | ;; 176 | help2man*) 177 | echo "You should only need it if you modified a dependency" \ 178 | "of a man page." 179 | echo "You may want to install the GNU Help2man package:" 180 | echo "<$gnu_software_URL/help2man/>" 181 | ;; 182 | makeinfo*) 183 | echo "You should only need it if you modified a '.texi' file, or" 184 | echo "any other file indirectly affecting the aspect of the manual." 185 | echo "You might want to install the Texinfo package:" 186 | echo "<$gnu_software_URL/texinfo/>" 187 | echo "The spurious makeinfo call might also be the consequence of" 188 | echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" 189 | echo "want to install GNU make:" 190 | echo "<$gnu_software_URL/make/>" 191 | ;; 192 | *) 193 | echo "You might have modified some files without having the proper" 194 | echo "tools for further handling them. Check the 'README' file, it" 195 | echo "often tells you about the needed prerequisites for installing" 196 | echo "this package. You may also peek at any GNU archive site, in" 197 | echo "case some other package contains this missing '$1' program." 198 | ;; 199 | esac 200 | } 201 | 202 | give_advice "$1" | sed -e '1s/^/WARNING: /' \ 203 | -e '2,$s/^/ /' >&2 204 | 205 | # Propagate the correct exit status (expected to be 127 for a program 206 | # not found, 63 for a program that failed due to version mismatch). 207 | exit $st 208 | 209 | # Local variables: 210 | # eval: (add-hook 'write-file-hooks 'time-stamp) 211 | # time-stamp-start: "scriptversion=" 212 | # time-stamp-format: "%:y-%02m-%02d.%02H" 213 | # time-stamp-time-zone: "UTC" 214 | # time-stamp-end: "; # UTC" 215 | # End: 216 | -------------------------------------------------------------------------------- /src/capabilities.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2008 Henrik Rydberg 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | * 20 | **************************************************************************/ 21 | 22 | #include "capabilities.h" 23 | 24 | #define SETABS(c, x, map, key, fd) \ 25 | (c->has_##x = getbit(map, key) && getabs(&c->x, key, fd)) 26 | 27 | #define ADDCAP(s, c, x) strcat(s, c->has_##x ? " " #x : "") 28 | 29 | static const int SN_COORD = 250; /* coordinate signal-to-noise ratio */ 30 | static const int SN_WIDTH = 100; /* width signal-to-noise ratio */ 31 | static const int SN_ORIENT = 10; /* orientation signal-to-noise ratio */ 32 | 33 | static const int bits_per_long = 8 * sizeof(long); 34 | 35 | static inline int nlongs(int nbit) 36 | { 37 | return (nbit + bits_per_long - 1) / bits_per_long; 38 | } 39 | 40 | static inline int getbit(const unsigned long *map, int key) 41 | { 42 | return (map[key / bits_per_long] >> (key % bits_per_long)) & 0x01; 43 | } 44 | 45 | static int getabs(struct input_absinfo *abs, int key, int fd) 46 | { 47 | int rc; 48 | SYSCALL(rc = ioctl(fd, EVIOCGABS(key), abs)); 49 | return rc >= 0; 50 | } 51 | 52 | static int has_mt_data(const struct Capabilities *cap) 53 | { 54 | return cap->has_abs[MTDEV_POSITION_X] && cap->has_abs[MTDEV_POSITION_Y]; 55 | } 56 | 57 | static int has_integrated_button(const struct Capabilities *cap) 58 | { 59 | static const int bcm5974_vmask_ibt = 1; 60 | /* magic trackpad */ 61 | if (cap->devid.vendor == 0x05ac && cap->devid.product == 0x030e) 62 | return 1; 63 | /* macbooks */ 64 | if (strcmp(cap->devname, "bcm5974")) 65 | return 0; 66 | return cap->devid.version & bcm5974_vmask_ibt; 67 | } 68 | 69 | static void default_fuzz(struct Capabilities *cap, unsigned int code, int sn) 70 | { 71 | int bit = mtdev_abs2mt(code); 72 | if (cap->has_abs[bit] && cap->abs[bit].fuzz == 0) 73 | cap->abs[bit].fuzz = 74 | (cap->abs[bit].maximum - cap->abs[bit].minimum) / sn; 75 | } 76 | 77 | int read_capabilities(struct Capabilities *cap, int fd) 78 | { 79 | unsigned long evbits[nlongs(EV_MAX)]; 80 | unsigned long absbits[nlongs(ABS_MAX)]; 81 | unsigned long keybits[nlongs(KEY_MAX)]; 82 | int rc, i; 83 | 84 | memset(cap, 0, sizeof(struct Capabilities)); 85 | 86 | SYSCALL(rc = ioctl(fd, EVIOCGID, &cap->devid)); 87 | if (rc < 0) 88 | return rc; 89 | SYSCALL(rc = ioctl(fd, EVIOCGNAME(sizeof(cap->devname)), cap->devname)); 90 | if (rc < 0) 91 | return rc; 92 | SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_SYN, sizeof(evbits)), evbits)); 93 | if (rc < 0) 94 | return rc; 95 | SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits)); 96 | if (rc < 0) 97 | return rc; 98 | SYSCALL(rc = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits)); 99 | if (rc < 0) 100 | return rc; 101 | 102 | cap->has_left = getbit(keybits, BTN_LEFT); 103 | cap->has_middle = getbit(keybits, BTN_MIDDLE); 104 | cap->has_right = getbit(keybits, BTN_RIGHT); 105 | 106 | SETABS(cap, slot, absbits, ABS_MT_SLOT, fd); 107 | for (i = 0; i < MT_ABS_SIZE; i++) 108 | SETABS(cap, abs[i], absbits, mtdev_mt2abs(i), fd); 109 | 110 | cap->has_mtdata = has_mt_data(cap); 111 | cap->has_ibt = has_integrated_button(cap); 112 | 113 | default_fuzz(cap, ABS_MT_POSITION_X, SN_COORD); 114 | default_fuzz(cap, ABS_MT_POSITION_Y, SN_COORD); 115 | default_fuzz(cap, ABS_MT_TOUCH_MAJOR, SN_WIDTH); 116 | default_fuzz(cap, ABS_MT_TOUCH_MINOR, SN_WIDTH); 117 | default_fuzz(cap, ABS_MT_WIDTH_MAJOR, SN_WIDTH); 118 | default_fuzz(cap, ABS_MT_WIDTH_MINOR, SN_WIDTH); 119 | default_fuzz(cap, ABS_MT_ORIENTATION, SN_ORIENT); 120 | 121 | return 0; 122 | } 123 | 124 | int get_cap_xsize(const struct Capabilities *cap) 125 | { 126 | const struct input_absinfo *x = &cap->abs[MTDEV_POSITION_X]; 127 | return x->maximum - x->minimum; 128 | } 129 | 130 | int get_cap_ysize(const struct Capabilities *cap) 131 | { 132 | const struct input_absinfo *y = &cap->abs[MTDEV_POSITION_Y]; 133 | return y->maximum - y->minimum; 134 | } 135 | 136 | int get_cap_wsize(const struct Capabilities *cap) 137 | { 138 | const struct input_absinfo *w = &cap->abs[MTDEV_TOUCH_MAJOR]; 139 | return w->maximum - w->minimum; 140 | } 141 | 142 | int get_cap_xmid(const struct Capabilities *cap) 143 | { 144 | const struct input_absinfo *x = &cap->abs[MTDEV_POSITION_X]; 145 | return (x->maximum + x->minimum) >> 1; 146 | } 147 | 148 | int get_cap_ymid(const struct Capabilities *cap) 149 | { 150 | const struct input_absinfo *y = &cap->abs[MTDEV_POSITION_Y]; 151 | return (y->maximum + y->minimum) >> 1; 152 | } 153 | 154 | int get_cap_xflip(const struct Capabilities *cap, int x) 155 | { 156 | const struct input_absinfo *i = &cap->abs[MTDEV_POSITION_X]; 157 | return i->maximum - (x - i->minimum); 158 | } 159 | 160 | int get_cap_yflip(const struct Capabilities *cap, int y) 161 | { 162 | const struct input_absinfo *i = &cap->abs[MTDEV_POSITION_Y]; 163 | return i->maximum - (y - i->minimum); 164 | } 165 | 166 | void output_capabilities(const struct Capabilities *cap) 167 | { 168 | char line[1024]; 169 | int i; 170 | memset(line, 0, sizeof(line)); 171 | ADDCAP(line, cap, left); 172 | ADDCAP(line, cap, middle); 173 | ADDCAP(line, cap, right); 174 | ADDCAP(line, cap, mtdata); 175 | ADDCAP(line, cap, ibt); 176 | xf86Msg(X_INFO, "mtrack: devname: %s\n", cap->devname); 177 | xf86Msg(X_INFO, "mtrack: devid: %x %x %x\n", 178 | cap->devid.vendor, cap->devid.product, cap->devid.version); 179 | xf86Msg(X_INFO, "mtrack: caps:%s\n", line); 180 | for (i = 0; i < MT_ABS_SIZE; i++) { 181 | if (cap->has_abs[i]) 182 | xf86Msg(X_INFO, "mtrack: %d: min: %d max: %d\n", 183 | i, 184 | cap->abs[i].minimum, 185 | cap->abs[i].maximum); 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/hwstate.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2008 Henrik Rydberg 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | * 20 | **************************************************************************/ 21 | 22 | #include "hwstate.h" 23 | 24 | void hwstate_init(struct HWState *s, const struct Capabilities *caps) 25 | { 26 | int i; 27 | memset(s, 0, sizeof(struct HWState)); 28 | for (i = 0; i < DIM_FINGER; i++) 29 | s->data[i].tracking_id = MT_ID_NULL; 30 | s->max_x = get_cap_xsize(caps); 31 | s->max_y = get_cap_ysize(caps); 32 | } 33 | 34 | static void finish_packet(struct HWState *s, const struct Capabilities *caps, 35 | const struct input_event *syn) 36 | { 37 | static const mstime_t ms = 1000; 38 | int i; 39 | foreach_bit(i, s->used) { 40 | if (!caps->has_abs[MTDEV_TOUCH_MINOR]) 41 | s->data[i].touch_minor = s->data[i].touch_major; 42 | if (!caps->has_abs[MTDEV_WIDTH_MINOR]) 43 | s->data[i].width_minor = s->data[i].width_major; 44 | } 45 | timercp(&s->evtime, &syn->time); 46 | } 47 | 48 | static int read_event(struct HWState *s, const struct Capabilities *caps, 49 | const struct input_event *ev) 50 | { 51 | switch (ev->type) { 52 | case EV_SYN: 53 | switch (ev->code) { 54 | case SYN_REPORT: 55 | finish_packet(s, caps, ev); 56 | return 1; 57 | } 58 | break; 59 | case EV_KEY: 60 | switch (ev->code) { 61 | case BTN_LEFT: 62 | MODBIT(s->button, MT_BUTTON_LEFT, ev->value); 63 | break; 64 | case BTN_MIDDLE: 65 | MODBIT(s->button, MT_BUTTON_MIDDLE, ev->value); 66 | break; 67 | case BTN_RIGHT: 68 | MODBIT(s->button, MT_BUTTON_RIGHT, ev->value); 69 | break; 70 | } 71 | break; 72 | case EV_ABS: 73 | switch (ev->code) { 74 | case ABS_MT_SLOT: 75 | if (ev->value >= 0 && ev->value < DIM_FINGER) 76 | s->slot = ev->value; 77 | break; 78 | case ABS_MT_TOUCH_MAJOR: 79 | s->data[s->slot].touch_major = ev->value; 80 | break; 81 | case ABS_MT_TOUCH_MINOR: 82 | s->data[s->slot].touch_minor = ev->value; 83 | break; 84 | case ABS_MT_WIDTH_MAJOR: 85 | s->data[s->slot].width_major = ev->value; 86 | break; 87 | case ABS_MT_WIDTH_MINOR: 88 | s->data[s->slot].width_minor = ev->value; 89 | break; 90 | case ABS_MT_ORIENTATION: 91 | s->data[s->slot].orientation = ev->value; 92 | break; 93 | case ABS_MT_PRESSURE: 94 | s->data[s->slot].pressure = ev->value; 95 | break; 96 | case ABS_MT_POSITION_X: 97 | s->data[s->slot].position_x = ev->value; 98 | break; 99 | case ABS_MT_POSITION_Y: 100 | s->data[s->slot].position_y = ev->value; 101 | break; 102 | case ABS_MT_TRACKING_ID: 103 | s->data[s->slot].tracking_id = ev->value; 104 | MODBIT(s->used, s->slot, ev->value != MT_ID_NULL); 105 | break; 106 | } 107 | break; 108 | } 109 | return 0; 110 | } 111 | 112 | int hwstate_modify(struct HWState *s, struct mtdev *dev, int fd, 113 | const struct Capabilities *caps) 114 | { 115 | struct input_event ev; 116 | int ret; 117 | while ((ret = mtdev_get(dev, fd, &ev, 1)) > 0) { 118 | if (read_event(s, caps, &ev)) 119 | return 1; 120 | } 121 | return ret; 122 | } 123 | 124 | int find_finger(const struct HWState *s, int tracking_id) { 125 | int i; 126 | foreach_bit(i, s->used) { 127 | if (s->data[i].tracking_id == tracking_id) 128 | return i; 129 | } 130 | return -1; 131 | } 132 | -------------------------------------------------------------------------------- /src/mconfig.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2011 Ryan Bourgeois 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | * 20 | **************************************************************************/ 21 | 22 | #include "mconfig.h" 23 | 24 | void mconfig_defaults(struct MConfig* cfg) 25 | { 26 | // Configure MTState 27 | cfg->touch_down = DEFAULT_TOUCH_DOWN; 28 | cfg->touch_up = DEFAULT_TOUCH_UP; 29 | cfg->ignore_thumb = DEFAULT_IGNORE_THUMB; 30 | cfg->ignore_palm = DEFAULT_IGNORE_PALM; 31 | cfg->disable_on_palm = DEFAULT_DISABLE_ON_PALM; 32 | cfg->disable_on_thumb = DEFAULT_DISABLE_ON_THUMB; 33 | cfg->thumb_ratio = DEFAULT_THUMB_RATIO; 34 | cfg->thumb_size = DEFAULT_THUMB_SIZE; 35 | cfg->palm_size = DEFAULT_PALM_SIZE; 36 | cfg->bottom_edge = DEFAULT_BOTTOM_EDGE; 37 | 38 | // Configure Gestures 39 | cfg->trackpad_disable = DEFAULT_TRACKPAD_DISABLE; 40 | cfg->button_enable = DEFAULT_BUTTON_ENABLE; 41 | cfg->button_integrated = DEFAULT_BUTTON_INTEGRATED; 42 | cfg->button_expire = DEFAULT_BUTTON_EXPIRE; 43 | cfg->button_zones = DEFAULT_BUTTON_ZONES; 44 | cfg->button_1touch = DEFAULT_BUTTON_1TOUCH; 45 | cfg->button_2touch = DEFAULT_BUTTON_2TOUCH; 46 | cfg->button_3touch = DEFAULT_BUTTON_3TOUCH; 47 | cfg->tap_1touch = DEFAULT_TAP_1TOUCH; 48 | cfg->tap_2touch = DEFAULT_TAP_2TOUCH; 49 | cfg->tap_3touch = DEFAULT_TAP_3TOUCH; 50 | cfg->tap_4touch = DEFAULT_TAP_4TOUCH; 51 | cfg->tap_timeout = DEFAULT_TAP_TIMEOUT; 52 | cfg->tap_hold = DEFAULT_TAP_HOLD; 53 | cfg->tap_dist = DEFAULT_TAP_DIST; 54 | cfg->gesture_hold = DEFAULT_GESTURE_HOLD; 55 | cfg->gesture_wait = DEFAULT_GESTURE_WAIT; 56 | cfg->scroll_dist = DEFAULT_SCROLL_DIST; 57 | cfg->scroll_up_btn = DEFAULT_SCROLL_UP_BTN; 58 | cfg->scroll_dn_btn = DEFAULT_SCROLL_DN_BTN; 59 | cfg->scroll_lt_btn = DEFAULT_SCROLL_LT_BTN; 60 | cfg->scroll_rt_btn = DEFAULT_SCROLL_RT_BTN; 61 | cfg->swipe_dist = DEFAULT_SWIPE_DIST; 62 | cfg->swipe_up_btn = DEFAULT_SWIPE_UP_BTN; 63 | cfg->swipe_dn_btn = DEFAULT_SWIPE_DN_BTN; 64 | cfg->swipe_lt_btn = DEFAULT_SWIPE_LT_BTN; 65 | cfg->swipe_rt_btn = DEFAULT_SWIPE_RT_BTN; 66 | cfg->swipe4_dist = DEFAULT_SWIPE4_DIST; 67 | cfg->swipe4_up_btn = DEFAULT_SWIPE4_UP_BTN; 68 | cfg->swipe4_dn_btn = DEFAULT_SWIPE4_DN_BTN; 69 | cfg->swipe4_lt_btn = DEFAULT_SWIPE4_LT_BTN; 70 | cfg->swipe4_rt_btn = DEFAULT_SWIPE4_RT_BTN; 71 | cfg->scale_dist = DEFAULT_SCALE_DIST; 72 | cfg->scale_up_btn = DEFAULT_SCALE_UP_BTN; 73 | cfg->scale_dn_btn = DEFAULT_SCALE_DN_BTN; 74 | cfg->rotate_dist = SQRVAL(DEFAULT_ROTATE_DIST); 75 | cfg->rotate_lt_btn = DEFAULT_ROTATE_LT_BTN; 76 | cfg->rotate_rt_btn = DEFAULT_ROTATE_RT_BTN; 77 | cfg->drag_enable = DEFAULT_DRAG_ENABLE; 78 | cfg->drag_timeout = DEFAULT_DRAG_TIMEOUT; 79 | cfg->sensitivity = DEFAULT_SENSITIVITY; 80 | } 81 | 82 | void mconfig_init(struct MConfig* cfg, 83 | const struct Capabilities* caps) 84 | { 85 | cfg->touch_minor = caps->has_abs[MTDEV_TOUCH_MINOR]; 86 | cfg->pad_width = get_cap_xsize(caps); 87 | cfg->pad_height = get_cap_ysize(caps); 88 | 89 | if (caps->has_abs[MTDEV_TOUCH_MAJOR] && caps->has_abs[MTDEV_WIDTH_MAJOR]) { 90 | cfg->touch_type = MCFG_SCALE; 91 | cfg->touch_min = caps->abs[MTDEV_TOUCH_MAJOR].minimum; 92 | cfg->touch_max = caps->abs[MTDEV_TOUCH_MAJOR].maximum; 93 | xf86Msg(X_INFO, "Touchpad supports regular and approaching touches.\n"); 94 | xf86Msg(X_INFO, " touch_min = %d, touch_max = %d\n", cfg->touch_min, cfg->touch_max); 95 | } 96 | else if (caps->has_abs[MTDEV_TOUCH_MAJOR]) { 97 | cfg->touch_type = MCFG_SIZE; 98 | cfg->touch_min = caps->abs[MTDEV_TOUCH_MAJOR].minimum; 99 | cfg->touch_max = caps->abs[MTDEV_TOUCH_MAJOR].maximum; 100 | xf86Msg(X_INFO, "Touchpad supports regular touches.\n"); 101 | xf86Msg(X_INFO, " touch_min = %d, touch_max = %d\n", cfg->touch_min, cfg->touch_max); 102 | } 103 | else if (caps->has_abs[MTDEV_PRESSURE]) { 104 | cfg->touch_type = MCFG_PRESSURE; 105 | cfg->touch_min = caps->abs[MTDEV_PRESSURE].minimum; 106 | cfg->touch_max = caps->abs[MTDEV_PRESSURE].maximum; 107 | xf86Msg(X_INFO, "Touchpad is pressure based.\n"); 108 | xf86Msg(X_INFO, " touch_min = %d, touch_max = %d\n", cfg->touch_min, cfg->touch_max); 109 | } 110 | else { 111 | cfg->touch_type = MCFG_NONE; 112 | xf86Msg(X_WARNING, "Touchpad has minimal capabilities. Some features will be unavailable.\n"); 113 | } 114 | 115 | if (cfg->touch_minor) 116 | xf86Msg(X_INFO, "Touchpad supports minor touch widths.\n"); 117 | } 118 | 119 | void mconfig_configure(struct MConfig* cfg, 120 | pointer opts) 121 | { 122 | // Configure MTState 123 | cfg->touch_down = CLAMPVAL(xf86SetIntOption(opts, "FingerHigh", DEFAULT_TOUCH_DOWN), 0, 100); 124 | cfg->touch_up = CLAMPVAL(xf86SetIntOption(opts, "FingerLow", DEFAULT_TOUCH_UP), 0, 100); 125 | cfg->ignore_thumb = xf86SetBoolOption(opts, "IgnoreThumb", DEFAULT_IGNORE_THUMB); 126 | cfg->ignore_palm = xf86SetBoolOption(opts, "IgnorePalm", DEFAULT_IGNORE_PALM); 127 | cfg->disable_on_thumb = xf86SetBoolOption(opts, "DisableOnThumb", DEFAULT_DISABLE_ON_THUMB); 128 | cfg->disable_on_palm = xf86SetBoolOption(opts, "DisableOnPalm", DEFAULT_DISABLE_ON_PALM); 129 | cfg->thumb_ratio = CLAMPVAL(xf86SetIntOption(opts, "ThumbRatio", DEFAULT_THUMB_RATIO), 0, 100); 130 | cfg->thumb_size = CLAMPVAL(xf86SetIntOption(opts, "ThumbSize", DEFAULT_THUMB_SIZE), 0, 100); 131 | cfg->palm_size = CLAMPVAL(xf86SetIntOption(opts, "PalmSize", DEFAULT_PALM_SIZE), 0, 100); 132 | cfg->bottom_edge = CLAMPVAL(xf86SetIntOption(opts, "BottomEdge", DEFAULT_BOTTOM_EDGE), 0, 100); 133 | 134 | // Configure Gestures 135 | cfg->trackpad_disable = CLAMPVAL(xf86SetIntOption(opts, "TrackpadDisable", DEFAULT_TRACKPAD_DISABLE), 0, 3); 136 | cfg->button_enable = xf86SetBoolOption(opts, "ButtonEnable", DEFAULT_BUTTON_ENABLE); 137 | cfg->button_integrated = xf86SetBoolOption(opts, "ButtonIntegrated", DEFAULT_BUTTON_INTEGRATED); 138 | cfg->button_expire = MAXVAL(xf86SetIntOption(opts, "ButtonTouchExpire", DEFAULT_BUTTON_EXPIRE), 0); 139 | cfg->button_zones = xf86SetBoolOption(opts, "ButtonZonesEnable", DEFAULT_BUTTON_ZONES); 140 | cfg->button_1touch = CLAMPVAL(xf86SetIntOption(opts, "ClickFinger1", DEFAULT_BUTTON_1TOUCH), 0, 32); 141 | cfg->button_2touch = CLAMPVAL(xf86SetIntOption(opts, "ClickFinger2", DEFAULT_BUTTON_2TOUCH), 0, 32); 142 | cfg->button_3touch = CLAMPVAL(xf86SetIntOption(opts, "ClickFinger3", DEFAULT_BUTTON_3TOUCH), 0, 32); 143 | cfg->button_move = xf86SetBoolOption(opts, "ButtonMoveEmulate", DEFAULT_BUTTON_MOVE); 144 | cfg->tap_1touch = CLAMPVAL(xf86SetIntOption(opts, "TapButton1", DEFAULT_TAP_1TOUCH), 0, 32); 145 | cfg->tap_2touch = CLAMPVAL(xf86SetIntOption(opts, "TapButton2", DEFAULT_TAP_2TOUCH), 0, 32); 146 | cfg->tap_3touch = CLAMPVAL(xf86SetIntOption(opts, "TapButton3", DEFAULT_TAP_3TOUCH), 0, 32); 147 | cfg->tap_4touch = CLAMPVAL(xf86SetIntOption(opts, "TapButton4", DEFAULT_TAP_4TOUCH), 0, 32); 148 | cfg->tap_hold = MAXVAL(xf86SetIntOption(opts, "ClickTime", DEFAULT_TAP_HOLD), 1); 149 | cfg->tap_timeout = MAXVAL(xf86SetIntOption(opts, "MaxTapTime", DEFAULT_TAP_TIMEOUT), 1); 150 | cfg->tap_dist = MAXVAL(xf86SetIntOption(opts, "MaxTapMove", DEFAULT_TAP_DIST), 1); 151 | cfg->gesture_hold = MAXVAL(xf86SetIntOption(opts, "GestureClickTime", DEFAULT_GESTURE_HOLD), 1); 152 | cfg->gesture_wait = MAXVAL(xf86SetIntOption(opts, "GestureWaitTime", DEFAULT_GESTURE_WAIT), 0); 153 | cfg->scroll_dist = MAXVAL(xf86SetIntOption(opts, "ScrollDistance", DEFAULT_SCROLL_DIST), 1); 154 | cfg->scroll_up_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollUpButton", DEFAULT_SCROLL_UP_BTN), 0, 32); 155 | cfg->scroll_dn_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollDownButton", DEFAULT_SCROLL_DN_BTN), 0, 32); 156 | cfg->scroll_lt_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollLeftButton", DEFAULT_SCROLL_LT_BTN), 0, 32); 157 | cfg->scroll_rt_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollRightButton", DEFAULT_SCROLL_RT_BTN), 0, 32); 158 | cfg->swipe_dist = MAXVAL(xf86SetIntOption(opts, "SwipeDistance", DEFAULT_SWIPE_DIST), 1); 159 | cfg->swipe_up_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeUpButton", DEFAULT_SWIPE_UP_BTN), 0, 32); 160 | cfg->swipe_dn_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeDownButton", DEFAULT_SWIPE_DN_BTN), 0, 32); 161 | cfg->swipe_lt_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeLeftButton", DEFAULT_SWIPE_LT_BTN), 0, 32); 162 | cfg->swipe_rt_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeRightButton", DEFAULT_SWIPE_RT_BTN), 0, 32); 163 | cfg->swipe4_dist = MAXVAL(xf86SetIntOption(opts, "Swipe4Distance", DEFAULT_SWIPE4_DIST), 1); 164 | cfg->swipe4_up_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4UpButton", DEFAULT_SWIPE4_UP_BTN), 0, 32); 165 | cfg->swipe4_dn_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4DownButton", DEFAULT_SWIPE4_DN_BTN), 0, 32); 166 | cfg->swipe4_lt_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4LeftButton", DEFAULT_SWIPE4_LT_BTN), 0, 32); 167 | cfg->swipe4_rt_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4RightButton", DEFAULT_SWIPE4_RT_BTN), 0, 32); 168 | cfg->scale_dist = MAXVAL(xf86SetIntOption(opts, "ScaleDistance", DEFAULT_SCALE_DIST), 1); 169 | cfg->scale_up_btn = CLAMPVAL(xf86SetIntOption(opts, "ScaleUpButton", DEFAULT_SCALE_UP_BTN), 0, 32); 170 | cfg->scale_dn_btn = CLAMPVAL(xf86SetIntOption(opts, "ScaleDownButton", DEFAULT_SCALE_DN_BTN), 0, 32); 171 | cfg->rotate_dist = MAXVAL(xf86SetIntOption(opts, "RotateDistance", DEFAULT_ROTATE_DIST), 1); 172 | cfg->rotate_lt_btn = CLAMPVAL(xf86SetIntOption(opts, "RotateLeftButton", DEFAULT_ROTATE_LT_BTN), 0, 32); 173 | cfg->rotate_rt_btn = CLAMPVAL(xf86SetIntOption(opts, "RotateRightButton", DEFAULT_ROTATE_RT_BTN), 0, 23); 174 | cfg->drag_enable = xf86SetBoolOption(opts, "TapDragEnable", DEFAULT_DRAG_ENABLE); 175 | cfg->drag_timeout = MAXVAL(xf86SetIntOption(opts, "TapDragTime", DEFAULT_DRAG_TIMEOUT), 1); 176 | cfg->drag_wait = MAXVAL(xf86SetIntOption(opts, "TapDragWait", DEFAULT_DRAG_WAIT), 0); 177 | cfg->drag_dist = MAXVAL(xf86SetIntOption(opts, "TapDragDist", DEFAULT_DRAG_DIST), 0); 178 | cfg->axis_x_invert = xf86SetBoolOption(opts, "AxisXInvert", DEFAULT_AXIS_X_INVERT); 179 | cfg->axis_y_invert = xf86SetBoolOption(opts, "AxisYInvert", DEFAULT_AXIS_Y_INVERT); 180 | cfg->sensitivity = MAXVAL(xf86SetRealOption(opts, "Sensitivity", DEFAULT_SENSITIVITY), 0); 181 | } 182 | 183 | -------------------------------------------------------------------------------- /src/mtouch.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2008 Henrik Rydberg 5 | * Copyright (C) 2011 Ryan Bourgeois 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | * 21 | **************************************************************************/ 22 | 23 | #include "mtouch.h" 24 | 25 | static const int use_grab = 0; 26 | 27 | int mtouch_configure(struct MTouch* mt, int fd) 28 | { 29 | mt->fd = fd; 30 | int rc = read_capabilities(&mt->caps, mt->fd); 31 | if (rc < 0) 32 | return rc; 33 | output_capabilities(&mt->caps); 34 | return 0; 35 | } 36 | 37 | 38 | int mtouch_open(struct MTouch* mt, int fd) 39 | { 40 | int ret; 41 | mt->fd = fd; 42 | ret = mtdev_open(&mt->dev, mt->fd); 43 | if (ret) 44 | goto error; 45 | mconfig_init(&mt->cfg, &mt->caps); 46 | hwstate_init(&mt->hs, &mt->caps); 47 | mtstate_init(&mt->state); 48 | gestures_init(mt); 49 | if (use_grab) { 50 | SYSCALL(ret = ioctl(fd, EVIOCGRAB, 1)); 51 | if (ret) 52 | goto close; 53 | } 54 | return 0; 55 | close: 56 | mtdev_close(&mt->dev); 57 | error: 58 | return ret; 59 | } 60 | 61 | 62 | int mtouch_close(struct MTouch* mt) 63 | { 64 | int ret; 65 | if (use_grab) { 66 | SYSCALL(ret = ioctl(mt->fd, EVIOCGRAB, 0)); 67 | if (ret) 68 | xf86Msg(X_WARNING, "mtouch: ungrab failed\n"); 69 | } 70 | mtdev_close(&mt->dev); 71 | return 0; 72 | } 73 | 74 | int mtouch_read(struct MTouch* mt) 75 | { 76 | int ret = hwstate_modify(&mt->hs, &mt->dev, mt->fd, &mt->caps); 77 | if (ret <= 0) 78 | return ret; 79 | mtstate_extract(&mt->state, &mt->cfg, &mt->hs, &mt->caps); 80 | gestures_extract(mt); 81 | return 1; 82 | } 83 | 84 | int mtouch_delayed(struct MTouch* mt) 85 | { 86 | return gestures_delayed(mt); 87 | } 88 | 89 | -------------------------------------------------------------------------------- /src/mtstate.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2008 Henrik Rydberg 5 | * Copyright (C) 2011 Ryan Bourgeois 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | * 21 | **************************************************************************/ 22 | 23 | #include "mtstate.h" 24 | #include "trig.h" 25 | 26 | static int inline percentage(int dividend, int divisor) 27 | { 28 | return (double)dividend / (double)divisor * 100; 29 | } 30 | 31 | static int inline touch_range_ratio(const struct MConfig* cfg, int value) 32 | { 33 | return (double)(value - cfg->touch_min) / (double)(cfg->touch_max - cfg->touch_min) * 100; 34 | } 35 | 36 | /* Check if a finger is touching the trackpad. 37 | */ 38 | static int is_touch(const struct MConfig* cfg, 39 | const struct FingerState* hw) 40 | { 41 | if (cfg->touch_type == MCFG_SCALE) 42 | return percentage(hw->touch_major, hw->width_major) > cfg->touch_down; 43 | else if (cfg->touch_type == MCFG_SIZE) 44 | return touch_range_ratio(cfg, hw->touch_major) > cfg->touch_down; 45 | else if (cfg->touch_type == MCFG_PRESSURE) 46 | return touch_range_ratio(cfg, hw->pressure) > cfg->touch_down; 47 | else 48 | return 1; 49 | } 50 | 51 | /* Check if a finger is released from the touchpad. 52 | */ 53 | static int is_release(const struct MConfig* cfg, 54 | const struct FingerState* hw) 55 | { 56 | if (cfg->touch_type == MCFG_SCALE) 57 | return percentage(hw->touch_major, hw->width_major) < cfg->touch_up; 58 | else if (cfg->touch_type == MCFG_SIZE) 59 | return touch_range_ratio(cfg, hw->touch_major) < cfg->touch_up; 60 | else if (cfg->touch_type == MCFG_PRESSURE) 61 | return touch_range_ratio(cfg, hw->pressure) < cfg->touch_up; 62 | else 63 | return 0; 64 | } 65 | 66 | static int is_thumb(const struct MConfig* cfg, 67 | const struct FingerState* hw) 68 | { 69 | if (!cfg->touch_minor) 70 | return 0; 71 | 72 | int min = MINVAL(hw->touch_minor, hw->touch_major); 73 | int max = MAXVAL(hw->touch_minor, hw->touch_major); 74 | int pct = percentage(min, max); 75 | int size = touch_range_ratio(cfg, hw->touch_major); 76 | 77 | if (pct < cfg->thumb_ratio && size > cfg->thumb_size) { 78 | #if DEBUG_MTSTATE 79 | xf86Msg(X_INFO, "is_thumb: yes %d > %d && %d > %d\n", 80 | pct, cfg->thumb_ratio, size, cfg->thumb_size); 81 | #endif 82 | return 1; 83 | } 84 | else { 85 | #if DEBUG_MTSTATE 86 | xf86Msg(X_INFO, "is_thumb: no %d > %d && %d > %d\n", 87 | pct, cfg->thumb_ratio, size, cfg->thumb_size); 88 | #endif 89 | return 0; 90 | } 91 | } 92 | 93 | static int is_palm(const struct MConfig* cfg, 94 | const struct FingerState* hw) 95 | { 96 | if (cfg->touch_type != MCFG_SCALE && cfg->touch_type != MCFG_SIZE) 97 | return 0; 98 | 99 | int size = touch_range_ratio(cfg, hw->touch_major); 100 | if (size > cfg->palm_size) { 101 | #if DEBUG_MTSTATE 102 | xf86Msg(X_INFO, "is_palm: yes %d > %d\n", size, cfg->palm_size); 103 | #endif 104 | return 1; 105 | } 106 | else { 107 | #if DEBUG_MTSTATE 108 | xf86Msg(X_INFO, "is_palm: no %d > %d\n", size, cfg->palm_size); 109 | #endif 110 | return 0; 111 | } 112 | } 113 | 114 | /* Find a touch by its tracking ID. Return -1 if not found. 115 | */ 116 | static int find_touch(struct MTState* ms, 117 | int tracking_id) 118 | { 119 | int i; 120 | foreach_bit(i, ms->touch_used) { 121 | if (ms->touch[i].tracking_id == tracking_id) 122 | return i; 123 | } 124 | return -1; 125 | } 126 | 127 | /* Add a touch to the MTState. Return the new index of the touch. 128 | */ 129 | static int touch_append(struct MTState* ms, 130 | const struct MConfig* cfg, 131 | const struct Capabilities* caps, 132 | const struct HWState* hs, 133 | int fn) 134 | { 135 | int x, y; 136 | int n = firstbit(~ms->touch_used); 137 | const struct FingerState* fs = &hs->data[fn]; 138 | if (n < 0) 139 | xf86Msg(X_WARNING, "Too many touches to track. Ignoring touch %d.\n", fs->tracking_id); 140 | else { 141 | x = cfg->axis_x_invert ? get_cap_xflip(caps, fs->position_x) : fs->position_x; 142 | y = cfg->axis_y_invert ? get_cap_yflip(caps, fs->position_y) : fs->position_y; 143 | ms->touch[n].state = 0U; 144 | ms->touch[n].flags = 0U; 145 | timercp(&ms->touch[n].down, &hs->evtime); 146 | ms->touch[n].direction = TR_NONE; 147 | ms->touch[n].tracking_id = fs->tracking_id; 148 | ms->touch[n].x = x; 149 | ms->touch[n].y = y; 150 | ms->touch[n].dx = 0; 151 | ms->touch[n].dy = 0; 152 | ms->touch[n].total_dx = 0; 153 | ms->touch[n].total_dy = 0; 154 | SETBIT(ms->touch[n].state, MT_NEW); 155 | SETBIT(ms->touch_used, n); 156 | } 157 | return n; 158 | } 159 | 160 | /* Update a touch. 161 | */ 162 | static void touch_update(struct MTState* ms, 163 | const struct MConfig* cfg, 164 | const struct Capabilities* caps, 165 | const struct FingerState* fs, 166 | int touch) 167 | { 168 | int x, y; 169 | x = cfg->axis_x_invert ? get_cap_xflip(caps, fs->position_x) : fs->position_x; 170 | y = cfg->axis_y_invert ? get_cap_yflip(caps, fs->position_y) : fs->position_y; 171 | ms->touch[touch].dx = x - ms->touch[touch].x; 172 | ms->touch[touch].dy = y - ms->touch[touch].y; 173 | ms->touch[touch].total_dx += ms->touch[touch].dx; 174 | ms->touch[touch].total_dy += ms->touch[touch].dy; 175 | ms->touch[touch].x = x; 176 | ms->touch[touch].y = y; 177 | ms->touch[touch].direction = trig_direction(ms->touch[touch].dx, ms->touch[touch].dy); 178 | CLEARBIT(ms->touch[touch].state, MT_NEW); 179 | } 180 | 181 | /* Release a touch. 182 | */ 183 | static void touch_release(struct MTState* ms, 184 | int touch) 185 | { 186 | ms->touch[touch].dx = 0; 187 | ms->touch[touch].dy = 0; 188 | ms->touch[touch].direction = TR_NONE; 189 | CLEARBIT(ms->touch[touch].state, MT_NEW); 190 | SETBIT(ms->touch[touch].state, MT_RELEASED); 191 | } 192 | 193 | /* Invalidate all touches. 194 | */ 195 | static void touches_invalidate(struct MTState* ms) 196 | { 197 | int i; 198 | foreach_bit(i, ms->touch_used) 199 | SETBIT(ms->touch[i].state, MT_INVALID); 200 | } 201 | 202 | /* Update all touches. 203 | */ 204 | static void touches_update(struct MTState* ms, 205 | const struct MConfig* cfg, 206 | const struct HWState* hs, 207 | const struct Capabilities* caps) 208 | { 209 | int i, n, disable = 0; 210 | // Release missing touches. 211 | foreach_bit(i, ms->touch_used) { 212 | if (find_finger(hs, ms->touch[i].tracking_id) == -1) 213 | touch_release(ms, i); 214 | } 215 | 216 | // Add and update touches. 217 | foreach_bit(i, hs->used) { 218 | n = find_touch(ms, hs->data[i].tracking_id); 219 | if (n >= 0) { 220 | if (is_release(cfg, &hs->data[i])) 221 | touch_release(ms, n); 222 | else 223 | touch_update(ms, cfg, caps, &hs->data[i], n); 224 | } 225 | else if (is_touch(cfg, &hs->data[i])) 226 | n = touch_append(ms, cfg, caps, hs, i); 227 | 228 | if (n >= 0) { 229 | // Track and invalidate thumb, palm, and bottom edge touches. 230 | if (is_thumb(cfg, &hs->data[i])) 231 | SETBIT(ms->touch[n].state, MT_THUMB); 232 | else 233 | CLEARBIT(ms->touch[n].state, MT_THUMB); 234 | 235 | if (is_palm(cfg, &hs->data[i])) 236 | SETBIT(ms->touch[n].state, MT_PALM); 237 | else 238 | CLEARBIT(ms->touch[n].state, MT_PALM); 239 | 240 | if (ms->touch[n].y > (100 - cfg->bottom_edge)*cfg->pad_height/100) { 241 | if (GETBIT(ms->touch[n].state, MT_NEW)) 242 | SETBIT(ms->touch[n].state, MT_BOTTOM_EDGE); 243 | } 244 | else 245 | CLEARBIT(ms->touch[n].state, MT_BOTTOM_EDGE); 246 | 247 | MODBIT(ms->touch[n].state, MT_INVALID, 248 | GETBIT(ms->touch[n].state, MT_THUMB) && cfg->ignore_thumb || 249 | GETBIT(ms->touch[n].state, MT_PALM) && cfg->ignore_palm || 250 | GETBIT(ms->touch[n].state, MT_BOTTOM_EDGE)); 251 | 252 | disable |= cfg->disable_on_thumb && GETBIT(ms->touch[n].state, MT_THUMB); 253 | disable |= cfg->disable_on_palm && GETBIT(ms->touch[n].state, MT_PALM); 254 | } 255 | } 256 | 257 | if (disable) 258 | touches_invalidate(ms); 259 | } 260 | 261 | /* Remove released touches. 262 | */ 263 | static void touches_clean(struct MTState* ms) 264 | { 265 | int i, used; 266 | used = ms->touch_used; 267 | foreach_bit(i, used) { 268 | if (GETBIT(ms->touch[i].state, MT_RELEASED)) 269 | CLEARBIT(ms->touch_used, i); 270 | } 271 | } 272 | 273 | #if DEBUG_MTSTATE 274 | static void mtstate_output(const struct MTState* ms, 275 | const struct HWState* hs) 276 | { 277 | int i, n; 278 | char* type; 279 | struct timeval tv; 280 | n = bitcount(ms->touch_used); 281 | if (bitcount(ms->touch_used) > 0) { 282 | microtime(&tv); 283 | xf86Msg(X_INFO, "mtstate: %d touches at event time %llu (rt %llu)\n", 284 | n, timertoms(&hs->evtime), timertoms(&tv)); 285 | } 286 | foreach_bit(i, ms->touch_used) { 287 | if (GETBIT(ms->touch[i].state, MT_RELEASED)) { 288 | timersub(&hs->evtime, &ms->touch[i].down, &tv); 289 | xf86Msg(X_INFO, " released p(%d, %d) d(%+d, %+d) dir(%f) down(%llu) time(%lld)\n", 290 | ms->touch[i].x, ms->touch[i].y, ms->touch[i].dx, ms->touch[i].dy, 291 | ms->touch[i].direction, timertoms(&ms->touch[i].down), timertoms(&tv)); 292 | } 293 | else if (GETBIT(ms->touch[i].state, MT_NEW)) { 294 | xf86Msg(X_INFO, " new p(%d, %d) d(%+d, %+d) dir(%f) down(%llu)\n", 295 | ms->touch[i].x, ms->touch[i].y, ms->touch[i].dx, ms->touch[i].dy, 296 | ms->touch[i].direction, timertoms(&ms->touch[i].down)); 297 | } 298 | else if (GETBIT(ms->touch[i].state, MT_INVALID)) { 299 | timersub(&hs->evtime, &ms->touch[i].down, &tv); 300 | xf86Msg(X_INFO, " invalid p(%d, %d) d(%+d, %+d) dir(%f) down(%llu) time(%lld)\n", 301 | ms->touch[i].x, ms->touch[i].y, ms->touch[i].dx, ms->touch[i].dy, 302 | ms->touch[i].direction, timertoms(&ms->touch[i].down), timertoms(&tv)); 303 | } 304 | else { 305 | xf86Msg(X_INFO, " touching p(%d, %d) d(%+d, %+d) dir(%f) down(%llu)\n", 306 | ms->touch[i].x, ms->touch[i].y, ms->touch[i].dx, ms->touch[i].dy, 307 | ms->touch[i].direction, timertoms(&ms->touch[i].down)); 308 | } 309 | } 310 | } 311 | #endif 312 | 313 | void mtstate_init(struct MTState* ms) 314 | { 315 | memset(ms, 0, sizeof(struct MTState)); 316 | } 317 | 318 | // Process changes in touch state. 319 | void mtstate_extract(struct MTState* ms, 320 | const struct MConfig* cfg, 321 | const struct HWState* hs, 322 | const struct Capabilities* caps) 323 | { 324 | ms->state = 0; 325 | 326 | touches_clean(ms); 327 | touches_update(ms, cfg, hs, caps); 328 | 329 | #if DEBUG_MTSTATE 330 | mtstate_output(ms, hs); 331 | #endif 332 | } 333 | 334 | -------------------------------------------------------------------------------- /src/trig.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2011 Ryan Bourgeois 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | * 20 | **************************************************************************/ 21 | 22 | #include "trig.h" 23 | #include "common.h" 24 | #include 25 | 26 | /* Convert a radians value into an mtrack angle. 27 | */ 28 | static double trig_encode_radians(double radians) { 29 | double angle = (radians / M_PI) * 4; 30 | if (angle < 0) 31 | angle = angle + 8; 32 | return angle; 33 | } 34 | 35 | /* Convert an mtrack angle value into radians. 36 | */ 37 | static double trig_decode_radians(double angle) { 38 | if (angle < 4) 39 | return (angle * M_PI) / 4; 40 | else 41 | return ((8 - angle) * M_PI) / -4; 42 | } 43 | 44 | double trig_direction(double dx, double dy) { 45 | double angle = TR_NONE; 46 | if (dx != 0 || dy != 0) 47 | return trig_encode_radians(atan2(dx, dy*-1)); 48 | return angle; 49 | } 50 | 51 | int trig_generalize(double dir) 52 | { 53 | if (dir == -1) 54 | return TR_NONE; 55 | else if (dir > 1 && dir <= 3) 56 | return TR_DIR_RT; 57 | else if (dir > 3 && dir <= 5) 58 | return TR_DIR_DN; 59 | else if (dir > 5 && dir <= 7) 60 | return TR_DIR_LT; 61 | else 62 | return TR_DIR_UP; 63 | } 64 | 65 | double trig_angles_add(double a1, double a2) 66 | { 67 | double a = MODVAL(a1 + a2, 8.0); 68 | if (a < 0) 69 | a = a + 8.0; 70 | return a; 71 | } 72 | 73 | double trig_angles_sub(double a1, double a2) 74 | { 75 | return trig_angles_add(a1, -1.0*a2); 76 | } 77 | 78 | double trig_angles_acute(double a1, double a2) 79 | { 80 | double angle; 81 | if (a1 > a2) 82 | angle = trig_angles_sub(a1, a2); 83 | else 84 | angle = trig_angles_sub(a2, a1); 85 | if (angle > 4) 86 | angle = 8 - angle; 87 | return angle; 88 | } 89 | 90 | double trig_angles_avg(double* angles, int len) 91 | { 92 | int i; 93 | double dx, dy, r; 94 | dx = dy = 0; 95 | for (i = 0; i < len; i++) { 96 | r = trig_decode_radians(angles[i]); 97 | dx += cos(r); 98 | dy += sin(r); 99 | } 100 | return trig_encode_radians(atan2(dy, dx)); 101 | } 102 | 103 | int trig_angles_cmp(double a1, double a2) 104 | { 105 | double m1, m2; 106 | m1 = MODVAL(a1, 8); 107 | m2 = MODVAL(a2, 8); 108 | if (m1 == m2) 109 | return 0; 110 | else if (m1 > m2) 111 | return 1; 112 | else 113 | return -1; 114 | } 115 | -------------------------------------------------------------------------------- /tools/mtrack-test.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Multitouch X driver 4 | * Copyright (C) 2008 Henrik Rydberg 5 | * Copyright (C) 2011 Ryan Bourgeois 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | * 21 | **************************************************************************/ 22 | 23 | #include "mtouch.h" 24 | #include 25 | #include 26 | 27 | void xf86Msg(int type, const char *format, ...) 28 | { 29 | va_list args; 30 | va_start(args, format); 31 | vfprintf(stderr, format, args); 32 | va_end(args); 33 | } 34 | 35 | #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) <= 13 36 | typedef XF86OptionPtr pointer; 37 | #endif 38 | 39 | int xf86SetIntOption(XF86OptionPtr opts, const char *name, int deflt) 40 | { 41 | return deflt; 42 | } 43 | 44 | int xf86SetBoolOption(XF86OptionPtr opts, const char *name, int deflt) 45 | { 46 | return deflt; 47 | } 48 | 49 | double xf86SetRealOption(XF86OptionPtr opts, const char *name, double deflt) 50 | { 51 | return deflt; 52 | } 53 | 54 | static void print_gestures(const struct Gestures* gs) 55 | { 56 | int i; 57 | static bitmask_t buttons_prev = 0U; 58 | for (i = 0; i < 32; i++) { 59 | if (GETBIT(gs->buttons, i) == GETBIT(buttons_prev, i)) 60 | continue; 61 | 62 | if (GETBIT(gs->buttons, i)) 63 | printf("button %d down\n", i+1); 64 | else 65 | printf("button %d up\n", i+1); 66 | } 67 | 68 | if (gs->move_dx != 0 || gs->move_dy != 0) 69 | printf("moving (%+4d, %+4d)\n", gs->move_dx, gs->move_dy); 70 | 71 | buttons_prev = gs->buttons; 72 | } 73 | 74 | static void loop_device(int fd) 75 | { 76 | struct MTouch mt; 77 | if (mtouch_configure(&mt, fd)) { 78 | fprintf(stderr, "error: could not configure device\n"); 79 | return; 80 | } 81 | if (mtouch_open(&mt, fd)) { 82 | fprintf(stderr, "error: could not open device\n"); 83 | return; 84 | } 85 | 86 | mconfig_defaults(&mt.cfg); 87 | printf("width: %d\n", mt.hs.max_x); 88 | printf("height: %d\n", mt.hs.max_y); 89 | 90 | //while (!mtdev_idle(&mt.dev, fd, 5000)) { 91 | while (1) { 92 | while (mtouch_read(&mt) > 0) 93 | print_gestures(&mt.gs); 94 | if (mtouch_delayed(&mt)) 95 | print_gestures(&mt.gs); 96 | } 97 | mtouch_close(&mt); 98 | } 99 | 100 | int main(int argc, char *argv[]) 101 | { 102 | if (argc < 2) { 103 | fprintf(stderr, "Usage: test \n"); 104 | return -1; 105 | } 106 | int fd = open(argv[1], O_RDONLY | O_NONBLOCK); 107 | if (fd < 0) { 108 | fprintf(stderr, "error: could not open file\n"); 109 | return -1; 110 | } 111 | loop_device(fd); 112 | close(fd); 113 | return 0; 114 | } 115 | --------------------------------------------------------------------------------