summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Osterlund <petero2@telia.com>2002-07-04 00:40:37 +0200
committerPeter Osterlund <petero2@telia.com>2006-04-09 04:00:49 +0200
commit0d8042d8b68e259457de14a0c4365459b1de7d30 (patch)
treea9a0e8a6fcaa138d8cb6e1e77b7f9b7036b6f4e8
Added source code for the synaptics touchpad XFree86
driver.
-rw-r--r--FEATURES13
-rw-r--r--FILES7
-rw-r--r--INSTALL58
-rw-r--r--INSTALL.DE58
-rw-r--r--LICENSE280
-rw-r--r--Makefile63
-rw-r--r--NEWS2
-rw-r--r--PARAMETER15
-rw-r--r--TODO10
-rw-r--r--VERSION1
-rw-r--r--pc_keyb.c.diff.2.4.357
-rw-r--r--ps2comm.c346
-rw-r--r--ps2comm.h67
-rw-r--r--synaptics.c903
-rw-r--r--synaptics.h97
-rw-r--r--synclient.c26
16 files changed, 2003 insertions, 0 deletions
diff --git a/FEATURES b/FEATURES
new file mode 100644
index 0000000..e731e1f
--- /dev/null
+++ b/FEATURES
@@ -0,0 +1,13 @@
+The touchpad driver has the following functions (some function requires features from the touchpad that must be present, multifinger taps for example):
+- Movement with adjustable, non-linear acceleration and speed (Options: MinSpeed, MaxSpeed, AccelFactor)
+- Button events through short touching of the touchpad (Options: MaxTapTime, MaxTapMove)
+- Double-Button events through double short touching of the touchpad
+- Dragging through short touching and holding down the finger on the touchpad
+- Middle and right button events on the upper and lower corner of the touchpad (Option: Edges)
+- Scrolling (button four and five events) through moving the finger on the right side of the touchpad (Options: Edges, VertScrollDelta)
+- The up/down button sends button four/five events
+- Adjustable finger detection (Option: Finger)
+- Ext Mouse repeater support - Alpha! (Option: Repeater)
+- Multifinger taps: two finger for middle button and three finger for right button events
+- Online configuration through short-memory (in development) (Option: SHMConfig)
+
diff --git a/FILES b/FILES
new file mode 100644
index 0000000..b6c3e0a
--- /dev/null
+++ b/FILES
@@ -0,0 +1,7 @@
+pc_keyb.c.diff.2.4.3 Patch for the reconnect message handling
+ps2comm.c Synaptics communication routines
+ps2comm.h see above
+synaptics.c Synaptics driver-module for xfree
+synaptics.h see above
+synclient.c Program for testing the shared-memory
+ shows the x, y-coordinates of the finger
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..7a6ae68
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,58 @@
+Installation of the Synaptics-Touchpad-Driver for XFree 4.x
+===========================================================
+
+Author: Stefan Gmeiner <riddlebox@freesurf.ch>
+Date: 17.02.02
+
+needs: - XFree 4.x
+ - Using with Kernel 2.4.x for x < 10 needs a kernel-patch (see
+ source-code)
+
+1. If you installing the driver by binary (recommended) you can go to
+step 3.
+
+2. Change in the "Makefile" the path to the xfree-sourcecode tree by
+changig the Variable TOP. Then type "make" to build the driver
+"synaptics_drv.o".
+
+3. Copy the driver-modul "snyaptics_drv.o" into the XFree-module path
+"ex. /usr/X11R6/lib/modules/input/".
+
+4. Load the driver by changig the XFree configuration file through
+adding the line 'Load "synaptics"' in the modul-section.
+
+5. Add/Replace in the InputDevice-section for the touchpad the
+following lines:
+
+Section "InputDevice"
+ Driver "synaptics"
+ Identifier "Mouse[1]"
+ Option "Device" "/dev/psaux"
+ Option "Edges" "1900 5400 1800 3900"
+ Option "Finger" "25 30"
+ Option "MaxTapTime" "20"
+ Option "MaxTapMove" "220"
+ Option "VertScrollDelta" "100"
+ Option "MinSpeed" "0.02"
+ Option "MaxSpeed" "0.18"
+ Option "AccelFactor" "0.0010"
+# Option "Repeater" "/dev/ps2mouse"
+# Option "SHMConfig" "on"
+EndSection
+
+Change the Identifier to the same name as in the ServerLayout-section.
+The Option "Repeater" und "SHMConfig" are at the moment for testing.
+
+6. Start/Restart the X-Server. If the touchpad doesn't work go to
+step 7.
+
+7. a) Check the XFree-Logfiles
+ b) Try to start the XServer with 'startx -- -logverbose 8' for more
+ Output
+If you can't get the driver working, mail the logfiles and the
+configuration file to me.
+
+
+
+
+
diff --git a/INSTALL.DE b/INSTALL.DE
new file mode 100644
index 0000000..ff5131c
--- /dev/null
+++ b/INSTALL.DE
@@ -0,0 +1,58 @@
+Installation des Synaptics-Touchpad-Treibers für XFree 4.x
+==========================================================
+
+Autor: Stefan Gmeiner <riddlebox@freesurf.ch>
+Datum: 17.02.02
+
+Vorraussetzungen für die Installation:
+- XFree 4.x
+- Bei Kernel 2.4.x für x < 10 muss ein Kernel-Patch installiert
+ werden (siehe Source-Tree des Treibers)
+
+1. Wenn du den Treiber als Binary installierst (empfohlen), kannst du direkt
+zum Schritt 2 übergehen.
+
+2. Nach dem im "Makefile" der Pfad zum XFree Sourcetree angepasst
+wurde (TOP=<Pfad zum XFree-Quellcode , kann der Treiber mit
+"make" übersetzt werden.
+
+3. Der Treiber "synaptics_drv.o" muss in das Modul-Verzeichnis
+der XFree Installation kopiert werden.
+
+4. In der Konfigurationsdatei ist der Treiber über "Load
+"synaptics"" in der Modul-Section zu laden.
+
+5. In der InputDevice-Section für das Touchpad sind folgende
+Optionen einzufügen/ersetzen:
+
+Section "InputDevice"
+ Driver "synaptics"
+ Identifier "Mouse[1]"
+ Option "Device" "/dev/psaux"
+ Option "Edges" "1900 5400 1800 3900"
+ Option "Finger" "25 30"
+ Option "MaxTapTime" "20"
+ Option "MaxTapMove" "220"
+ Option "VertScrollDelta" "100"
+ Option "MinSpeed" "0.02"
+ Option "MaxSpeed" "0.18"
+ Option "AccelFactor" "0.0010"
+# Option "Repeater" "/dev/ps2mouse"
+# Option "SHMConfig" "on"
+EndSection
+
+Als Identifier muss der gleiche Name wie in der
+ServerLayout-Section verwendet werden.
+Die Optionen "Repeater" und "SHMConfig" sind noch in der
+Testphase. Über die "Repeater"-Option kann eine ext. Maus auf ein
+Repeater-FiFo umgeleitet werden. Über die Option "SHMConfig" soll
+der Treiber später einaml online konfigurierbar werden.
+
+6. Der X-Server ist neu zu starten. Sollte das Touchpad nicht
+funktionieren, siehe Schritt 7.
+
+7. a) Die Ausgaben des XFree-Logfiles anschauen.
+ b) Den XServer mit "startx -- -logverbose 8" starten um mehr
+ Ausgaben zu erzeugen.
+
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..c7aea18
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,280 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..33cab24
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,63 @@
+TOP = /usr/src/packages/BUILD/xc
+XTOP = $(TOP)
+BUILDINCROOT = $(TOP)/exports
+EXTINCSRC = $(XTOP)/include/extensions
+INCLUDESRC = $(BUILDINCROOT)/include
+XINCLUDESRC = $(INCLUDESRC)/X11
+SERVERSRC = $(XTOP)/programs/Xserver
+TOP_X_INCLUDES = -I$(TOP)/exports/include
+TOP_INCLUDES = -I$(TOP) $(TOP_X_INCLUDES)
+
+
+XF86SRC = $(SERVERSRC)/hw/xfree86
+XF86COMSRC = $(XF86SRC)/common
+XF86OSSRC = $(XF86SRC)/os-support
+
+
+INCLUDES = -I. -I$(XF86COMSRC) -I$(SERVERSRC)/hw/xfree86/loader -I$(XF86OSSRC) -I$(SERVERSRC)/mi -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+ALLINCLUDES = $(INCLUDES) $(TOP_INCLUDES)
+
+MODULE_DEFINES = -DIN_MODULE -DXFree86Module
+PROTO_DEFINES = -DFUNCPROTO=15 -DNARROWPROTO
+
+STD_DEFINES = -Dlinux -D__i386__ -D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE -D_GNU_SOURCE -DSHAPE -DXINPUT -DXKB -DLBX -DXAPPGROUP -DXCSECURITY -DTOGCUP -DDPMSExtension -DPIXPRIV -DPANORAMIX -DRENDER -DGCCUSESGAS -DAVOID_GLYPHBLT -DPIXPRIV -DSINGLEDEPTH -DXFreeXDGA -DXvExtension -DXFree86LOADER -DXFree86Server -DXF86VIDMODE -DSMART_SCHEDULE -DBUILDDEBUG -DX_BYTE_ORDER=X_LITTLE_ENDIAN -DNDEBUG
+ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(PROTO_DEFINES) $(MODULE_DEFINES)
+
+CCOPTIONS = -ansi -pedantic -Wall -Wpointer-arith
+CDEBUGFLAGS = -O2
+CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
+
+CC = gcc
+CCOPTIONS = -ansi -pedantic -Wall -Wpointer-arith
+
+LDCOMBINEFLAGS = -r
+
+SRCS = synaptics.c ps2comm.c
+OBJS = synaptics.o ps2comm.o
+
+DRIVER = synaptics
+
+.c.o:
+ $(RM) $@
+ $(CC) -c $(CFLAGS) $(_NOOP_) $*.c
+
+all:: $(DRIVER)_drv.o
+
+$(DRIVER)_drv.o: $(OBJS) $(EXTRALIBRARYDEPS)
+ $(RM) $@
+ $(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $@
+
+test:
+ $(CC) $(CFLAGS) -o synclient synclient.c
+
+clean::
+ $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut synclient "#"*
+
+tags::
+ $(TAGS) -w *.[ch]
+ $(TAGS) -xw *.[ch] > TAGS
+
+
+
+
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..d2e677e
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,2 @@
+13.10.01 - Version 0.10
+- multifinger taps
diff --git a/PARAMETER b/PARAMETER
new file mode 100644
index 0000000..39cd31d
--- /dev/null
+++ b/PARAMETER
@@ -0,0 +1,15 @@
+Device String Synaptics device
+SHMConfig Bool switch on/off shared-memory for configuration
+LeftEdge Int coordinates for left edge
+RightEdge Int coordinates for right edge
+TopEdge Int coordinates for top edge
+BottomEdge Int coordinates for bottom edge
+FingerLow Int min. finger pressure after ending with movement
+FingerHigh Int max. finger pressure before beginning with movement
+MaxTapTime Int max. time (time of 1/80s) for detecting a tap
+MaxTapMove Int max. movement of the finger for detecting a tap
+VertScrollDelta Int move-distance of the finger for a scroll event
+Repeater String repeater device
+MinSpeed Float min. Speed-factor
+MaxSpeed Float max. Speed-factor
+AccelFactor Float acceleration-factor
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..1cededd
--- /dev/null
+++ b/TODO
@@ -0,0 +1,10 @@
+* horz. Scrolling möglich (Button 6,7 mit imwheel?)
+* edge draging - bewegung geht am Rand bei dragging weiter
+* Resetsequenz für repeater treiber
+* feartures über optionen abschalten
+* schnelleres scrolling (buttonrelease events)
+* shared-memory für online konfiguration
+* ftok benutzen um Shared-Memory ID zu erzeugen
+
+
+
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..68c123c
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+0.10
diff --git a/pc_keyb.c.diff.2.4.3 b/pc_keyb.c.diff.2.4.3
new file mode 100644
index 0000000..0d211a3
--- /dev/null
+++ b/pc_keyb.c.diff.2.4.3
@@ -0,0 +1,57 @@
+*** pc_keyb.c.orig Thu Oct 4 21:48:24 2001
+--- pc_keyb.c Thu Oct 4 21:52:41 2001
+***************
+*** 63,68 ****
+--- 63,69 ----
+ #ifdef CONFIG_PSMOUSE
+ static void aux_write_ack(int val);
+ static void __aux_write_ack(int val);
++ static int aux_reconnect = 0;
+ #endif
+
+ static spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
+***************
+*** 403,409 ****
+ }
+ mouse_reply_expected = 0;
+ }
+! else if(scancode == AUX_RECONNECT){
+ queue->head = queue->tail = 0; /* Flush input queue */
+ __aux_write_ack(AUX_ENABLE_DEV); /* ping the mouse :) */
+ return;
+--- 404,411 ----
+ }
+ mouse_reply_expected = 0;
+ }
+! else if(scancode == AUX_RECONNECT && aux_reconnect){
+! printk(KERN_DEBUG "AUX_RECONNECT scancode read\n");
+ queue->head = queue->tail = 0; /* Flush input queue */
+ __aux_write_ack(AUX_ENABLE_DEV); /* ping the mouse :) */
+ return;
+***************
+*** 751,756 ****
+--- 753,776 ----
+ }
+
+ #if defined CONFIG_PSMOUSE
++
++ /*
++ AUX_RECONNECT support becomes a boot option, default off
++
++ WARNING: aux-reconnect breaks synaptics ps2 touchpad support
++ (synaptics generates spurious AUX_RECONNECT scancodes ?)
++
++ ported from 2.2.18 by MAtteo HCE Valsasna (hce@uninsubria.it)
++ */
++
++ static int __init aux_reconnect_setup(char *str, int *ints)
++ {
++ aux_reconnect=1;
++ printk(KERN_INFO "AUX_RECONNECT support enabled, forget your synaptics\n");
++ return 1;
++ }
++
++ __setup("aux-reconnect", aux_reconnect_setup);
+
+ /*
+ * Check if this is a dual port controller.
diff --git a/ps2comm.c b/ps2comm.c
new file mode 100644
index 0000000..cc43724
--- /dev/null
+++ b/ps2comm.c
@@ -0,0 +1,346 @@
+/* Copyright (C) 2001 Stefan Gmeiner <riddlebox@freesurf.ch>
+ *
+ * Copyright (c) 1997 C. Scott Ananian <cananian@alumni.priceton.edu>
+ * Copyright (c) 1998-2000 Bruce Kalk <kall@compass.com>
+ * code für the special synaptics commands (from the tpconfig-source)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "xf86_OSproc.h"
+
+#include "ps2comm.h"
+
+/* acknowledge for commands and parameter */
+#define PS2_ACK 0xFA
+#define PS2_ERROR 0xFC
+
+/* standard PS/2 commands */
+#define PS2_CMD_RESET 0xFF
+#define PS2_CMD_RESEND 0xFE
+#define PS2_CMD_SET_DEFAULT 0xF6
+#define PS2_CMD_DISABLE 0xF5
+#define PS2_CMD_ENABLE 0xF4
+#define PS2_CMD_SET_SAMPLE_RATE 0xF3
+#define PS2_CMD_READ_DEVICE_TYPE 0xF2
+#define PS2_CMD_SET_REMOTE_MODE 0xF0
+#define PS2_CMD_SET_WRAP_MODE 0xEE
+#define PS2_CMD_RESET_WRAP_MODE 0xEC
+#define PS2_CMD_READ_DATA 0xEB
+#define PS2_CMD_SET_STREAM_MODE 0xEA
+#define PS2_CMD_STATUS_REQUEST 0xE9
+#define PS2_CMD_SET_RESOLUTION 0xE8
+#define PS2_CMD_SET_SCALING_2_1 0xE7
+#define PS2_CMD_SET_SCALING_1_1 0xE6
+
+/* synaptics queries */
+#define SYN_QUE_IDENTIFY 0x00
+#define SYN_QUE_MODES 0x01
+#define SYN_QUE_CAPABILITIES 0x02
+#define SYN_QUE_MODEL 0x03
+#define SYN_QUE_SERIAL_NUMBER_PREFIX 0x06
+#define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07
+#define SYN_QUE_RESOLUTION 0x08
+
+/* status request response bits (PS2_CMD_STATUS_REQUEST) */
+#define PS2_RES_REMOTE(r) (r&(1<<22))
+#define PS2_RES_ENABLE(r) (r&(1<<21))
+#define PS2_RES_SCALING(r) (r&(1<<20))
+#define PS2_RES_LEFT(r) (r&(1<<18))
+#define PS2_RES_MIDDLE(r) (r&(1<<17))
+#define PS2_RES_RIGHT(r) (r&(1<<16))
+#define PS2_RES_RESOLUTION(r) ((r>>8)&0x03)
+#define PS2_RES_SAMPLE_RATE(r) (r&0xff)
+
+
+
+/*****************************************************************************
+ * PS/2 Utility functions.
+ * Many parts adapted from tpconfig.c by C. Scott Ananian
+ ****************************************************************************/
+
+/*
+ * Read a byte from the ps/2 port
+ */
+static Bool
+ps2_getbyte(int fd, byte *b)
+{
+ if(xf86WaitForInput(fd, 50000) > 0) {
+ if(xf86ReadSerial(fd, b, 1) != 1) {
+#ifdef DEBUG
+ ErrorF("ps2_getbyte: No byte read\n");
+#endif
+ return !Success;
+ }
+#ifdef DEBUG
+ ErrorF("ps2_getbyte: byte %02X read\n", *b);
+#endif
+ return Success;
+ }
+#ifdef DEBUG
+ ErrorF("ps2_getbyte: timeout xf86WaitForInput\n");
+#endif
+ return !Success;
+}
+
+/*
+ * Write a byte to the ps/2 port, wair for ACK
+ */
+static Bool
+ps2_putbyte(int fd, byte b)
+{
+ byte ack;
+
+ if(xf86WriteSerial(fd, &b, 1) != 1) {
+#ifdef DEBUG
+ ErrorF("ps2_putbyte: error xf86WriteSerial\n");
+#endif
+ return !Success;
+ }
+#ifdef DEBUG
+ ErrorF("ps2_putbyte: byte %02X send\n", b);
+#endif
+ /* wait for an ACK */
+ if(ps2_getbyte(fd, &ack) != Success) {
+ return !Success;
+ }
+ if(ack != PS2_ACK) {
+#ifdef DEBUG
+ ErrorF("ps2_putbyte: wrong acknowledge 0x%02x\n", ack);
+#endif
+ return !Success;
+ }
+ return Success;
+}
+
+/*
+ * Use the Synaptics extended ps/2 syntax to write a special command byte. Needed by
+ * ps2_send_cmd and ps2_set_mode.
+ * special command: 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
+ * is the command. A 0xF3 or 0xE9 must follow (see ps2_send_cmd, ps2_set_mode)
+ */
+static Bool
+ps2_special_cmd(int fd, byte cmd)
+{
+ int i;
+
+ /* initialize with 'inert' command */
+ if(ps2_putbyte(fd, PS2_CMD_SET_SCALING_1_1) == Success)
+ /* send 4x 2-bits with set resolution command */
+ for (i=0; i<4; i++) {
+ if(((ps2_putbyte(fd, PS2_CMD_SET_RESOLUTION)) != Success) ||
+ ((ps2_putbyte(fd, (cmd>>6)&0x3) != Success)))
+ return !Success;
+ cmd<<=2;
+ }
+ else
+ return !Success;
+ return Success;
+}
+
+/*
+ * Send a command to the synpatics touchpad by special commands
+ */
+static Bool
+ps2_send_cmd(int fd, byte c)
+{
+#ifdef DEBUG
+ ErrorF("send command: 0x%02X\n", c);
+#endif
+ return(ps2_special_cmd(fd, c) || ps2_putbyte(fd, PS2_CMD_STATUS_REQUEST));
+}
+
+/*****************************************************************************
+ * Synaptics communications functions
+ ****************************************************************************/
+
+/*
+ * Set the synaptics touchpad mode byte by special commands
+ */
+Bool
+synaptics_set_mode(int fd, byte mode)
+{
+#ifdef DEBUG
+ ErrorF("set mode byte to: 0x%02X\n", mode);
+#endif
+ return(ps2_special_cmd(fd, mode) ||
+ ps2_putbyte(fd, PS2_CMD_SET_SAMPLE_RATE) ||
+ ps2_putbyte(fd, 0x14));
+}
+
+/*
+ * reset the touchpad
+ */
+Bool
+synaptics_reset(int fd)
+{
+ byte r[2];
+
+ xf86FlushInput(fd);
+#ifdef DEBUG
+ ErrorF("Reset the Touchpad...\n");
+#endif
+ if(ps2_putbyte(fd, PS2_CMD_RESET) != Success) {
+#ifdef DEBUG
+ ErrorF("...failed\n");
+#endif
+ return !Success;
+ }
+ xf86WaitForInput(fd, 1500000);
+ if((ps2_getbyte(fd, &r[0]) == Success) &&
+ (ps2_getbyte(fd, &r[1]) == Success)) {
+ if(r[0] == 0xAA && r[1] == 0x00) {
+#ifdef DEBUG
+ ErrorF("...done\n");
+#endif
+ return Success;
+ } else {
+#ifdef DEBUG
+ ErrorF("...failed. Wrong reset ack 0x%02x, 0x%02x\n", r[0], r[1]);
+#endif
+ return !Success;
+ }
+ }
+#ifdef DEBUG
+ ErrorF("...failed\n");
+#endif
+ return !Success;
+}
+
+/*
+ * Read the model-id bytes from the touchpad
+ * see also SYN_MODEL_* macros
+ */
+Bool
+synaptics_model_id(int fd, unsigned long int *model_id)
+{
+ byte mi[3];
+
+#ifdef DEBUG
+ ErrorF("Read mode id...\n");
+#endif
+
+ if((ps2_send_cmd(fd, SYN_QUE_MODEL) == Success) &&
+ (ps2_getbyte(fd, &mi[0]) == Success) &&
+ (ps2_getbyte(fd, &mi[1]) == Success) &&
+ (ps2_getbyte(fd, &mi[2]) == Success)) {
+ *model_id = (mi[0]<<16) | (mi[1]<<8) | mi[2];
+#ifdef DEBUG
+ ErrorF("mode-id %06X\n", *model_id);
+#endif
+#ifdef DEBUG
+ ErrorF("...done.\n");
+#endif
+ return Success;
+ }
+#ifdef DEBUG
+ ErrorF("...failed.\n");
+#endif
+ return !Success;
+}
+
+/*
+ * Read the capability-bits from the touchpad
+ * see also the SYN_CAP_* macros
+ */
+Bool
+synaptics_capability(int fd, unsigned long int *capability)
+{
+ byte cap[3];
+
+#ifdef DEBUG
+ ErrorF("Read capabilites...\n");
+#endif
+
+ if((ps2_send_cmd(fd, SYN_QUE_CAPABILITIES) == Success) &&
+ (ps2_getbyte(fd, &cap[0]) == Success) &&
+ (ps2_getbyte(fd, &cap[1]) == Success) &&
+ (ps2_getbyte(fd, &cap[2]) == Success)) {
+ *capability = (cap[0]<<16) | (cap[1]<<8) | cap[2];
+#ifdef DEBUG
+ ErrorF("capability %06X\n", *capability);
+#endif
+ if(SYN_CAP_VALID(*capability)) {
+#ifdef DEBUG
+ ErrorF("...done.\n");
+#endif
+ return Success;
+ }
+ }
+#ifdef DEBUG
+ ErrorF("...failed.\n");
+#endif
+ return !Success;
+}
+
+/*
+ * Identify Touchpad
+ * See also the SYN_ID_* macros
+ */
+Bool
+synaptics_identify(int fd, unsigned long int *ident)
+{
+ byte id[3];
+
+#ifdef DEBUG
+ ErrorF("Identify Touchpad...\n");
+#endif
+
+ if((ps2_send_cmd(fd, SYN_QUE_IDENTIFY) == Success) &&
+ (ps2_getbyte(fd, &id[0]) == Success) &&
+ (ps2_getbyte(fd, &id[1]) == Success) &&
+ (ps2_getbyte(fd, &id[2]) == Success)) {
+ *ident = (id[0]<<16) | (id[1]<<8) | id[2];
+#ifdef DEBUG
+ ErrorF("ident %06X\n", *ident);
+#endif
+ if(SYN_ID_IS_SYNAPTICS(*ident)) {
+#ifdef DEBUG
+ ErrorF("...done.\n");
+#endif
+ return Success;
+ }
+ }
+#ifdef DEBUG
+ ErrorF("...failed.\n");
+#endif
+ return !Success;
+}
+
+Bool
+SynapticsEnableDevice(int fd)
+{
+ return(ps2_putbyte(fd, PS2_CMD_ENABLE));
+}
+
+Bool
+QueryIsSynaptics(int fd)
+{
+ unsigned long id;
+
+ xf86FlushInput(fd);
+ if(synaptics_identify(fd, &id) == Success) {
+ return TRUE;
+ } else {
+ ErrorF("Query no Synaptics: %06X\n", id);
+ return FALSE;
+ }
+}
+
+/*
+ * vim: ts=4 sw=4 cindent
+ */
+
diff --git a/ps2comm.h b/ps2comm.h
new file mode 100644
index 0000000..e509238
--- /dev/null
+++ b/ps2comm.h
@@ -0,0 +1,67 @@
+#ifndef _PS2COMM_H_
+#define _PS2COMM_H_
+
+/* synatics modes */
+#define SYN_BIT_ABSOLUTE_MODE (1<<7)
+#define SYN_BIT_HIGH_RATE (1<<6)
+#define SYN_BIT_SLEEP_MODE (1<<3)
+#define SYN_BIT_DISABLE_GESTURE (1<<2)
+#define SYN_BIT_W_MODE (1<<0)
+
+/* synaptics model ID bits */
+#define SYN_MODEL_ROT180(m) (m&(1<<23))
+#define SYN_MODEL_PORTRAIT(m) (m&(1<<22))
+#define SYN_MODEL_SENSOR(m) ((m>>16)&0x3f)
+#define SYN_MODEL_HARDWARE(m) ((m>>9)0x7f)
+#define SYN_MODEL_NEWABS(m) (m&(1<<7))
+#define SYN_MODEL_PEN(m) (m&(1<<6))
+#define SYN_MODEL_SIMPLIC(m) (m&(1<<5))
+#define SYN_MODEL_GEOMETRY(m) (m&0x0f)
+
+/* synaptics capability bits */
+#define SYN_CAP_EXTENDED(c) (c&(1<<23))
+#define SYN_CAP_SLEEP(c) (c&(1<<4))
+#define SYN_CAP_FOUR_BUTTON(c) (c&(1<<3))
+#define SYN_CAP_MULTIFINGER(c) (c&(1<<1))
+#define SYN_CAP_PALMDETECT(c) (c&(1<<0))
+#define SYN_CAP_VALID(c) (((c&0x00ff00)>>8)==0x47)
+
+/* synaptics modes query bits */
+#define SYN_MODE_ABSOLUTE(m) (m&(1<<7))
+#define SYN_MODE_RATE(m) (m&(1<<6))
+#define SYN_MODE_BAUD_SLEEP(m) (m&(1<<3))
+#define SYN_MODE_DISABLE_GESTURE(m) (m&(1<<2))
+#define SYN_MODE_PACKSIZE(m) (m&(1<<1))
+#define SYN_MODE_WMODE(m) (m&(1<<0))
+#define SYN_MODE_VALID(m) ((m&0xffff00)==0x3B47)
+
+/* synaptics identify query bits */
+#define SYN_ID_MODEL(i) ((i>>4)&0x0f)
+#define SYN_ID_MAJOR(i) (i&0x0f)
+#define SYN_ID_MINOR(i) ((i>>16)&0xff)
+#define SYN_ID_IS_SYNAPTICS(i) (((i>>8)&0xff)==0x47)
+
+typedef unsigned char byte;
+
+Bool
+synaptics_reset(int fd);
+
+Bool
+synaptics_model_id(int fd, unsigned long int *model_id);
+
+Bool
+synaptics_capability(int fd, unsigned long int *capability);
+
+Bool
+synaptics_identify(int fd, unsigned long int *ident);
+
+Bool
+synaptics_set_mode(int fd, byte cmd);
+
+Bool
+SynapticsEnableDevice(int fd);
+
+Bool
+QueryIsSynaptics(int fd);
+
+#endif /* _PS2COMM_H_ */
diff --git a/synaptics.c b/synaptics.c
new file mode 100644
index 0000000..0396fdb
--- /dev/null
+++ b/synaptics.c
@@ -0,0 +1,903 @@
+/* Copyright (C) 2001 Stefan Gmeiner <riddlebox@freesurf.ch>
+ *
+ * Copyright (c) 1999 Henry Davies <hdavies@ameritech.net> for the
+ * absolut to relative translation code (from the gpm-source)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+/*****************************************************************************
+ * Standard Headers
+ ****************************************************************************/
+
+#include <misc.h>
+#include <xf86.h>
+#define NEED_XF86_TYPES
+#include <xf86_ansic.h>
+#include <xf86_OSproc.h>
+#include <xf86Xinput.h>
+#include <xisb.h>
+#include <exevents.h> /* Needed for InitValuator/Proximity stuff */
+#include "mipointer.h"
+#include <xf86Optrec.h> /* needed for Options */
+
+/*****************************************************************************
+ * Local Headers
+ ****************************************************************************/
+#include "synaptics.h"
+#include "ps2comm.h"
+
+/*****************************************************************************
+ * Variables without includable headers
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Local Variables
+ ****************************************************************************/
+
+typedef enum {
+ BOTTOM_EDGE = 1,
+ TOP_EDGE = 2,
+ LEFT_EDGE = 4,
+ RIGHT_EDGE = 8,
+ LEFT_BOTTOM_EDGE = BOTTOM_EDGE | LEFT_EDGE,
+ RIGHT_BOTTOM_EDGE = BOTTOM_EDGE | RIGHT_EDGE,
+ RIGHT_TOP_EDGE = TOP_EDGE | RIGHT_EDGE,
+ LEFT_TOP_EDGE = TOP_EDGE | LEFT_EDGE
+} edge_type;
+
+#define DIFF_TIME(a, b) (((a)>(b))?(a)-(b):(b)-(a))
+#define VERSION "0.10"
+
+static InputInfoPtr
+SynapticsPreInit(InputDriverPtr drv, IDevPtr dev, int flags);
+
+
+InputDriverRec SYNAPTICS = {
+ 1,
+ "synaptics",
+ NULL,
+ SynapticsPreInit,
+ /*SynapticsUnInit*/ NULL,
+ NULL,
+ 0
+};
+
+#ifdef XFree86LOADER
+
+static XF86ModuleVersionInfo VersionRec =
+{
+ "synaptics",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
+ {0, 0, 0, 0} /* signature, to be patched into the file by
+ * a tool */
+};
+
+
+static pointer
+SetupProc(pointer module, pointer options, int *errmaj, int *errmin )
+{
+ xf86AddInputDriver(&SYNAPTICS, module, 0);
+ return module;
+}
+
+XF86ModuleData synapticsModuleData = {&VersionRec, &SetupProc, NULL };
+
+#endif /* XFree86LOADER */
+
+
+/*****************************************************************************
+ * Function Definitions
+ ****************************************************************************/
+
+static InputInfoPtr
+SynapticsPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
+{
+ LocalDevicePtr local;
+ SynapticsPrivatePtr priv;
+ XF86OptionPtr optList;
+ char *s;
+ int shmid;
+
+ /* allocate memory for SynaticsPrivateRec */
+ priv = xcalloc (1, sizeof (SynapticsPrivateRec));
+ if (!priv)
+ return NULL;
+
+ /* Allocate a new InputInfoRec and add it to the head xf86InputDevs. */
+ local = xf86AllocateInput(drv, 0);
+ if (!local) {
+ xfree(priv);
+ return NULL;
+ }
+
+ /* initialize the InputInfoRec */
+ local->name = dev->identifier;
+ local->type_name = XI_MOUSE; /* XI_TOUCHPAD and KDE killed the X-Server at startup ? */
+ local->device_control = DeviceControl;
+ local->read_input = ReadInput;
+ local->control_proc = ControlProc;
+ local->close_proc = CloseProc;
+ local->switch_mode = SwitchMode;
+ local->conversion_proc = ConvertProc;
+ local->reverse_conversion_proc = NULL;
+ local->dev = NULL;
+ local->private = priv;
+ local->private_flags = 0;
+ local->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
+ local->conf_idev = dev;
+ local->motion_history_proc = xf86GetMotionEvents;
+ local->history_size = 0;
+ local->always_core_feedback = 0;
+
+ xf86CollectInputOptions(local, NULL, NULL);
+
+ xf86OptionListReport(local->options);
+
+ /* open the touchpad device */
+ local->fd = xf86OpenSerial (local->options);
+ if (local->fd == -1)
+ {
+ ErrorF ("Synaptics driver unable to open device\n");
+ goto SetupProc_fail;
+ }
+ xf86ErrorFVerb( 6, "port opened successfully\n" );
+
+ /* initialize variables */
+ priv->repeat_timer = NULL;
+ priv->repeatButtons = 0;
+
+ /* install shared memory or normal memory for parameter */
+ if(xf86SetBoolOption(local->options, "SHMConfig", FALSE)) {
+ xf86shmctl(SHM_SYNAPTICS, XF86IPC_RMID, NULL);
+ if((shmid = xf86shmget(SHM_SYNAPTICS, sizeof(SynapticsSHM), 0777 | XF86IPC_CREAT)) == -1) {
+ xf86Msg(X_ERROR, "%s error shmget\n", local->name);
+ goto SetupProc_fail;
+ } else if((priv->synpara = (SynapticsSHM*) xf86shmat(shmid, NULL, 0)) == NULL) {
+ xf86Msg(X_ERROR, "%s error shmat\n", local->name);
+ goto SetupProc_fail;
+ }
+ } else {
+ priv->synpara = xcalloc (1, sizeof (SynapticsSHM));
+ if(!priv->synpara)
+ goto SetupProc_fail;
+ }
+
+ /* read the parameter */
+ priv->synpara->left_edge = xf86SetIntOption(local->options, "LeftEdge", 1900);
+ priv->synpara->right_edge = xf86SetIntOption(local->options, "RightEdge", 5400);
+ priv->synpara->top_edge = xf86SetIntOption(local->options, "TopEdge", 3900);
+ priv->synpara->bottom_edge = xf86SetIntOption(local->options, "BottomEdge", 1800);
+ priv->synpara->finger_low = xf86SetIntOption(local->options, "FingerLow", 25);
+ priv->synpara->finger_high = xf86SetIntOption(local->options, "FingerHigh", 30);
+ priv->synpara->tap_time = xf86SetIntOption(local->options, "MaxTapTime", 20);
+ priv->synpara->tap_move = xf86SetIntOption(local->options, "MaxTapMove", 220);
+ priv->synpara->scroll_dist_vert = xf86SetIntOption(local->options, "VertScrollDelta", 100);
+ priv->synpara->repeater = xf86SetStrOption(local->options, "Repeater", NULL);
+ s = xf86FindOptionValue(local->options, "MinSpeed");
+ if((!s) || (xf86sscanf(s, "%lf", &priv->synpara->min_speed) != 1))
+ priv->synpara->min_speed=0.02;
+ s = xf86FindOptionValue(local->options, "MaxSpeed");
+ if((!s) || (xf86sscanf(s, "%lf", &priv->synpara->max_speed) != 1))
+ priv->synpara->max_speed=0.18;
+ s = xf86FindOptionValue(local->options, "AccelFactor");
+ if((!s) || (xf86sscanf(s, "%lf", &priv->synpara->accl) != 1))
+ priv->synpara->accl=0.0015;
+
+ priv->buffer = XisbNew(local->fd, 200);
+ DBG(9, XisbTrace (priv->buffer, 1));
+
+ if(priv->synpara->repeater) {
+ /* create repeater fifo */
+ if((xf86mknod(priv->synpara->repeater, 666, XF86_S_IFIFO) != 0) &&
+ (xf86errno != xf86_EEXIST)) {
+ xf86Msg(X_ERROR, "%s can't create repeater fifo\n", local->name);
+ xf86free(priv->synpara->repeater);
+ priv->synpara->repeater = NULL;
+ priv->fifofd = -1;
+ } else {
+ /* open the repeater fifo */
+ optList = xf86NewOption("Device", priv->synpara->repeater);
+ if((priv->fifofd = xf86OpenSerial(optList)) == -1) {
+ xf86Msg(X_ERROR, "%s repeater device open failed\n", local->name);
+ xf86free(priv->synpara->repeater);
+ priv->synpara->repeater = NULL;
+ priv->fifofd = -1;
+ }
+ }
+ }
+
+ if(QueryHardware(local) != Success) {
+ xf86Msg(X_ERROR, "%s Unable to query/initialize Synaptics hardware.\n", local->name);
+ goto SetupProc_fail;
+ }
+
+ local->history_size = xf86SetIntOption( local->options, "HistorySize", 0 );
+
+ /* this results in an xstrdup that must be freed later */
+ /*local->name = xf86SetStrOption( local->options, "DeviceName", "Synaptics-Touchpad" );*/
+ xf86ProcessCommonOptions(local, local->options);
+ local->flags |= XI86_CONFIGURED;
+
+ if (local->fd != -1) {
+ RemoveEnabledDevice (local->fd);
+ if (priv->buffer) {
+ XisbFree(priv->buffer);
+ priv->buffer = NULL;
+ }
+ xf86CloseSerial(local->fd);
+ }
+ RemoveEnabledDevice (local->fd);
+ local->fd = -1;
+ return (local);
+
+ SetupProc_fail:
+ if ((local) && (local->fd))
+ xf86CloseSerial (local->fd);
+
+ /* If it fails, the name will be printed
+ if ((local) && (local->name))
+ xfree (local->name);
+ */
+
+ if ((priv) && (priv->buffer))
+ XisbFree (priv->buffer);
+ if ((priv) && (priv->synpara))
+ xfree (priv->synpara);
+ if (priv)
+ xfree (priv);
+ return (local);
+}
+
+/*
+ * SynapticsCtrl --
+ * Alter the control parameters for the mouse. Note that all special
+ * protocol values are handled by dix.
+ */
+static void
+SynapticsCtrl(DeviceIntPtr device, PtrCtrl *ctrl)
+{
+ ErrorF("SynapticsCtrl called.\n");
+/*
+ pInfo = device->public.devicePrivate;
+ pMse = pInfo->private;
+
+ pMse->num = ctrl->num;
+ pMse->den = ctrl->den;
+ pMse->threshold = ctrl->threshold;
+*/
+}
+
+static Bool
+DeviceControl (DeviceIntPtr dev, int mode)
+{
+ Bool RetValue;
+
+ switch (mode)
+ {
+ case DEVICE_INIT:
+ DeviceInit(dev);
+ RetValue = Success;
+ break;
+ case DEVICE_ON:
+ RetValue = DeviceOn( dev );
+ break;
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ RetValue = DeviceOff( dev );
+ break;
+ default:
+ RetValue = BadValue;
+ }
+
+ return( RetValue );
+}
+
+static Bool
+DeviceOn (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ SynapticsPrivatePtr priv = (SynapticsPrivatePtr) (local->private);
+
+ ErrorF("Synaptics DeviceOn called\n");
+
+ local->fd = xf86OpenSerial(local->options);
+ if (local->fd == -1) {
+ xf86Msg(X_WARNING, "%s: cannot open input device\n", local->name);
+ return (!Success);
+ }
+
+ priv->buffer = XisbNew(local->fd, 64);
+ if (!priv->buffer) {
+ xf86CloseSerial(local->fd);
+ local->fd = -1;
+ return (!Success);
+ }
+
+ xf86FlushInput(local->fd);
+ xf86AddEnabledDevice (local);
+ dev->public.on = TRUE;
+ return (Success);
+}
+
+static Bool
+DeviceOff(DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ SynapticsPrivatePtr priv = (SynapticsPrivatePtr) (local->private);
+
+ ErrorF("Synaptics DeviceOff called\n");
+
+ if (local->fd != -1) {
+ xf86RemoveEnabledDevice (local);
+ if (priv->buffer) {
+ XisbFree(priv->buffer);
+ priv->buffer = NULL;
+ }
+ xf86CloseSerial(local->fd);
+ }
+
+ RemoveEnabledDevice (local->fd);
+ dev->public.on = FALSE;
+ return (Success);
+}
+
+static Bool
+DeviceInit(DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ unsigned char map[] = {0, 1, 2, 3, 4, 5};
+
+ ErrorF("Synaptics DeviceInit called\n");
+
+ dev->public.on = FALSE;
+
+ InitPointerDeviceStruct((DevicePtr)dev, map,
+ 5,
+ miPointerGetMotionEvents, SynapticsCtrl,
+ miPointerGetMotionBufferSize());
+
+ /* X valuator */
+ xf86InitValuatorAxisStruct(dev, 0, 0, -1, 1, 0, 1);
+ xf86InitValuatorDefaults(dev, 0);
+ /* Y valuator */
+ xf86InitValuatorAxisStruct(dev, 1, 0, -1, 1, 0, 1);
+ xf86InitValuatorDefaults(dev, 1);
+
+ xf86MotionHistoryAllocate(local);
+
+ return Success;
+}
+
+static int
+move_distance(int dx, int dy) {
+ return(xf86sqrt((dx * dx) + (dy * dy)));
+}
+
+static edge_type
+edge_detection( SynapticsPrivatePtr priv, int x, int y ) {
+
+ edge_type edge = 0;
+
+ if(x > priv->synpara->right_edge)
+ edge |= RIGHT_EDGE;
+ else if(x < priv->synpara->left_edge)
+ edge |= LEFT_EDGE;
+
+ if(y > priv->synpara->top_edge)
+ edge |= TOP_EDGE;
+ else if(y < priv->synpara->bottom_edge)
+ edge |= BOTTOM_EDGE;
+
+ return( edge );
+}
+
+static CARD32
+updownTimer(OsTimerPtr timer, CARD32 now, pointer arg)
+{
+ LocalDevicePtr local = (LocalDevicePtr) (arg);
+ SynapticsPrivatePtr priv = (SynapticsPrivatePtr) (local->private);
+ int sigstate, change, id;
+
+ sigstate = xf86BlockSIGIO ();
+
+ change = priv->repeatButtons;
+ while(change) {
+ id = ffs(change);
+ change &= ~(1 << (id - 1));
+ xf86PostButtonEvent(local->dev, FALSE, id, FALSE, 0, 0);
+ xf86PostButtonEvent(local->dev, FALSE, id, TRUE, 0, 0);
+ }
+
+ xf86UnblockSIGIO (sigstate);
+
+ priv->repeat_timer = TimerSet(priv->repeat_timer, 0, 100, updownTimer, local);
+
+ return 0;
+}
+
+
+#define MOVE_HIST(a) ((priv->count_packet_finger-(a))%SYNAPTICS_MOVE_HISTORY)
+
+static void
+ReadInput(LocalDevicePtr local)
+{
+ SynapticsPrivatePtr priv = (SynapticsPrivatePtr) (local->private);
+ SynapticsSHMPtr para = priv->synpara;
+ Bool finger;
+ int x, y, z, w, dist, dx, dy, buttons, id;
+ edge_type edge;
+ Bool left, mid, right, up, down;
+ double speed, integral;
+ int change;
+
+ /*
+ * set blocking to -1 on the first call because we know there is data to
+ * read. Xisb automatically clears it after one successful read so that
+ * succeeding reads are preceeded buy a select with a 0 timeout to prevent
+ * read from blocking indefinately.
+ */
+ XisbBlockDuration(priv->buffer, -1);
+ while(SynapticsGetPacket(local, priv) == Success)
+ {
+ /* process input data */
+ x = ((priv->protoBuf[3] & 0x10) << 8) |
+ ((priv->protoBuf[1] & 0x0f) << 8) |
+ priv->protoBuf[4];
+ y = ((priv->protoBuf[3] & 0x20) << 7) |
+ ((priv->protoBuf[1] & 0xf0) << 4) |
+ priv->protoBuf[5];
+ /* pressure */
+ z = priv->protoBuf[2];
+ w = ((priv->protoBuf[0] & 0x30) >> 2) |
+ ((priv->protoBuf[0] & 0x04) >> 1) |
+ ((priv->protoBuf[3] & 0x04) >> 2);
+
+ left = (priv->protoBuf[0] & 0x01) ? TRUE : FALSE;
+ mid = FALSE;
+ right = (priv->protoBuf[0] & 0x2) ? TRUE : FALSE;
+ up = ((priv->protoBuf[3] & 0x01) && !left) ? TRUE : FALSE;
+ down = ((priv->protoBuf[3] & 0x02) && !right) ? TRUE : FALSE;
+
+ edge = edge_detection(priv, x, y);
+
+ dx = dy = 0;
+
+ /* shared memory */
+ para->x = x;
+ para->y = y;
+
+ /* 3rd button emulation */
+ if(!left && !right) {
+ priv->count_button_delay = priv->count_packet;
+ priv->third_button = FALSE;
+ } else if(DIFF_TIME(priv->count_packet, priv->count_button_delay) < 6) {
+ left = right = FALSE;
+ } else if(DIFF_TIME(priv->count_packet, priv->count_button_delay) == 6) {
+ priv->third_button = left && right;
+ }
+ if(priv->third_button) {
+ mid = TRUE;
+ left = right = FALSE;
+ }
+
+ /* finger detection thru pressure an threshold */
+ finger = (((z > para->finger_high) && !priv->finger_flag) ||
+ ((z > para->finger_low) && priv->finger_flag));
+
+ /* tap and drag detection */
+ if(finger && !priv->finger_flag) { /* touched */
+ DBG(7, ErrorF("touched - x:%d, y:%d packet:%lu\n", x, y, priv->count_packet));
+ if(priv->tap) {
+ DBG(7, ErrorF("drag detected - tap time:%lu\n", priv->count_packet_tapping));
+ priv->drag = TRUE; /* drag gesture */
+ }
+ priv->touch_on.x = x;
+ priv->touch_on.y = y;
+ priv->touch_on.packet = priv->count_packet;
+ } else if(!finger && priv->finger_flag) { /* untouched */
+ DBG(7, ErrorF("untouched - x:%d, y:%d packet:%lu finger:%d\n",
+ x, y, priv->count_packet, priv->finger_count));
+ /* check if
+ 1. the tap is in tap_time
+ 2. the max movement is in tap_move or more than one finger are tapped */
+ if((DIFF_TIME(priv->count_packet, priv->touch_on.packet) < para->tap_time) &&
+ (((abs(x - priv->touch_on.x) < para->tap_move) &&
+ (abs(y - priv->touch_on.y) < para->tap_move)) ||
+ priv->finger_count)) {
+ if(priv->drag) {
+ DBG(7, ErrorF("double tapping detected\n"));
+ priv->doubletap = TRUE;
+ priv->tap = FALSE;
+ } else {
+ DBG(7, ErrorF("tapping detected @ "));
+ priv->count_packet_tapping = priv->count_packet;
+ priv->tap = TRUE;
+ if(priv->finger_count == 0) {
+ switch(edge) {
+ case RIGHT_TOP_EDGE:
+ DBG(7, ErrorF("right top edge\n"));
+ priv->tap_mid = TRUE;
+ break;
+ case RIGHT_BOTTOM_EDGE:
+ DBG(7, ErrorF("right bottom edge\n"));
+ priv->tap_right = TRUE;
+ break;
+ case LEFT_TOP_EDGE:
+ DBG(7, ErrorF("left top edge\n"));
+ break;
+ case LEFT_BOTTOM_EDGE:
+ DBG(7, ErrorF("left bottom edge\n"));
+ break;
+ default:
+ DBG(7, ErrorF("no edge\n"));
+ priv->tap_left = TRUE;
+ }
+ } else {
+ switch(priv->finger_count) {
+ case 2:
+ DBG(7, ErrorF("two finger tap\n"));
+ priv->tap_mid = TRUE;
+ break;
+ case 3:
+ DBG(7, ErrorF("three finger tap\n"));
+ priv->tap_right = TRUE;
+ break;
+ default:
+ DBG(7, ErrorF("one finger\n"));
+ priv->tap_left = TRUE;
+ }
+ }
+ }
+ } /* tap detection */
+ priv->drag = FALSE;
+ } /* finger lost */
+
+ /* detecting 2 and 3 fingers */
+ if(finger && (DIFF_TIME(priv->count_packet, priv->touch_on.packet) < para->tap_time)) {
+ if((w == 0) && (priv->finger_count == 0))
+ priv->finger_count = 2;
+ if(w == 1)
+ priv->finger_count = 3;
+ } else
+ priv->finger_count = 0;
+
+ /* reset tapping button flags */
+ if(!priv->tap && !priv->drag && !priv->doubletap) {
+ priv->tap_left = priv->tap_mid = priv->tap_right = FALSE;
+ }
+
+ /* tap processing */
+ if(priv->tap &&
+ (DIFF_TIME(priv->count_packet, priv->count_packet_tapping) < para->tap_time)) {
+ left = priv->tap_left;
+ mid = priv->tap_mid;
+ right = priv->tap_right;
+ } else {
+ priv->tap = FALSE;
+ }
+
+ /* drag processing */
+ if(priv->drag) {
+ left = priv->tap_left;
+ mid = priv->tap_mid;
+ right = priv->tap_right;
+ }
+
+ /* double tap processing */
+ if(priv->doubletap && !priv->finger_flag) {
+ left = priv->tap_left;
+ mid = priv->tap_mid;
+ right = priv->tap_right;
+ priv->doubletap = FALSE;
+ }
+
+ /* scroll detection */
+ if(finger && !priv->finger_flag) {
+ if(edge & RIGHT_EDGE) {
+ priv->vert_scroll_on = TRUE;
+ priv->scroll_y = y;
+ DBG(7, ErrorF("edge scroll detected on right edge\n"));
+ }
+ }
+ if(priv->vert_scroll_on && (!(edge & RIGHT_EDGE) || !finger)) {
+ DBG(7, ErrorF("edge scroll off\n"));
+ priv->vert_scroll_on = FALSE;
+ }
+
+ /* scroll processing */
+ if(priv->vert_scroll_on) {
+ dist = y - priv->scroll_y; /* + = up, - = down */
+ if(dist > para->scroll_dist_vert) {
+ up = TRUE;
+ priv->scroll_y += para->scroll_dist_vert;
+ }
+ else if(dist < (-1 * para->scroll_dist_vert)) {
+ down = TRUE;
+ priv->scroll_y -= para->scroll_dist_vert;
+ }
+ }
+
+ /* movement */
+ if(finger && !priv->vert_scroll_on && !priv->finger_count) {
+ if(priv->count_packet_finger > 3) { /* min. 3 packets */
+ dy = (1 *
+ (((priv->move_hist[MOVE_HIST(1)].y + priv->move_hist[MOVE_HIST(2)].y) / 2) -
+ ((y + priv->move_hist[MOVE_HIST(1)].y) / 2)));
+ dx = (-1 *
+ (((priv->move_hist[MOVE_HIST(1)].x + priv->move_hist[MOVE_HIST(2)].x) / 2) -
+ ((x + priv->move_hist[MOVE_HIST(1)].x) / 2)));
+
+ /* speed in depence of distance/packet */
+ dist = move_distance( dx, dy );
+ speed = dist * para->accl;
+ if(speed > para->max_speed)
+ speed = para->max_speed;
+ else if(speed < para->min_speed)
+ speed = para->min_speed;
+
+ /* save the fraction for adding to the next priv->count_packet */
+ priv->frac_x = xf86modf((dx * speed) + priv->frac_x, &integral);
+ dx = integral;
+ priv->frac_y = xf86modf((dy * speed) + priv->frac_y, &integral);
+ dy = integral;
+ }
+
+ priv->count_packet_finger++;
+ } else {
+ priv->count_packet_finger = 0;
+ }
+
+
+ buttons = ((left ? 0x01 : 0) |
+ (mid ? 0x02 : 0) |
+ (right ? 0x04 : 0) |
+ (up ? 0x08 : 0) |
+ (down ? 0x10 : 0));
+
+ priv->count_packet++;
+
+ /* Flags */
+ priv->finger_flag = finger;
+ priv->move_hist[MOVE_HIST(0)].y = y;
+ priv->move_hist[MOVE_HIST(0)].x = x;
+
+ /* repeat timer for up/down buttons */
+ /* when you press a button the packets will only send for a second, so
+ we have to use a timer for repeating */
+ if((up || down) && !priv->vert_scroll_on) {
+ if(!priv->repeat_timer) {
+ priv->repeatButtons = buttons & 0x18;
+ priv->repeat_timer = TimerSet(priv->repeat_timer,
+ 0, 200, updownTimer, local);
+ }
+ } else if(priv->repeat_timer) {
+ TimerFree(priv->repeat_timer);
+ priv->repeat_timer = NULL;
+ priv->repeatButtons = 0;
+ }
+
+ /* Post events */
+ if(dx || dy)
+ xf86PostMotionEvent(local->dev, 0, 0, 2, dx, dy);
+
+ change = buttons ^ priv->lastButtons;
+ while(change) {
+ id = ffs(change);
+ change &= ~(1 << (id - 1));
+ xf86PostButtonEvent(local->dev, FALSE, id, (buttons & (1 << (id - 1))), 0, 0);
+ }
+ priv->lastButtons = buttons;
+ }
+}
+
+static int
+ControlProc(LocalDevicePtr local, xDeviceCtl * control)
+{
+ ErrorF("Control Proc called\n");
+ return (Success);
+}
+
+static void
+CloseProc (LocalDevicePtr local)
+{
+ ErrorF("Close Proc called\n");
+}
+
+static int
+SwitchMode (ClientPtr client, DeviceIntPtr dev, int mode)
+{
+ ErrorF("SwitchMode called\n");
+ return (Success);
+}
+
+static Bool
+ConvertProc (LocalDevicePtr local,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int *x,
+ int *y)
+{
+ if(first != 0 || num != 2)
+ return FALSE;
+
+ *x = v0;
+ *y = v1;
+
+ return TRUE;
+}
+
+
+static Bool
+QueryHardware (LocalDevicePtr local)
+{
+ SynapticsPrivatePtr priv = (SynapticsPrivatePtr) local->private;
+ SynapticsSHMPtr para = priv->synpara;
+ int retries;
+
+ xf86Msg(X_INFO, "synaptics touchpad driver %s\n", VERSION);
+
+ /* is the synaptics touchpad active? */
+ priv->isSynaptics = QueryIsSynaptics(local->fd);
+
+ if((!priv->isSynaptics) && (!para->repeater || (priv->fifofd == -1))) {
+ xf86Msg(X_ERROR, "%s no synaptics touchpad detected and no repeater device\n",
+ local->name);
+ priv->isSynaptics = TRUE;
+ return(!Success);
+ }
+
+ if(!priv->isSynaptics) {
+ xf86Msg(X_PROBED, "%s no synaptics touchpad, data piped to repeater fifo\n", local->name);
+ synaptics_reset(local->fd);
+ SynapticsEnableDevice(local->fd);
+ return(Success);
+ }
+
+ xf86Msg(X_PROBED, "%s synaptics touchpad found\n", local->name);
+
+ retries = 3;
+ while((retries++ <= 3) && (synaptics_reset(local->fd) != Success))
+ xf86Msg(X_ERROR, "%s reset failed\n", local->name);
+
+ if(synaptics_identify(local->fd, &priv->identity) != Success)
+ return !Success;
+
+ if(synaptics_model_id(local->fd, &priv->model_id) != Success)
+ return !Success;
+
+ if(synaptics_capability(local->fd, &priv->capabilities) != Success)
+ return !Success;
+
+ if(synaptics_set_mode(local->fd, SYN_BIT_ABSOLUTE_MODE |
+ SYN_BIT_HIGH_RATE |
+ SYN_BIT_DISABLE_GESTURE |
+ SYN_BIT_W_MODE) != Success)
+ return !Success;
+
+ PrintIdent(priv);
+ return Success;
+}
+
+static Bool
+SynapticsGetPacket(LocalDevicePtr local, SynapticsPrivatePtr priv)
+{
+ int count = 0;
+ int c;
+ unsigned char *pBuf, u;
+
+ pBuf = priv->protoBuf;
+
+ while((c = XisbRead(priv->buffer)) >= 0) {
+ u = (unsigned char)c;
+
+ /* test if there is a reset sequence received */
+ if((c == 0x00) && (priv->lastByte == 0xAA)) {
+ if(xf86WaitForInput(local->fd, 50000) == 0 ) {
+ DBG(7, ErrorF("Reset received\n"));
+ QueryHardware(local);
+ } else
+ ErrorF("faked reset received\n");
+ }
+ priv->lastByte = u;
+
+ /* when there is no synaptics touchpad pipe the data to the repeater fifo */
+ if(!priv->isSynaptics) {
+ xf86write(priv->fifofd, &u, 1);
+ if(++count >= 3)
+ return(!Success);
+ continue;
+ }
+
+ /* to avoid endless loops */
+ if(count++ > 100) {
+ return (!Success);
+ }
+
+ pBuf[priv->protoBufTail++] = u;
+
+ /* check first byte */
+ if((priv->protoBufTail == 1) && ((u & 0xC8) != 0x80)) {
+ priv->inSync = FALSE;
+ priv->protoBufTail = 0;
+ DBG(4, ErrorF("Synaptics driver lost sync at 1st byte\n"));
+ continue;
+ }
+
+ /* check 4th byte */
+ if((priv->protoBufTail == 4) && ((u & 0xc8) != 0xc0)) {
+ priv->inSync = FALSE;
+ priv->protoBufTail = 0;
+ DBG(4, ErrorF("Synaptics driver lost sync at 4th byte\n"));
+ continue;
+ }
+
+ if(priv->protoBufTail >= 6) { /* Full packet received */
+ if(!priv->inSync) {
+ priv->inSync = TRUE;
+ DBG(4, ErrorF("Synaptics driver resynced.\n"));
+ }
+ priv->protoBufTail = 0;
+ return Success;
+ }
+ }
+
+ return !Success;
+}
+
+static void
+PrintIdent(SynapticsPrivatePtr priv) {
+
+ xf86Msg(X_PROBED, " Synaptics Touchpad, model: %d\n", SYN_ID_MODEL(priv->identity));
+ xf86Msg(X_PROBED, " Firware: %d.%d\n", SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity));
+
+ if(SYN_MODEL_ROT180(priv->model_id))
+ xf86Msg(X_PROBED, " 180 degree mounted touchpad\n");
+ if(SYN_MODEL_PORTRAIT(priv->model_id))
+ xf86Msg(X_PROBED, " portrait touchpad\n");
+ xf86Msg(X_PROBED, " Sensor: %d\n", SYN_MODEL_SENSOR(priv->model_id));
+ if(SYN_MODEL_NEWABS(priv->model_id))
+ xf86Msg(X_PROBED, " new absolute packet format\n");
+ if(SYN_MODEL_PEN(priv->model_id))
+ xf86Msg(X_PROBED, " pen detection\n");
+
+ if(SYN_CAP_EXTENDED(priv->capabilities)) {
+ xf86Msg(X_PROBED, " Touchpad has extended capabiliety bits\n");
+ if(SYN_CAP_FOUR_BUTTON(priv->capabilities))
+ xf86Msg(X_PROBED, " -> four buttons\n");
+ if(SYN_CAP_MULTIFINGER(priv->capabilities))
+ xf86Msg(X_PROBED, " -> multifinger detection\n");
+ if(SYN_CAP_PALMDETECT(priv->capabilities))
+ xf86Msg(X_PROBED, " -> palm detection\n");
+ }
+}
+
+/* vim:ts=2:sw=2:cindent:
+*/
diff --git a/synaptics.h b/synaptics.h
new file mode 100644
index 0000000..9a18ef0
--- /dev/null
+++ b/synaptics.h
@@ -0,0 +1,97 @@
+#ifndef _SAMPLE_H_
+#define _SAMPLE_H_
+
+/******************************************************************************
+ * Definitions
+ * structs, typedefs, #defines, enums
+ *****************************************************************************/
+#define SYNAPTICS_MOVE_HISTORY 5
+#define SHM_SYNAPTICS 23947
+
+typedef struct _SynapticsTapRec {
+ int x, y;
+ unsigned int packet;
+} SynapticsTapRec;
+
+typedef struct _SynapticsMoveHist {
+ int x, y;
+} SynapticsMoveHistRec;
+
+typedef struct _SynapticsSHM {
+ int x, y; /* actual x, y Coordinates */
+
+ unsigned long int model_id; /* Model-ID */
+ unsigned long int capabilities; /* Capabilities */
+ unsigned long int identity; /* Identification */
+ Bool isSynaptics; /* Synaptics touchpad aktiv */
+
+ /* Parameter data */
+ int left_edge, right_edge, top_edge, bottom_edge;
+ /* edge coordinates absolute */
+ int finger_low, finger_high; /* finger detection values in Z-values */
+ int tap_time, tap_move; /* max. tapping-time and movement in packets and coord. */
+ int scroll_dist_vert; /* Scrolling distance in absolute coordinates */
+ double min_speed, max_speed, accl; /* movement parameters */
+ char* repeater; /* Repeater on or off */
+} SynapticsSHM, *SynapticsSHMPtr;
+
+typedef struct _SynapticsPrivateRec
+{
+ /* shared memory pointer */
+ SynapticsSHMPtr synpara;
+
+ /* Data read from the touchpad */
+ unsigned long int model_id; /* Model-ID */
+ unsigned long int capabilities; /* Capabilities */
+ unsigned long int identity; /* Identification */
+ Bool isSynaptics; /* Synaptics touchpad aktiv */
+
+ /* Data for normal processing */
+ XISBuffer *buffer;
+ unsigned char protoBuf[6]; /* Buffer for Packet */
+ unsigned char lastByte; /* letztes gelesene byte */
+ Bool inSync; /* Packets in sync */
+ int protoBufTail;
+ int fifofd; /* fd for fifo */
+ SynapticsTapRec touch_on; /* data when the touchpad is touched */
+ SynapticsMoveHistRec move_hist[SYNAPTICS_MOVE_HISTORY];
+ /* movement history */
+ int scroll_y; /* last y-scroll position */
+ unsigned int count_packet_finger; /* packet counter with finger on the touchpad */
+ unsigned int count_packet; /* packet counter */
+ unsigned int count_packet_tapping; /* packet counter for tapping */
+ unsigned int count_button_delay; /* button delay for 3rd button emulation */
+ Bool finger_flag; /* previous finger */
+ Bool tap, drag, doubletap; /* feature flags */
+ Bool tap_left, tap_mid, tap_right; /* tapping buttons */
+ Bool vert_scroll_on; /* scrolling flag */
+ double frac_x, frac_y; /* absoulte -> relative fraction */
+ Bool third_button; /* emulated 3rd button */
+ OsTimerPtr repeat_timer; /* for up/down-button repeat */
+ int repeatButtons; /* buttons for repeat */
+ int lastButtons; /* last State of the buttons */
+ int finger_count; /* tap counter for fingers */
+}
+SynapticsPrivateRec, *SynapticsPrivatePtr;
+
+
+static Bool DeviceControl(DeviceIntPtr, int);
+static void ReadInput(LocalDevicePtr);
+static int ControlProc(LocalDevicePtr, xDeviceCtl*);
+static void CloseProc(LocalDevicePtr);
+static int SwitchMode(ClientPtr, DeviceIntPtr, int);
+static Bool ConvertProc(LocalDevicePtr, int, int, int, int, int, int, int, int, int*, int*);
+static Bool QueryHardware(LocalDevicePtr);
+static Bool DeviceInit(DeviceIntPtr);
+static Bool DeviceOn(DeviceIntPtr);
+static Bool DeviceOff(DeviceIntPtr);
+static Bool DeviceInit(DeviceIntPtr);
+static Bool SynapticsGetPacket(LocalDevicePtr, SynapticsPrivatePtr);
+static void PrintIdent(SynapticsPrivatePtr);
+/*
+ * DO NOT PUT ANYTHING AFTER THIS ENDIF
+ */
+#endif
+/* vim:ts=4:sw=4:cindent:
+*/
+
diff --git a/synclient.c b/synclient.c
new file mode 100644
index 0000000..89e6def
--- /dev/null
+++ b/synclient.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <unistd.h>
+#define SHM_SYNAPTICS 23947
+typedef struct _SynapticsSHM {
+ int x, y;
+} SynapticsSHM;
+
+int main() {
+ SynapticsSHM *synshm;
+ int shmid;
+
+ if((shmid = shmget(SHM_SYNAPTICS, 0, 0)) == -1)
+ printf("shmget Fehler\n");
+ if((synshm = (SynapticsSHM*) shmat(shmid, NULL, 0)) == NULL)
+ printf("shmat Fehler\n");
+
+ while(1) {
+ printf("x:%d y:%d\n", synshm->x, synshm->y);
+ usleep(100000);
+ }
+
+ exit(0);
+}