diff options
86 files changed, 93 insertions, 43894 deletions
diff --git a/Makefile.am b/Makefile.am index 3d11a39..d2909a6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,5 +5,4 @@ noinst_SCRIPT = wrapitup x-includes: @sh mkxincludes -EXTRA_DIST = docs/docs.html GPL prebuilt/wacom_drv.o \ - docs/docs_files/null.gif docs/docs_files/sflogo.png +EXTRA_DIST = GPL prebuilt/wacom_drv.o diff --git a/bootstrap b/bootstrap deleted file mode 100755 index cb69525..0000000 --- a/bootstrap +++ /dev/null @@ -1,9 +0,0 @@ -#! /bin/sh - -aclocal -if test $? != 0; then exit; fi -libtoolize --force --copy -if test $? != 0; then exit; fi -automake --foreign --add-missing -if test $? != 0; then exit; fi -autoconf diff --git a/configure.in b/configure.in index aaf649d..c93f401 100644 --- a/configure.in +++ b/configure.in @@ -4,8 +4,6 @@ AM_INIT_AUTOMAKE([foreign]) AM_MAINTAINER_MODE AM_CONFIG_HEADER(src/include/xdrv-config.h) -AM_CONFIG_HEADER(src/include/kernel-config.h) -AM_CONFIG_HEADER(src/include/util-config.h) AC_PROG_CC AC_PROG_AWK diff --git a/docs/docs.html b/docs/docs.html deleted file mode 100644 index 4214b00..0000000 --- a/docs/docs.html +++ /dev/null @@ -1,4729 +0,0 @@ -<html><head> -<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> - -<title>The Linux Wacom Project</title> -<style><!-- - BODY { background: #FFFFFF; font: 10pt helvetica; color: black } - .motd { font:12pt helvetica; color: navy } - .allhead { font: bold 24pt helvetica; } - .allsub { font: bold 16pt helvetica; } - .tit { font: bold 24pt helvetica; color: navy } - .diff { background: #EEEEFF } - .nav { background: #EEEEEE } - DIV.copy { font: 8pt helvetica; color: gray } - TD.blkhead { font: bold 10pt helvetica; color: gray } - TD.blkbody { font: 10pt helvetica; color: black } - TD.head { background: #000000 } - .title { font: bold 16pt helvetica; color: white } - .menu { font: bold 8pt helvetica; color: white; background: #000066 } - A.menu { text-decoration: none } - A.menu:link { color: #FFFFFF } - A.menu:hover { color: #FFFF00 } - A.copy:link { color: gray } - A.copy:visited { color: gray } - /* Support /PRE scalability. For details, refer to */ - /* http://www.longren.org/2006/09/27/wrapping-text-inside-pre-tags */ - pre { - white-space: pre; /* CSS2 */ - white-space: pre-wrap; /* css 2.1 */ - white-space: pre-line; /* CSS3 (and 2.1 as well, actually) */ - white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ - white-space: -pre-wrap; /* Opera 4-6 */ - white-space: -o-pre-wrap; /* Opera 7 */ - word-wrap: break-word; /* IE 5.5+ */ - /* IE only to re-specify in addition to word-wrap */ - _white-space: pre; - width: 99%; - } ---></style> -</head><body topmargin="0" leftmargin="0" rightmargin="0" marginheight="0" marginwidth="0"> -<table border="0" cellpadding="0" cellspacing="0" width="100%"> -<tbody><tr><td class="head" align="center" valign="middle"> -<div class="title">The Linux Wacom Project </div> - -</td><td class="head" align="right" valign="middle" width="125"><a href="http://sourceforge.net/"><img src="docs_files/sflogo.png" alt="SourceForge.net Logo" border="0" height="37" width="125"></a></td></tr> -</tbody></table> -<table border="0" cellpadding="0" cellspacing="0" width="100%"> -<tbody><tr><td colspan="2" bgcolor="white"><img src="docs_files/null.gif" height="1" width="1"></td></tr> -<tr><td colspan="2" bgcolor="#000066"><img src="docs_files/null.gif" height="4" width="1"></td></tr> -<tr><td class="menu" align="center"> - <a class="menu" href="http://linuxwacom.sourceforge.net/index.php/main">Main</a> | - <a class="menu" href="http://linuxwacom.sourceforge.net/index.php/news">News</a> | - <a class="menu" href="http://linuxwacom.sourceforge.net/index.php/faq">FAQ</a> | - <a class="menu" href="http://linuxwacom.sourceforge.net/index.php/dl">Downloads</a> | - <a class="menu" href="http://linuxwacom.sourceforge.net/index.php/help">Help</a> | - <a class="menu" href="http://sourceforge.net/projects/linuxwacom">Development</a> | - <a class="menu" href="http://linuxwacom.sourceforge.net/index.php/toc">TOC</a> | - <a class="menu" href="http://linuxwacom.sourceforge.net/index.php/all">All</a> -</td><td class="menu" align="right">Apr 29, 2009</td></tr> -<tr><td colspan="2" bgcolor="#000066"><img src="docs_files/null.gif" height="4" width="1"></td></tr> -<tr><td colspan="2" bgcolor="#aaaaaa"><img src="docs_files/null.gif" height="2" width="1"></td></tr> -</tbody></table> - -<br> - -<center><table border="0" width="80%"><tbody><tr><td> -<center><h1>Linux Wacom Project HOWTO</h1></center><br><center class="nav">Navigation: -<a href="http://linuxwacom.sourceforge.net/index.php/howto/main">MAIN</a> <a href="http://linuxwacom.sourceforge.net/index.php/howto/copy">NEXT</a> <a href="http://linuxwacom.sourceforge.net/index.php/howto/toc">INDEX</a> <a href="http://linuxwacom.sourceforge.net/index.php/howto/all"><b>ALL</b></a> </center><br><br> -<a name="copy"> -</a><center> -<a name="copy">Copyright (C) 2002-2009 - LinuxWacom<br> -<br> -Permission is granted to copy, distribute and/or modify this document<br> -under the terms of the GNU GENERAL PUBLIC LICENSE as published by the<br> -Free Software Foundation; either version 2 of the License, or <br> -(at your option) any later version. A copy of the license is <br> -included in the section entitled -</a><a href="#lic">GNU Free Documentation License</a>.<br> -</center> -<br> -<br> -<a name="intro"> -</a><h1><a name="intro">1.0 - Introduction</a></h1> -<p><a name="intro">This document began in November 2002 as a HOWTO for setting up a USB -Wacom Intuos2 on Redhat 8.0. It has since grown to cover all Wacom -tablets, USB and serial, running on various different Linux -distributions. As of December 2002, this project has transformed into -the Linux Wacom Project. Work on this -document is on-going so if you find an error, have a question, or have -something to add, please send an email to: -</a><a href="mailto:linuxwacom-discuss@lists.sf.net?subject=LinuxWacom">linuxwacom-discuss@lists.sf.net</a>.<a name="howto"> -</a></p><h2><a name="howto">1.1 - How To Use This Document</a></h2> -<p><a name="howto">In terms of document organization, if you have not figured it out already, -you can browse the document one page at a time, or you can click on the -</a><a href="http://linuxwacom.sourceforge.net/index.php/howto/all">ALL</a> link and view the entire -thing in one long page. - -</p><blockquote><div class="diff"> -Where the guide differs between distributions or packages, I have added a -comment which appears indented with a light blue background. -</div></blockquote> - -<p>Also, it bears mentioning since it's a detail often missed: there are -two drivers in the Linux Wacom Project- wacom.o and wacom_drv.o. The first -driver is the USB kernel driver. The second driver is the XFree86 Wacom -driver. Serial users need only be concerned with the wacom_drv.o driver. -USB users need both. If you try to use the wacom_drv.o driver in place of -the wacom.o kernel driver or visa-versa, things generally won't work. - -</p><p>Next, this document was written with the assumption that you are starting -from scratch with a relatively recent distribution of the Linux kernel. Also, -if you have already added lines to your XFree86/Xorg configuration file -(XF86Config/XF86Config-4 or xorg.conf), you should comment them out and -restart X. Since we'll be stepping through the entire process, we need X to -ignore the tablet until we're ready. Otherwise, X will just get in the way. - -</p><p>Finally, if you know what you're doing, you can leave your X settings -intact, print this out, switch to runlevel 3, and follow along from the -console. An HTML version of this document can be found in the docs directory at <a href="http://linuxwacom.cvs.sourceforge.net/linuxwacom/linuxwacom-dev/docs/">docs.html</a>. -<a name="theory"> -</a></p><h2><a name="theory">1.2 - Wacom Driver Theory of Operation</a></h2> -<p><a name="theory">Wacom tablets are available in serial and USB configurations. They are -also sold as embedded products in certain tablet PC's. I will cover all -three types, but the serial case is the most straightforward, -so we'll start there. - -<br><br> - -</a></p><p><a name="theory"><b>Serial Tablet Operation - The Short Story</b> - -</a></p><p><a name="theory">When a Wacom serial tablet is connected to a COM port, software can -interact with it directly by opening the appropriate device, usually -/dev/ttyS0. The XFree86 Wacom driver (wacom_drv.o) does precisely this, -and all stylus movements are converted into XInput events for programs -like the Gimp to turn into fluid brush strokes. - -</a></p><p><a name="theory">Wacom tablets are capable of handling a number of different data -protocols, and the Linux Wacom Project code currently utilitizes two, -Wacom Protocol IV and Protocol V. Each operates with a fixed-sized -packet, the length of which depends on the model and ROM version. - -</a></p><p><a name="theory">When the serial tablet is reset, it defaults to a standard baud rate, -often 9600 baud. From there, the device type can be queried, and if the -tablet supports it, the baud rate increased to a higher value. Additionally, -model parameters like tablet size can be queried directly to determine -which features are available. - -</a></p><p><a name="theory">Once configured, the tablet streams data back to the application as -tools are brought into and out of proximity, are pressed against the -tablet surface, or are tilted or inverted. - -<br><br> - -</a></p><p><a name="theory"><b>USB Tablet Operation - The Long Story</b> - -</a></p><p><a name="theory">Initially at least, the USB Wacom tablet is an HID compliant device, and when -first connected to the computer, will identify itself as such. -Unfortunately, this is not what you want because in this mode, you will not -get any of the fancy features. The hid-core.c, mousedev.c, and usbmouse.c kernel -drivers contain exceptions for the wacom; when the device is detected, they ignore -the tablet. In this way, the more sophisticated wacom driver has the -opportunity to assume control. - -</a></p><p><a name="theory">The first thing that the driver does is register itself with the USB -subsystem and wait for work to do. When the user plugs the device in, or -the device is first detected, the USB subsystem shops the vendor and -device identifier around, checking it against different drivers. The -wacom driver takes responsibility for the tablet and then notifies the -event system that it will be providing data. It then asks the tablet to -switch from HID-compliant mode to "mode 2", a wacom-specific protocol which -allows for values like pressure, Z rotation, -and tilt. As information arrives, the wacom driver dutifully converts -the data into real-world values and hands it on to the event system. - -</a></p><p><a name="theory">From here, any usermode application can get access to the event data -by opening /dev/input/event0. A stream of events including mouse movements, -clicks, and proximity updates can be read from the device. Similar to the -serial case, XFree86's Wacom driver (wacom_drv.o) has the ability to read -this device, and performs filtering on the data before convert the Linux -input events into XInput events. - -</a></p><p><a name="theory">By breaking the responsibility for the data into three distinct levels, -the kernel code remains simple and robust, the applications generalized, -and the fancy features commonly accessible to all GUI applications in the -X window system itself. This document walks down the entire data path from -the USB kernel driver to the gimp application. - -<br><br> -</a></p><p><a name="theory"><b>Embedded Device Operation - Tablet PC with Wacom Digitizer</b> - -</a></p><p><a name="theory">Refer to </a><a href="#tabletpc">Tablet PC</a> page for detail. - -<a name="starthere"> -</a></p><h1><a name="starthere">2.0 - Getting It Together</a></h1> -<p><a name="starthere">This section is devoted to preparing your system for the installation. -Every distribution handles kernel modules and file locations a bit differently, -so the goal here is to return everything to a known state. - -</a></p><p><a name="starthere">USB users will need to pay specific attention to discussions related to -kernel drivers and modules. Serial tablet users have it much easier, and -can bypass this. Both users will need to make changes to the XFree86/Xorg -configuration file. - -</a><a name="beforestart"> -</a></p><h2><a name="beforestart">2.1 - Before We Start</a></h2> -<p><a name="beforestart">From the beginning, let's make certain that we are on the -same page. First, if you have Wacom related lines in your -XF86Config/XF86Config-4 or xorg.conf files already, you should -comment them out or remove them. In particular, this includes InputDevice -sections with a driver set to "wacom" and their corresponding InputDevice -lines in ServerLayout. When that's done, restart X.<br> - -</a></p><p><a name="beforestart">It would be a wise idea at this time to check your XFree86 or Xorg log -file for references to wacom, wcm, or tablet. If X persists in trying to -interact with the tablet, things will only be problematic later. The log -file is often found at /var/log/XFree86.0.log or /var/log/Xorg.0.log. - -</a></p><p><a name="beforestart">To be prepared for the coming steps, it would be nice if you know what -X server and Linux kernel versions are running on your system. The <i>X -version</i> -command reveals those information for you. - -</a></p><p><a name="beforestart">If you have a USB tablet, you need to check Wacom kernel drvier first -</a><a href="#kernel">The USB Kernel Driver</a>. -Serial tablet or Tablet PC users can go directly to the next section -<a href="#download">Downloading the Code</a> page. -<a name="download"> -</a></p><h2><a name="download">2.2 - Downloading the Code</a></h2> - -<p><a name="download">The file </a><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.8.2-2.tar.bz2">linuxwacom-0.8.2-2.tar.bz2</a> is the stable package and contains -files that you will need to get your serial or USB tablet working. The -current beta package <a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.8.3-3.tar.bz2">linuxwacom-0.8.3-3.tar.bz2</a> is also available and may be -used by people who are willing to help test new features. I will never put a -beta package on this site that I am not running myself on my primary -development machine. So you can be certain that if there are any obvious -show stoppers, they will be fixed before you get to see them. - -</p><p>Unpacking the tarball is usually a one-step process, but I show both -steps in case the typical -jxf option doesn't work with tar. - -</p><blockquote><pre>[jej@ayukawa jej]$ bunzip2 linuxwacom-0.8.2-2.tar.bz2 -[jej@ayukawa jej]$ tar -xf linuxwacom-0.8.2-2.tar -[jej@ayukawa jej]$ cd linuxwacom-0.8.2-2</pre></blockquote> - -Once in the package directory, you need only to configure and build the code. -This is described in more detail as you continue. The executables and -wacom_drv.o are installed automatically; the kernel drivers have different -installation procedures depend on the kernel source you use. - -<p>If you are interested, the following tables contain the package contents -and release dates. Otherwise, let's continue. - - -</p><h3>Stable files included for linuxwacom-0.8.2-2:</h3> -<table border="0" cellspacing="5"> -<tbody><tr><th align="left">File</th><th align="left">Comment</th></tr> -<tr><td valign="top">configure</td><td valign="top">- configure script for distribution independent builds</td></tr> -<tr><td valign="top">prebuilt/install</td><td valign="top">- installer for the executables and Wacom X driver to a system identical to the development system.</td></tr> -<tr><td valign="top">prebuilt/uninstall</td><td valign="top">- unistaller for the executables</td></tr> -<tr><td valign="top">prebuilt/wacom.4x.gz</td><td valign="top">- man page for Wacom driver</td></tr> -<tr><td valign="top">prebuilt/32</td><td valign="top">- Wacom X driver and its utility programs for XFree86 and X11R6/Xorg on x86 systems</td></tr> -<tr><td valign="top">prebuilt/64</td><td valign="top">- Wacom X driver and its utility programs for XFree86 and X11R6/Xorg on x86-64 systems</td></tr> -<tr><td valign="top">src/util/wacdump.c</td><td valign="top">- a simple program for displaying tablet event data directly using ncurses</td></tr> -<tr><td valign="top">src/util/xidump.c</td><td valign="top">- a diagnostic program for displaying XInput event data</td></tr> -<tr><td valign="top">src/util/wacscrn.c</td><td valign="top">- curses library for wacdump</td></tr> -<tr><td valign="top">src/util/wactablet.c</td><td valign="top">- wacom tablet library for wacdump</td></tr> -<tr><td valign="top">src/util/wacusb.c</td><td valign="top">- wacom USB protocol library for wacdump</td></tr> -<tr><td valign="top">src/util/wacserial.c</td><td valign="top">- wacom serial protocol library for wacdump</td></tr> -<tr><td valign="top">src/util/wactablet.h</td><td valign="top">- wacom tablet library for wacdump</td></tr> -<tr><td valign="top">src/util/wacusb.h</td><td valign="top">- wacom USB protocol library for wacdump</td></tr> -<tr><td valign="top">src/util/wacserial.h</td><td valign="top">- wacom serial protocol library for wacdump</td></tr> -<tr><td valign="top">src/util/xsetwacom.c</td><td valign="top">- a command line configuration tool for Wacom X driver</td></tr> -<tr><td valign="top">src/util/wacomcfg.c</td><td valign="top">- configuration option library for xsetwacom</td></tr> -<tr><td valign="top">src/util/wcmAction.c</td><td valign="top">- keystroke and modifier encoding/decoding</td></tr> -<tr><td valign="top">src/util/wcmAction.h</td><td valign="top">- keystroke routine definitions</td></tr> -<tr><td valign="top">src/util/hal-setup-wacom.c</td><td valign="top">- a HAL service program for Wacom devices</td></tr> -<tr><td valign="top">src/util/10-linuxwacom.fdi</td><td valign="top">- a HAL script for Wacom devices</td></tr> -<tr><td valign="top">src/include/Xwacom.h</td><td valign="top">- configuration options for xsetwacom</td></tr> -<tr><td valign="top">src/2.6.x/wacom.c</td><td valign="top">- replacement kernel driver for kernel 2.6.x where x can be 9 and 10</td></tr> -<tr><td valign="top">src/2.6.x/wacom_sys.c</td><td valign="top">- wacom kernel driver specific to each major kernel release, where x can be 11 to 28</td></tr> -<tr><td valign="top">src/2.6.x/wacom_wac.c</td><td valign="top">- wacom kernel driver processes tablet specific information, where x can be 16 or 28</td></tr> -<tr><td valign="top">src/2.6.x/wacom.h</td><td valign="top">- wacom kernel driver header specific to each major kernel release, where x can be 11 to 28</td></tr> -<tr><td valign="top">src/2.6.16/wacom_wac.h</td><td valign="top">- part of wacom kernel driver header for tablet specific declaration and definitions </td></tr> -<tr><td valign="top">src/2.6.x/hid-core.c</td><td valign="top">- replacement kernel driver for kernel 2.6.x where x can be 8 to 16, use only if needed</td></tr> -<tr><td valign="top">src/xdrv/xf86Wacom.c</td><td valign="top">- source for wacom_drv.o; requires XFree86/Xorg build environment to compile. Binary available in prebuilt directory.</td></tr> -<tr><td valign="top">src/xdrv/xf86Wacom.h</td><td valign="top">- source for wacom_drv.o; requires XFree86/Xorg build environment to compile.</td></tr> -<tr><td valign="top">src/xdrv/wcmCommon.c</td><td valign="top">- source for wacom_drv.o; requires XFree86/Xorg build environment to compile. Common to USB and serial tablets</td></tr> -<tr><td valign="top">src/xdrv/wcmXCommand.c</td><td valign="top">- source for wacom_drv.o; requires XFree86/Xorg build environment to compile. APIs to xsetwacom.</td></tr> -<tr><td valign="top">src/xdrv/wcmCompat.c</td><td valign="top">- source for wacom_drv.o; requires XFree86/Xorg build environment to compile. XFree86 4.x support</td></tr> -<tr><td valign="top">src/xdrv/wcmConfig.c</td><td valign="top">- source for wacom_drv.o; requires XFree86/Xorg build environment to compile. Configuration setup</td></tr> -<tr><td valign="top">src/xdrv/wcmFilter.c</td><td valign="top">- source for wacom_drv.o; requires XFree86/Xorg build environment to compile. Raw data filters</td></tr> -<tr><td valign="top">src/xdrv/wcmFilter.h</td><td valign="top">- source for wacom_drv.o; requires XFree86/Xorg build environment to compile. Raw data filters</td></tr> -<tr><td valign="top">src/xdrv/wcmISDV4.c</td><td valign="top">- source for wacom_drv.o; requires XFree86/Xorg build environment to compile. General Tablet PC</td></tr> -<tr><td valign="top">src/xdrv/wcmSerial.c</td><td valign="top">- source for wacom_drv.o; requires XFree86/Xorg build environment to compile. Serial tablet support</td></tr> -<tr><td valign="top">src/xdrv/wcmSerial.h</td><td valign="top">- source for wacom_drv.o; requires XFree86/Xorg build environment to compile. Serial tablet support</td></tr> -<tr><td valign="top">src/xdrv/wcmUSB.c</td><td valign="top">- source for wacom_drv.o; requires XFree86/Xorg build environment to compile. USB tablet support</td></tr> -<tr><td valign="top">src/xdrv/wcmTilt2Rotation.c</td><td valign="top">- source for wacom_drv.o; requires XFree86/Xorg build environment to compile. Converting mouse tilt to rotation</td></tr> -<tr><td valign="top">src/wacomxi/wacomcpl-exec</td><td valign="top">- a graphic configuration tool for wacom XFree86 driver</td></tr> -<tr><td valign="top">src/wacomxi/wacomxi.c</td><td valign="top">- calibration library for xsetwacom</td></tr> -<tr><td valign="top">src/wacomxi/wacomxi.h</td><td valign="top">- calibration library for xsetwacom</td></tr> -<tr><td valign="top">GPL</td><td valign="top">- the GNU General Public License, in case you did not already have one lying around</td></tr> -</tbody></table> - -<h3>Stable Packages by Version and Date:</h3> -<table border="0" cellspacing="5"> -<tbody><tr><th align="left">File</th><th></th><th align="left">Date</th><th align="left">Comment</th></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.8.2-2.tar.bz2">linuxwacom-0.8.2-2.tar.bz2</a></td><td valign="top">-</td><td valign="top">2009-01-19</td><td valign="top">Support: USB Tablet PC with and without touch; kernels up to 2.6.28; Bamboo1 and Monarch; new wacomcpl features.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.8.0-3.tar.bz2">linuxwacom-0.8.0-3.tar.bz2</a></td><td valign="top">-</td><td valign="top">2008-05-23</td><td valign="top">Support: -kernels up to 2.6.25; Keystrokes for both buttons and expresskeys; New -tablets: Bamboo series and Cintiq 12WX & 20WSX, and so much more -that you can not afford to miss.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.7.8-3.tar.bz2">linuxwacom-0.7.8-3.tar.bz2</a></td><td valign="top">-</td><td valign="top">2007-08-15</td><td valign="top">Supports -new tablet, Bamboo. Provides prebuilt Wacom X driver and its utility -programs for x86_32 and x86_64 systems. Adds many new xsetwacom options.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.7.6-4.tar.bz2">linuxwacom-0.7.6-4.tar.bz2</a></td><td valign="top">-</td><td valign="top">2006-12-01</td><td valign="top">Updated xsetwacom and support kernel 2.6.17/18, Intuos3 4x6 and on-the-fly tablet rotation.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.7.4-3.tar.bz2">linuxwacom-0.7.4-3.tar.bz2</a></td><td valign="top">-</td><td valign="top">2006-06-19</td><td valign="top">Supports kernels 2.6.15/16, 2 new Intuos3 (12x12 and 12x19), and DTF 521.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.7.2.tar.bz2">linuxwacom-0.7.2.tar.bz2</a></td><td valign="top">-</td><td valign="top">2005-12-21</td><td valign="top">Updated configuration script and support kernel 2.6.13/14, Graphire4, PL710, DTF720, Intuos3 6x11 and Volito2 .</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.7.0-1.tar.bz2">linuxwacom-0.7.0-1.tar.bz2</a></td><td valign="top">-</td><td valign="top">2005-09-23</td><td valign="top">Updated wacomcpl and support 16 buttons for all tools.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.7.0-x86-64-1.tar.bz2">linuxwacom-0.7.0-x86-64-1.tar.bz2</a></td><td valign="top">-</td><td valign="top">2005-09-23</td><td valign="top">Updated wacomcpl and support 16 buttons for all tools.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.6.8.tar.bz2">linuxwacom-0.6.8.tar.bz2</a></td><td valign="top">-</td><td valign="top">2005-05-05</td><td valign="top">Support Cintiq 21UX and kernel 2.6.11.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.6.6.tar.bz2">linuxwacom-0.6.6.tar.bz2</a></td><td valign="top">-</td><td valign="top">2004-12-01</td><td valign="top">Build .ko locally and support kernel 2.6.10.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.6.4.tar.bz2">linuxwacom-0.6.4.tar.bz2</a></td><td valign="top">-</td><td valign="top">2004-08-06</td><td valign="top">Updated wacusb.c and fixed USB tablet protocol V dual input bug.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.6.3.tar.bz2">linuxwacom-0.6.3.tar.bz2</a></td><td valign="top">-</td><td valign="top">2004-05-25</td><td valign="top">Fixed tool on tablet and relative speed bugs.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.6.2.tar.bz2">linuxwacom-0.6.2.tar.bz2</a></td><td valign="top">-</td><td valign="top">2004-04-02</td><td valign="top">Fixed DoubleSpeed, DoubleRadius, and TwinView issues.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.6.1.tar.bz2">linuxwacom-0.6.1.tar.bz2</a></td><td valign="top">-</td><td valign="top">2004-03-02</td><td valign="top">added wacomcpl, support kernel 2.4.24 and 2.6.2/3</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.6.0.tar.bz2">linuxwacom-0.6.0.tar.bz2</a></td><td valign="top">-</td><td valign="top">2004-02-04</td><td valign="top">added wacomcpl, support kernel 2.4.22 and 2.6.0</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.4.1.tar.gz">linuxwacom-0.4.1.tar.gz</a></td><td valign="top">-</td><td valign="top">2003-03-22</td><td valign="top">added xidump, checks for ncurses</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.4.0.tar.gz">linuxwacom-0.4.0.tar.gz</a></td><td valign="top">-</td><td valign="top">2003-01-31</td><td valign="top">production release from 0.3.7-beta</td></tr> -</tbody></table> -<h3>Beta Packages by Version and Date:</h3> -<table border="0" cellspacing="5"> -<tbody><tr><th align="left">File</th><th></th><th align="left">Date</th><th align="left">Comment</th></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.8.3-3.tar.bz2">linuxwacom-0.8.3-3.tar.bz2</a></td><td valign="top">-</td><td valign="top">2009-04-27</td><td valign="top">Support Inutos4 tablets. Support kernel upto 2.6.29. Support Xorg 1.6. Updated multi-monitor suppport</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.8.1-6.tar.bz2">linuxwacom-0.8.1-6.tar.bz2</a></td><td valign="top">-</td><td valign="top">2008-10-24</td><td valign="top">Support USB Tablet PC with and without touch. Support kernel 2.6.27</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.7.9-11.tar.bz2">linuxwacom-0.7.9-11.tar.bz2</a></td><td valign="top">-</td><td valign="top">2008-04-11</td><td valign="top">Support -kernel 2.6.22 & 2.6.24. Temporary workaround for Xorg 7.3. Support -Bamboo series and Cintiq 12WX & 20WSX. Updated wacomcpl for -keystrokes. Support serial Tablet PC with touch.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.7.7-12.tar.bz2">linuxwacom-0.7.7-12.tar.bz2</a></td><td valign="top">-</td><td valign="top">2007-06-15</td><td valign="top">Support -Bamboo. Updated installer under prebuilt directory to install X driver -as well as its associated utilities. Support non-overlapped multi-areas -for same InputDevice. Support pad with button and keystroke events -through xsetwacom</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.7.5-4.tar.bz2">linuxwacom-0.7.5-4.tar.bz2</a></td><td valign="top">-</td><td valign="top">2006-09-29</td><td valign="top">Support kernel 2.6.17/18, Intuos3 4x6, and tablet detach/attach as well as rotation while X running. </td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.7.3-1.tar.bz2">linuxwacom-0.7.3-1.tar.bz2</a></td><td valign="top">-</td><td valign="top">2006-04-07</td><td valign="top">Support kernel 2.6.15/16, Intuos3 12x12 and 12x19. </td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.7.1-2.tar.bz2">linuxwacom-0.7.1-2.tar.bz2</a></td><td valign="top">-</td><td valign="top">2005-12-06</td><td valign="top">Support kernel 2.6.13/14, Graphire4, PL710, DTF720, Intuos3 6x11 and Volito2. </td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.6.9.tar.bz2">linuxwacom-0.6.9.tar.bz2</a></td><td valign="top">-</td><td valign="top">2005-08-08</td><td valign="top">Support tablet orentation rotation. </td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.6.9-x86-64.tar.bz2">linuxwacom-0.6.9-x86-64.tar.bz2</a></td><td valign="top">-</td><td valign="top">2005-08-08</td><td valign="top">Support x86-64 system. </td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.6.7.tar.bz2">linuxwacom-0.6.7.tar.bz2</a></td><td valign="top">-</td><td valign="top">2005-03-28</td><td valign="top">Added Cintiq 21UX and kernel 2.6.11 support. </td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.6.5.tar.bz2">linuxwacom-0.6.5.tar.bz2</a></td><td valign="top">-</td><td valign="top">2004-11-05</td><td valign="top">Added Intuos3 support. </td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.5.4-beta.tar.bz2">linuxwacom-0.5.4-beta.tar.bz2</a></td><td valign="top">-</td><td valign="top">2003-12-22</td><td valign="top">General Tablet PC support. 2.6.0 kernel support.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.5.3-beta.tar.gz">linuxwacom-0.5.3-beta.tar.gz</a></td><td valign="top">-</td><td valign="top">2003-11-12</td><td valign="top">Added wacomcpl utility. 2.4.22 kernel support. TwinView support.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.5.2-beta.tar.gz">linuxwacom-0.5.2-beta.tar.gz</a></td><td valign="top">-</td><td valign="top">2003-07-10</td><td valign="top">Fixed Intuos filter code. 2.5 kernel support. Minor bug fixes.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.5.1-beta.tar.gz">linuxwacom-0.5.1-beta.tar.gz</a></td><td valign="top">-</td><td valign="top">2003-06-15</td><td valign="top">Completely refactored data path, configurability.</td></tr> -<tr><td valign="top"><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.5.0-beta.tar.gz">linuxwacom-0.5.0-beta.tar.gz</a></td><td valign="top">-</td><td valign="top">2003-02-12</td><td valign="top">Updated PL code. Numerous tweaks.</td></tr> -</tbody></table> -<a name="root"> -</a><h2><a name="root">2.3 - The Root Account</a></h2> -<p><a name="root">If you are comfortable with the root account, paths, the /sbin directory, -and programs like <i>modprobe</i>, you can skip this section. This is largely -to clarify some things for people who are new to Linux and get tripped up -with the root account and paths. This is not meant to be a tutorial, so if -this is over your head, I would recommend reading a book on Linux command line -usage. All examples in this document assume the bash shell. - -</a></p><p><a name="root"> Many of the procedures in this document need root access, and the -commands that are executed are located in places on the system that are -not normally accessed by typical users. In order to run the <i>modprobe</i> -command, for instance, you must have root access. Additionally, if the -/sbin directory which contains <i>modprobe</i> does not appear in your -path, you must specify the full pathname, /sbin/modprobe, to run the command. -Here is an example of the problem, followed by solutions. - -</a></p><blockquote><pre><a name="root">[jej@ayukawa jej]$ modprobe foo -bash: modprobe: command not found -[jej@ayukawa jej]$ locate modprobe -/sbin/modprobe -[jej@ayukawa jej]$ echo $PATH -/bin:/usr/bin: ... :/home/jej/bin -</a></pre></blockquote> - -<a name="root">Normal users do not have /sbin in their path, so running <i>modprobe</i> -directly fails. Running the program using the full pathname (/sbin/modprobe) -will solve this, as will adding /sbin to the path. But there is another -problem, as we will see: - -</a><blockquote><pre><a name="root">[jej@ayukawa jej]$ /sbin/modprobe foo -foo.o: create_module: Operation not permitted -</a></pre></blockquote> - -<a name="root">Normal users are not allowed to run this command. For that, we need -to be root. The <i>su</i> command stands for "substitute user" since -it can be used to become <i>any</i> user on the system, but it is generally -known by the incorrect but very memorable mnemonic "superuser." - -</a><blockquote><pre><a name="root">[jej@ayukawa jej]$ su -Password: -[<b>root</b>@ayukawa jej]# whoami -root -</a></pre></blockquote> - -<p><a name="root">Note the change to the root account, and the additional change from -$ to # on the prompt. I maintain this convention in all the examples in -this document, so if you get an "access denied" error, check the prompt. -You probably need to be root. - -</a></p><p><a name="root">Now that we have root access, is /sbin in our path? No. We have only -been granted the privileges of root; we are not really in the root -account's environment. Most notably, the home directory ($HOME) changes, -but the path ($PATH) stays the same. Thus, becoming root is not sufficient to -run <i>modprobe</i> without the full pathname, but does solve the access -problem. - -</a></p><blockquote><pre><a name="root">[root@ayukawa jej]# modprobe foo -bash: modprobe: command not found -[root@ayukawa jej]# export PATH=$PATH:/sbin -[root@ayukawa jej]# modprobe foo -[root@ayukawa jej]# -</a></pre></blockquote> - -<p><a name="root">In this example, the user adds the /sbin directory to the path and can run -<i>modprobe</i> normally. <i>export</i> is a bash shell command that changes -aspects of your environment; in this case, /sbin is appended to the path. In -the highly unlikely event that you are using a different shell, which for -novice users seems unwise to me, you would need to use a different command. -Redhat, Mandrake, and similar distributions all use bash by default, so it is -unlikely that you would be using anything else. - -</a></p><p><a name="root">At any rate, changing the path is a reasonably good solution, if you can -remember the syntax of the <i>export</i> command. - -</a></p><p><a name="root">Another approach to this problem is to do more than just "be root," but to -run in the root account's environment. This is accomplished with the -"su -" command and provides you with root's normal path, including the /sbin -directory. The unfortunate side-effect is that you wind up in root's home -directory, requiring you to <i>cd</i> back to the original directory in -which you were working. - -</a></p><blockquote><pre><a name="root">[jej@ayukawa src]$ pwd -/home/jej/src/linuxwacom/src -[jej@ayukawa src]$ su - -[root@ayukawa root]# cd /home/jej/src/linuxwacom/src -[root@ayukawa src]# echo $PATH -/bin:<b>/sbin</b>:/usr/bin: ... :/root/bin -</a></pre></blockquote> - -<p><a name="root">Here, the user starts in the package's src directory, but upon invoking -"su -" is magically shuttled off to root's home directory. A quick -<i>cd</i> back to the package directory and all is better. And, as -demonstrated above, the path conveniently contains /sbin. - -</a></p><p><a name="root">So that leaves you with two immediate options, and one potential -long-term option: - -</a></p><p><a name="root">Option One: Become root and add /sbin to the path. - -</a></p><blockquote><pre><a name="root">[jej@ayukawa src]$ su -[jej@ayukawa src]# export PATH=$PATH:/sbin -</a></pre></blockquote> - -<a name="root">Option Two: Become root using root's environment and <i>cd</i> back. - -</a><blockquote><pre><a name="root">[jej@ayukawa src]$ su - -[root@ayukawa root]# cd /home/jej/src/linuxwacom/src -</a></pre></blockquote> - -<a name="root">Option Three (recommended): Add /sbin to your personal account's path - -</a><blockquote><pre><a name="root">[jej@ayukawa src]$ export PATH=$PATH:/sbin -[jej@ayukawa src]$ su -[root@ayukawa src]# echo $PATH -/bin:/usr/bin: ... :/home/jej/bin:<b>/sbin</b> -</a></pre></blockquote> - -<p><a name="root">By adding the path early in the session, it becomes available every time -you <i>su</i> to root later on. You could also add the <i>export</i> -command to the .bash_profile file in your home directory and have the -path set automatically when you log in. - -</a></p><p><a name="root">To exit from the root account and return to your normal account, you can -use the <i>exit</i> command or type Ctrl-D on an empty line. - -</a></p><blockquote><pre><a name="root">[root@ayukawa src]# exit -[jej@ayukawa src]$ -</a></pre></blockquote> - -<p><a name="root">If any of this is not explained clearly, drop me a line and let me know -where you got stuck. I'd be happy to clarify directly and update this page -for future readers. -</a><a name="install"> -</a></p><h2><a name="install">2.4 - Install from Prebuilt </a></h2> - -<p><a name="install">We have created 2 sets of prebuilt Wacom X driver and its utility programs under -linuxwacom-0.8.2-2/prebuilt; one for x86-32 systems, the other for x86-64 systems. - -</a></p><p><a name="install">If you don't plan to change anything in the driver, following steps will install the prebuilt files for you: - -</a></p><p><a name="install"><b>Note:</b> Please remove the existing linuxwacom package first if your system has one. - -</a></p><blockquote><pre><a name="install">[jej@ayukawa jej]$ cd linuxwacom-0.8.2-2/prebuilt -[jej@ayukawa prebuilt]$ su -[jej@ayukawa prebuilt]# ./uninstall -[jej@ayukawa prebuilt]# ./install -</a></pre></blockquote> - -<p><a name="install">Serial tablet (most Tablet PCs are serial) users can skip the rest -sections and go to </a><a href="#wacdump">Viewing Wacom Data (wacdump)</a> page for details on viewing the tablet output now. - -</p><p>If you use an older USB tablet and your running kernel was released 6 months later than -your tablet was first seen in market, you most probably can skip next section of this chapter -and the whole chapter 4 too. If you would like to make certain, continue to next section. -<a name="config"> -</a></p><h2><a name="config">2.5 - Configuring the Package</a></h2> - -<p><a name="config">This section describes how to configure the package. You can run -the configure script now as the samples below demonstrate, or later -when you reach the section of the document that explains what -specifically needs to be configured and why. This page is provided -largely as a reference. - -</a></p><p><a name="config">By default, xidump, wacdump, xsetwacom, wacom_drv.o, and wacomcpl -are built. Additional options include replacement of kernel drivers -for hid, mousedev, evdev, and usbmouse as well as building the -XFree86/Xorg driver from scratch. Lastly, remember that for every ---enable option, there is also an equivalent --disable option. - -</a></p><p><a name="config">The configuration options are listed on this page. You can also -see the online list by issuing <i>./configure -help</i> under -linuxwacom's base directory. - -</a></p><p><a name="config"><b>Note: </b> You should remove the existing linuxwacom package on -your system before installing the drivers and utilities from this project. - -</a></p><h3><a name="config">Building Kernel Modules - USB Only</a></h3> - -<p><a name="config">In order to build kernel modules, you will need the kernel source -installed on your system. If you are running on Redhat or Mandrake, -you can get it by installing the kernel-source RPM. - -</a></p><p><a name="config">The kernel source directory is assumed to be in /usr/src/linux-2.4, -/usr/src/linux, /usr/src/linux-2.6, /usr/src/linux-`uname -r`, or -/lib/modules/`uname -r`/source. If your kernel sources are elsewhere, -you will need to specify the directory with the --with-kernel option -described below. - -</a></p><p><a name="config">For older 2.6 kernels, you need to configure the kernel modules (wacom -and hid) under your kernel source directory before configuring linuxwacom. - -</a></p><p class="diff"><a name="config">Note, for kernel 2.6.18 and later, no need to build hid -any more. Refer to </a><a href="#testtablet">Testing Tablet Detection</a> to see if you need to build hid or not.</p> - -<h3>Module Versioning - USB Only</h3> - -<p>The script attempts to discover if the kernel is using module -versioning by detecting the presence of version numbers in the hid.o -module of the currently active kernel. Recent package versions also -check for hid.o.gz which exist on Mandrake systems. The configure -script may not be able to determine if kernel module versioning -should be enabled or not, in which case it will say "unknown, -assuming no." - -</p><p>If module versioning is disabled when it should be enabled, depmod -will complain about missing symbols but otherwise, things will probably -work fine. If it is enabled when it should be disabled, the code may -not compile, and it almost certainly will not load properly. If the -configure script fails to determine the correct value, the default -action of disabling module versioning is the better choice, and you can -allows enable it manually and rebuild if depmod complains. - -</p><h3>The XFree86/Xorg XInput Driver - USB and Serial</h3> - -<p>Generally, you will not need to build wacom_drv.o since it ships in -binary form in the prebuilt directory. There are prebuilt binaries for -XFree86 and Xorg corresponding to x86 and x86-64 systems, respectively. -If no one works for you, building from source may be your only option. -See the <a href="#builddrv">Building wacom_drv.o from Scratch</a> -page for more information. - -</p><h3>Library Dependencies - ncurses and XLib</h3> - -<p>Various utilities in the linuxwacom package require not only specific -libraries, but their development header files as well. The ncurses -package is one such example. Most distributions install the ncurses -libraries by default, but the header files are often located in a -separate package. You will need both. On Redhat 8.0, they can be -found in the ncurses-devel RPM. - -</p><p>Similarly, if you wish to test your tablet using xidump to view -XFree86/Xorg input events, you will need the XFree86/Xorg development -headers. On Redhat/Fedore Core, they are contained in the XFree86-devel/xorg-sdk package. - -</p><p>If any packages are missing, the configuration will warn you and -disable building any programs that depend on them. - -</p><h3>Processor Type</h3> - -<p>The processor type is determined by the script and used to build the -kernel modules. If it guesses incorrectly, or you would prefer a -different setting, use the --with-arch option described below. - -</p><h3>Linux Specific Features</h3> - -<p>The Linux wacom driver uses the Linux input subsystem, as does the -USB portions of the XFree86/Xorg driver. Consequently, if you are -building on a non-Linux system, the USB code will not work for you. -This is detected, and a comment to that effect is added to the -configuration summary. I recognize that FreeBSD and similar systems -have USB support; however, until someone can bridge the gap between -the FreeBSD kernel and the XFree86/X.org driver, the problem is largely -unsolved. Contributions are of course welcome. The Linux-specific -features can be enabled/disabled using the --with-linux argument. - -</p><h3>Configuration Options</h3> - -The following options are provided as reference. Normally, you will -only need a few of these options. Some obscure systems or you want to -build a driver for another platform may need all of them. Each section -of the document identifies which options are needed and when.<br><br> - -<table border="0" cellspacing="5"> -<tbody><tr><th align="left">Option</th><th align="left">Default</th> - <th align="left">Builds</th></tr> -<tr><td>--enable-wacom</td><td><b>no</b></td> - <td>wacom.o kernel driver</td></tr> -<tr><td>--enable-wacdump</td><td><b>yes</b></td> - <td>wacdump LinuxInput event monitor</td></tr> -<tr><td>--enable-xidump</td><td><b>yes</b></td> - <td>xidump XInput event monitor</td></tr> -<tr><td>--enable-libwacomcfg</td><td><b>yes</b></td> - <td>libwacomcfg Dynamic library for xsetwacom</td></tr> -<tr><td>--enable-libwacomxi</td><td><b>yes</b></td> - <td>libwacomxi Dynamic library for wacomcpl</td></tr> -<tr><td>--enable-xsetwacom</td><td><b>yes</b></td> - <td>xsetwacom XFree86 wacom driver configuration - comannd</td></tr> -<tr><td>--enable-quirk-tablet-rescale</td><td>best guess</td> - <td>Enable tablet to screen rescale code. <b> Note: </b> - If you have TwinView setup running on a X server 1.4 and later, - and your mappping doesn't properly, enable this option may - resolve the issue.</td></tr> -<tr><td>--enable-quirk-Uninit-called</td><td>best guess</td> - <td>Enable Uninit called</td></tr> -<tr><td>--enable-hid</td><td>no</td> - <td>hid.o replacement kernel driver (not normally - needed)</td></tr> -<tr><td>--enable-usbmouse</td><td>no</td> - <td>usbmouse.o replacement kernel driver (not - normally needed)</td></tr> -<tr><td>--enable-evdev</td><td>no</td> - <td>evdev.o replacement kernel driver (not - normally needed)</td></tr> -<tr><td>--enable-mousedev</td><td>no</td> - <td>mousedev.o replacement kernel driver (not - normally needed)</td></tr> -<tr><td>--enable-wacomdrv</td><td><b>yes</b></td> - <td>wacom_drv.o XFree86/Xorg driver (binary is - available in prebuilt directory)</td></tr> -<tr><td>--enable-modver=yes|no</td><td>best guess</td> - <td>enables kernel module versioning; usually - guesses correctly, but can be enabled or - disabled if not</td></tr> -<tr><td>--with-kernel=dir</td><td>best guess</td> - <td>Specifies the kernel source directory if - configure cannot guess correctly.</td></tr> -<tr><td>--with-x-src=dir</td><td>best guess</td> - <td>Specifies the X driver build source - directory</td></tr> -<tr><td>--with-xorg-sdk=dir</td><td>best guess</td> - <td>Specifies the Xorg SDK directory</td></tr> -<tr><td>--with-tcl=dir</td><td>/usr</td> - <td>Specifies the tcl directory. The tcl's include - and lib directories should be under this directory. - If tcl.h is not in dir/include, it will be searched - under dir directly</td></tr> -<tr><td>--with-tk=dir</td><td>/usr</td> - <td>Specifies the tk directory. If tk is under the - same directory as tcl, this option can be - eliminated. Otherwise, the tk's include and lib - directories should be under this directory. If tk.h - is not in dir/include, it will be searched under - dir directly</td></tr> -<tr><td>--with-arch=arch</td><td>best guess</td> - <td>Specifies the architecture if configure guesses - incorrectly</td></tr> -<tr><td>--enable-xserver64=yes|no</td><td>best guess</td> - <td>enables 64-bit X server. You probably need to - define xlib directory by adding option - --with-xlib=xlib-dir so compiler can link with - the right Xlib.</td></tr> -<tr><td>--with-linux=yes|no</td><td>best guess</td> - <td>Specifies if compiled on a Linux system; USB - code is Linux specific</td></tr> -<tr><td>--with-xlib=yes|no</td><td>best guess</td> - <td>Specifies if building xlib-based programs; - xidump uses XInput headers</td></tr> -<tr><td>--enable-dlloader=yes|no</td><td>best guess</td> - <td>Enable dlloader build option and built - wacom_drv.so instead of wacom_drv.o</td></tr> -<tr><td>--with-xmoduledir=dir</td><td>best guess</td> - <td>Specify wacom_drv path explicitly. - Implies --enable-dlloader</td></tr> -</tbody></table> - -<h3>Configuration Samples</h3> - -<p>Here is a sample output of the script on a Fedora Core 5 system: - -</p><blockquote><pre>[jej@ayukawa linuxwacom]$ ./configure -checking for a BSD-compatible install... /usr/bin/install -c -checking whether build environment is sane... yes -... -checking for arch type... <b>i386-redhat-linux</b> -checking for kernel type... <b>Linux</b> -checking for linux-based kernel... <b>yes</b> -checking for kernel sources... <b>/lib/modules/2.6.20-1.2320.fc5/source</b> -checking for kernel module support... <b>yes</b> -checking for kernel module versioning... <b>yes</b> -checking for valid Xorg SDK... <b>ok</b> -checking for X... <b>libraries , headers</b> -... -checking for X lib directory... <b>found</b> -checking for tclsh... <b>/usr/bin/tclsh</b> -checking for tcl version... <b>8.4</b> -checking for tcl header files... <b>/usr/include/</b> -checking for tk header files... <b>found</b> -checking ncurses.h usability... <b>yes</b> -checking ncurses.h presence... <b>yes</b> -checking for ncurses.h... <b>yes</b> -... ----------------------------------------- - BUILD ENVIRONMENT: - architecture - i386-redhat-linux - linux kernel - yes 2.6.19 - module versioning - yes -DCONFIG_MODVERSIONS -DMODVERSIONS -include /lib/modules/2.6.20-1.2320.fc5/source/include/linux/modversions.h - kernel source - yes /lib/modules/2.6.20-1.2320.fc5/source - Xorg SDK - yes /usr/include/xorg - XSERVER64 - no - dlloader - yes - XLib - yes /usr/lib - TCL - yes /usr/include - TK - yes /usr/include - ncurses - yes - - BUILD OPTIONS: - wacom.o - no - wacdump - yes - xidump - yes - libwacomcfg - yes - libwacomxi - yes - xsetwacom - yes - hid.o - no - usbmouse.o - no - evdev.o - no - mousedev.o - no - input.o - no - tabletdev.o - no - wacom_drv.so - yes /usr/lib/xorg/modules/input - wacom_drv.o - no - wacom*_drv quirks - libc-wrapper key-events dixScreenOrigins ----------------------------------------- -</pre></blockquote> - -<p>If the configure script fails to find something that it is looking -for, it may disable some options that you previously enabled on the -command-line. If this happens, check the output for a warning like the -following: - -</p><blockquote><pre>checking for valid XFree86/X.org build environment... xf86Version.h missing -Tried /usr/programs/Xserver/hw/xfree86 and /usr/xc/programs/Xserver/hw/xfree86 -... -*** -*** WARNING: -*** Unable to compile wacom_drv.{o,so} -*** without Xorg SDK or XFree86 build environment -*** wacom_drv.o will not be built -*** -</pre></blockquote> - -<p>In this particular case, the X driver was enabled. The ---with-x-src option was not specified. And the configure can not find -the header file, xf86Version.h, under any of the predefined paths. -Without the build environment, the module cannot be compiled and was consequently disabled. - - -</p><p>The following sample command-line will build everything but wacdump -while disabling module versioning. It also has a user-specified kernel -source directory: - -</p><blockquote><pre>[jej@ayukawa linuxwacom]$ ./configure --enable-wacom \ - --enable-hid --enable-usbmouse --enable-evdev \ - --enable-moudedev --enable-input --disable-modver \ - --with-x-src=/usr/src/redhat/BUILD/XFree86-4.2.0 \ - --with-kernel=/home/jej/src/linux \ - --disable-wacdump --with-tcl=/usr/local/ActiveTcl -checking for a BSD-compatible install... /usr/bin/install -c -checking whether build environment is sane... yes -... -checking for processor type... i686 -checking for kernel module versioning... <b>yes</b> -checking for kernel sources... /usr/src/linux-2.4 -checking for valid XFree86 build environment... <b>ok</b> -... ----------------------------------------- - BUILD ENVIRONMENT: - architecture - i686 - linux kernel - yes 2.4 - module versioning - <b>no</b> - kernel source - <b>yes /home/jej/src/linux</b> - XFree86 - <b>yes /usr/src/redhat/BUILD/XFree86-4.2.0</b> - XLib - yes /usr/X11R6/lib - TCL - <b>yes /usr/local/ActiveTcl</b> - TK - <b>yes /usr/local/ActiveTcl</b> - ncurses - yes - - BUILD OPTIONS: - wacom.o - <b>yes</b> - wacdump - <b>no</b> - xidump - yes - libwacomcfg - yes - libwacomxi - yes - xsetwacom - yes - hid.o - <b>yes</b> - usbmouse.o - <b>yes</b> - evdev.o - <b>yes</b> - mousedev.o - <b>yes</b> - input.o - <b>yes</b> - tabletdev.o - no - wacom_drv.so - no - wacom_drv.o - <b>yes</b> - wacom*_drv quirks - libc-wrapper key-events ----------------------------------------- -</pre></blockquote> - -<p>Notice that the configure script guessed module versioning was -enabled by default, but was disabled by the command-line option ---disable-modver. Similarly, the wacdump program which is enabled -by default was also disabled. All the kernel modules and the -XFree86 wacom driver are enabled. - - -</p><p>Here is another sample from Red Hat Enterprise Linux ES v.4: - -</p><blockquote><pre>[jej@ayukawa linuxwacom-x86-64]$ ./configure \ - --enable-wacom --enable-hid \ - --with-xf86=/home/jej/Desktop/X11R6.8 \ - --with-tcl=/usr/local/ActiveTcl \ - <b>--enable-xserver64 \ - --with-xlib=/usr/X11R6/lib64 </b> -checking for a BSD-compatible install... /usr/bin/install -c -checking whether build environment is sane... yes -... -checking build system type... x86_64-redhat-linux-gnu -checking host system type... x86_64-redhat-linux-gnu -checking for ld used by g++... /usr/bin/ld -m elf_x86_64 -... - ----------------------------------------- - BUILD ENVIRONMENT: - architecture - <b>x86-64</b> - linux kernel - yes 2.6.9 - module versioning - yes -DCONFIG_MODVERSIONS -DMODVERSIONS -include /usr/src/linux/include/linux/modversions.h - kernel source - yes /usr/src/linux - XFree86 - yes /home/jej/Desktop/X11R6.8 - XSERVER64 - <b>yes</b> - XLib - <b>yes /usr/X11R6/lib64</b> - TCL - yes /usr/local/ActiveTcl - TK - yes /usr/local/ActiveTcl - ncurses - yes - - BUILD OPTIONS: - wacom.o - yes - wacdump - yes - xidump - yes - libwacomcfg - yes - libwacomxi - yes - xsetwacom - yes - hid.o - yes - usbmouse.o - no - evdev.o - no - mousedev.o - no - input.o - no - tabletdev.o - no - wacom_drv.so - no - wacom_drv.o - yes - wacom*_drv quirks - libc-wrapper key-events ----------------------------------------- -</pre></blockquote> - -<a name="kernel"> -</a><h1><a name="kernel">3.0 - The USB Kernel Driver</a></h1> -<p><a name="kernel">Serial tablet users rejoice: you can skip this entire section. Please -go to the </a><a href="#wacdump">Viewing Wacom Data (wacdump)</a> page for details on viewing the tablet output. -USB users stay put; we need to tweak your kernel. - -</p><p>Kernel modules must be recompiled for each new kernel so I can't -just provide binaries. By the time you read this, my present kernel -will be entirely out of date with yours. </p> - -<p>In any event, many new features are available in the latest drivers -from the Linux Wacom Project, so I wholly recommend using them over the -drivers provided by your standard distribution. Rest assured, continuous -efforts are being made to get these changes merged back into the Linux -kernel. However, the changes can normally only merged into the next -kernel release, instead of the current one. </p> - -<p>For those who don't like upgrading kernels, here is a safe statement: -if you are not using a newly released tablet model and you are running a -recently released kernel version, chances are that you don't need to -update your kernel driver from linuxwacom.</p> - -<p><b>Note:</b> If your system is running a 2.4 kernel and you don't have -any application required to run on kernel 2.4, upgrading to version 2.6 -(preferablely 2.6.18 or later) may save you the steps to update wacom -kernel related modules. </p> -<a name="testtablet"> -</a><h2><a name="testtablet">3.1 - Testing Tablet Detection</a></h2> - -<p><a name="testtablet">In this section we will determine which driver, if any, claims control -over the tablet. There are at least three drivers that are interested: <br> -1) (usb)hid.o which may think it is an HID device, <br> -2) usbmouse.o which may think it is an HID mouse (for kernel 2.4), and <br> -3) the wacom driver which should identify the tablet as its own. <br> - -</a></p><p><a name="testtablet">To see which driver is driving the tablet, issuing <i>more /proc/bus/usb/devices</i> -should list something similiar to the following: - -</a></p><blockquote><pre><a name="testtablet">[jej@ayukawa wacom]$more /proc/bus/usb/devices -T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 3 Spd=12 MxCh= 0 -D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 -P: <b>Vendor=056a ProdID=0042</b> Rev= 1.15 -S: Manufacturer=Tablet -S: Product=XD-0608-U -C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=140mA -I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=02 <b>Driver=wacom</b> -E: Ad=81(I) Atr=03(Int.) MxPS= 10 Ivl=5ms -</a></pre></blockquote> - -<p><a name="testtablet">where <b>Vendor=056a</b> indicates a Wacom device. <b>Driver=wacom</b> -means Wacom driver is in control of the tablet. If you see anything other -than <b>wacom</b> after <b>Driver=</b>, at least hid-core.c needs to be -updated. - -</a></p><p><a name="testtablet">On newer 2.6 systems, <i>more /proc/bus/input/devices</i> gives you - -</a></p><blockquote><pre><a name="testtablet">[jej@ayukawa wacom]$more /proc/bus/input/devices -I: Bus=0003 <b>Vendor=056a Product=0042</b> Version=1.15 -N: <b>Name="Wacom Intuos2 6x8"</b> -P: Phys=usb-0000:00:1d.1-2/input0 -H: Handlers=event3 -B: EV=1f -B: KEY=1cff 0 1f00ff 0 0 0 0 0 0 0 0 -B: REL=100 -B: ABS=f00017b -B: MSC=1 -</a></pre></blockquote> - -<p><a name="testtablet">where, again, <b>Vendor=056a</b> indicates a Wacom device. <b>Name="Wacom - Intuos2 6x8"</b> means an Intuos2 6x8 tablet reported to /dev/input/event3. -If there is no <b>Wacom</b> after <b>Name=</b>, you need to update wacom.c. - - -</a></p><p><a name="testtablet">On kernel 2.4 or older 2.6 systems, unplug then replug your tablet after -issuing <i>tail -f /var/log/messages</i>, you should see a flurry of activity. -The exact output depends a lot on your particular kernel and distribution. - -</a></p><blockquote><pre><a name="testtablet">This is Redhat 8.0 (2.4.18-17.8.0):<br> -[jej@ayukawa usb]# tail /var/log/messages -Apr 29 21:26:11 ayukawa kernel: hub.c: USB new device connect on bus2/2, assigned device number 2 -Apr 29 21:26:11 ayukawa kernel: <b>input0: Wacom Intuos2 12x12</b> on usb2:2.0 -Apr 29 21:26:11 ayukawakernel: <b>wacom.c: Setting tablet report for tablet data</b> -Apr 29 21:26:11 ayukawa kernel: <b>wacom.c: input1: Wacom Intuos2 12x12</b> on usb1:6.0 -Apr 29 21:26:14 ayukawa /etc/hotplug/usb.agent: Setup wacom hid for USB product <b>56a/44</b>/115 -Apr 29 21:26:14 ayukawa /etc/hotplug/usb.agent: Setup mousedev for USB product <b>56a/44</b>/115 -</a></pre> -<pre class="diff"><a name="testtablet">And here it is again on Redhat 7.2 (2.4.18-17.7.x):<br> -[jej@sasami root]# tail /var/log/messages -Apr 29 21:28:38 sasami kernel: hub.c: USB new device connect on bus1/1, assigned device number 2 -Apr 29 21:28:38 sasami kernel: <b>input0: Wacom Intuos2 12x12</b> on usb1:2.0 -Apr 29 21:28:39 sasami kernel: usb.c: registered new driver hiddev -Apr 29 21:28:39 sasami kernel: usb.c: registered new driver hid -Apr 29 21:28:39 sasami kernel: hid-core.c: v1.8.1 Andreas Gal, Vojtech Pavlik <vojtech@suse.cz> -Apr 29 21:28:39 sasami kernel: hid-core.c: USB HID support drivers -Apr 29 21:28:39 sasami kernel: mice: <b>PS/2 mouse</b> device common for all mice -</a></pre> -</blockquote> - -<p><a name="testtablet">If all went well like above, the USB device was successfully detected and -handled by the wacom driver. This presumably means that information like -pressure and tilt will be received on /dev/input/event0. You are ready to -configure the X driver </a><a href="#download">Downloading the Code</a>. - -</p><p>If instead you got any of the following lines in your log, the wacom -driver <i>did not get control</i>. Either hid or usbmouse did. - -</p><blockquote><pre> <b>input0,hiddev0: USB HID v1.00 Mouse [Tablet XD-1212-U]</b> on usb1:5.0 - <b>input0: Tablet XD-1212-U</b> on usb1:5.0 -<pre></pre></pre></blockquote> -<a name="newwacom"> -</a><h2><a name="newwacom">3.2 - Updated wacom.c</a></h2> -<p><a name="newwacom">The wacom kernel driver (wacom_wac.c and wacom_sys.c) that is available -in </a><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.8.2-2.tar.bz2">linuxwacom-0.8.2-2.tar.bz2</a> supports USB Tablet PC, Bamboo1 Medium, and -Monarch, which will be available in kernel version 2.6.28. - -</p><p>You can link Wacom USB tablet to "/dev/input/wacom". It can be done -by adding the following rules in /etc/udev/rules.d/60-wacom.rules. Some -distributions use a different number for the file name. Please look for -proper one with wacom under /etc/udev/rules.d. - -</p><p>Below are examples from Debian GNU/Linux distribution: - -</p><p><b>60-wacom.rules on systems using ATTRS</b> - -</p><p><b>1. </b>Systems with only one Wacom device - -</p><div class="diff"> -<blockquote><pre># udev rules for wacom tablets. - -KERNEL!="event[0-9]*", GOTO="wacom_end" - -# Multiple interface support for stylus and touch devices. -DRIVERS=="wacom", ATTRS{bInterfaceNumber}=="00", ENV{WACOM_TYPE}="stylus" -DRIVERS=="wacom", ATTRS{bInterfaceNumber}=="01", ENV{WACOM_TYPE}="touch" - -# Convenience links for the common case of a single tablet. We could do just this: -#ATTRS{idVendor}=="056a", SYMLINK+="input/wacom-$env{WACOM_TYPE}" -# but for legacy reasons, we keep the input/wacom link as the generic stylus device. -ATTRS{idVendor}=="056a", ENV{WACOM_TYPE}!="touch", SYMLINK+="input/wacom" -ATTRS{idVendor}=="056a", ENV{WACOM_TYPE}=="touch", SYMLINK+="input/wacom-touch" - -# Check and repossess the device if a module other than the wacom one -# is already bound to it. -ATTRS{idVendor}=="056a", ACTION=="add", RUN+="check_driver wacom $devpath $env{ID_BUS}" - -LABEL="wacom_end" - -</pre></blockquote> -</div> - -<p><b>2. </b>Systems with more than one Wacom devices - -</p><div class="diff"> -<blockquote><pre># udev rules for wacom tablets. -# These rules were compiled for the Debian GNU/Linux distribution, -# but others may, and indeed are encouraged to, use them also. -# -# Should you do so, PLEASE CO-ORDINATE ANY CHANGES OR ADDITIONS -# of new devices with Ron <ron@debian.org> so that we can try -# to present users with a standard set of device nodes -# which they can rely on across the board. - -KERNEL!="event[0-9]*", GOTO="wacom_end" - -# Port specific link for users of multiple tablets of the same type. -# The ID_PATH variable is set by the "path_id" script in an earlier rule file. -ATTRS{idVendor}=="056a", ENV{ID_PATH}=="?*", SYMLINK="input/by-path/$env{ID_PATH}-wacom" - -# Multiple interface support for stylus and touch devices. -DRIVERS=="wacom", ATTRS{bInterfaceNumber}=="00", ENV{WACOM_TYPE}="stylus" -DRIVERS=="wacom", ATTRS{bInterfaceNumber}=="01", ENV{WACOM_TYPE}="touch" - -# Type-named links for multiple tablets. If you want to use multiple -# tablets of the _same_ type, you will probably need to use the links -# from /dev/input/by-path to identify which is plugged into what usb -# port. For different tablet types though, just pick your links from -# the list below. -# -# We override SYMLINK for tabletpc devices because the by-path link -# is not required with such devices, there will only ever be one. -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0000", SYMLINK+="input/tablet-penpartner" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0003", SYMLINK+="input/tablet-cintiq_partner" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0010", SYMLINK+="input/tablet-graphire" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0011", SYMLINK+="input/tablet-graphire2-4x5" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0012", SYMLINK+="input/tablet-graphire2-5x7" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0013", SYMLINK+="input/tablet-graphire3" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0014", SYMLINK+="input/tablet-graphire3-6x8" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0015", SYMLINK+="input/tablet-graphire4-4x5" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0016", SYMLINK+="input/tablet-graphire4-6x8" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0017", SYMLINK+="input/tablet-bamboofun-4x5" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0018", SYMLINK+="input/tablet-bamboofun-6x8" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0019", SYMLINK+="input/tablet-bamboo1-medium" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0020", SYMLINK+="input/tablet-intuos-4x5" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0021", SYMLINK+="input/tablet-intuos-6x8" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0022", SYMLINK+="input/tablet-intuos-9x12" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0023", SYMLINK+="input/tablet-intuos-12x12" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0024", SYMLINK+="input/tablet-intuos-12x18" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0030", SYMLINK+="input/tablet-pl400" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0031", SYMLINK+="input/tablet-pl500" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0032", SYMLINK+="input/tablet-pl600" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0033", SYMLINK+="input/tablet-pl600sx" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0034", SYMLINK+="input/tablet-pl550" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0035", SYMLINK+="input/tablet-pl800" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0037", SYMLINK+="input/tablet-pl700" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0038", SYMLINK+="input/tablet-pl510" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0039", SYMLINK+="input/tablet-dtu710" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="003f", SYMLINK+="input/tablet-cintiq21ux" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0041", SYMLINK+="input/tablet-intuos2-4x5" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0042", SYMLINK+="input/tablet-intuos2-6x8" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0043", SYMLINK+="input/tablet-intuos2-9x12" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0044", SYMLINK+="input/tablet-intuos2-12x12" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0045", SYMLINK+="input/tablet-intuos2-12x18" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0047", SYMLINK+="input/tablet-intuos2-6x8a" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0060", SYMLINK+="input/tablet-volito" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0061", SYMLINK+="input/tablet-penstation2" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0062", SYMLINK+="input/tablet-volito2-4x5" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0063", SYMLINK+="input/tablet-volito2-2x3" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0064", SYMLINK+="input/tablet-penpartner2" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0065", SYMLINK+="input/tablet-bamboo" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0069", SYMLINK+="input/tablet-bamboo1" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0081", SYMLINK+="input/tablet-graphire_bt-6x8" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0090", SYMLINK="input/tablet-tpc90" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0093", SYMLINK="input/tablet-tpc93-$env{WACOM_TYPE}" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="009a", SYMLINK="input/tablet-tpc9a-$env{WACOM_TYPE}" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b0", SYMLINK+="input/tablet-intuos3-4x5" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b1", SYMLINK+="input/tablet-intuos3-6x8" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b2", SYMLINK+="input/tablet-intuos3-9x12" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b3", SYMLINK+="input/tablet-intuos3-12x12" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b4", SYMLINK+="input/tablet-intuos3-12x19" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b5", SYMLINK+="input/tablet-intuos3-6x11" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b7", SYMLINK+="input/tablet-intuos3-4x6" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b8", SYMLINK+="input/tablet-intuos4-4x6" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b9", SYMLINK+="input/tablet-intuos4-6x9" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00ba", SYMLINK+="input/tablet-intuos4-8x13" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00bb", SYMLINK+="input/tablet-intuos4-12x19" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00c0", SYMLINK+="input/tablet-dtf521" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00c4", SYMLINK+="input/tablet-dtf720" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00c5", SYMLINK+="input/tablet-cintiq20wsx" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00c6", SYMLINK+="input/tablet-cintiq12wx" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00c7", ENV{WACOM_TYPE}!="touch", SYMLINK+="input/tablet-dtu1931" - -# Convenience links for the common case of a single tablet. We could do just this: -#ATTRS{idVendor}=="056a", SYMLINK+="input/wacom-$env{WACOM_TYPE}" -# but for legacy reasons, we keep the input/wacom link as the generic stylus device. -ATTRS{idVendor}=="056a", ENV{WACOM_TYPE}!="touch", SYMLINK+="input/wacom" -ATTRS{idVendor}=="056a", ENV{WACOM_TYPE}=="touch", SYMLINK+="input/wacom-touch" - -# Check and repossess the device if a module other than the wacom one -# is already bound to it. -ATTRS{idVendor}=="056a", ACTION=="add", RUN+="check_driver wacom $devpath $env{ID_BUS}" - -LABEL="wacom_end" - - -</ron@debian.org></pre></blockquote> -</div> - -<p><b>60-wacom.rules on systems using SYSFS</b> - -</p><p><b>1. </b>Systems with only one Wacom device - -</p><div class="diff"> -<blockquote><pre># udev rules for wacom devices -# will create: -# /dev/input/wacom -# /dev/input/wacom-touch -BUS=="usb", KERNEL=="event*", SYSFS{bInterfaceNumber}=="00", ENV{WACOM_TYPE}="stylus" -BUS=="usb", KERNEL=="event*", SYSFS{bInterfaceNumber}=="01", ENV{WACOM_TYPE}="touch" - -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", ENV{WACOM_TYPE}!="touch", SYMLINK+="input/wacom" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", ENV{WACOM_TYPE}=="touch", SYMLINK+="input/wacom-touch" -</pre></blockquote> -</div> - -<p><b>2. </b>Systems with more than one Wacom devices - -</p><div class="diff"> -<blockquote><pre># udev rules for wacom devices -# will create: -# /dev/input/wacom -# /dev/input/wacom-tablets/<model> -# /dev/input/wacom-tablets/<model>-<device id=""> -# -# The last rule is intended for cases when you have more than one tablet -# of the same model. The id is usb port dependent. -# -BUS=="usb", KERNEL=="event*", SYSFS{bInterfaceNumber}=="00", ENV{WACOM_TYPE}="stylus" -BUS=="usb", KERNEL=="event*", SYSFS{bInterfaceNumber}=="01", ENV{WACOM_TYPE}="touch" - -# Type-named links for multiple tablets. If you want to use multiple -# tablets of the _same_ type, you will probably need to use the links -# from /dev/input/wacom-tablets to identify which is plugged into what usb -# port. For different tablet types though, just pick your links from -# the list below. -# -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0000", SYMLINK+="input/wacom-tablets/penpartner input/wacom-tablets/penpartner-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0010", SYMLINK+="input/wacom-tablets/graphire input/wacom-tablets/graphire-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0011", SYMLINK+="input/wacom-tablets/graphire2-4x5 input/wacom-tablets/graphire2-4x5-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0012", SYMLINK+="input/wacom-tablets/graphire2-5x7 input/wacom-tablets/graphire2-5x7-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0013", SYMLINK+="input/wacom-tablets/graphire3 input/wacom-tablets/graphire3-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0014", SYMLINK+="input/wacom-tablets/graphire3-6x8 input/wacom-tablets/graphire3-6x8-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0015", SYMLINK+="input/wacom-tablets/graphire4-4x5 input/wacom-tablets/graphire4-4x5-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0016", SYMLINK+="input/wacom-tablets/graphire4-6x8 input/wacom-tablets/graphire4-6x8-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0017", SYMLINK+="input/wacom-tablets/bamboofun-4x5 input/wacom-tablets/bamboofun-4x5-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0018", SYMLINK+="input/wacom-tablet/bamboofun-6x8 input/wacom-tablets/bamboofun-6x8" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0019", SYMLINK+="input/wacom-tablet/bamboo1-medium input/wacom-tablets/bamboo1-medium" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0060", SYMLINK+="input/wacom-tablets/volito input/wacom-tablets/volito-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0061", SYMLINK+="input/wacom-tablets/penstation2 input/wacom-tablets/penstation2-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0062", SYMLINK+="input/wacom-tablets/volito2-4x5 input/wacom-tablets/volito2-4x5-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0063", SYMLINK+="input/wacom-tablets/volito2-2x3 input/wacom-tablets/volito2-2x3-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0064", SYMLINK+="input/wacom-tablets/penpartner2 input/wacom-tablets/penpartner2-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0020", SYMLINK+="input/wacom-tablets/intuos-4x5 input/wacom-tablets/intuos-4x5-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0021", SYMLINK+="input/wacom-tablets/intuos-6x8 input/wacom-tablets/intuos-6x8-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0022", SYMLINK+="input/wacom-tablets/intuos-9x12 input/wacom-tablets/intuos-9x12-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0023", SYMLINK+="input/wacom-tablets/intuos-12x12 input/wacom-tablets/intuos-12x12-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0024", SYMLINK+="input/wacom-tablets/intuos-12x18 input/wacom-tablets/intuos-12x18-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0030", SYMLINK+="input/wacom-tablets/pl400 input/wacom-tablets/pl400-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0031", SYMLINK+="input/wacom-tablets/pl500 input/wacom-tablets/pl500-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0032", SYMLINK+="input/wacom-tablets/pl600 input/wacom-tablets/pl600-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0033", SYMLINK+="input/wacom-tablets/pl600sx input/wacom-tablets/pl600sx-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0034", SYMLINK+="input/wacom-tablets/pl550 input/wacom-tablets/pl550-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0035", SYMLINK+="input/wacom-tablets/pl800 input/wacom-tablets/pl800-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0037", SYMLINK+="input/wacom-tablets/pl700 input/wacom-tablets/pl700-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0038", SYMLINK+="input/wacom-tablets/pl510 input/wacom-tablets/pl510-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0039", SYMLINK+="input/wacom-tablets/dtu710 input/wacom-tablets/dtu710-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="00c0", SYMLINK+="input/wacom-tablets/dtf521 input/wacom-tablets/dtf521-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="00c4", SYMLINK+="input/wacom-tablets/dtf720 input/wacom-tablets/dtf720-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0003", SYMLINK+="input/wacom-tablets/cintiq_partner input/wacom-tablets/cintiq_partner-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0041", SYMLINK+="input/wacom-tablets/intuos2-4x5 input/wacom-tablets/intuos2-4x5-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0042", SYMLINK+="input/wacom-tablets/intuos2-6x8 input/wacom-tablets/intuos2-6x8-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0043", SYMLINK+="input/wacom-tablets/intuos2-9x12 input/wacom-tablets/intuos2-9x12-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0044", SYMLINK+="input/wacom-tablets/intuos2-12x12 input/wacom-tablets/intuos2-12x12-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0045", SYMLINK+="input/wacom-tablets/intuos2-12x18 input/wacom-tablets/intuos2-12x18-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="00b0", SYMLINK+="input/wacom-tablets/intuos3-4x5 input/wacom-tablets/intuos3-4x5-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="00b1", SYMLINK+="input/wacom-tablets/intuos3-6x8 input/wacom-tablets/intuos3-6x8-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="00b2", SYMLINK+="input/wacom-tablets/intuos3-9x12 input/wacom-tablets/intuos3-9x12-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="00b3", SYMLINK+="input/wacom-tablets/intuos3-12x12 input/wacom-tablets/intuos3-12x12-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="00b4", SYMLINK+="input/wacom-tablets/intuos3-12x19 input/wacom-tablets/intuos3-12x19-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="00b5", SYMLINK+="input/wacom-tablets/intuos3-6x11 input/wacom-tablets/intuos3-6x11-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="003f", SYMLINK+="input/wacom-tablets/cintiq21ux input/wacom-tablets/cintiq21ux-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0047", SYMLINK+="input/wacom-tablets/intuos2-6x8a input/wacom-tablets/intuos2-6x8-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="00b7", SYMLINK+="input/wacom-tablets/intuos3-4x6 input/wacom-tablets/intuos3-4x6-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="00b8", SYMLINK+="input/wacom-tablets/intuos4-4x6 input/wacom-tablets/intuos4-4x6-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="00b9", SYMLINK+="input/wacom-tablets/intuos4-6x9 input/wacom-tablets/intuos4-6x9-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="00ba", SYMLINK+="input/wacom-tablets/intuos4-8x13 input/wacom-tablets/intuos4-8x13-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="00bb", SYMLINK+="input/wacom-tablets/intuos4-12x19 input/wacom-tablets/intuos4-12x19-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0065", SYMLINK+="input/wacom-tablets/bamboo input/wacom-tablets/bamboo-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="00c6", SYMLINK+="input/wacom-tablets/cintiq12wx input/wacom-tablets/cintiq12wx-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="00c5", SYMLINK+="input/wacom-tablets/cintiq20wsx input/wacom-tablets/cintiq20wsx-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="00c7", ENV{WACOM_TYPE}!="touch", SYMLINK+="input/wacom-tablets/dtu1931 input/wacom-tablets/dtu1931-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0069", SYMLINK+="input/wacom-tablets/bamboo1 input/wacom-tablets/bamboo1-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0081", SYMLINK+="input/wacom-tablets/graphire_bt-6x8 input/wacom-tablets/graphire_bt-6x8-%b" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0090", SYMLINK="input/wacom-tablets/tpc90" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="0093", SYMLINK="input/wacom-tablets/tpc93-$env{WACOM_TYPE}" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", SYSFS{idProduct}=="009a", SYMLINK="input/wacom-tablets/tpc9a-$env{WACOM_TYPE}" - -# Convenience links for the common case of a single tablet. We could do just this: -#SYSFS{idVendor}=="056a", SYMLINK+="input/wacom-$env{WACOM_TYPE}" -# but for legacy reasons, we keep the input/wacom link as the generic stylus device. -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", ENV{WACOM_TYPE}!="touch", SYMLINK+="input/wacom" -BUS=="usb", KERNEL=="event*", SYSFS{idVendor}=="056a", ENV{WACOM_TYPE}=="touch", SYMLINK+="input/wacom-touch" - -</device></model></model></pre></blockquote> -</div> - - -<div class="diff"> -Newer Mandriva Linux (Mandriva 2007 Spring and later) has an application called -mousedrake which takes care of the setup and configuration of linuxwacom driver. -If you use Mandriva Linux and you see InputDevice sections for Wacom device in -your Xorg.conf, chances are your Wacom tablet is ready for you to draw. -</div> - -<a name="buildwacom6"> -</a><h2><a name="buildwacom6">3.3 - Building wacom.c</a></h2> - -<a name="buildwacom6">To build the wacom.ko kernel module, you need to configure wacom as a kernel -module under your kernel source tree first. The kernel sources are required -as described on the </a><a href="#config">configuration</a> page. - -<p>Then, you need to configure the package with --enable-wacom option. -Here's how the configuration should generally look: - -</p><blockquote><pre>[jej@ayukawa linuxwacom]$ ./configure --enable-wacom -... -checking for valid kernel source tree... <b>ok</b> -... ----------------------------------------- - BUILD ENVIRONMENT: - architecture - i686 - linux kernel - <b>yes 2.6.9</b> - module versioning - yes - kernel - <b>yes /usr/src/linux</b> - XFree86 - no - XLib - yes /usr/X11R6 - TCL - yes /usr - TK - yes /usr - ncurses - yes - GTK - 2.0.6 - - BUILD OPTIONS: - wacom.o - <b>yes</b> - wacdump - yes - xidump - yes - libwacomcfg - yes - libwacomxi - yes - xsetwacom - yes - hid.o - no - usbmouse.o - no - evdev.o - no - mousedev.o - no - input.o - no - tabletdev.o - no - wacom_drv.o - no ----------------------------------------- -</pre></blockquote> - -<p>As shown above, the kernel directory was detected and the wacom.o -module will be built. If the kernel option shows "no", you will need -to specify the --with-kernel option and the correct directory. - -</p><blockquote><div class="diff">For those who feel comfortable to -build everything from the source tree, please skip the make and install -steps below. Scroll down to the end of this page to see the steps with -light blue background. -</div></blockquote> - -<p>To build the driver, just run <i>make</i>. - -</p><p>If everything works properly, you'll see the following from the make: - -</p><blockquote><pre>[jej@ayukawa linuxwacom]$ make -... -Making all in 2.6.9 -make[3]: Entering directory `/home/jej/linuxwacom/src/2.6.9' - Building linuxwacom drivers for 2.6 kernel. -make -C /usr/src/linux M=/home/jej/linuxwacom/src/2.6.9 -make[4]: Entering directory `/home/jej/linux-2.6.9' - LD /home/jej/linuxwacom/src/2.6.9/built-in.o - CC [M] /home/jej/linuxwacom/src/2.6.9/wacom.o - Building modules, stage 2. - MODPOST - CC /home/jej/linuxwacom/src/2.6.9/wacom.mod.o - LD [M] /home/jej/linuxwacom/src/2.6.9/wacom.ko -make[4]: Leaving directory `/usr/src/linux' -make[3]: Leaving directory `/home/jej/linuxwacom/src/2.6.9' -... -</pre></blockquote> - -<p></p><div class="diff">This part is for those who want to manually -build the wacom kernel driver in source tree. If you already followed -the steps above, you can move on to next page. <p>Please backup wacom.c in your kernel tree first. Then copy wacom.c -(or wacom_wac.c, wacom_wac.h, wacom_sys.c, and wacom.h if defined) from -the related linuxwacom directory to the source tree (if 4 files were -copies, you need to add <b>wacom-objs := wacom_sys.o wacom_wac.o </b> -to the Makefile under your kernel source input directory) and rebuild -the kernel. An example for kernel 2.6.9 is as following: </p><blockquote><pre> - [jej@ayukawa linuxwacom]$ cp /usr/src/linux/drivers/usb/input/wacom.c /usr/src/linux/drivers/usb/input/wacom.c.2.6.9 - [jej@ayukawa linuxwacom]$ cp src/2.6.9/wacom.c /usr/src/linux/drivers/usb/input/ - [jej@ayukawa linuxwacom]$ cd /usr/src/linux - [jej@ayukawa linux]$ make - [jej@ayukawa linux]$ su - [jej@ayukawa linux]#make install - [jej@ayukawa linux]#make modules_install - [jej@ayukawa linux]#reboot - </pre></blockquote> - </div> -<a name="testwacom"> -</a><h2><a name="testwacom">3.4 - Testing If wacom.(k)o Will Load</a></h2> -<p><a name="testwacom">Before we install the wacom driver, we need to test that it will load -properly. We do this by loading the driver manually. We will also -</a><a href="#root">need to be root</a> to do this. - -</p><p>WARNING: there is a small chance that this will bomb your kernel, -so we run <i>sync</i> to write all the stale buffers to the disk. People -using ext3 have little to worry about, but it's always good to be prepared -for the worst. At the very least, save your work. - -</p><blockquote><pre>[root@ayukawa linuxwacom]# sync -</pre></blockquote> - -<p>From the package's associated kernel directory, we unload any previous modules and -load the new one. The following example is from a kernel 2.4.22 system. - -</p><pre class="diff"> -<p>For Kernel 2.6.x, replace wacom.o with wacom.ko where it is used. - -</p><p>Kernel 2.6.11 and 2.6.12 are in src/2.6.11. Kernels 2.6.15 and 2.6.17 are handled in src/2.6.16. -</p></pre> - -<blockquote><pre>[root@ayukawa linuxwacom]# cd src/2.4.22 -[root@ayukawa 2.4.22]# /sbin/rmmod wacom -[root@ayukawa 2.4.22]# /sbin/insmod ./wacom.o # for those about to rock, we salute you. -</pre></blockquote> - -<p>Well, if you did not bomb, then good. And if you did, well, sorry. So -far, we have not had any reports of this happening, so please send in yours. - -</p><p>Incidentally, if you run "/sbin/insmod wacom.o" and happen to be in the -wrong directory, the old driver reloads, sometimes without warning. I -therefore changed this to read "/sbin/insmod ./wacom.o" which seems to prevent -this from happening. To be certain, you can check the log file for the -correct version number. - -</p><blockquote><pre>[root@ayukawa src]# tail /var/log/messages -Apr 29 20:34:41 ayukawa kernel: usb.c: registered new driver wacom -Apr 29 20:34:41 ayukawa kernel: Reporting max 30480, 31680 -Apr 29 20:34:41 ayukawa kernel: wacom.c: Setting tablet report for tablet data -Apr 29 20:34:41 ayukawa kernel: input0: Wacom Intuos2 12x12 on usb2:3.0 -Apr 29 20:34:41 ayukawa kernel: wacom.c: <b>$1.43-0.8.2-2</b> Vojtech Pavlik <vojtech@suse.cz> -Apr 29 20:34:41 ayukawa kernel: wacom.c: USB Wacom Graphire and Wacom Intuos tablet driver - -</pre></blockquote> - -<p>The important detail is the version number. A version number like -"1.46" -is an original kernel version and not from the linuxwacom package. The -correct version should also have the -j#.# or -pc#.# portion as well. -This is to help differentiate between the stock kernel driver and those -available from the Linux Wacom Project. -</p><p>If you get errors inserting the module, then you may need to reconfigure -and build with module versioning disabled. If it loads without a hitch, -move on to the next part. -<a name="installwacom"> -</a></p><h2><a name="installwacom">3.5 - Installing wacom.(k)o</a></h2> - -<pre class="diff"><p><a name="installwacom">For Kernel 2.4.x, replace wacom.ko with wacom.o where it is used. -</a></p></pre> - -<p><a name="installwacom">To install or not to install, that is the question. -Since the driver is in memory, you can pretty much use it this way -throughout the rest of this document. Anywhere you see -"modprobe wacom", you'll instead need to "insmod ./wacom.ko". -You'll also need to be careful that you are in the package's src directory. -If you instead use the less-specific command "insmod wacom.ko" from a -directory other than the package's src directory, <i>insmod</i> will load -the driver from the kernel modules directory instead. The result is that -you'll be using the wrong driver. - -</a></p><p><a name="installwacom">Why would you not install the driver? Well, for one, you may be building -a driver against a wrong kernel source, and if the system crashes (you get -an Oops or things come unglued in other ways), it would be nice to reboot -and have the original drivers load instead. - -</a></p><p><a name="installwacom">When should I install the driver? When you're comfortable that the -driver will not crash your system. If you really know what you're doing, -just load the drivers manually like in the previous section </a><a href="#testwacom">Testing If wacom.(k)o Will Load</a>. - -</p><p class="diff">On some distributions, Mandriva (a.k.a Mandrake) included, the -wacom.ko driver that appears in the kernel modules directory appears to be -compressed. If you cannot find wacom.ko using the method below, try locating -wacom.ko.gz instead. People who encountered this problem were able to run -gzip on the module and copy that instead.</p> - -<p>Installing the driver requires knowing where it belongs. A little research -will help here. By using the <i>locate</i> command, you can find all copies -of the original driver on the computer.</p> - -<blockquote><pre>jej@ayukawa wacom]$ locate wacom.ko -/lib/modules/2.6.17-1.2157_FC5/kernel/drivers/usb/input/<b>wacom.ko</b> -/lib/modules/2.6.17-1.2174_FC5/kernel/drivers/usb/input/<b>wacom.ko</b> - -[jej@ayukawa wacom]$ uname -r -<b>2.6.17-1.2157_FC5</b> -</pre></blockquote> - -On this computer, there are two kernels installed. <i>uname</i> identifies -the currently active kernel as 2.6.17-1.2157_FC5. The correct driver to -replace is therefore at /lib/modules/2.6.17-1.2157_FC5/kernel/drivers/usb/input/wacom.ko. -You will need to be root to replace this file, and it is a very good idea to -make a backup copy. - -<blockquote><pre>[jej@ayukawa wacom]$ su - -[jej@ayukawa root]# cd /lib/modules/2.6.17-1.2157_FC5/kernel/drivers/usb/input -[jej@ayukawa usb]# cp <b>wacom.ko</b> /home/jej/linuxwacom/src/2.6.16/<b>wacom_old.ko</b> -[jej@ayukawa usb]# cp /home/jej/linuxwacom/src/2.6.16/<b>wacom.ko</b> <b>wacom.ko</b> -</pre></blockquote> - -Here, I've saved the original to wacom_old.ko and copied my new driver over it. -You should substitute directory names as appropriate. - -<p><b>NOTE: Don't leave the backup copy in the same directory as the -original.</b> <i>depmod</i> will treat both as valid drivers, regardless -of their names. Copy the original somewhere outside of the kernel module -directory to ensure that this does not happen. In at least one case, -the backup driver was loaded instead of the new one due to a curious -dependency issue. - -</p><p>Finally, it is always a good thing to update the module dependencies. -This is where you find out if the module was compiled without kernel module -versioning. The following command, even if it generates errors is relatively -benign. If it fails, then there is no harm done. It just means that you will -have to load modules in the correct order since the system will not be able to -guess for you. - -</p><blockquote><pre>[jej@ayukawa usb]# depmod -e -</pre></blockquote> - -<p>If you get no errors and no output, everything is fine, and the module was -compiled, linked, and installed properly. If you received unresolved symbols -like usb_set_idle or printk, then you need to reconfigure with module -versioning enabled and recompile. - - -</p><pre class="diff"><p>Here is an example from a 2.6.12 system on Mandriva. - -</p><blockquote><pre>jej@ayukawa wacom]$ locate wacom.ko.gz -/lib/modules/2.6.12-12mdksmp/kernel/drivers/usb/input/<b>wacom.ko.gz</b> -/lib/modules/2.6.12-12mdksmp/kernel/drivers/usb/input/<b>wacom.ko.gz</b> - -[jej@ayukawa wacom]$ uname -r -<b>2.6.12-12mdksmp</b> -</pre></blockquote> - - -</pre> -<a name="loadwacom"> -</a><h2><a name="loadwacom">3.6 - Loading the wacom Driver</a></h2> - -<pre class="diff"><p><a name="loadwacom">For Kernel 2.6.x, replace wacom.o with wacom.ko where it is used. -</a></p></pre> - -<p><a name="loadwacom">If you have installed the driver, now is the time to test whether it will -load when needed. If you have not installed it, but are instead using insmod, -substitute <i>insmod mydir/src/wacom.o</i> where you see -<i>modprobe wacom</i> below. It is important that you use the correct -wacom.o file, the one you just built, since insmod may load the old driver -if it cannot find the one you have specified. - -</a></p><blockquote><pre><a name="loadwacom">[jej@ayukawa usb]# rmmod wacom -[jej@ayukawa usb]# modprobe usb-uhci (or usb-ohci) -<span class="diff">[jej@ayukawa usb]# modprobe input</span> -<span class="diff">[jej@ayukawa usb]# modprobe mousedev</span> -[jej@ayukawa usb]# modprobe wacom (or insmod mydir/src/wacom.o) -[jej@ayukawa usb]# modprobe evdev -</a></pre></blockquote> - -<p><a name="loadwacom">Check the system log for status messages pertaining to the wacom. -Here's a copy of the messages from my version of the driver. - -</a></p><blockquote><pre><a name="loadwacom">[jej@ayukawa usb]# grep -i wacom /var/log/messages | tail -Apr 29 21:23:35 ayukawa kernel: usb.c: registered new driver wacom -Apr 29 21:23:35 ayukawa kernel: wacom.c: <b>v1.43-0.8.2-2</b> Vojtech Pavlik <vojtech@suse.cz> -Apr 29 21:23:35 ayukawa kernel: wacom.c: USB Wacom Graphire and Wacom Intuos tablet driver (MODIFIED) -</a></pre></blockquote> - -<p><a name="loadwacom">The original driver was version 1.43. This version number -is 1.43-0.8.2-2 so the correct driver was loaded.</a></p> -<a name="buildhid6"> -</a><h2><a name="buildhid6">3.7 - Building (usb)hid.ko</a></h2> - -<p><a name="buildhid6">In the </a><a href="http://prdownloads.sourceforge.net/linuxwacom/linuxwacom-0.8.2-2.tar.bz2">linuxwacom-0.8.2-2.tar.bz2</a> -file, you will find hid-core.c, which have special exceptions for -wacom. This file is not built by default, so you will need to -reconfigure the package and run make again. </p><p class="diff">Note, for kernel 2.6.18 and later, no need to build hid any more. For other kernels, refer to <a href="#testtablet">Testing Tablet Detection</a> to see if you need to build hid or not.</p> - -<p>You need to configure usbhid as a module under your kernel source tree before configuring linuxwacom. - -</p><p class="diff">On some distributions, Mandrake or Mandriva -included, the (usb)hid.ko driver that located in the kernel modules -directory appears to be compressed. You need to run gzip on the module -and copy (usb)hid.ko.gz instead.</p> - -<blockquote><pre>[jej@ayukawa wacom]$./configure --enable-hid --with-kernel=your-kernel-src-dir -... - BUILD OPTIONS: - hid.o - <b>yes</b> -... -</pre></blockquote> - -<p>Kernel 2.6.11 and 2.6.12 are in src/2.6.11. Kernels 2.6.16 and -2.6.17 are handled in src/2.6.16. Kernels 2.6.18/19/20/21/22 are in -src/2.6.18. All the other kernels are processed in its own src/2.6.x. -New 2.6 directories will be created when compatibility issue occurs. -</p><blockquote><div class="diff">For those who like to build everything from -the source tree, please skip the make and install steps below. Scroll down to the end of this -page to see the steps with light blue background. -</div></blockquote> - -<p>If everything works properly, you'll see the following from the make: - -</p><blockquote><pre>[jej@ayukawa linuxwacom]$ make -... -Making all in 2.6.9 -make[3]: Entering directory `/home/jej/linuxwacom/src/2.6.9' - Building linuxwacom drivers for 2.6 kernel. -make -C /usr/src/linux M=/home/jej/linuxwacom/src/2.6.9 -make[4]: Entering directory `/home/jej/linux-2.6.9' - LD /home/jej/linuxwacom/src/2.6.9/built-in.o - CC [M] /home/jej/linuxwacom/src/2.6.9/hid-core.o - CC [M] /home/jej/linuxwacom/src/2.6.9/hid-input.o - LD [M] /home/jej/linuxwacom/src/2.6.9/usbhid.o - Building modules, stage 2. - MODPOST - CC /home/jej/linuxwacom/src/2.6.9/usbhid.mod.o - LD [M] /home/jej/linuxwacom/src/2.6.9/usbhid.ko -make[4]: Leaving directory `/usr/src/linux' -... -</pre></blockquote> - -<p>Then, use the following steps to install the driver: - - -</p><blockquote><pre>[jej@ayukawa linuxwacom]$su -[jej@ayukawa linuxwacom]#cd src/2.6.9 -[jej@ayukawa 2.6.9]#cp usbhid.ko /lib/modules/<b>your-kernel-ver</b>/kernel/drivers/usb/input -[jej@ayukawa 2.6.9]#reboot -</pre></blockquote> - -<p></p><div class="diff">This part is for those who want to manually build the kernel drivers from source tree. -If you already followed the steps above, you can move on to next page. - -<p>Please backup your related kernel files first then copy the source from the related linuxwacom -directory to the source tree and rebuild the kernel. An example for kernel 2.6.9 is as following: - -</p><blockquote><pre>[jej@ayukawa linuxwacom]$ cp /usr/src/linux/drivers/usb/input/hid-core.c /usr/src/linux/drivers/usb/input/hid-core.c.2.6.9 -[jej@ayukawa linuxwacom]$ cp src/2.6.9/hid-core.c /usr/src/linux/drivers/usb/input/ -[jej@ayukawa linuxwacom]$ cd /usr/src/linux -[jej@ayukawa linux]$ make -[jej@ayukawa linux]$ su -[jej@ayukawa linux]# make install -[jej@ayukawa linux]# make modules_install -[jej@ayukawa linux]# reboot -</pre></blockquote> -</div> - -<a name="newtablet"> -</a><h2><a name="newtablet">3.8 - Unknown Tablet?</a></h2> -<a name="newtablet">To determine whether your device is listed in the driver, we need to determine -the device identifier. It can be discovered by issuing <i>more /proc/bus/usb/devices</i>: - -</a><blockquote><pre><a name="newtablet">[jej@ayukawa linuxwacom]# more /proc/bus/usb/devices -T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 3 Spd=12 MxCh= 0 -D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 -P: <b>Vendor=056a ProdID=0044</b> Rev= 1.15 -S: Manufacturer=Tablet -S: <b>Product=XD-1212-U</b> -C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=140mA -I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=02 Driver=wacom -E: Ad=81(I) Atr=03(Int.) MxPS= 10 Ivl=5ms -</a></pre></blockquote> - -<p><a name="newtablet">In this case, the tablet identifier is in Vendor=056a ProdID=<b>0044</b>. -The model (<b>Product=XD-1212-U</b>) is determined by ProdID; the Intuos2 12x12 is 0x44 for instance. - -</a></p><p><a name="newtablet">In the wacom.c (kernel 2.6.9/10) or wacom_wac.c (kernels 2.6.11 or later) file under linuxwacom/src/2.6.x, -you will find a table called "wacom_ids". Look for your device identifier. Only the identifiers listed are -handled by the wacom driver, so if it is missing, it needs to be added. Also look for routine usb_hid_configure() -in hid-core.c if you are running a kernel older than 2.6.18. At the beginning of the routine, we added the -following lines to let HID driver ignore all Wacom devices: - -</a></p><blockquote><pre><a name="newtablet"> /* ignore all Wacom devices */ - if (dev->descriptor.idVendor == USB_VENDOR_ID_WACOM) - return NULL; -</a></pre></blockquote> - -<p><a name="newtablet">If you've gotten this far, and still cannot get it to work, email me -with your device identifier and as much of an explanation of where things did and did not work as -described. I'll see what I can do about at least finding out why it did not work. Then we can -go on to solutions. - -</a></p><p><a name="newtablet">The next section assumes you have things working up to this point. - -</a><a name="viewdata"> -</a></p><h2><a name="viewdata">3.11 - Viewing the Raw Data (xxd)</a></h2> -<p><a name="viewdata">View the raw data from the tablet, by returning to the /dev/input -directory and streaming the data directly from the device. Be patient -here because this is where a lot of people are getting stuck. - -</a></p><blockquote><pre><a name="viewdata">[root@ayukawa usb]# cd /dev/input -[root@ayukawa input]# xxd event0 -0000000: e65d c33d 597d 0100 0100 4101 0100 0000 .].=Y}....A..... -0000010: e65d c33d 5c7d 0100 0400 0000 b701 2800 .].=\}........(. -0000020: e65d c33d d9bb 0100 0100 4101 0000 0000 .].=......A..... -0000030: e65d c33d dcbb 0100 0400 0000 b701 2800 .].=..........(. -(Ctrl-C) -</a></pre></blockquote> - -<p><a name="viewdata">First off, you have to move the mouse or tap the pen to get any output. -If the tablet is mapped to event0, a continuously data stream will be -displayed while you move the mouse or pen on the tablet. Second, you -might not get anything at all. Don't panic. This seems to happen -occasionally. If absolutely no output occurs, try event1 and event2. -<span class="diff">It is reported on Fedora Core 2 the event0 used for -kernel 2.4 is represented as event2 when switching to kernel 2.6.1-1.65.</span> - -If no output occurs on those ports, reload the drive: - -</a></p><blockquote><pre><a name="viewdata">[jej@sasami root]# /sbin/rmmod wacom -[jej@sasami root]# /sbin/modprobe wacom (or /sbin/insmod mydir/src/wacom.o) -[jej@sasami root]# tail /var/log/messages -Apr 29 17:31:31 sasami kernel: usb.c: deregistering driver wacom -Apr 29 17:31:34 sasami kernel: usb.c: registered new driver wacom -Apr 29 17:31:35 sasami kernel: input0: Wacom Intuos2 12x12 on usb1:2.0 -Apr 29 17:31:35 sasami kernel: wacom.c: v1.43-0.8.2-2 Vojtech Pavlik <vojtech@suse.cz> -</a></pre></blockquote> - -<p><a name="viewdata">The device driver and the tablet occassionally get out of -sync with the tablet thinking it's still in HID mode when in fact it -should be in "mode 2." By unloading and reloading the driver manually, -the initialization code has another opportunity to get it right. Try the -<i>xxd /dev/input/event0</i> again. This time, it -<i>should</i> work. If not, send me some email. - -</a></p><p><a name="viewdata">Incidentally, if you have a program running that is connected to -/dev/input/event0 (like X or wacdump for instance), it is possible that -the tablet will not reattach back to the same event. I have seen the -wacom reattach to /dev/input/event1 when unloading and reloading the -wacom driver with wacdump running for instance. So, try xxd on event1 -or event2 if event0 fails. - -</a></p><p><a name="viewdata">You should also try running <i>xxd</i> on /dev/input/mouse0. -You should get streams of data when the mouse and pen are moved -around the surface of the tablet. It is this device that X will -look at for mouse movement. Use Ctrl-C to exit xxd. -</a><a name="wacdump"> -</a></p><h1><a name="wacdump">4.0 - Viewing Wacom Data (wacdump)</a></h1> -<p><a name="wacdump">The wacdump program parses and displays raw data from the Linux event -subsystem or serial port. It is very handy for verifying that your -tablet works without having to hassle with X server. Generally, you -must be root to run it unless you've set the permissions on the -appropriate device such that you can read them. - -</a></p><p><a name="wacdump"><b>Running wacdump</b> - -</a></p><p><a name="wacdump">In the case of USB tablets, this program can run simultaneously with X, -but it's best if X has not been configured for the tablet yet. X will -not share the serial port with wacdump, so serial users should comment out the -wacom InputDevice sections from XF86Config (or xorg.conf) before -using. Alternatively, you could move your serial tablet to COM2 and -try /dev/ttyS1 instead. - -</a></p><p><a name="wacdump">The command line usage of wacdump is pretty simple: - -</a></p><blockquote><pre><a name="wacdump">Usage: wacdump [options] device -Options: - -h, --help - usage - -c, --class device_cls - use specified class (see below) - -f, --force device_name - use specified device (see below) - -l, --list - list all supported devices - -v, --verbose - increase log output; multiple OK - -V, --version - display version number - --logfile log_file - output log to file - -Example devices: - /dev/input/event0 - usb tablet device - /dev/ttyS0 - serial tablet on com1 - /dev/ttyUSB0 - serial tablet on USB adapter - -Supported device classes: - serial, usb -Supported device names: - serial: art, art2, dig, dig2, pp, gr, pl, int, int2, c100 - usb: pp, gr, gr2, int, int2, pl, vol -</a></pre></blockquote> - -<p><a name="wacdump">Older versions of wacdump assumed the device to be /dev/input/event0. -This is now deprecated. You should instead specify which device to use -on the command line directly. If you get an end-of-file error or the -device does not exist, then the wacom may be attached to a different event. -Serial users may experience a timeout error which indicates that either -the tablet is not responding or X server has it open. Access denied errors -probably indicate that -</a><a href="#root">you are not root</a>. -If you get different types of errors, let me know so we can get them -documented. - -</p><p>Serial users are advised that now is a good time to plug in your tablet, -if you haven't already. - -</p><p>Let's run wacdump. Here are some command line examples: - -</p><blockquote><pre>[jej@ayukawa src]$ ./wacdump /dev/input/event0 # typical USB tablet -[jej@ayukawa src]$ ./wacdump /dev/input/event1 # USB tablet on event1 -</pre></blockquote> - -<p>When you run wacdump, it will attempt to initialize and query the tablet. -For a number of reasons, it may not display anything immediately, but if you -place a mouse or pen near the surface, the screen should update. -You will then be presented with a screen similar to the following: - -</p><blockquote><pre>wacdump v0.4.0 -MODEL=Wacom Intuos2 12x12 ROM=1.1-5 -CLS=USB VNDR=Wacom DEV=Intuos2 SUB=XD-1212-U - -TOOLTYPE=NONE SERIAL=0x00000000 - IN_PROX=+00000 (+00000 .. +00000) BUTTON=+00000 (+00000 .. +00000) - POS_X=+00000 (+00000 .. +30480) POS_Y=+00000 (+00000 .. +31680) - ROT_Z=+00000 (-00900 .. +00899) DISTANCE=+00000 (+00000 .. +00015) -PRESSURE=+00000 (+00000 .. +01023) TILT_X=+00000 (+00000 .. +00127) - TILT_Y=+00000 (+00000 .. +00127) ABSWHEEL=+00000 (+00000 .. +01023) -RELWHEEL=+00000 (-00001 .. +00001) THROTTLE=+00000 (-01023 .. +01023) - - LEFT= MIDDLE= RIGHT= EXTRA= - SIDE= TOUCH= STYLUS= STYLUS2= -</pre></blockquote> - -<p>The top portion identifies the tablet, and unless you specifically -override the device type with the -f option, it should be auto-detected -from the tablet directly. In this case, the model is XD-1212-U, a USB -Intuos2 12x12. - -</p><p>The next section describes the dynamic attributes of the tablet, -including the current position of the pointer, the type of tool in proximity -to the surface, its pressure, and tilt. Some tablets (Protocol V tablets, -such as Intuos 1, 2, and 3 as well as Cintiq 21UX) provide serial numbers -for their tools. When a button is pressed, the button heading will change -to something like "STYLUS=DOWN". - -</p><p> Some tablet tools report wheel movements as single increments forward -and reverse, while others provide absolute positions. The 4D mouse has a -throttle instead of a wheel. All three cases are reported independently. - -</p><p>Different tablets will have different options. Here is the lowly -ArtPadII for comparison. - -</p><blockquote><pre>wacdump v0.4.0 -MODEL=Wacom ArtPadII 4x5 ROM=1.3-6 -CLS=Serial VNDR=Wacom DEV=ArtPadII SUB=KT-0405-R - -TOOLTYPE=NONE IN_PROX=+00000 (+00000 .. +00000) - BUTTON=+00000 (+00000 .. +00000) POS_X=+00000 (+00000 .. +06400) - POS_Y=+00000 (+00000 .. +04800) PRESSURE=+00000 (+00000 .. +00255) - - LEFT= MIDDLE= RIGHT= EXTRA= - SIDE= TOUCH= STYLUS= STYLUS2= -</pre></blockquote> - -<p>Notice that this tablet has no tilt, and the pressure range is -considerably reduced. This version of wacdump does not distinguish -between tablets with mice, so the left, right, and middle buttons are -present, even though the tablet itself has no mouse. -<a name="x11"> -</a></p><h1><a name="x11">5.0 - Configuring X11</a></h1> -<a name="x11">Two steps must be completed to get X to recognize your tablet. First, -you need to add some lines to XF86Config/xorg.conf to inform X of the tablet's -existence. Second, you need to update the XInput driver that pertains -to the tablet since the one that ships with XFree86/Xorg is not very functional. -Neither driver holds a candle to the windows driver though, so you'll -have to take what you get for the time being. Updates to the XFree86/Xorg driver -are available in the stable and beta releases on the -</a><a href="#download">Downloading the Code</a> page. -<a name="inputdev"> -</a><h2><a name="inputdev">5.1 - Adding the InputDevices</a></h2> - -<p><a name="inputdev">The X Window system identifies the stylus (tip and side switches -of your pen), eraser (the other end of your pen if it is clickable), -cursor (your Wacom mouse), and pad (buttons, strips and rings on -your tablet if your tablet has any) as XInput devices. Most settings, -such as stylus pressure level and system cursor movement mode can be -done in /etc/X11/XF86Config or /etc/X11/xorg.conf configuration -file before X server starts or live through command-line -</a><a href="#xsetwacom">xsetwacom</a> -or the simple GUI control panel <a href="#wacomcpl">wacomcpl</a> while Wacom driver is running. - -</p><p>However, adding the InputDevice sections to your XF86Config/ -xorg.conf file for Wacom devices is required. You should add these -devices to the <a href="#srvlayout">ServerLayout</a> section of your XF86Config/xorg.conf -file too. - -</p><p>We assume you are running Either XFree86 4.2 or later Or Xorg. -<span class="diff">On some distributions, this file is called XF86Config-4. -Notice that the serial and USB configurations are different, so only -include the appropriate lines. The default serial and USB devices are given. -For Tablet PCs, options "Device" and "ForceDevice" should be included. You -should also change the device (e.g. ttyS0) to the correct one for your -tablet. Tablet PC and Cintiq/PL/DTF models don't support cursor type. -</span> All the new driver options are listed in the manual page below. - - -</p><blockquote><pre>Section "InputDevice" - Driver "wacom" - Identifier "stylus" - <b>Option "Device" "/dev/ttyS0" # SERIAL ONLY</b> - <b>Option "Device" "/dev/input/event0" # USB ONLY</b> - Option "Type" "stylus" - <b>Option "USB" "on" # USB ONLY</b> - <b>Option "ForceDevice" "ISDV4" # Serial Tablet PC ONLY</b> -EndSection - -Section "InputDevice" - Driver "wacom" - Identifier "eraser" - <b>Option "Device" "/dev/ttyS0" # SERIAL ONLY</b> - <b>Option "Device" "/dev/input/event0" # USB ONLY</b> - Option "Type" "eraser" - <b>Option "USB" "on" # USB ONLY</b> - <b>Option "ForceDevice" "ISDV4" # Serial Tablet PC ONLY</b> -EndSection - -Section "InputDevice" - Driver "wacom" - Identifier "cursor" - <b>Option "Device" "/dev/ttyS0" # SERIAL ONLY</b> - <b>Option "Device" "/dev/input/event0" # USB ONLY</b> - Option "Type" "cursor" - <b>Option "USB" "on" # USB ONLY</b> - <b>Option "ForceDevice" "ISDV4" # Serial Tablet PC ONLY</b> -EndSection - -<b># This section is for Intuos3, CintiqV5, Graphire4, or Bamboo</b> -Section "InputDevice" - Driver "wacom" - Identifier "pad" - <b>Option "Device" "/dev/ttyS0" # SERIAL ONLY</b> - <b>Option "Device" "/dev/input/event0" # USB ONLY</b> - Option "Type" "pad" - <b>Option "USB" "on" # USB ONLY</b> -EndSection - -<b># This section is for the TabletPC that supports touch</b> -Section "InputDevice" - Driver "wacom" - Identifier "touch" - <b>Option "Device" "/dev/ttyS0" # SERIAL ONLY</b> - <b>Option "Device" "/dev/input/event0" # USB ONLY</b> - Option "Type" "touch" - <b>Option "ForceDevice" "ISDV4" # Serial Tablet PC ONLY</b> - <b>Option "USB" "on" # USB ONLY</b> -EndSection -</pre></blockquote> - -<p>The above four sections identify the stylus, eraser, cursor, touch, and pad devices -to XInput. Notice that all four reference the same device /dev/ttyS0 or -/dev/input/event0 depending on whether its a serial or USB tablet. - -</p><p>The configuration options listed by your system's man page may be way out of date. -Below is an updated wacom man page which will be installed by default when you issue -<i>make install</i>. </p> - -<blockquote><pre>WACOM(4) WACOM(4) - -NAME - wacom - Wacom input driver - -SYNOPSIS - Section "InputDevice" - Identifier "idevname" - Driver "wacom" - Option "Device" "devpath" - ... - EndSection - -DESCRIPTION - wacom is an X input driver for Wacom devices. - - The wacom driver functions as a pointer input device, and may be used - as the X server's core pointer. - -SUPPORTED HARDWARE - This driver supports the Wacom IV and Wacom V protocols. Serial tablets - only need this driver. USB tablet support is available on some Linux - platforms. USB tablets needs wacom Linux kernel driver being loaded - before this driver starts. Please check linuxwacom.sf.net for latest - updates of Wacom X and kernel drivers. - -CONFIGURATION DETAILS - Please refer to xorg.conf(5x) for general configuration details and for - options that can be used with all input drivers. This section only - covers configuration details specific to this driver. - - Multiple instances of the Wacom devices can cohabit. It can be useful - to define multiple devices with different active zones. Each device - supports the following entries: - - Option "Type" "stylus"|"eraser"|"cursor"|"touch"|"pad" - sets the type of tool the device represents. This option is - mandatory. The core options, such as "SendCoreEvents" or - "AlwaysCore", are unnecessary in Gimp if you don't need to - move system cursor outside of Gimp drawing area. "pad" is - for Intuos 3 and CintiqV5 ExpressKeys and menu strips, or - Graphire 4 and Bamboo tablet buttons and wheel/ring. It is - required for Intuos3, CintiqV5, Graphire 4, or Bamboo if - you want to use keystroke features. "pad" is reported as a - second tool in the driver. "touch" is for the tablet with - touch support. Right now only a few Tablet PCs have this - feature. - - Option "Device" "path" - sets the path to the special file which represents serial - line where the tablet is plugged. You have to specify it - for each subsection with the same value if you want to have - multiple devices with the same tablet. This option is - mandatory. - - Option "USB" "on" - tells the driver to dialog with the tablet the USB way. - This option is mandatory for USB tablets. - - Option "ForceDevice" "ISDV4" - tells the driver to dialog with the tablet the serial - Tablet PC way. It is a special Wacom IV protocol, called - ISDV4 protocol. This option is mandatory for serial Tablet - PCs only. - - Option "DeviceName" "name" - sets the name of the X device. - - Option "Suppress" "number" - sets the position increment under which not to transmit - coordinates. This entry must be specified only in the - first Wacom subsection if you have multiple devices for one - tablet. The default value is 2. If you don't specify this - entry or your value is less than the default vaule or - greater than 100, the default value will be used. To - disable suppression, the entry should be specified as 0. - When suppress is defined, an event will be sent only when - at least one of the following conditions is met: - - the change between the current X coordinate and the - previous one is greater than suppress; - - the change between the current Y coordinate and the - previous one is greater than suppress; - - the change between the current pressure and the previous - one is greater than suppress; - - the change between the current degree of rotation and - the previous one of the transducer is greater than suppress; - - the change between the current absolute wheel value and the - previous one is equal to or greater than suppress; - - the change between the current tilt value and the previous - one is equal to or greater than suppress (if tilt is - supported); - - relative wheel value has changed; - - button value has changed; - - proximity has changed. - - Option "Mode" "Relative"|"Absolute" - sets the mode of the device. The default value for stylus - and eraser is Absolute; cursor is Relative; pad mode is - decided according to its core option due to its nature of - not moving system cursor: Relative if it is a core device; - Absolute, otherwise. - - Option "TopX" "number" - X coordinate of the top corner of the active zone. - Default to 0. - - Option "TopY" "number" - Y coordinate of the top corner of the active zone. - Default to 0. - - Option "BottomX" "number" - X coordinate of the bottom corner of the active zone. - Default to width of the tablet. - - Option "BottomY" "number" - Y coordinate of the bottom corner of the active zone. - Default to height of the tablet. - - Option "ButtonsOnly" "on"|"off" - disables the device's motion events. Default to off. - - Option "ButtonM" "AC" - reports an action AC when button M is pressed, where M is - one of the device supported button numbers, it can be 1 to - 32. The default action reported to Xinput is mouse button M - click. To ignore the button click, i.e., to not report any - button click event to Xinput, use "0" or "button 0". - - Option "TPCButton" "on"|"off" - enables the stylus buttons as Tablet PC buttons, i.e., - reports stylus button event only when its tip is pressed. - Default to "on" for Tablet PCs; "off" for all other models. - - Option "Touch" "on"|"off" - enables the touch device for models that support touch - feature. Default to "on" for tablets with touch; "off" for - all other models. - - Option "Capacity" "number" - sets touch sensitivity level for capacitive touch device, - where number can be an integer from -1 to 5. Default is 3 - for capacitive tools and -1 for none capacitive tools. - - Option "Speed" "Rspeed" - sets the cursor's relative movement speed to Rspeed. The - default value is 1.0. A Rspeed greater than 1.0 will speed - up the cursor's relative movement. A Rspeed less than 1.0 - but greater than 0 will slow down the cursor's relative - movement. A Rspeed too close to 0 is not recommanded. - - Option "Twinview" "horizontal"|"vertical"|"leftof"|"aboveof"|"none" - sets the orientation of TwinView to map the tablet to one - screen and to be able to move the screen cursor from one - screen to the other when tool reaches the edge of the - tablet. The cursor can be constrained in a specific screen - if "ScreenNo" option is added. If you want to map the - tablet to the whole desktop, you should NOT add this - option. The default is "none". - - Option "TVResolution" "res1,res2" - specifies different resolutions for the two screens in - TwinView setup. For example, if the resolution of screen 1 - (res1) is 1024x768 and screen 2 (res2) is 1280x1024, the - option will be set to: - Option "TVResolution" "1024x768,1280x1024" - - This option is used only when TwinView option is not none. - It is unnecessary to add this option if your screens are - displaying in the same resolutions. - - Option "ScreenNo" "n" - In a multi-monitor environment, specifies the screen number - in which the cursor can move. - - Option "MMonitor" "on"|"off" - turns on/off across monitor movement on a non-TwinView - multi-monitor desktop. If you have specific tablet mappings, - i.e. TopX/Y or BottomX/Y were set, the mapping will be - applied before rotation. The default is "on". - - Option "Rotate" "CW"|"CCW"|"HALF"|"NONE" - rotates the tablet orientation counterclockwise (CCW) or - clockwise (CW) or 180 degrees (HALF). The default is "NONE". - - Option "PressCurve" "x1,y1,x2,y2" - sets pressure curve by control points x1, y1, x2, and y2. - Their values are in range from 0..100. The input for - - linear curve (default) is "0,0,100,100"; - slightly depressed curve (firmer) might be "5,0,100,95"; - slightly raised curve (softer) might be "0,5,95,100". - - Option "KeepShape" "on" - When this option is enabled, the active zone begins - according to TopX and TopY. The bottom corner is adjusted - to keep the ratio width/height of the active zone the same - as the screen while maximizing the area described by TopX, - TopY, BottomX, BottomY. - - Option "DebugLevel" "number" - sets the level of debugging info reported for the defined - device. There are 12 levels in use, specified by the - integers between 1 and 12. Once it is defined, all the - debug messages with a level less than or equal to the - "number" will be logged into /etc/X11/XFree86.0.log or - /etc/X11/Xorg.0.log. - - Option "CommonDBG" "number" - sets the level of debugging info for all devices defined - for the same tablet. There are 12 levels in use, specified - by the integers between 1 and 12. Once it is defined, all - the debug messages with a level less than or equal to the - "number" will be logged into /etc/X11/XFree86.0.log or - /etc/X11/Xorg.0.log. - - Option "CursorProx" "number" - sets the max distance from tablet to stop reporting - movement for cursor in relative mode. Default for Intuos - series is 10, Graphire series (including Volitos) is 42. - - Option "Serial" "number" - sets the serial number associated with the physical device. - This allows to have multiple devices of the same type (i.e. - multiple pens). This option is only available on wacom V - devices (Intuos series and Cintiq 21UX). To see the serial - number associated with a device, run <i><a href="#xsetwacom">xsetwacom</a></i>. - - Option "Threshold" "number" - sets the pressure threshold used to generate a button 1 - events of stylus. The default is MaxPressure*3/50. - -SEE ALSO - Xorg(1x), xorg.conf(5x), xorgconfig(1x), Xserver(1x), X(7). - -AUTHORS - Frederic Lepied <lepied@xfree86.org>, Ping Cheng <pingc@wacom.com>, - John E. Joganic <jej@j‐arkadia.com>, Magnus Vigerlöf <Magnus.Vigerlof@ipbo.se> - -X Version 11 linuxwacom 0.8.0 WACOM(4) -</pre></blockquote> -<a name="mouse1"> -</a><h2><a name="mouse1">5.2 - Mouse1 (for some 2.6 systems)</a></h2> -<p><a name="mouse1">This section largely deals with interaction problems between the mouse1 -device, PS/2 mouse, and USB tablets. Serial users can ignore this part. - -</a></p><p></p><div class="diff"><a name="mouse1">Starting from linuxwacom-0.7.1, this is not a problem -for most kernel 2.6 systems. If you use kernel 2.6 and a driver newer than 0.7.1, -you may ignore this page. However, it has been reported that on some vendors 2.6 -systems, the information detailed on this page still applies. So, if you tried -all the other steps and the tablet still has issues, you may want to apply this -page to elminate the /dev/input/mice issue.</a></div> - -<p><a name="mouse1">If you have a USB mouse or PS/2 mouse and are also using a USB tablet, -there are two solutions here for you: you may either change your -mouse1 or PS/2 InputDevice section to something other than /dev/input/mice -or build mousedev.o from this project for your kernel, which will ignore -Wacom tablets as USB mice. The wacom tablet appears as a mouse to the Linux -kernel, and consequently, the "mice" device combines the input from all your -mice, including the tablet. This will not give you the behavior you want. -A better choice is to specify the precise USB device or PS/2 mouse from which -you want to receive mouse events, namely /dev/input/mouse0 or /dev/input/mouse1 -or /dev/psaux. - -</a></p><p><a name="mouse1">If you do not have a USB mouse, adding the Mouse1 device -is <i>probably not something you want to do</i>. -Despite this, Redhat's Anaconda program will do it for you if -you boot the machine with the tablet plugged in. You'll need to be -careful about this. - -</a></p><p><a name="mouse1">When you use the mouse1 input device, the data flows from the USB wacom -kernel driver, through the event subsystem, down into the mousedev driver, -out the /dev/input/mouse0 device, and finally into the XInput mouse driver. -You effectively lose all your absolute positioning information because the -mousedev driver converts it into relative data. Additionally, the XFree86 -wacom driver does not get control of the cursor because mouse1 is providing -those events. - -</a></p><p><a name="mouse1">Therefore, if you have a Mouse1 section, leave it. Redhat 8.0 at least, -expects it to be there; however, if you do not have a USB mouse and you -are using a USB tablet, you will not be using this section, so make -certain that it is commented out of the ServerLayout section covered next. - -</a></p><p><a name="mouse1">There is one exception however. If you have no other mouse -device in your ServerLayout section, <i>do not</i> remove Mouse1. XFree86 -will not start without at least one core pointer, and the tablet -does not count unless it is specifically identified as a "CorePointer" -rather than merely "SendCoreEvents." - -</a><a name="srvlayout"> -</a></p><h2><a name="srvlayout">5.3 - ServerLayout</a></h2> -<p><a name="srvlayout">The ServerLayout section describes what devices the X server will use. -Modify the ServerLayout section to reflect the new devices. Make certain -to comment out the Mouse1 device if determined necessary from the previous -page. - -</a></p><blockquote><pre><a name="srvlayout">Section "ServerLayout" - Identifier "Default Layout" - Screen 0 "Screen0" 0 0 - InputDevice "Mouse0" "CorePointer" - InputDevice "Keyboard0" "CoreKeyboard" - <b>InputDevice "stylus" "SendCoreEvents" - InputDevice "eraser" "SendCoreEvents" - InputDevice "cursor" "SendCoreEvents" # For non-LCD tablets only - InputDevice "touch" "SendCoreEvents" # Only a few TabletPCs support this type - InputDevice "pad" # For Intuos3/CintiqV5/Graphire4/Bamboo tablets</b> -EndSection -</a></pre></blockquote> - -<p><a name="srvlayout">This section determines which devices are actually used by the server. -In the case above, the cursor, stylus, eraser, touch, and pad devices are selected. -At present, this is the correct configuration for proper -operation of the tablet whether you are using the beta package or the production package. - -</a></p><p><a name="srvlayout">You can configure one of your Wacom devices as a Core Pointer if you don't -have a regular mouse on your system. However, you lose the Wacom specific -functions, such as pressure sensitivity and absolute mode when you use that device. - -</a></p><p><a name="srvlayout">You have completed the -XF86Config/xorg.conf file changes. But aware that if you reboot -your computer with the Wacom plugged in and Redhat's Anaconda program -notices, -it may treat the tablet as a USB mouse and reconfigure this file -incorrectly. -You may need to go back and check the file to ensure that everything is -still correct afterwards. Rebooting with the device detached is not -recommended since X server doesn't properly support hotplugging yet. My -recommendation is to tell Anaconda to ignore the tablet until the -device -detection works properly. -</a><a name="restartx"> -</a></p><h2><a name="restartx">5.4 - Restart X</a></h2> -<p><a name="restartx">Finally, restart X. You may wish to do this from runlevel 3 for -testing purposes. - -</a></p><blockquote><pre><a name="restartx">[root@ayukawa root]# init 3 -...processes starting and stopping... -[root@ayukawa root]# startx -</a></pre></blockquote> - -<a name="restartx">If the X server dies, you can always back-out the -changes to the XF86Config or xorg.conf file and try again. But first, -look at the X log file (XFree86.0.log for XFree86 and Xorg.0.log for -Xorg) for clues. -You might want to do this even if everything works correctly. When -things -are running right, the following lines appear in my log file. -</a><blockquote><pre><a name="restartx">[root@ayukawa root]# grep -i wacom /var/log/XFree86.0.log -(II) LoadModule: "wacom" -(II) Loading /usr/X11R6/lib/modules/input/wacom_drv.o -(II) Module wacom: vendor="The XFree86 Project" -(II) Wacom driver level: <b>47-0.8.2-2</b> $ -(II) XINPUT: Adding extended input device "eraser" (type: Wacom Eraser) -(II) XINPUT: Adding extended input device "stylus" (type: Wacom Stylus) -(II) XINPUT: Adding extended input device "cursor" (type: Wacom Cursor) -(==) Wacom Kernel Input device name: "Wacom Intuos2 12x12" -(==) Wacom tablet maximum X=30480 maximum Y=30480 X resolution=0 Y resolution=0 -suppress=0 -(==) Wacom Cursor top X=0 top Y=0 bottom X=30480 bottom Y=30480 -(==) Wacom Stylus top X=0 top Y=0 bottom X=30480 bottom Y=30480 -(==) Wacom Eraser top X=0 top Y=0 bottom X=30480 bottom Y=30480 -</a></pre></blockquote> - -<a name="restartx">Notice the driver version 47-0.8.2-2 above. This is the new stable -wacom_drv.o driver. The beta driver is currently 47-0.8.3-3. - -</a><p><a name="restartx">First things first, you should lift the mouse off the tablet and place it -back down. This seems to help reset things internally. When you replace the -mouse, the cursor should jump to that portion of the screen. If everything is -working correctly, the mouse should work in absolute mode with the four -corners of the tablet corresponding with the four corners of the screen. If -the cursor stops short of an edge, then the kernel driver limits are probably -incorrect. Please let me know so that I can update the driver. - -</a></p><p><a name="restartx">Next, remove the mouse and try using the eraser end of the stylus. -Hovering over the surface of the tablet should move the cursor. Touching -the eraser tip to the surface should generate a click. If you invert the -pen and use the stylus tip, you should get a similar result. If the pen -tip generates spurious touch events, you will need to increase the -threshold value in the InputDevice section. Wacdump is useful for -determining the appropriate value. - -</a></p><p><a name="restartx">Lastly, if you would like more logging, the parameter "DebugLevel" (for -individual tools) and "CommonDBG" (for all tools associated with the same -tablet) can be set to values between 1 and 12, with 12 being way too much, -and 1 being fairly useful. - -</a></p><p><a name="restartx">If X server failed to start and you are running the prebuilt wacom_drv.(s)o, you may have to go back to </a><a href="#config">Configuring the Package</a> page to build the driver on your system. - -<a name="ptrstat"> -</a></p><h2><a name="ptrstat">5.5 - Check the Pointer Status</a></h2> -<p><a name="ptrstat">You can check the XInput pointer status by using <i>xsetpointer</i> -as below. The man page states that calling xsetpointer with the name of -a particular device will set it as the primary pointing device. - -</a></p><blockquote><pre><a name="ptrstat">[root@ayukawa log]# xsetpointer -l -"eraser" [XExtensionDevice] -"stylus" [XExtensionDevice] -"cursor" [XExtensionDevice] -"Mouse0" [XPointer] -"keyboard" [XKeyboard] -</a></pre></blockquote> - -<a name="xidump"> -</a><h1><a name="xidump">6.0 - Viewing XInput Events (xidump)</a></h1> -<p><a name="xidump">The xidump program is similar to wacdump, but it parses and displays -event data from the XFree86 XInput extension rather than from the tablet -itself. This is useful for seeing what programs like gimp and gsumi are -receiving from X. - -</a></p><p><a name="xidump">Presently, xidump will display proximity and motion events for -the stylus, cursor, eraser, and pad input devices. xidump supports -different display modes with "curses" and "raw" modes already -implemented and a GTK-based graphical mode in the works. The curses -mode is probably the most useful in terms of verifying that the tablet -is functioning correctly in the XFree environment; however, the raw -mode has the additional benefit of being able to verify the order, -timing, and history of events. - -</a></p><p><a name="xidump">Since xidump uses the same XInput interface that gimp and gsumi use -to get tablet data, the values displayed in xidump should be identical -to what they are receiving. If you are having trouble with pressure in -gimp, chances are that xidump will demonstrate the same problem. -xidump does not require root access to use. - -</a></p><p><a name="xidump"><b>Running xidump</b> - -</a></p><p><a name="xidump">xidump takes one argument, the input device specified in your -XF86Config/xorg.conf file. It is the Identifier entry in the -InputDevice section. Normally they are either stylus, cursor, eraser, -touch, or pad. You can get a complete list by running xidump -with the list option '-l'. xidump has the additional feature of dumping all -the device capabilities by specifying the verbose option '-v'. Both are -demonstrated below. - -</a></p><p><a name="xidump">Note: The device identifiers (input_device) are case sensitive. - -</a></p><blockquote><pre><a name="xidump">[jej@ayukawa src]$ ./xidump -l -eraser extension -stylus extension -cursor extension -Mouse0 disabled -keyboard keyboard - -[jej@ayukawa src]$ ./xidump -l -v eraser -eraser extension - key: min=8, max=39, num=32 - btn: num=1 - val: axes=6 mode=abs buf=0 - axis[0]: res=2540, min=0, max=30480 - axis[1]: res=2540, min=0, max=30480 - axis[2]: res=1, min=0, max=1023 - axis[3]: res=1, min=-64, max=63 - axis[4]: res=1, min=-64, max=63 - axis[5]: res=1, min=0, max=1023 -</a></pre></blockquote> - -<p><a name="xidump">In the first dump, we see the eraser, stylus, and cursor with the -additional Mouse0 pointer and keyboard. Only the first three are -"extension" devices. Using xidump on the keyboard or mouse pointer -will generate an error since neither are XInput devices. - -</a></p><p><a name="xidump">The second dump shows the capabilities of the eraser device including the -number of keys (32), buttons (1), and axes (6). It also shows the -mode to be absolute. In order, the axes are: x, y, pressure, tilt-x, -tilt-y, and wheel. When the cursor is used, axis 3 becomes z-rotation -instead of tilt-x. - -</a></p><p><a name="xidump">You should be aware that xidump and gimp must take ownership of the device -in order to get real-time data. This creates a conflict if you are running -both of them simultaneously. gimp is the more clever of the two programs in -that it only "grabs" the input device if you are hovering over the gimp -drawing window. xidump is less friendly. In order to display the absolute -position across the entire screen, it creates a small "listening window," -grabs the device immediately, and does not release it until you quit the -program. Neither program should fail, but you will not be able to draw -in gimp and run xidump at the same time if they are both using the same -input device. - -</a></p><p><a name="xidump">We will run xidump in raw mode for the first time to see the stylus -events directly. A small window will appear on the desktop while xidump -runs; you can safely ignore it. Closing it will kill the application. - -</a></p><blockquote><pre><a name="xidump">[jej@ayukawa src]$ ./xidump -u raw stylus -14.56291895: Proximity In -14.56305595: Motion: x= +5978 y=+28728 p= 0 tx= +64 ty= +64 w= +0 ID: 2323 Serial: -60 -... -16.87158095: Motion: x= +4941 y=+27842 p= 225 tx= +41 ty= +67 w= +0 ID: 2323 Serial: -60 -16.87164395: Button: 1 DOWN -16.87169595: Motion: x= +4964 y=+27844 p= 398 tx= +42 ty= +66 w= +0 ID: 2323 Serial: -60 -... -17.27328395: Motion: x= +5261 y=+27543 p= 3 tx= +48 ty= +64 w= +0 ID: 2323 Serial: -60 -17.27334395: Button: 1 UP -17.27515995: Motion: x= +5348 y=+27451 p= 4 tx= +48 ty= +63 w= +0 ID: 2323 Serial: -60 -... -17.35933795: Motion: x= +7089 y=+27061 p= 4 tx= +48 ty= +63 w= +0 ID: 2323 Serial: -60 -17.37444395: Proximity Out -<Ctrl-C> -</a></pre></blockquote> - -<p><a name="xidump">The timestamp on the left is seconds elapsed; the next field is the -event type. Mostly, you will encounter motion events although I've trimmed -many of them out of this listing. As you can see from the above, the first line -is a "proximity in" event which indicates the stylus came in range of the -tablet. The last event was a "proximity out." At 16.87 seconds, I tapped -the stylus to the tablet surface as recorded by the "Button: 1 DOWN" and -subsequent "UP" message. Raw mode is useful for verifying the order and -timing of messages, but is not particularly clean. The ncurses mode works -much better. - -</a></p><blockquote><pre><a name="xidump">[jej@ayukawa src]$ ./xidump stylus -InputDevice: stylus -Valuators: Absolute ID: 2323 Serial Number: -60 - - x-axis y-axis pressure x-tilt y-tilt wheel - data: +10826 +09919 +00084 +00058 +00065 +00000 - min: +00000 +00000 +00000 -00064 -00064 +00000 - max: +30480 +30480 +01023 +00063 +00063 +01023 - res: +00000 +00000 +00039 +00001 +00001 +00001 - -******** -Proximity: IN - Focus: - Buttons: 1-DOWN - Keys: -</a></pre></blockquote> - -<p><a name="xidump">All of the ranges are displayed above, include their resolutions which as -far as I know are not normally used. Only the proximity, focus, valuator, -and button events are currently implemented. - -</a></p><p><a name="xidump">For completeness sake, here are the command line options: - -</a></p><blockquote><pre><a name="xidump">Usage: xidump [options] input_device - -h, --help - usage - -v, --verbose - verbose - -V, --version - version - -l, --list - list available input devices - -u, --ui ui_type - use specified ui, see below - -Use --list option for input_device choices -UI types: curses, raw -</a></pre></blockquote> - -<p><a name="xidump">There are not many options, but the --list option is helpful for -identifying devices, and the --ui option allows you to switch between -curses and raw modes. Adding the --verbose option increases the amount of output, and -when used in conjunction with --list, displays the device capabilities. - -</a><a name="tabletpc"> -</a></p><h1><a name="tabletpc">7.0 - Tablet PC</a></h1> - -<p><a name="tabletpc">The Wacom digitizers embedded in Tablet PCs -utilitizes a special protocol IV, ISDV4. Most of them are serial -tablets. There are a few Wacom USB tablet PC OEMs on the market -recently. However, we don't support USB tablet PC yet. This page is for -serial Tablet PC only. </a></p><p><a name="tabletpc">Similar to the conventional serial -tablets, serial tablet PCs use a serial controller (UART). But, -normally, they are not set to any serial ports. They are effectively -serial devices, but require special configuration (setserial) under -Linux. </a></p><div class="diff"> -<p><a name="tabletpc">You can use <i>xxd</i> to see if your tablet has been mapped onto a serial port or not. To do so, follow the steps below: - -</a></p><blockquote><pre><a name="tabletpc">[jej@ayukawa ~]$su -Password: -[jej@ayukawa ~]# xxd /dev/ttyS0 -</a></pre></blockquote> - -<p><a name="tabletpc">Move your pen on your tabletPC. If you see output -from the terminal while you move the pen, your tablet has been mapped -to port 1. Quit xxd by Ctrl+c. Then ignore the rest of this page and go -to(see </a><a href="http://linuxwacom.sourceforge.net/index.php/howto/x11">Configuring X11</a>) page. Otherwise, apply xxd to port 1 to 4. If none of them show output, you need to manually map the tablet to a serial port. -</p></div> - -<p>Here is a sample command. The IO port may be different for your Tablet PC. - -</p><blockquote><pre>[jej@ayukawa src]$ setserial /dev/ttyS2 port 0x93f8 autoconfig -</pre></blockquote> - -<p>This command needs to be excuted with each reboot before X server starts. -</p><p>You can add the command into one of your favorite start script. I normally -add it into /etc/rc.d/rc.local. Here is my rc.local: - -</p><blockquote><pre>#!/bin/sh -# -# This script will be executed *after* all the other init scripts. -# You can put your own initialization stuff in here if you don't -# want to do the full Sys V style init stuff. - -touch /var/lock/subsys/local -setserial /dev/ttyS2 port 0x93f8 autoconfig -</pre></blockquote> - -<p>After installing wacom_drv.o and other programs, such as wacomcpl and wacdump, -restart X server. Now you can view raw tablet data by: - - -</p><blockquote><pre>[jej@ayukawa util]$ ./wacdump -f tpc /dev/ttyS2 # Wacom digitizer on fake COM3 - -<div class="diff"> -If your wacdump is from linuxwacom version 0.7.5 or older, issue -[jej@ayukawa util]$ ./wacdump -f c100 /dev/ttyS2 -</div> -</pre></blockquote> - -<p>If everything looks right from wacdump (see <a href="http://linuxwacom.sourceforge.net/index.php/howto/wacdump">Using wacdump</a>), -you can update /etc/X11/XF86Config or /etc/X11/xorg.conf to load wacom X driver - (see <a href="http://linuxwacom.sourceforge.net/index.php/howto/x11">Configuring XFree86/X11R6</a>). - -</p><p>Please notice that in Wacom InputDevice section, the following 2 options are -required for Tablet PC: - -</p><blockquote><pre> <b>Option "Device" "/dev/ttyS2" # SERIAL ONLY</b> - <b>Option "ForceDevice" "ISDV4" # Tablet PC ONLY</b> -</pre></blockquote> - -<p>Refer to <a href="http://linuxwacom.sourceforge.net/index.php/howto/inputdev">Adding the InputDevices</a> for details. - -</p><blockquote><div class="diff"> - -<p>Some HP Tablet PCs require you explicitly run the following program before setserial. This -is due to the fact that Wacom Digitizer on HP Tablet PCs are not mapped to any serial -port by default. - -</p><p>Please compile tc1100ts.c as mentioned below and copy the executable (tc1100ts) -to /usr/sbin. Then add the following two lines to the end of your /etc/rc.d/rc.local: - -</p><p>/usr/sbin/tc1100ts -</p><p>setserial /dev/ttyS2 port 0x03e8 autoconfig - -</p><pre><b>Mapping Wacom Digitizer to /dev/ttyS2 for HP Tablet PC</b> - - -/* - * HP TC1100 Touchscreen Enable - * Copyright (c) 2004 Hewlett-Packard Co. - * - * Compile with `cc -O2 -o tc1100ts tc1100ts.c', - * and run as root with `./tc1100ts'. - * - * This standalone program enables the Serial Port 1 - * (SP1) of the NS LPC Super I/O, where the Wacom - * Digitizer is connected to on the HP TC1100 Tablet PC. - * - * The serial device is mapped to 0x3e8 IRQ0-4 to match - * the default /dev/ttyS2 port and IRQ mapping on Linux. - * - * To proof that the Wacom Digitizer is enabled by this - * standalone, do the following: - * - Change to superuser mode, i.e. root - * - setserial /dev/ttyS2 - * it should return: - * /dev/ttyS2, UART: unknown, Port: 0x03e8, IRQ: 4 - * - ./tc1100ts - * - setserial /dev/ttyS2 autoconfig - * - setserial /dev/ttyS2 - * now returns: - * /dev/ttyS2, UART: 16550A, Port: 0x03e8, IRQ: 4 - * - */ - -#include <stdio.h> -#include <unistd.h> -#include <sys io.h=""> -#include <stdlib.h> - -const int cfgindex = 0x4e; -const int cfgdata = 0x4f; - -#define wsio(i,d) {outb(i,cfgindex); outb(d,cfgdata);} - -int main() -{ - /* Get access to the ports */ - if (iopl(3)) {perror("iopl"); exit(1);} - - // See the SuperIO Specificatio for details of each register - wsio(0x07,0x03); // Select Logical Device - Serial Port 1 - wsio(0x30,0x00); // De-activate Logical Device - wsio(0x60,0x03); // I/O Port Base [15-08] - wsio(0x61,0xe8); // I/O Port Base [07-00] - wsio(0x70,0x14); // Enables Wake-up on IRQ4 - wsio(0x71,0x03); // Level IRQ Req, Hi priority - wsio(0x74,0x04); // DMA Channel Select 0 - no DMA - wsio(0x75,0x04); // DMA Channel Select 1 - no DMA - wsio(0x30,0x01); // Activate Logical Device - - /* We don't need the ports anymore */ - if (iopl(0)) {perror("iopl"); exit(1);} - - exit(0); -} - -/* end of tc1100ts.c */ -</stdlib.h></sys></unistd.h></stdio.h></pre> - -</div></blockquote> - -<a name="wacomcpl"> -</a><h1><a name="wacomcpl">8.0 - GUI-Based (tcl/tk) Wacom Control Panel(wacomcpl)</a></h1> -<p><a name="wacomcpl">wacomcpl is a simple graphic Wacom driver configuration tool. It -changes the pressure sensitivity, click threshold, button functions, -cursor mode, speed, mapping, etc. without having to manually modify -XF86Config/xorg.conf file. For Cintiq and Tablet PC users, it is -also a tool to calibrate the tablet. wacomcpl should be launched -when you login as yourself since .xinitrc (or .xsession), a file -under your home directory, will be updated locally each time you -run wacomcpl. The .xinitrc (or .xsession) stores the preferences -you selected through wacomcpl for your next login. The goal is to -give each user a chance to use his/her own preference on a shared system. - -</a></p><div class="diff"> -<p><a name="wacomcpl">If you want all users on one system to share some settings, you can -copy those lines started with xsetwacom in ~/.xinitrc (or ~/.xsession) -to /etc/X11/xinit/xinitrc (/etc/X11/xinit/Xsession). - -</a></p><p><a name="wacomcpl">If your system doesn't execute .xinitrc (or .xsession) at login, each -time after exiting from wacomcpl, you will need to copy those xsetwacom -lines in .xinitrc (or .xsession) to a startup script (.bashrc, .cshrc, -.profile, etc.) that your system launches. You can also modify wacomcpl-exec -to automate this step. - -</a></p><p><a name="wacomcpl">However, it is reported that there are older systems on which can not run -wacomcpl due to some XFree86 interface error. The workaround is to add the -configuration options to your X config file, refer to </a><a href="#x11">Configuring X11</a> page for details. -</p></div> - -<p><b>Running wacomcpl</b> - -</p><p>If wacom_drv.(s)o was running while installing wacomcpl, wacomcpl can be -launched immediately after <i>make install</i> and <i>exit</i>. - -</p><p>If wacom_drv.(s)o is installed by the same <i>make install</i> -as wacomcpl is, restarting X server is required to use the newly built -wacom_drv.(s)o. We strongly recommand to build and install the -wacom_drv.(s)o and wacomcpl from the same release package since the out -of sync wacom_drv.(s)o and wacomcpl may crash your X server. -<a name="xsetwacom"> -</a></p><h1><a name="xsetwacom">9.0 - Command Line Configuration Interface (xsetwacom)</a></h1> -<p><a name="xsetwacom">The xsetwacom is a command-line Wacom driver configuration tool. It -changes the pressure sensitivity, click threshold, button functions, -cursor mode and speed, and much more without having to manually modify -XF86Config or xorg.conf file. - -</a></p><p><a name="xsetwacom">The basic usage and options can be viewed by issuing <i>xsetwacom</i>. - -</a></p><p><a name="xsetwacom"><b>Note: </b>The device identifiers (dev_name) are case sensitive. You should -use the dev_name exactly the same as <i>xsetwacom list</i> shows. The examples -below assume that Stylus, cursor, and pad are used. - -</a></p><blockquote><pre><a name="xsetwacom">[jej@ayukawa linuxwacom]$xsetwacom -Usage: xsetwacom [options] [command [arguments...]] -Options: - -h, --help - usage - -v, --verbose - verbose output - -V, --version - version info - -d, --display disp_name - override default display - -s, --shell - generate shell commands for 'get' - -x, --xconf - generate X.conf lines for 'get' - -Commands: - list [dev|param] - display known devices, parameters - list mod - display supported modifier and specific keys for keystokes - set dev_name param [values...] - set device parameter by name - get dev_name param [param...] - get current device parameter(s) value by name - getdefault dev_name param [param...] - get device parameter(s) default value by name -</a></pre></blockquote> - -<p><a name="xsetwacom">xsetwacom supports 3 forms of get/getdefault commands: <i>xsetwacom get</i> -returns the parameter's raw value; <i>xsetwacom -x get</i> returns the value in Xorg.conf -form; and <i>xsetwacom -s get</i> returns the value in shell command form. - -</a></p><p><a name="xsetwacom">The most used xsetwacom command is <i>xsetwacom set dev_name param [values...]</i>, -where param is an option which will be set to values in wacom_drv.o after excuting xsetwacom. -To better understand the use of this command, let's see some examples. Assume that you use -<i>Stylus</i> as your Wacom tool's Identifier, which is considered as dev_name in xsetwacom command. - -</a></p><p><a name="xsetwacom">If you want to change <i>Stylus's</i> mode from absolute (default) to relative, then: - -</a></p><blockquote><pre><a name="xsetwacom">[jej@ayukawa linuxwacom]$xsetwacom set Stylus mode relative -</a></pre></blockquote> - -<p><a name="xsetwacom">If you want to change button 2 to left-double-click, then: - -</a></p><blockquote><pre><a name="xsetwacom">[jej@ayukawa linuxwacom]$xsetwacom set Stylus button2 "dblclick 1" -</a></pre></blockquote> - -<p><a name="xsetwacom">If you want to change button 2 to button 5, then: - -</a></p><blockquote><pre><a name="xsetwacom">[jej@ayukawa linuxwacom]$xsetwacom set Stylus Button2 "button 5" -or -[jej@ayukawa linuxwacom]$xsetwacom set Stylus Button2 5 -</a></pre></blockquote> - -<p><a name="xsetwacom">If you want to change button 3 to ModeToggle, then: - -</a></p><blockquote><pre><a name="xsetwacom">[jej@ayukawa linuxwacom]$xsetwacom set Stylus button3 modetoggle -</a></pre></blockquote> - -<p><a name="xsetwacom">If you want to know what the current (or default) pressure sensitivity setting is, then: - -</a></p><blockquote><pre><a name="xsetwacom">[jej@ayukawa linuxwacom]$xsetwacom -s get Stylus PressCurve (output in xsetwacom format) -xsetwacom set stylus PressCurve "0 15 85 100" -or -[jej@ayukawa linuxwacom]$xsetwacom -x get Stylus PressCurve (output in xorg.conf Option format) - Option "PressCurve" "0,15,85,100" - -[jej@ayukawa linuxwacom]$xsetwacom -x getdefault Stylus PressCurve - Option "PressCurve" "0,0,100,100" -</a></pre></blockquote> - -<p><a name="xsetwacom">If you want to set the pressure sensitivity a bit softer, then: - -</a></p><blockquote><pre><a name="xsetwacom">[jej@ayukawa linuxwacom]$xsetwacom set Stylus PressCurve 0 15 85 100 -</a></pre></blockquote> - -<p><a name="xsetwacom">If you want the buttons behave the Tablet PC way, i.e., sending button event only when -button1 (the tip) is pressed, then: - -</a></p><blockquote><pre><a name="xsetwacom">[jej@ayukawa linuxwacom]$xsetwacom set Stylus TPCButton on -</a></pre></blockquote> - -<p><a name="xsetwacom">If you want to change <i>pad's</i> button 1 to ctrl alt F2, then: - -</a></p><blockquote><pre><a name="xsetwacom">[jej@ayukawa linuxwacom]$xsetwacom set pad Button1 "core key ctrl alt F2" -</a></pre></blockquote> - -<p><a name="xsetwacom">If you want to change <i>pad's</i> button 2 to ctrl alt backspace, then: - -</a></p><blockquote><pre><a name="xsetwacom">[jej@ayukawa linuxwacom]$xsetwacom set pad Button2 "core key ctrl alt backspace" -</a></pre></blockquote> - -<div class="diff"><a name="xsetwacom"><b>Note:</b> keystrokes and modifiers are only supported for Xorg 6.8 or later. -</a></div> - - -<p><a name="xsetwacom"><b>xsetwacom supported parameters</b> - -</a></p><p><a name="xsetwacom">Below is a list of the parameters and their values used by <i>xsetwacom</i> command (a similar -output can be viewed by <i>xsetwacom list param</i>. All functions apply to the associated tool -unless explicitly stated otherwise): - -</a></p><blockquote><pre><a name="xsetwacom"> param [values...] results ------------------------------------------------------------------- - Mode Relative|Absolute sets the mode of the device - TopX integer sets the X coordinate of the top corner of the active zone - TopY integer sets the Y coordinate of the top corner of the active zone - BottomX integer sets the X coordinate of the bottom corner of the active zone - BottomY integer sets the Y coordinate of the bottom corner of the active zone - STopX<i>i</i> integer returns screen <i>i</i> left coordinate in pixels - STopY<i>i</i> integer returns screen <i>i</i> top coordinate in pixels - SBottomX<i>i</i> integer returns screen <i>i</i> right coordinate in pixels - SBottomY<i>i</i> integer returns screen <i>i</i> bottom coordinate in pixels - Button<i>M</i> integer|keystroke sets button <i>M</i> to button integer click or keystroke - Button<i>M</i> 0 ignores button <i>M</i> click - RelWUp integer|keystroke sets relative wheel up to button click or keystroke - RelWDn integer|keystroke sets relative wheel down to button click or keystroke - AbsWUp integer|keystroke sets absolute wheel up to button click or keystroke - AbsWDn integer|keystroke sets absolute wheel down to button click - StripLUp integer|keystroke sets left strip up to button click or keystroke - StripLDn integer|keystroke sets left strip down to button click or keystroke - StripRUp integer|keystroke sets right strip up to button click or keystroke - StripRDn integer|keystroke sets right strip down to button click or keystroke - PressCurve i1 i2 i3 i4 sets the pressure bezier curve, where i1+i4=100; i2+i3=100 - DebugLevel integer (0 - 12) sets the level of debugging trace for the specified tool - CommonDBG integer (0 - 12) sets the level of debugging trace for all tools - associated with the same tablet. - Suppress integer (0 - 100) number of data trimmed for the tools associated - with the same tablet. - Screen_No integer (-1 - 5) sets screen number the tablet is mapped to. - TwinView none|vertical|horizontal - |leftof|aboveof sets the mapping to TwinView. Tablet mappings applied after - this command will be based on the new tablet orientation. - TVResolution0 width x height sets MetaModes option for TwinView Screen 0. - TVResolution1 width x height sets MetaModes option for TwinView Screen 1. - SpeedLevel integer (1 - 11) sets relative cursor movement speed - ClickForce integer (1 - 21) sets tip/eraser pressure threshold with clickforce scale - Threshold integer sets tip/eraser pressure threshold directly to the pressure - xyDefault resets the bounding coordinates to default in tablet units - mmonitor on|off turns on/off across monitor movement on (non-TwinView) - multi-monitor desktop - TPCButton on|off turns on/off the buttons as Tablet PC buttons - Touch on|off turns on/off Touch events (default is enable/on for tablets with touch). - Capacity integer (-1 - 5) sets the touch sensitivity level for capacitive touch device - (default is 3 for capacitive tools, -1 for none capacitive tools). - CursorProx integer (distance) sets cursor distance margin for proximity-out - in distance from the tablet surface - Rotate none|cw|ccw|half sets the rotation of the tablet. - ToolID returns the ID of the associated device. - ToolSerial returns the serial number of the associated device. - GetTabletID/TabletID returns the tablet ID of the associated device. - NumScreen returns number of screens configured for the desktop. ------------------------------------------------------------------- - -Event description format: -[CORE] [EVENT TYPE] [MODIFIERS] [CODE] - CORE: Emit core events irrespective of the SendCoreEvents setting - EVENT TYPE: the type of event to emit: - KEY: Emit a key event - BUTTON: Emit a button event - DBLCLICK: Emit a double-click button event - MODETOGGLE: Toggle absolute/relative tablet mode - DISPLAYTOGGLE: Toggle cursor movement among screens - for the selected tool except pad which - applies to all tools asssociated with the tablet - MODIFIERS: use "xsetwacom list mod" - to see a list of modifiers and specific keys - CODE: Button number if emit a button event - or specific keys and any other keys not listed as mod - -</a></pre></blockquote> - - -<p><a name="xsetwacom"><b>Associating parameters to physical devices</b> - -</a></p><p><a name="xsetwacom">Following is a list of the parameters that are associated with the elements of devcies. - -</a></p><blockquote><pre><a name="xsetwacom"> param tools --------------------------------------------------------------------------- -Button# All Wacom styli/pucks buttons - Tablet ExpressKeys -RelWUp/RelWDn Graphire4 tablet wheel - Wacom puck Fingerwheel -AbsWUp/AbsWDn Intuos puck Thumbwheel - Intuos Airbrush Fingerwheel - Bamboo tabelt Touch Ring -StripLUp/StripLUp Left Touch Strip on Intuos3 and V5 Cintiq (Cintiq 21UX/12WX/20WSX) tablets -StripRUp/StripRUp Right Touch Strip on Intuos3 and V5 Cintiq (Cintiq 21UX/12WX/20WSX) tablets --------------------------------------------------------------------------- - -</a></pre></blockquote> - - -<p><a name="xsetwacom"><b>Automatically excuting predefined xsetwacom commands at logging in</b> - -</a></p><p><a name="xsetwacom">The xsetwacom commands can be added to the .xinitrc under your home directory so next time when -you login as yourself, the driver will be set to the options you choose. - -</a></p><p><a name="xsetwacom">Below is an example of my .xinitrc: - -</a></p><blockquote><pre><a name="xsetwacom">[jej@ayukawa jej]$ more .xinitrc -xsetwacom set Stylus TopX 10 -xsetwacom set Stylus TopY 67 -xsetwacom set Stylus BottomX 7170 -xsetwacom set Stylus BottomY 5778 -xsetwacom set Stylus TPCButton 1 -# run the primary system script -. /etc/X11/xinit/xinitrc -</a></pre></blockquote> - -<div class="diff"> -<p><a name="xsetwacom">To see what's under your home directory, use <i>ls -al ~</i>. - -</a></p><p><a name="xsetwacom">If your system doesn't execute .xinitrc at login, you can add those xsetwacom commands into the -startup script (.bashrc, .cshrc, .profile, etc.) that your system launches, for example, you should -use .Xsession instead of .xinitrc on Debian. - -</a></p><p><a name="xsetwacom">It has been reported that xsetwacom can not run on some older systems due to a XFree86 interface -error. A generic solution to this issue is directly adding your configuration options to the -/etc/X11/XF86Config file. Please refer to </a><a href="#x11">Configuring X11</a> for details. -</p></div> - -<p><b>More examples</b> - -</p><p>If you are confused with the usages above, let's see some more confusing examples. - -</p><p> <b>1.</b> Usage of keystroke and modifiers - -</p><p>keystroke and modifiers can be used through buttons, ExpressKeys, wheels, Touch Strips, and -Touch Ring. A list of supported modifiers and special keys can be viewed through -<i>xsetwacom list mod</i>. Special keys are symbols that go together to represent one XInput key event. - -</p><p>In the following example, <b>Up</b> represents the <b>up arrow</b> key: - -</p><blockquote><pre>[jej@ayukawa jej]$ xsetwacom set cursor button4 "key core Up" -</pre></blockquote> - -<p>When you press button4 on your Wacom puck, Xinput will receive an <b>up arrow</b> event. - -</p><p>If you want to send the <b>Up</b> keystroke, the universal escape character <b>\</b> has to be used: - -</p><blockquote><pre>[jej@ayukawa jej]$ xsetwacom set cursor button4 "key core \Up" -</pre></blockquote> - -<p>If you press button4 on your Wacom puck, Xinput will receive an <b>U</b> and a <b>p</b> events, -i.e., <b>Up</b> would be displayed on your active console or application. - -</p><p>Sending <b>down arrow</b> event when button5 is pressed: - -</p><blockquote><pre>[jej@ayukawa jej]$ xsetwacom set cursor button5 "key core Down" -</pre></blockquote> - -<p>Sending <b>PageUp</b> event when tablet wheel scrolls up: - -</p><blockquote><pre>[jej@ayukawa jej]$ xsetwacom set pad RelWUp "key core pgup" -</pre></blockquote> - -<p>Sending <b>PageDown</b> event when tablet wheel scrolls down: - -</p><blockquote><pre>[jej@ayukawa jej]$ xsetwacom set pad RelWDn "key core pgdn" -</pre></blockquote> - -<p>The same functions work for parameters AbsWUp, AbsWDn, StripLUp, -StripLDn, StripRUp, and StripRDn. - -</p><p> <b>2.</b> Changing debug level while driver is running - -</p><p>xsetwacom supports 2 ways of enabling/disabling debugging information, for individual device -and/or for all tools associated with the same tablet, through parameters DebugLevel and CommonDBG. For example, - -</p><blockquote><pre>[jej@ayukawa jej]$ xsetwacom set cursor DebugLevel 10 -</pre></blockquote> - -<p>Turns debugger on to level 10 for device "cursor" only. Other devices -will not report information to Xorg.0.log file. - -</p><blockquote><pre>[jej@ayukawa jej]$ xsetwacom set cursor CommonDBG 3 -</pre></blockquote> - -<p>Turns debugger on to level 3 for all devices associated with the same -tablet as "cursor" does. But only common debug information will be -reported. - -</p><p> <b>3.</b> Configuring TwinView setup while system running - -</p><p>TwinView parameter sets the mapping of TwinView to -horizontal/vertical/none. The current TwinView setup can be retrieved -by the corresponding get command. For example: - -</p><blockquote><pre>[jej@ayukawa jej]$ xsetwacom -x get cursor TwinView - Option "TwinView" "none" -[jej@ayukawa jej]$ -</pre></blockquote> - -which means device <b>cursor</b> was not set to TwinView display. - -<p>Two other parameters, TVResolution0 and TVResolution1, made the change of MetaModes option -in TwinView setup possible when system is running. TVResolution0 sets MetaModes option for -TwinView Screen 0, while TVResolution1 sets MetaModes option for TwinView Screen 1. -However, you need to make sure that the MetaModes you are going to set is the same as -the TwinView setup in your xorg.conf for Nvidia Graphic card driver. - -</p><p> <b>4.</b> Changing Suppress and RawSample to filter the raw data - -</p><p>Use of Suppress will reduce the number of raw data we process in the driver. So, unless -you know what you are doing, changing Suppress is not recommended. Valid values for Suppress -is 0 to 100, where 0 means raw data is used as is. Suppress less than 101 means data will -be used only when its change compared to the last processed event is larger than Suppress in -points. Default is 2. - -</p><p>RawSample was originally introduced to smooth x/y coordinates to a certain degree. -A four-points averaging was tested and convinced to be effective. In 0.7.8, we made -RawSample changeable through xsetwacom. However, same as with Suppress, changing -RawSample is not recommended. The maximum value can be as large as 20. -But the default stays at 4. - -</p><p>Both Suppress and RawSample apply to the devices on the same tablet, that is, -it is global to all devices associated with the same tablet. - -<a name="gimp"> -</a></p><h1><a name="gimp">10.0 - Working With Gimp</a></h1> -<div class="diff"><a name="gimp">It has been suggested that gimp should be recompiled from -source (v1.2.3) on Mandrake 9.0. This does not seem to be true for Redhat -8.0. - -It is also reported that Slackware didn't configure gtk with xinput support. -So, when you rebuild gtk, please make sure to configure the package with -xinput=xfree option, i.e., use <i>./configure --with-xinput=xfree</i>. As of -March 23, 2004, newer Slackware shipping with gtk2 has configured with -xinput. </a></div> - -<p><a name="gimp">Bring up <i>gimp</i> and select "File -> Dialogs -> Input Devices" if -using 1.x or "File -> Preferences -> Input Devices -> Configure Extended -Input Devices" if using 2.x. You will see a drop-down list with all -devices present. After enabling them, you can see their respective statuses -by calling up "File -> Dialogs -> Device Status". It has been recommended -that the devices be set to "Screen" mode rather than "Window". - -</a></p><p><a name="gimp">I have successfully been able to use gimp with several different pens, -including the tips and erasers. Tilt does not appear to be used by gimp -at present, but pressure works fine. If the pressure is too coarse, or -doesn't kick in until too late, you may need to lower your threshold value. -The pressure curve setting can be changed through graphic tool, wacomcpl, -and command line tool, xsetwacom. - -</a></p><p><a name="gimp">Also, a useability note with Gimp: Each input device (stylus,cursor,eraser) -has a completely different set of attributes in Gimp, and in theory, you can -even assign a unique serial number to different pens to get even -more granularity. You will experience this when -you try to use your eraser for the first time. Rather than selecting the -eraser tool, you get the rectangle selection tool instead. This is by design, -believe it or not. Gimp does not care that its an eraser, just that it's not -the pen you were just using. If you choose the eraser tool now, it will -remember that for the next time you try to use it. On the plus side, you -can set the eraser to be anything, including the Airbrush tool or Clone tool. - -</a></p><p><a name="gimp">If you change the tool's mapping area while -Gimp was running, you need to relaunch Gimp to use the new settings. -Otherwise, the tool tip will be off from the drawing point. -</a></p><p><a name="gimp">One tablet user has pointed out that deleting his .gimp directory and -rerunning gimp was necessary before his airbrush worked correctly. If you -are having trouble, it's worth a shot. - -</a></p><p><a name="gimp">Good luck! -</a><a name="multimonitor"> -</a></p><h1><a name="multimonitor">11.0 - Tablet-Screen Mapping</a></h1> - -<p><a name="multimonitor">This page explains how multi-monitor settings -are supported and how to use the InputDevices options to setup your -desired tablet-to-screen mapping. </a></p><p><a name="multimonitor">Linux Wacom X driver (wacom_drv.so) -mainly supports three types of dual/multi-monitor setup in use with X -server on Linux: TwinView, Xinerama, as well as non-TwinView and -non-Xinerama case, where you normally can move the cursor from one -screen to the other, but you can not move an application window, such -as a terminal, from one screen to the other. -</a></p><p><a name="multimonitor"><b>TwinView setup </b> - -</a></p><p><a name="multimonitor">By TwinView setup, we mean the two screens are configured in such a way that X "thinks" it only has one screen. - -</a></p><p><a name="multimonitor">There are three kinds of tablet-to-screen mappings in this setup: - -</a></p><p><a name="multimonitor">1. map the tablet to the whole desktop; -</a></p><p><a name="multimonitor"> In this case, there is no extra -option required in the InputDevices section for Wacom driver in your -X11's configuration file. So this is the default state for TwinView -setup. -</a></p><p><a name="multimonitor">2. map the tablet to one screen at a time, but can switch screens at wish; -</a></p><p><a name="multimonitor"> Option "TwinView" is used in the InputDevices section of the X11's configuration file to configure Wacom driver. - -</a></p><p><a name="multimonitor"> This feature was initially supported -by Dreamwork developers. Their idea was to maximize the accuracy of the -tablet on one screen and be able to move the cursor between screens -without issuing a command (such as xsetwacom) or press a button (such -as display toggle). The tradeoff is that you lost about 60 tablet count -of points on the side that enables the screen switch. </a></p><p><a name="multimonitor">3. map the tablet to a specific screen. -</a></p><p><a name="multimonitor"> Option "TwinView", "TVResolution0", -"TVResolution1", and "ScreenNo" are used in the InputDevices section of -the X11's configuration file to configure Wacom driver . Detailed use -of these options can be found by "man wacom". -</a></p><div class="diff"> -<p><a name="multimonitor">I've seen displays with Xinerama in their -xorg.conf files in fact fall into TwinView setup since the whole -desktop is reported as one screen. Use <i>xsetwacom get stylus NumScreen</i> -to see how many screen you have. You need to use this command without -adding any screen mapping related options in your xorg.conf file for -Wacom device. -</a></p></div> - -<a name="multimonitor"><b>Xinerama setup </b> - -</a><p><a name="multimonitor">1. map the tablet to the whole desktop; -</a></p><p><a name="multimonitor"> No extra option required in the -InputDevices section for Wacom driver in your X11's configuration file -to support this setup. It is the default state. -</a></p><p><a name="multimonitor">2. map the tablet to one screen at a time, but can switch screens with the regular mouse or a user defined button/app; -</a></p><p><a name="multimonitor"> Option "MMonitor" "off" is used in -the InputDevices section of the X11's configuration file to configure -Wacom driver. The cursor will stay in the screen where you started to -use the configured Wacom device. You can change screens by moving the -cursor with another device/app, such as system mouse or another Wacom -device which is not configured with "MMonitor" "off", then use the -configured Wacom device in that screen. -</a></p><p><a name="multimonitor">3. map the tablet to a specific screen. -</a></p><p><a name="multimonitor"> Only option "ScreenNo" is needed to configure Wacom driver in this setting. - -</a></p><p><a name="multimonitor"><b>non-TwinView and non-Xinerama setup </b> - -</a></p><p><a name="multimonitor">In this setup, we only support tablet -to a specific screen mapping, that is, you have to map the tablet to a -specific screen by option "ScreenNo". Otherwise, your tablet may be -mapped half on the first screen and the other half on the second -screen. </a></p><p><a href="#inputdev">X11 InputDevices Options</a> details all options for your Wacom device that we mentioned above. - - -<a name="contact"> -</a></p><h1><a name="contact">12.0 - Contacts</a></h1> -<p><a name="contact">Ping Cheng can be contacted at the following email address: -</a><a href="mailto:%20pingc@wacom.com?SUBJECT=WACOM">pingc@wacom.com</a>. -<a name="appendix"> -</a></p><h1><a name="appendix">13.0 - Appendix</a></h1> -<p><a name="appendix">This section is for everything that is either not critical or simply -too complex to describe in the document above without becoming overly -distracting. -</a><a name="dump"> -</a></p><h2><a name="dump">13.1 - Building wacdump and xidump</a></h2> - -<p><a name="dump"><b>Building wacdump</b> - -</a></p><p><a name="dump">wacdump is enabled by default in the configure script, so let's do that now: - -</a></p><blockquote><pre><a name="dump">[jej@ayukawa linuxwacom]$ ./configure -... ----------------------------------------- - BUILD OPTIONS: - wacom.o - no - wacdump - <b>yes</b> - hid.o - no - usbmouse.o - no - wacom_drv.o - no ----------------------------------------- -</a></pre></blockquote> - -<p><a name="dump">As shown above, the build options indicate that wacdump will be built. -If not, then scroll back through the configuration to see if there aren't -any errors or warnings that would explain this. - -</a></p><p><a name="dump">Next, run <i>make</i>. The output will be a file called wacdump in the -linuxwacom package's src/util directory. Running <i>make install</i>, will -install it under /usr/local/bin. - -</a></p><p><a name="dump"><b>Building xidump</b> - -</a></p><p><a name="dump">xidump builds by default so if you've configured and built the project -in previous steps, you probably have it already. If not, we can build it now. - -</a></p><p><a name="dump">xidump requires the XLib and XInput header files to be present on -the system. On Redhat 8.0, these files are located in the XFree86-devel -RPM package. Other distributions may be organized differently, and -people who build X from source probably get them by default. When -configuring, check that XLib is detected in the build environment, -and if not, refer to the warnings and "checking for" messages for -additional clues. - -</a></p><p><a name="dump">The preferred display mode for xidump uses ncurses. To compile it, you -will need the ncurses header files. On Redhat 8.0, these files are located -in the ncurses-devel package. Without ncurses, xidump defaults to raw mode -automatically. - -</a></p><blockquote><pre><a name="dump">[jej@ayukawa linuxwacom]$ ./configure -checking for XLib include directory... <b>found</b> -checking for XLib header files... <b>found</b> -checking for ncurses.h... <b>yes</b> -... ----------------------------------------- - BUILD ENVIRONMENT: - ... - <b>XLib - yes</b> - <b>ncurses - yes</b> - ... - - BUILD OPTIONS: - ... - <b>xidump - yes</b> - ... ----------------------------------------- - -</a></pre></blockquote> - -<p><a name="dump">The configuration above indicates that the XLib and ncurses header files -were found and xidump will be built. If ncurses.h is not found, xidump -will still build, but it will also warn you that ncurses will not be -available. If you encounter warnings, it is most likely that your -development environment is missing some packages. - -</a></p><p><a name="dump">When you run <i>make</i>, the xidump program will be built along with any -other programs that are specified in the build options. The output file is -called 'xidump' and is located in the linuxwacom package's src/util directory. -It is installed by running <i>make install</i>. -</a><a name="xset"> -</a></p><h2><a name="xset">13.2 - Building xsetwacom</a></h2> - -<p><a name="xset"><b>Building xsetwacom</b> - -</a></p><p><a name="xset">xsetwacom uses libwacomcfg.so to communicate with Wacom X (XFree86 or -Xorg) driver, wacom_drv.(s)o. So, libwacomcfg.so should be built and -installed. - -</a></p><p><a name="xset">libwacomcfg.so relies on Xlib. In the -configure script, it will default the Xlib path to /usr/X11R6 or -/usr/lib (/usr/X11R6/lib64 or /usr/lib64 if --enable-xserver64 option -is set) by checking the existence of xf86Version.h. If your Xlib is not -installed under /usr/X11R6 or /usr/lib, you'll need to specify the path -(dir) by <i>--with-xlib=dir</i>. Let's see -what we get from configure: - -</a></p><blockquote><pre><a name="xset">[jej@ayukawa linuxwacom]$./configure -... ----------------------------------------- - BUILD ENVIRONMENT: - architecture - i686 - linux kernel - yes 2.4 - module versioning - yes -DONFIG_MODVERSIONS -DMODVERSIONS -include /usr/src/linux/include/linux/modversions.h - kernel source - yes /usr/src/linux - XFree86 - no - XSERVER64 - no - dlloader - no - XLib - yes /usr/X11R6 - TCL - yes /usr - TK - yes /usr - ncurses - yes - - BUILD OPTIONS: - wacom.o - no - wacdump - yes - xidump - yes - libwacomcfg - yes - libwacomxi - yes - xsetwacom - yes - hid.o - no - usbmouse.o - no - evdev.o - no - mousedev.o - no - input.o - no - tabletdev.o - no - wacom_drv.so - no - wacom_drv.o - no ----------------------------------------- -</a></pre></blockquote> - -<p><a name="xset">As shown above, the build options indicate that libwacomcfg and xsetwacom -will be built. If not, then scroll back through the configuration to see -if there aren't any errors or warnings that would explain this. - -</a></p><p><a name="xset">Next, run <i>make</i>. The output will be stored in the linuxwacom -package's src/util and src/util/.libs directory. They will be installed by running -<i>make install</i> (you need to switch to superuser to run this command). - -</a></p><p><a name="xset">If wacom_drv.(s)o was running while installing xsetwacom, xsetwacom can be -launched immediately after <i>make install</i> and <i>exit</i>. - -</a></p><p><a name="xset">If wacom_drv.o is installed by the same <i>make install</i> as xsetwacom -is, restarting X server is required to use the newly built wacom_drv.(s)o. We -strongly recommand to build and install wacom_drv.(s)o and xsetwacom from -the same release package since the out of sync wacom_drv.(s)o and xsetwacom -may crash your X server. -</a><a name="cpl"> -</a></p><h2><a name="cpl">13.3 - Building wacomcpl</a></h2> - -<p><a name="cpl">wacomcpl is written in tcl/tk. It uses libwacomxi.so and xsetwacom to -communicate with Wacom XFree86/Xorg driver, wacom_drv.(s)o. So, to run -wacomcpl, tcl/tk should be installed, libwacomxi.so and xsetwacom should -be built and installed. - -</a></p><p><a name="cpl">libwacomxi.so and xsetwacom are enabled by -default in the configure script. By default, the script will assume -that tcl/tk is installed under /usr. That is, tcl.h and tk.h should be -under /usr/include; libtcl.so.0 and libtk.so.0 should be under -/usr/lib. Let's see what we get from configure: -</a></p><blockquote><pre><a name="cpl">[jej@ayukawa linuxwacom]$./configure -... ----------------------------------------- - BUILD ENVIRONMENT: - architecture - i686 - linux kernel - yes 2.4 - module versioning - yes - kernel source - yes /usr/src/linux - XFree86 - no - XLib - yes /usr/X11R6 - TCL - yes /usr - TK - yes /usr - ncurses - yes - - BUILD OPTIONS: - wacom.o - no - wacdump - yes - xidump - yes - libwacomcfg - yes - libwacomxi - yes - xsetwacom - yes - hid.o - no - usbmouse.o - no - evdev.o - no - mousedev.o - no - input.o - no - tabletdev.o - no - wacom_drv.o - no ----------------------------------------- -</a></pre></blockquote> - -<p><a name="cpl">As shown above, the build options indicate that libwacomxi and xsetwacom -will be built. If not, then scroll back through the configuration to see -if there aren't any errors or warnings that would explain this. - -</a></p><p><a name="cpl">For example, on another system, I have installed tcl/tk under /usr/local/ActiveTcl. -That is, tcl.h and tk.h are under /usr/local/ActiveTcl/include. If I run configure -without options, I get: - -</a></p><blockquote><pre><a name="cpl">[jej@ayukawa linuxwacom]$./configure -... ----------------------------------------- - BUILD ENVIRONMENT: - architecture - i686 - linux kernel - yes 2.4 - module versioning - yes - kernel source - yes /usr/src/linux - XFree86 - no - XLib - yes /usr/X11R6 - TCL - no - TK - no - ncurses - yes - GTK - 2.0.6 - - BUILD OPTIONS: - wacom.o - no - wacdump - yes - xidump - yes - libwacomcfg - yes - libwacomxi - no - xsetwacom - yes - hid.o - no - usbmouse.o - no - evdev.o - no - mousedev.o - no - input.o - no - tabletdev.o - no - wacom_drv.o - no ----------------------------------------- -</a></pre></blockquote> - -<p><a name="cpl">The build options show that libwacomxi will not be built. When I scroll -back through the configuration, I see: - -</a></p><blockquote><pre><a name="cpl">... -checking for tcl header files... not found; tried /usr/include/tcl.h -*** -*** WARNING: -*** The tcl development environment does not appear to -*** be installed. The header file tcl.h does not appear -*** in the include path. Do you have the tcl rpm or -*** equivalent package properly installed? Some build -*** features will be unavailable. -*** -checking for tk header files... not found; tried /usr/include/tk.h and /include/tk.h -*** -*** WARNING: -*** The tk development environment does not appear to -*** be installed. The header file tk.h does not appear -*** in the include path. Do you have the tk rpm or -*** equivalent package properly installed? Some build -*** features will be unavailable. -*** -checking ncurses.h usability... yes -checking ncurses.h presence... yes -checking for ncurses.h... yes -*** -*** WARNING: -*** libwacomxi requires tcl environment; libwacomxi will not be built. -*** -... -</a></pre></blockquote> - -<p><a name="cpl">Then I run configure with option --with-tcl=/usr/local/ActiveTcl: - -</a></p><blockquote><pre><a name="cpl">[jej@ayukawa linuxwacom]$./configure --with-tcl=/usr/local/ActiveTcl -... ----------------------------------------- - BUILD ENVIRONMENT: - architecture - i686 - linux kernel - yes 2.4 - module versioning - yes - kernel source - yes /usr/src/linux - XFree86 - no - XLib - yes /usr/X11R6 - TCL - yes /usr/local/ActiveTcl - TK - yes /usr/local/ActiveTcl - ncurses - yes - - BUILD OPTIONS: - wacom.o - no - wacdump - yes - xidump - yes - libwacomcfg - yes - libwacomxi - yes - xsetwacom - yes - hid.o - no - usbmouse.o - no - evdev.o - no - mousedev.o - no - input.o - no - tabletdev.o - no - wacom_drv.o - no ----------------------------------------- -</a></pre></blockquote> - -<p><a name="cpl"><b>Note:</b> You may need to issue the following commands before running wacomcpl: - -</a></p><blockquote><pre><a name="cpl">[jej@ayukawa linuxwacom]$export LD_LIBRARY_PATH=/usr/local/ActiveTcl/lib:$LD_LIBRARY_PATH -[jej@ayukawa linuxwacom]$su -[jej@ayukawa linuxwacom]#cd /usr/local/ActiveTcl/lib -[jej@ayukawa lib]#ln -s libtcl.8.4.so libtcl.so.0 -[jej@ayukawa lib]#ln -s libtk.8.4.so libtk.so.0 -</a></pre></blockquote> - -<p><a name="cpl">If your tcl and tk are installed on different paths, you'll need to -specify them separately. Suppose that your tcl is under /usr/local/tcl8.4 -and your tk is under /usr/local/tk8.4, the proper configuration and setup -commands will be: - -</a></p><blockquote><pre><a name="cpl">[jej@ayukawa linuxwacom]$./configure --with-tcl=/usr/local/tcl8.4 --with-tk=/usr/local/tk8.4 -[jej@ayukawa linuxwacom]$export LD_LIBRARY_PATH=/usr/local/tcl8.4/lib:/usr/local/tk8.4/lib:$LD_LIBRARY_PATH -[jej@ayukawa linuxwacom]$su -[jej@ayukawa linuxwacom]#cd /usr/local/tcl8.4/lib -[jej@ayukawa lib]#ln -s libtcl.8.4.so libtcl.so.0 -[jej@ayukawa lib]#cd /usr/local/tk8.4/lib -[jej@ayukawa lib]#ln -s libtk.8.4.so libtk.so.0 -</a></pre></blockquote> - -<p><a name="cpl">Next, run <i>make</i>. The output will be stored in the linuxwacom -package's src/wacomxi and src/wacomxi/.libs directories. They will be -installed by running <i>make install (you need to switch to superuser -to run this command)</i>. -</a><a name="builddrv"> -</a></p><h2><a name="builddrv">13.4 - Building wacom_drv.o from Scratch</a></h2> -<h3><a name="builddrv">Introduction</a></h3> - -<p><a name="builddrv">I should tell you out-right that this is a time consuming process. - -</a></p><p><a name="builddrv">Why would you want to do this? Two reasons. One, you are a developer -and need to make changes to the source code directly. Two, your distribution -uses c libraries or configuration options that are not compatible with the -wacom_drv.o file that I provide. People running libc5 for instance, would -need to build their own driver. - -</a></p><blockquote><div class="diff"> -<a name="builddrv">Timothy Klein has submitted a brief howto for compiling on Debian Stable -which is still running XFree86 4.1 as of this writing. It covers steps -one through four of this document, and a savvy developer should be able -to figure out step five on his own. If someone solves step five and -generates a patch to Makefile.am, I'll see what I can do about getting -it into the configuration script. That document is on the </a><a href="#debwcmdrv">Installing wacom driver On Debian</a> page. -</div></blockquote> - -<p>You will need the X source code to rebuild the wacom_drv.o driver. -The build configuration for X generates a number of header files that are -necessary but not installed by default on most distributions. Consequently, -you will need to not only get the source, but build it, practically in its -entirety. Then, after all that, the configure script can be instructed to -hook into the X build tree and rebuild wacom_drv.o at any time without -having to rebuild X again. - -</p><p>Since I am running Redhat 8.0 and cannot really pull down the original -XFree86 4.2.0 source code, compile it, and expect it to work on my -system, I need to instead use the source RPM provided by Redhat. If you -choose to go this route, I provide pretty detailed instructions for making -this work. If your distribution works differently, or you are using Gentoo -where most everything is source code by default, you'll need to handle this -as best as possible according to your particular situation. - -</p><p></p><h3>Step One: Get The Source</h3> - -<p>On Redhat 8.0, I discovered the version number for my currently installed -XFree86 packages by running <i>rpm -q XFree86</i>. This reported version -4.2.0-72, therefore the source package is XFree86-4.2.0-72.src.rpm. -I downloaded the package from Redhat directly and installed it to the system -as follows: - -</p><blockquote><pre>[root@sen src]# rpm -ivh XFree86-4.2.0-72.src.rpm - 1:XFree86 ########################################### [100%] -</pre></blockquote> - -<p>This installs a number of files to the /usr/src/redhat directory, -particularly in the SOURCES and SPECS subdirectories. Other distributions -undoubtedly install elsewhere. Look for the XFree86.spec file which should -be located in the SPECS directory. This file contains all the information -necessary to patch the orginal XFree86-4.2.0 source code to the level that -Redhat is distributing in their regular binary package. The source code -and patch files are located in SOURCES. - -</p><h3>Step Two: Build the Source</h3> - -<p>This step describes how to build the source from the RPM itself. If -you are building from some other mechanism, I honestly cannot offer much -assistance since I generally don't build my X system from scratch. -If you'd like to write up a short section on building the -server for your particular distribution, I would be happy to include it here. - -</p><p>Next, you don't actually have to build the entire thing. The -point at which the xf86Wacom.c driver can be built however, -is not until somewhere in the middle of the build process. The driver -depends on a number of header files that are created dynamically so until -they are generated, wacom_drv.o cannot be compiled. My solution -was to open a separate terminal in the wacom driver directory and -periodically attempt to build it. When it successfully built, I stopped -the X build process. Here's how to build the source for an RPM that's -been exploded out into the SPECS and SOURCES directories. - -</p><blockquote><pre>[root@sen root]# cd /usr/src/redhat -[root@sen redhat]# rpmbuild -bc SPECS/XFree86.spec -</pre></blockquote> - -<p>Not every distribution has <i>rpmbuild</i>; try using just <i>rpm</i> -instead. At some point, Redhat split the build functionality into separate -programs. If after looking through the <i>rpm</i> man page, you still -cannot get this to work, send me some email, and I'll look into it. - -</p><p>The important item is the "-bc" option of <i>rpmbuild</i> which unpacks, -patches, and builds the source without actually installing. While it is also -possible to simply unpack and patch using the "-bp" option, there does not -seem to be a way to just build. The "-bc" option simply deletes all the -files provided by "-bp" and recreates them again. The downside of this is -that if you wanted to simply unpack, patch, and then copy the new xf86Wacom.c -file over the old one, you'll find that the build step deletes it and starts -over again. I have gotten this to work by creating a new patch file, but -this requires a bit more effort, so I don't recommend it right off. - -</p><h3>Step Three: Build the Original Driver</h3> - -<p>The xf86Wacom.c file is buried pretty deep in the X build tree. If it -is in a different location than the one I have provided below, try using -<i>find . -name xf86Wacom.c</i> from the BUILD directory. - -</p><blockquote><pre>[root@sen redhat]# cd BUILD/XFree86-4.2.0/xc/programs/Xserver/hw/xfree86/input/wacom -[root@sen wacom]# ls -Imakefile wacom.man xf86Wacom.c.Wacom-USB-driver-a25-update -Makefile xf86Wacom.c -</pre></blockquote> - -The "a25-update" file is the original xf86Wacom.c file before Redhat's patch. -If you open xf86Wacom.c, you'll find that it is version 25, at least as -of this writing and this distribution. The presence of the Makefile means -that the configuration has at least been run for this directory. If you -have built a sufficient portion of the X source files, then all the header -files that you need have been generated, and you can build xf86Wacom.c. Try -it, and if it does not build, wait a bit. The absence of xf86Version.h -for instance, is a good indication that the build process is not ready. - -<blockquote><pre>[root@sen wacom]# make -rm -f xf86Wacom.o -gcc -O2 -march=i386 ... -c xf86Wacom.c -ld -r xf86Wacom.o -o wacom_drv.o -</pre></blockquote> - -<h3> Step Four: Automating the Build Process</h3> - -<p>By configuring the package with the --with-xf86 option set to the XFree86 -build tree, you can build the driver outside of the X build tree. -</p><blockquote><pre>[jej@ayukawa wacom]$ ./configure \ - --with-xf86=/usr/src/redhat/BUILD/XFree86-4.2.0 -... -BUILD ENVIRONMENT: - XFree86 - yes - BUILD OPTIONS: - wacom_drv.o - yes -[jej@ayukawa wacom]$ make -</pre></blockquote> - -<p>The makefile rule which builds the driver is contained within src/Makefile.am -and is modified according to the configuration to generate a rule similar to -this in src/Makefile: - -</p><blockquote><pre>xf86Wacom.o: xf86Wacom.c - gcc -O2 -march=i386 -mcpu=$(ARCHITECTURE) -pipe -ansi \ - -pedantic -Wall -Wpointer-arith -fno-merge-constants \ - -I. -I$(XF86_DIR)/programs/Xserver/hw/xfree86/common \ - -I$(XF86_DIR)/programs/Xserver/hw/xfree86/loader \ - -I$(XF86_DIR)/programs/Xserver/hw/xfree86/os-support \ - -I$(XF86_DIR)/programs/Xserver/include \ - -I$(XF86_DIR)/programs/Xserver/mi \ - -I$(XF86_DIR)/exports/include/X11 \ - -I$(XF86_DIR)/include/extensions \ - -I$(XF86_DIR) \ - -I$(XF86_DIR)/exports/include \ - -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 -DXF86BIGFONT -DDPMSExtension -DPIXPRIV -DPANORAMIX \ - -DRENDER -DGCCUSESGAS -DAVOID_GLYPHBLT -DPIXPRIV \ - -DSINGLEDEPTH -DXFreeXDGA -DXvExtension -DXFree86LOADER \ - -DXFree86Server -DXF86VIDMODE -DXvMCExtension \ - -DSMART_SCHEDULE -DBUILDDEBUG -DXResExtension \ - -DX_BYTE_ORDER=X_LITTLE_ENDIAN -DNDEBUG -DFUNCPROTO=15 \ - -DNARROWPROTO -DIN_MODULE -DXFree86Module -DLINUX_INPUT \ - -o xf86Wacom.o -c xf86Wacom.c -</pre></blockquote> - -<blockquote><div class="diff">similar rules applie to wcmSerial.c, wcmUSB.c, -wcmISDV4.c, wcmCommon.c, wcmCompat.c, wcmConfig.c, and, wcmFilter.c. -</div></blockquote> - -<p>The options and directories specified come directly from the output of the -make command in the previous step. All the root and parent directories have -been replaced with the macro XF86_DIR which in this case is set by the -configuration script to /usr/src/redhat/BUILD/XFree86-4.2.0/xc. If the -options that you see in your build are identical to those above, then the -default rule will work for you now. If not, you'll need to make some -alterations. You can update the Makefile.am file and rerun automake, -update the Makefile.in and rerun configure, or just update the Makefile -directly. - -</p><p>So long as the X build tree exists, the include directories will point to -the correct locations, and the driver will build. If space is an issue, you -can probably remove all the non-essential directories, but be careful; the -dependency tree in X is huge. - -<a name="debwcmdrv"> -</a></p><h2><a name="debwcmdrv">13.5 - Installing wacom driver On Debian</a></h2> -<a name="debwcmdrv">The following documentation for building wacom driver on Debian was -written by Olivier Lecarme. You can also refer to Olivier's page -</a><a href="http://www.i3s.unice.fr/%7Eol/success.html">here</a> for updates. - -<br><br><br><br> - -Copyright (C) June 14, 2005 Olivier Lecarme. <br><br> - -<pre>I'm using the Sid version of Debian, but I was told that the Sarge -distribution, recently become the stable one, already contains what -is necessary. Version 2.6.11 of the kernel is the highly preferred -one by people maintaining the Linux Wacom software. - -<b>Download the 2.6.11 kernel</b> - -I was completely unsuccessful when trying to configure and compile -my own kernel: certainly I omitted some capital module, but I could -not decide what it was. Thus, I chose the last pre-compiled kernel. - - 1. apt-get kernel-image-2.6.11-1-686 - - 2. apt-get kernel-headers-2.6.11-1-686 - -If you use Lilo, configure your /etc/lilo.conf file, taking into -account that this kernel needs an initrd= line. - -<b>Optionally</b> - -If your case is irrelevant, please skip this section and the following one. - - 1. I Have a Broadcom NetXtreme BCM5751 Ethernet card, which needs -the tigon3 driver, unavailable in Debian kernel 2.6.11. The solution is here. - - Thus I got the package: - - 1. cd /usr/src - 2. wget http://www.acm.rpi.edu/~dilinger/kernel-source-nonfree-2.6.11 -/kernel-nonfree-modules-2.6.11-1-686-2.6.11-1_i386.deb - - 2. I have an ATI X 300 video card, whose driver is not available -in Debian kernel 2.6.11. The solution is here. - - Thus I got the packages: - - 1. for the driver: wget http://www.stanchina.net/~flavio/ -debian-fglrx-xfree86/fglrx-driver_8.12.10-1_i386.deb - 2. and for the kernel module: wget http://www.stanchina.net/~flavio -/debian-fglrx-modules/fglrx-kernel-2.6.11-1-686-smp_8.12.10-1+2.6.11-2_i386.deb - -<b>Install the optional packages</b> - - 1. cd /usr/src - - 2. dpkg -i kernel-nonfree-modules-2.6.11-1-686_2.6.11-1_i386.deb - - 3. dpkg -i fglrx-driver_8.12.10-1_i386.deb - - 4. dpkg -i fglrx-kernel-2.6.11-1-686_8.12.10-1+2.6.11-2_i386.deb - -<b>Install the wacom tools package</b> - - 1. apt-get install wacom-tools - - 2. dpkg-reconfigure wacom-kernel-source - - Since your debconf configuration probably did not ask for the lowest -priority questions, this step is needed. You might also use it later if you -update your kernel, for instance. - - When asked whether you want to build the modules, answer yes, and tell -where the headers are located (normally /usr/src/kernel-headers-2.6.11-1-686). - -<b>Prepare for the /dev/input/wacom link</b> - -In /etc/udev/rules.d/10-wacom.rules, add the following line: - -KERNEL="event*", SYSFS{idVendor}="056a", NAME="input/%k", SYMLINK="input/wacom%e" - -Thus the drivers will find the Wacom tablet, whatever its /dev/input/eventX address is. - -<b>Change your XF86Config-4 file</b> - -The important sections are: - - 1. The ServerLayout section: - -Section "ServerLayout" - [ ... ] - InputDevice "stylus" "SendCoreEvents" - InputDevice "eraser" "SendCoreEvents" - InputDevice "cursor" "SendCoreEvents" - InputDevice "pad" -EndSection - - 2. The InputDevice sections: - -Section "InputDevice" - Identifier "stylus" - Driver "wacom" - Option "Type" "stylus" - Option "USB" "on" - Option "Threshold" "10" - Option "Device" "/dev/input/wacom" -EndSection - -Section "InputDevice" - Identifier "eraser" - Driver "wacom" - Option "Type" "eraser" - Option "USB" "on" - Option "Threshold" "10" - Option "Device" "/dev/input/wacom" -EndSection - -Section "InputDevice" - Identifier "cursor" - Driver "wacom" - Option "Type" "cursor" - Option "USB" "on" - Option "Threshold" "10" - Option "Device" "/dev/input/wacom" -EndSection - -Section "InputDevice" - Identifier "pad" - Driver "wacom" - Option "Device" "/dev/input/wacom" - Option "Type" "pad" - Option "USB" "on" -EndSection - - 3. The section dealing with your normal mouse must be considered too. See <a href="#mouse1">Mouse1 (for some 2.6 systems)</a>. -I didn't use /dev/psaux nor /dev/input/mice. /dev/input/mouse0 works for a PS/2 -mouse. For a USB mouse, there is a problem mentioned in the <b>Remaining problems</b>. - - 4. If you use the ATI X300 card, you need to change also the Device section: - -Section "Device" - Identifier "ATI" - Driver "fglrx" - Option "VideoOverlay" "on" - Option "OpenGLOverlay" "off" - Option "UseInternalAGPGART" "no" -EndSection - -<b>Final steps</b> - - 1. Reboot. This will also restart the X server, of course. - 2. Enjoy! - -<b>If you want to use the expresskeys of your Intuos tablet</b> - -If you do nothing more, the pad is not usable at all. However, you will find <a href="http://web.telia.com/%7Eu46133770/wacom/index.html">here</a> a specific -tool for having the pad available in various programs, for example XTerm, Gimp, or Blender. - -This tool is very easy to compile, install, and use. If you want to use the pad -in Gimp, do <b>not</b> enable it in "Preferences -> Input Devices -> Configure -the extended input devices", contrarily to the three other tools (stylus, eraser, -and cursor). You can easily configure what the expresskeys send, according to -your tastes, and use only them for the tasks that need a good control of the -stylus or eraser. - -<b>Remaining problems</b> - -If your tablet is always plugged, everything works perfectly. If you want to plug -it out, for example in order to move it onto another computer, and then to plug -it back later, problems begin. - -For the present, you must take care of the following things: - - 1. If you plug in the tablet again, the corresponding driver is not informed -of this, thus you must restart the X server. - - 2. If the tablet is plugged when you reboot, and you have an USB mouse, maybe -the /dev/input address of this mouse is not the same as the previous time. Thus -you will have to change this in your XF86Config-4 file. - - 3. If you use GDM or KDM or XDM, you should plug in the tablet after rebooting, -but before the X server starts, which is somewhat difficult! Thus you will be forced -to restart the X server, i.e. kill it (Ctrl+Alt+Backspace) and not simply logging out. - -<b>Final remarks</b> - - I would like to thank all persons who helped me, on the LinuxWacom or the -Gimp-user discussion lists, especially Carol Spears, Karine Delvare, Ping Cheng, and Ron. - -</pre> -<a name="ppcwcmdrv"> -</a><h2><a name="ppcwcmdrv">13.6 - Building wacom driver On PowerMac</a></h2> -<a name="ppcwcmdrv">The following documentation for building wacom driver on PowerMac [silver] -was written by Joseph E. Sacco. If you have any problems or questions, -go ahead and post them to the list, or send email to me directly. I'll -forward your email on to Joseph. - -<br><br><br><br> - -Copyright (C) 2004 Joseph E. Sacco<br><br> - -</a><pre><a name="ppcwcmdrv">System: - -<< Hardware >> -* PowerMac [silver] with dual 533 MHz G4 [7410] CPU's, 1GB RAM, - (3) 73 GB SCSI drives -* Contour UniMouse [USB, optical, three button] -* Wacom Intuos Tablet [USB]: GD-1218-U - * 4-d mouse - * pen - * air brush - -<< Software >> -* Yellow Dog Linux 3.0.1 [Redhat variant for PPC] -* kernel: 2.4.25-ben1 -* linuxwacom-0.6.1 - -* XFree86-4.3.0-2.1e -* atk-1.6.0-1 -* freetype-2.1.3-4 -* gcc-3.3 -* gtk+-2.4.0 -* glib2-2.4.0 -* ncurses-5.2-28 -* pango-1.4.0 - -============================================================ - -I have a Wacom Intuos tablet "working" [after a fashion] on a PPC -running Yellow Dog Linux 3.0.1. - -<< What works >> -* input devices: - * cursor movement - * button clicks - * wheel rotation [as seen from wacdump] - * pressure [as seen from wacdump & gimp] - * tilt [as seen from wacdump] - -* applications: - * wacdump - * xidump - * xev - * xinput-1.2 - * gimp-1.25 & gimp-2.0 - * dia-0.9.2 - -< What does *not* work >> -* input devices: - * Mode "Relative" for pen & air brush [should it???] - -* applications: - * xsetwacom - * wacomcpl [because of xsetwacom] - -There are some issues I would like to report. ----------------------------------------------------------------------------------------------------------------------------------------- - -* Makefiles -The makefiles are set up for Intel architecture. Some options are not -applicable for PPC's. - -[ from ./src/2.4.22/Makefile.in ] -KCFLAGS = -Wall $(DEBUG_FLAGS) -D__KERNEL__ \ - -DMODULE -DEXPORT_SYMTAB $(MODS) \ - -Wstrict-prototypes -Wno-trigraphs -O2 \ - -fno-strict-aliasing \ - -fno-common -fomit-frame-pointer -pipe \ - ===> -mpreferred-stack-boundary=2 \ - ===> -march=$(ARCHITECTURE) - -The last two options are not applicable to a PPC. - -A more appropriate set of flags, taken from building the 2.4.25 kernel -modules, might be: - -KCFLAGS = -Wall $(DEBUG_FLAGS) -D__KERNEL__ \ - -Wstrict-prototypes -Wno-trigraphs -O2 \ - -fno-strict-aliasing -fno-common -fomit-frame-pointer \ - -fsigned-char -msoft-float -pipe -ffixed-r2 \ - -Wno-uninitialized -mmultiple -mstring \ - -DMODULE -DMODVERSIONS -iwithprefix - -[ from ./src/Makefile.in ] -$(XF86OBJS): xf86Wacom.c Makefile - ==> gcc -O2 $(DEPFLAGS) -march=i386 -mcpu=$(ARCHITECTURE) -pipe -ansi \ - -pedantic -Wall -Wpointer-arith $(NO_MERGE_CONSTANTS) \ - -I. -I$(XF86_DIR)/programs/Xserver/hw/xfree86/common \ - -I$(XF86_DIR)/programs/Xserver/hw/xfree86/loader \ - -I$(XF86_DIR)/programs/Xserver/hw/xfree86/os-support \ - -I$(XF86_DIR)/programs/Xserver/include \ - -I$(XF86_DIR)/programs/Xserver/mi \ - -I$(XF86_DIR)/exports/include/X11 \ - -I$(XF86_DIR)/include/extensions \ - -I$(XF86_DIR) \ - -I$(XF86_DIR)/exports/include \ -==> -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 -DXF86BIGFONT -DDPMSExtension -DPIXPRIV -DPANORAMIX \ - -DRENDER -DGCCUSESGAS -DAVOID_GLYPHBLT -DPIXPRIV \ - -DSINGLEDEPTH -DXFreeXDGA -DXvExtension -DXFree86LOADER \ - -DXFree86Server -DXF86VIDMODE -DXvMCExtension \ - -DSMART_SCHEDULE -DBUILDDEBUG -DXResExtension \ - -DX_BYTE_ORDER=X_LITTLE_ENDIAN -DNDEBUG -DFUNCPROTO=15 \ - -DNARROWPROTO -DIN_MODULE -DXFree86Module $(LINUX_INPUT) \ - -o $@ -c $(subst .o,.c,$@) - -A more appropriate set of flags, taken from building XFree86-4.3.0, might be: - -$(XF86OBJS): xf86Wacom.c Makefile - gcc -O2 $(DEPFLAGS) -mcpu=$(ARCHITECTURE) -pipe -ansi \ - -pedantic -Wall -Wpointer-arith $(NO_MERGE_CONSTANTS) \ - -I. -I$(XF86_DIR)/programs/Xserver/hw/xfree86/common \ - -I$(XF86_DIR)/programs/Xserver/hw/xfree86/loader \ - -I$(XF86_DIR)/programs/Xserver/hw/xfree86/os-support \ - -I$(XF86_DIR)/programs/Xserver/include \ - -I$(XF86_DIR)/programs/Xserver/mi \ - -I$(XF86_DIR)/exports/include/X11 \ - -I$(XF86_DIR)/include/extensions \ - -I$(XF86_DIR) \ - -I$(XF86_DIR)/exports/include \ - -Dlinux -D__powerpc__ -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 -DXF86BIGFONT -DDPMSExtension -DPIXPRIV -DPANORAMIX \ - -DRENDER -DGCCUSESGAS -DAVOID_GLYPHBLT -DPIXPRIV \ - -DSINGLEDEPTH -DXFreeXDGA -DXvExtension -DXFree86LOADER \ - -DXFree86Server -DXF86VIDMODE -DXvMCExtension \ - -DSMART_SCHEDULE -DBUILDDEBUG -DXResExtension \ - -DX_BYTE_ORDER=X_BIG_ENDIAN -DNDEBUG -DFUNCPROTO=15 \ - -DNARROWPROTO -DIN_MODULE -DXFree86Module $(LINUX_INPUT) \ - -o $@ -c $(subst .o,.c,$@) - -where $(ARCHITECTURE) = powerppc [ppc will not work] - -* Kernel modules -I experimented with different ways of building [and loading] the kernel -modules: - * evdev.o - * hid.o - * mousedev.o - * wacom.o - -I settled on building the modules within the existing framework for building -the Linux kernel rather than using the makefiles provided by linuxwacom-0.6.1. -I did so to insure that I got all the PPC dependency stuff right. - -* Hotplug kernel module issues -I had some issues using 'modprobe' to load the wacom kernel module that forced -me to reconfigure and rebuild the 2.4.25-ben1 kernel. - -A typical YDL kernel build for a PowerMac statically links most of the input -core support into the kernel: - - [from .config file provided by YDL] - # Input core support - # - CONFIG_INPUT=y - CONFIG_INPUT_KEYBDEV=y - CONFIG_INPUT_MOUSEDEV=y - CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 - CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 - CONFIG_INPUT_JOYDEV=m - CONFIG_INPUT_EVDEV=y - -I had initially built only wacom.o as a loadable module. The other modules -were statically linked into the kernel. - -When wacom.o was loaded using: - - $ /sbin/insmod wacom.o - -all went well: - -[output from /var/log/messages] - -Mar 24 10:26:33 plantain kernel: usb.c: registered new driver wacom -Mar 24 10:26:33 plantain kernel: Reporting max 45720, 31680 -Mar 24 10:26:33 plantain kernel: wacom.c: Setting tablet report for tabletdata -Mar 24 10:26:33 plantain kernel: input4: Wacom Intuos 12x18 on usb2:3.0 -Mar 24 10:26:33 plantain kernel: wacom.c: v1.30-j0.6.1 Vojtech Pavlik -<vojtech@suse.cz> -Mar 24 10:26:33 plantain kernel: wacom.c: USB Wacom Graphire and Wacom Intuos -tablet driver (LINUXWACOM-DEBUG) -Mar 24 10:26:33 plantain kernel: wacom_events - -When wacom.o was loaded using: - - $ /sbin/modprobe wacom - -the module failed to load: - - $ /sbin/rmmod wacom - $ /sbin/modprobe wacom - modprobe: Can't locate module evdev which is needed for wacom - -I was perplexed about this failure because "evdev" was statically linked into -the kernel. I puzzled over this for a while and concluded that it had -something to do with how USB hotplug was configured. - -I arrived at this conclusion by unplugging the tablet, waiting, and then -plugging it back in. I found that the tablet "worked" but there are complaints -in /var/log/messages: - -Mar 24 10:34:51 plantain kernel: usb.c: USB disconnect on device 10:19.0-1 -address 3 - -Mar 24 10:35:53 plantain kernel: hub.c: new USB device 10:19.0-1, assigned -address 4 -Mar 24 10:35:53 plantain kernel: Reporting max 45720, 31680 -Mar 24 10:35:53 plantain kernel: wacom.c: Setting tablet report for tablet -data -Mar 24 10:35:53 plantain kernel: input4: Wacom Intuos 12x18 on usb2:4.0 -Mar 24 10:35:53 plantain kernel: wacom_intuos_irq: tool change 0x094 -Mar 24 10:35:56 plantain /etc/hotplug/usb.agent: Setup wacom for USB product -56a/24/101 -Mar 24 10:35:56 plantain /etc/hotplug/usb.agent: Setup evdev mousedev for USB -product 56a/24/101 -Mar 24 10:35:56 plantain modprobe: modprobe: Can't locate module evdev -Mar 24 10:35:56 plantain modprobe: modprobe: Can't locate module mousedev - -I really don't understand how the USB hotplug mechanisms are supposed to be -configured. Yes... I did look at the scripts in /etc/hotplug. Yes.. I did -attempt a few unsucessful modifications to usb.handmap and usb.distmap. I -pondered over this for a while and then decided on a work-around: - -I reconfigured and rebuilt the kernel to dynamically load - * evdev.o - * hid.o - * mousedev.o - * wacom.o - -which "eliminated" the problem. - -If someone out there knows what should have been done to allow modprobe to -successfully load wacom when evdev and friends are already statically linked -into the kernel, please send me email. - -* XFree86 module: wacom_drv.o -I rebuilt wacom_drv.o using the linuxwacom-0.6.1 makefile and the flags listed -above. The build was uneventful. - -* Mouse1 -I do not have a Mouse1 entry in XF86Config. I mention this because there is an -obscure reference in the documentation to potential mouse conflict problems -when running a USB Wacom mouse on a system with a USB mouse. The USB mouse -connected to the system and the Wacom input devices all seem to work. - -On my system: - - /dev/mouse is a link to /dev/input/mice - -Mouse0 is configured in XF86Config as: - -Section "InputDevice" - Identifier "Mouse0" - Driver "mouse" - Option "ZAxisMapping" "4 5" - Option "Protocol" "IMPS/2" - Option "Device" "/dev/input/mice" -EndSection - -Maybe something nasty is going on that I don't know about. Thoughts??? - -* xsetwacom -There are problems... - -The 'list' command prints stuff: - -$ xsetwacom list -eraser eraser -stylus stylus -cursor cursor - -The set command fails: - -$ xsetwacom -v set stylus FileModel -Set: sending 100 0 (0x0) -Error (5): WacomConfigSetRawParam: Unknown X error -Set: Failed to set stylus value for 'FileModel' - -Looking at the code, I see that it is failing in a call to -XChangeDeviceControl() made from WacomConfigSetRawParam(). I also poked -around in this one with GDB. The X-Display gets opened properly. Things look -OK until the request is dispatched, which then returns an unknown X error. - -I also tried to use xsetwacom to toggle the cursor mode between relative and -absolute. Again the command fails with an unkown X error. Note that the -XFree86 command 'xsetmode' works fine. - --Joseph -</vojtech@suse.cz></a></pre> -<a name="debwacomnosrc"> -</a><h2><a name="debwacomnosrc">13.7 - Building wacom driver On Fedora Core 3</a></h2> -<a name="debwacomnosrc">The following documentation for building wacom kernel modules and x.org -driver on Fedora Core 3 was written by Paul Duffy. If you have any problems -or questions, go ahead and post them to the list, or send email to me directly. -If I cannot provide a satisfactory answer, I'll forward your email on to Paul. - -<br><br><br><br> - -Copyright (C) 2005 Paul Duffy<br><br> - -</a><pre><a name="debwacomnosrc">Procedure for building linuxwacom package on Fedora Core 3 with 2.6 series -kernel. These instructions are current as of May 23, 2005. -There are several reasons why FC3 is different. The two main reasons -being: - -- evdev, hid-core and mousedev are compiled into the kernel core so you can't -just recompile them as modules. - -- the Fedora Core kernel is heavily patched, which I don't mind as it means my -Creative Live! Drive II works, but it does mean that compiling the kernel -from www.kernel.org may lose you some hardware support. - -Additionally, Red Hat no longer supply a simple linux-source rpm so if you -want the official kernel source for Fedora Core 3 you're going to have to use -the source RPM. - -At this stage, I am assuming that you have a fully updated system and are -using kernel 2.6.11-1.14_FC3 - -<b>What you will need:</b> - -At this stage you're going to need all of the development packages required to -compile the kernel (gcc, automake, etc) and the xorg-x11-sdk package -installed (under Development >> X Software Development). If you're unsure -where this all is, you can select the hat menu in KDE or Gnome and you want -to select System Settings >> Add/Remove Applications. - -If you're unsure as to exactly what you need to install, install everything -(except gcc-java, it causes problems with Sun or IBM java installs) assuming -you have the hard drive space. - -Also the vast majority of this will require you to be in SuperUser mode so you -might as well 'su' from the start; not normally advice I'd be giving anyone -but it's kinda necessary in this case. - -You have two choices for the first step; you can either download the kernel -SRPM from one of the mirrors at -http://fedora.redhat.com/download/mirrors.html where you can find the correct -package as updates/3/SRPMS/kernel-2.6.11-1.14_FC3.src.rpm and install it -with - -rpm -ivh kernel-2.6.11-1.14_FC3.src.rpm - -or you can use - -up2date --get-source kernel - -Either method should leave you with a lot of files in /usr/src/redhat/SOURCES -and the file /usr/src/redhat/SPECS/kernel-2.6.spec -At this stage, don't worry about all the files starting linux-2.6.9... the -main file you are looking for is linux-2.6.11.tar.bz2. As long as that's -there you should be fine. - -Now, to actually get all the kernel sources setup in a compilable form you -need to run the command - -rpmbuild -bp --target=<arch> /usr/src/redhat/SPECS/kernel-2.6.spec - -If you don't know what <arch> is, run the command - -uname -m - -and it should tell you. -Of course, it should be noted at this point that if my architecture is i686 -and I select that, what will actually be installed is the source -configuration for i386 and above so if you're still not sure but you know you -can run Windows then --target=i386 is a safe default. - -After everything has been setup the rpmbuild will have applied all the -standard patches and setup a default configuration so the only reason to run -'make config', or 'make xconfig', is to change something from the default. - -Having said this, I like to run 'make xconfig' to alter the selected chip the -kernel is going to compile for as it defaults to compiling for i386 whereas -anyone with a reasonably recent chip (Athlon, Pentium III even) is going to -want something a bit more advanced. - -So, the first thing you want to do, if you want most add-on modules to find -the kernel source without adding a really long command-line parameter, is to -add a symbolic link to the source directory. - -cd /usr/src -ln -s redhat/BUILD/kernel-2.6.11/linux-2.6.11 linux - -So now everything can find the current kernel source in /usr/src/linux - -cd linux -make xconfig - -select 'Processor type and features' and change 'Processor family' from 386 to -whatever it is you're running. -If you make a mistake and you don't know what you've done you can always close -the program and select 'Discard changes' and start again. -Otherwise, click on the floppy disk icon to save and exit safe in the -knowledge that you're not compiling for a CPU that doesn't even have a -floating point unit. - -OK, so by now you should have the basic kernel source setup and available -in /usr/src/linux and, due to the setup of the default kernel, we can't just -recompile a few modules, we have to recompile the whole kernel. - -So at this stage, we're just about where we'd like to be if we wanted to -compile the kernel as it is, with no support for the Intuos3 or any of the -Cintix range but if you've got an AthlonXP or a Pentium 4 you might get a -little bit more performance out of it. - -We now want to be getting the latest linuxwacom-0.6.8.tar.bz2 You may want to -setup your own arrangement for wherever you want it but your home directory -should be fine and... - -tar jxvf linuxwacom-0.6.8.tar.bz2 -cd linuxwacom-0.6.8 - -...and you're in the source directory for the code that enables proper Wacom -support. - -Now we need to copy just four files, usbmouse.c has been deprecated in favour -of hid-core.c and can be safely ignored, also we don't need to do anything to -input.c. Now we copy all the necessary source files. - -cd src/2.6.11 -cp evdev.c mousedev.c /usr/src/linux/drivers/input/ -cp hid-core.c wacom.c /usr/src/linux/drivers/usb/input/ - -Now, with the manual patching done everything should work and, unless I've -somehow missed a stage, everything should compile just fine. - -cd /usr/src/linux -make all - -Now, this is going to take a while, especially if your system's a bit aold -like mine so now would be a good time to get some tea, coffee, go down the -corner shop or have lunch. - -Assuming there have been no errors, everything should now be compiled. - -make modules_install -make install - -You need to install the modules first or 'make install' will quit, complaining -about there being no '/lib/modules/2.6.11-prep' and sulk in the corner. - -After all this, there's still one last thing you need to do and that's make -this new kernel the default on boot. You will need to -edit /boot/grub/menu.lst and change the 'default' value from 1 to 0. - -Those of you with nVidia and other such graphics cards who like their 3D -acceleration will need to reinstall the drivers before X Windows will work. - -As it is, on reboot you will need to change the boot parameters. When Grub -comes up, press a to alter the boot parameters. It is advisable at this stage -to remove 'rhgb' as, one of the effects of running the Red Hat Graphical Boot -is that if you want a change in the xorg.conf file to take effect you have to -reboot the entire system and this just gets to be a PITA when you're trying -to configure something. Then add '3' (without quotes) to the end of the line -to make FC3 boot to the command line. - -Right, so by now we should have the kernel set up to recognise whatever tablet -you have properly. We can check this. - -cat /proc/bus/usb/devices - -should give you a readout of every device on your usb system and we're looking -for the line which includes Vendor=056a - -With my Intuos 3 I have ProdID 00b1, manufacturer is listed as 'Tablet' and -Product is listed as PTZ-630 although this may differ depending on which -tablet you have and what size it is. - -The most important line is the one beginning with I: which should end with -'Driver=wacom'. - -If this is that case, congratulations, your kernel is now fully set up to -recgonise your tablet :o) - -Now, to get it running with X Windows we need to update the wacom_drv driver -and this, in itself is going to be different as the configuration script will -not know where to find your x11 SDK and so will efuse to compile the driver. - -The xorg SDK in the case of FC3 is located in /usr/X11R6/lib/Server and we can -tell the configuration script this - -./configure --with-xorg-sdk=/usr/X11R6/lib/Server - -should do the trick and - -make install - -should compile and install the module in the appropriate place. - -After all this is done, now all you need to do is setup the configuration -in /etc/X11 xorg.conf - -The ServerLayout section is at the start of the configuration file and, as an -example, mine looks like this: - -Section "ServerLayout" - Identifier "Default Layout" - Screen 0 "Screen0" 0 0 - InputDevice "Mouse0" "CorePointer" - InputDevice "Keyboard0" "CoreKeyboard" - InputDevice "eraser" "SendCoreEvents" - InputDevice "stylus" "SendCoreEvents" -EndSection - -Where Mouse3 and Mouse5 are the identifiers for the pen and eraser. - -My InputDevice sections look like this: - -Section "InputDevice" - Identifier "eraser" - Driver "wacom" -# Option "TopX" "0" -# Option "TopY" "0" -# Option "BottomX" "1600" -# Option "BottomY" "1200" - Option "Device" "/dev/input/event3" - Option "Type" "eraser" - Option "USB" "On" -EndSection - -Section "InputDevice" - Identifier "stylus" - Driver "wacom" -# Option "TopX" "0" -# Option "TopY" "0" -# Option "BottomX" "1600" -# Option "BottomY" "1200" - Option "Device" "/dev/input/event3" - Option "Type" "stylus" - Option "USB" "On" -EndSection - -It's important to note, at this point, that the TopX/Y and BottomX/Y options -are not actually necessary unless you have problem with the detection of the -tablet as all the lpi information is included in the source code for the -wacom module so it's perfectly safe to leave these out if you don't know what -the values should be. - -Also note, that at this stage I still don't have /dev/input/wacom and the -tablet appears on /dev/input/event3 - -If you're unsure as to which device your tablet is using, then wacdump should -be able to find it. It is, to be honest, a bit trial and error but you'll -know when you've found it as the readout will look like this: - -wacdump v0.5.2 - -MODEL=Wacom Intuos3 6x8 ROM=1.0-2 -CLS=USB VNDR=Wacom DEV=Intuos3 SUB=PTZ-630 - - - - -TOOLTYPE=NONE IN_PROX=+00000 (+00000 .. +00000) - BUTTON=+00000 (+00000 .. +00000) POS_X=+00000 (+00000 .. +40640) - POS_Y=+00000 (+00000 .. +30480) ROT_Z=+00000 (-00900 .. +00899) -DISTANCE=+00000 (+00000 .. +00015) PRESSURE=+00000 (+00000 .. +01023) - TILT_X=+00000 (+00000 .. +00127) TILT_Y=+00000 (+00000 .. +00127) -ABSWHEEL=+00000 (+00000 .. +01023) RELWHEEL=+00000 (-00001 .. +00001) -THROTTLE=+00000 (-01023 .. +01023) - - LEFT= MIDDLE= RIGHT= EXTRA= - SIDE= TOUCH= STYLUS= STYLUS2= - - -Once you've setup all the configuration with the correct input device execute - -init 5; exit - -and you should find yourself in X with a fully working graphics tablet. -Instructions for configuring GIMP 2.2 are the same as in the official HowTo. - -Good luck. - -regards, Paul - -</arch></arch></a></pre> -<a name="susewacom"> -</a><h2><a name="susewacom">13.8 - Building wacom driver On Suse 9.2</a></h2> - -<a name="susewacom">Nico Kadel-Garcia has provided a changed SPEC file for SuSE 9.2. -You can download the spec </a><a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1117278&group_id=69596&atid=525124">here</a>. - -<pre> -"There are only a few needed changes: use the new -software, throw out an old patch, teach it to use the right -options for x86_64 compilation, and stop it from -generating symlinks into /usr/include/X11 at compilation -time, and it's done. ". Nico said on Mar 21 2005. - -</pre><a name="laptop"> -</a><h2><a name="laptop">13.9 - Laptop Suspend/Resume Tips</a></h2> -<a name="laptop">Thomas Netter (tnetter at iniDOTunizhDOTc) kindly provided a solution -to the following problem: - -</a><blockquote><pre><a name="laptop">When laptop recovers from suspend/resume, XFree86/X.org no longer -registers the tablet. The laptop, however, receives all the tablet data -(I can "cat /dev/input/event2" and see the data). - -The only way I know for X to recover the tablet is to restart X. -</a></pre></blockquote> - -<a name="laptop">The peoblem lies in the step that when unplugging tablet cable while the -laptop is entering Suspend Mode. The proper steps to plug/unplug, suspend/resume -a Wacom tablet on a laptop are: - -</a><blockquote><pre><a name="laptop">- Fold the laptop's screen -- Wait 4 or 5 seconds for the tablet's orange LED to extinguish -- Unplug the tablet's USB cable - -THEN you can recover the tablet functionalities after resuming the -laptop and repluging the tablet. - -However, If you: -- Fold the laptop's screen -- Immediately unplug the tablet's USB cable before the LED extinguishes - -THEN you cannot recover the tablet functionalities after resuming the -laptop and replugging the tablet, even if you replug the tablet before -resuming the laptop. - -Therefore, old airline operations apply: Extinguish LEDs before take-off! - --Thomas -</a></pre></blockquote> -<a name="lic"> -</a><h2><a name="lic">13.10 - GNU GENERAL PUBLIC LICENSE</a></h2> -<a name="lic"> GNU GENERAL PUBLIC LICENSE<br> - Version 2, June 1991<br> -<br> - Copyright (C) 1989, 1991 Free Software Foundation, Inc.<br> - 675 Mass Ave, Cambridge, MA 02139, USA<br> - Everyone is permitted to copy and distribute verbatim copies<br> - of this license document, but changing it is not allowed.<br> -<br> - Preamble<br> -<br> - </a><p><a name="lic"> 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. - -</a></p><p><a name="lic"> 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. - -</a></p><p><a name="lic"> 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. - -</a></p><p><a name="lic"> 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. - -</a></p><p><a name="lic"> 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. - -</a></p><p><a name="lic"> 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. - -</a></p><p><a name="lic"> 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. - -</a></p><p><a name="lic"> The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - -</a></p><p><a name="lic"> 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". - -</a></p><p><a name="lic">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. - -</a></p><p><a name="lic"> 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. - -</a></p><p><a name="lic">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. - -</a></p><p><a name="lic"> 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></p><p><a name="lic"> a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - -</a></p><p><a name="lic"> 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. - -</a></p><p><a name="lic"> 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. - -</a></p><p><a name="lic">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. - -</a></p><p><a name="lic">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. - -</a></p><p><a name="lic">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. - -</a></p><p><a name="lic"> 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></p><p><a name="lic"> 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, - -</a></p><p><a name="lic"> 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, - -</a></p><p><a name="lic"> 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.) - -</a></p><p><a name="lic">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. - -</a></p><p><a name="lic">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. - -</a></p><p><a name="lic"> 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. - -</a></p><p><a name="lic"> 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. - -</a></p><p><a name="lic"> 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. - -</a></p><p><a name="lic"> 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. - -</a></p><p><a name="lic">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. - -</a></p><p><a name="lic">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. - -</a></p><p><a name="lic">This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - -</a></p><p><a name="lic"> 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. - -</a></p><p><a name="lic"> 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. - -</a></p><p><a name="lic">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. - -</a></p><p><a name="lic"> 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 - -</a></p><p><a name="lic"> 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. - -</a></p><p><a name="lic"> 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 -</a></p></td></tr></tbody></table></center> - -<br><br> - -<div class="copy" align="center"> - Copyright (C) 2002-2009 - LinuxWacom -Last updated April 29, 2009<br> - This website and its contents are licensed under the GNU GENERAL PUBLIC LICENSE.<br> -</div> -</body></html>
\ No newline at end of file diff --git a/docs/docs_files/null.gif b/docs/docs_files/null.gif Binary files differdeleted file mode 100644 index e565824..0000000 --- a/docs/docs_files/null.gif +++ /dev/null diff --git a/docs/docs_files/sflogo.png b/docs/docs_files/sflogo.png Binary files differdeleted file mode 100644 index 39cc3b4..0000000 --- a/docs/docs_files/sflogo.png +++ /dev/null diff --git a/mkxincludes.in b/mkxincludes.in deleted file mode 100755 index 50ae5dd..0000000 --- a/mkxincludes.in +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash -# -# mkxincludes -# -# Copyright (C) 2003 - John Joganic -# Copyright (C) 2003 - 2007 Ping Cheng -# -# Based on code by Jonathan Paisley -# -# mkxinc takes an existing XFree86 build tree, grabs the important -# header files, moves them to a new directory, and makes a tarball out -# of it. -# - -XF86_DIR=@WCM_XFREE86_DIR@/xc -XF86MODS="@WCM_XF86MODULES@" -DEPFLAGS=@WCM_DEPFLAGS@ - -X_INCLUDES=x-includes - -FILES="wcmCommon.d wcmCompat.d wcmConfig.d wcmFilter.d wcmISDV4.d wcmSerial.d wcmUSB.d xf86Wacom.d wcmXCommand.d" - -if test -z "$DEPFLAGS" || test -z "$XF86MODS"; then - echo "Either mkxincludes or wacomdrv was not enabled..." - echo "Please reconfigure with --enable-mkxincludes and" - echo " --enable-wacomdrv options enabled. You will" - echo " also need to specify --with-xf86=path_to_original_xf86" - exit 1 -fi - -echo "mkxincludes: using $XF86_DIR" - -# Build wacom_drv.o -( - cd src - - echo "Building wacom_drv.o..." - make wacom_drv.o 2>&1 >/dev/null - if test $? != 0; then - echo "Failed to build wacom_drv.o. Sorry." - exit 1; - fi - - echo "Examining dependencies..." - DEPS=`cat $FILES | \ - sed -e 's/\\\\//' -e 's/.*://' | \ - tr ' ' '\n' | \ - sort -u | \ - sed -e "s:$XF86_DIR:xc:" | \ - grep xc/` - if test $? != 0; then - echo "Failed to find the dependency files. Sorry." - exit 1; - fi - - cd .. - - echo "Building directory..." - rm -rf $X_INCLUDES - mkdir -p $X_INCLUDES - echo `uname -a` > $X_INCLUDES/environ - echo `gcc --version | head -1` > $X_INCLUDES/gcc_version - echo "$XF86_DIR" > $X_INCLUDES/xf86_version - (cd $XF86_DIR/.. && tar chf - $DEPS) | (cd $X_INCLUDES && tar xf -) - - echo "Building package... ($X_INCLUDES.tar.gz)" - tar -c $X_INCLUDES | gzip -9 > $X_INCLUDES.tar.gz -) diff --git a/prebuilt/install b/prebuilt/install deleted file mode 100755 index 1d190b1..0000000 --- a/prebuilt/install +++ /dev/null @@ -1,144 +0,0 @@ -#!/bin/bash -#install prebuilt wacom X driver and associated utilities - -# Make sure the script is running under root -if [ "$(id -u)" != "0" ]; then - echo "This installer must be run as root" 1>&2 - exit -fi - -libp="lib" -arch=`uname -p` -if [ `echo $arch | grep -c "86"` == 0 ]; then - arch=`uname -m` - if [ `echo $arch | grep -c "86"` == 0 ]; then - arch=`uname -i` - if [ `echo $arch | grep -c "86"` == 0 ]; then - echo "Error: Failed to get system architecture" - echo "Reason: uname, with options -i, -p, and -m, doesn't work properly" - exit - fi - fi -fi - -echo "Installing Wacom man page......" -test -z "/usr/share/man/man4" || mkdir -p -- "/usr/share/man/man4" -/usr/bin/install -c -m 644 'wacom.4x.gz' '/usr/share/man/man4/wacom.4x.gz' -echo "Installed under /usr/share/man/man4" - -if [ `echo $arch | grep -c "64"` != 0 ]; then - cd 64 - libp="lib64" -else - cd 32 -fi - -echo -echo "Installing wacom_drv...." -drv="" -path=/usr/X11R6/$libp/modules/input -path1=/usr/$libp/xorg/modules/input -if [ -d $path ]; then - if [ -f $path/wacom_drv.so ]; then - drv="wacom_drv.so" - elif [ -f $path/wacom_drv.o ]; then - drv="wacom_drv.o" - fi -elif [ -d $path1 ]; then - if [ -f $path1/wacom_drv.so ]; then - path=$path1 - drv="wacom_drv.so" - elif [ -f $path1/wacom_drv.o ]; then - path=$path1 - drv="wacom_drv.o" - fi -fi -if [ -n "$drv" ]; then - /usr/bin/install -c -m 644 $drv $path/$drv -elif [ `echo $arch | grep -c "64"` != 0 ]; then - path=/usr/X11R6/lib/modules/input - path1=/usr/lib/xorg/modules/input - if [ -d $path ]; then - if [ -f $path/wacom_drv.so ]; then - drv="wacom_drv.so" - elif [ -f $path/wacom_drv.o ]; then - drv="wacom_drv.o" - fi - elif [ -d $path1 ]; then - if [ -f $path1/wacom_drv.so ]; then - path=$path1 - drv="wacom_drv.so" - elif [ -f $path1/wacom_drv.o ]; then - path=$path1 - drv="wacom_drv.o" - fi - fi -fi -if [ -n "$drv" ]; then - /usr/bin/install -c -m 644 $drv $path/$drv - echo "$drv installed under $path" - echo - echo "Installing utility programs (wacdump, xidump, xsetwacom....)" - test -z "/usr/local/lib" || mkdir -p -- "/usr/local/lib" - /usr/bin/install -c 'libwacomcfg.la' '/usr/local/lib/libwacomcfg.la' - /usr/bin/install -c .libs/libwacomcfg.so.0.0.1 /usr/local/lib/libwacomcfg.so.0.0.1 - (cd /usr/local/lib && { ln -s -f libwacomcfg.so.0.0.1 libwacomcfg.so.0 || { rm -f libwacomcfg.so.0 && ln -s libwacomcfg.so.0.0.1 libwacomcfg.so.0; }; }) - (cd /usr/local/lib && { ln -s -f libwacomcfg.so.0.0.1 libwacomcfg.so || { rm -f libwacomcfg.so && ln -s libwacomcfg.so.0.0.1 libwacomcfg.so; }; }) - /usr/bin/install -c .libs/libwacomcfg.lai /usr/local/lib/libwacomcfg.la - /usr/bin/install -c .libs/libwacomcfg.a /usr/local/lib/libwacomcfg.a - chmod 644 /usr/local/lib/libwacomcfg.a - ranlib /usr/local/lib/libwacomcfg.a - PATH="$PATH:/sbin" ldconfig -n /usr/local/lib - /usr/bin/install -c wacdump /usr/local/bin/wacdump - /usr/bin/install -c xidump /usr/local/bin/xidump - /usr/bin/install -c .libs/xsetwacom /usr/local/bin/xsetwacom - echo "Installed under /usr/local/bin" - test -z "/usr/local/libexec" || /bin/mkdir -p "/usr/local/libexec" - /usr/bin/install -c hal-setup-wacom /usr/local/libexec/hal-setup-wacom - test -z "/usr/local/share/hal/fdi/policy/20thirdparty" || /bin/mkdir -p "/usr/local/share/hal/fdi/policy/20thirdparty" - /usr/bin/install -c '10-linuxwacom.fdi' '/usr/local/share/hal/fdi/policy/20thirdparty/10-linuxwacom.fdi' - echo "hal-setup-wacom installed under /usr/local/libexec" - echo "10-linuxwacom.fdi installed under /usr/local/share/hal/fdi/policy/20thirdparty" - test -z "/usr/local/include/wacomcfg" || /bin/mkdir -p "/usr/local/include/wacomcfg" - test -z "/usr/local/include/wacomcfg" || mkdir -p -- "/usr/local/include/wacomcfg" - /usr/bin/install -c -m 644 'wacomcfg.h' '/usr/local/include/wacomcfg/wacomcfg.h' - echo - echo "Installing wacomcpl......" - wout=`which wish` - if [ `echo $wout | grep -c wish` = 0 ]; then - echo - echo "Warning: wacomcpl requires tcl/tk being installed" - echo - yum install tcl;yum install tk - fi - wout=`which wish` - if [ `echo $wout | grep -c wish` = 1 ]; then - test -z "/usr/local/bin" || mkdir -p -- "/usr/local/bin" - /usr/bin/install -c 'wacomcpl' '/usr/local/bin/wacomcpl' - /usr/bin/install -c 'wacomcpl-exec' '/usr/local/bin/wacomcpl-exec' - echo "Installed under /usr/local/bin" - test -z "/usr/local/lib/TkXInput" || mkdir -p -- "/usr/local/lib/TkXInput" - /usr/bin/install -c -m 644 'pkgIndex.tcl' '/usr/local/lib/TkXInput/pkgIndex.tcl' - /usr/bin/install -c 'libwacomxi.la' '/usr/local/lib/TkXInput/libwacomxi.la' - /usr/bin/install -c .libs/libwacomxi.so.0.0.0 /usr/local/lib/TkXInput/libwacomxi.so.0.0.0 - (cd /usr/local/lib/TkXInput && { ln -s -f libwacomxi.so.0.0.0 libwacomxi.so.0 || { rm -f libwacomxi.so.0 && ln -s libwacomxi.so.0.0.0 libwacomxi.so.0; }; }) - (cd /usr/local/lib/TkXInput && { ln -s -f libwacomxi.so.0.0.0 libwacomxi.so || { rm -f libwacomxi.so && ln -s libwacomxi.so.0.0.0 libwacomxi.so; }; }) - /usr/bin/install -c .libs/libwacomxi.lai /usr/local/lib/TkXInput/libwacomxi.la - /usr/bin/install -c .libs/libwacomxi.a /usr/local/lib/TkXInput/libwacomxi.a - chmod 644 /usr/local/lib/TkXInput/libwacomxi.a - ranlib /usr/local/lib/TkXInput/libwacomxi.a - PATH="$PATH:/sbin" ldconfig -n /usr/local/lib/TkXInput - echo - else - echo - echo "Please install tcl/tk then run this script again" - fi -else - echo "WARNING: Can not install Wacom X driver (wacom_drv)" - echo "since the proper directory has not been found" -fi -echo -echo "You need to compile and install wacom.(k)o manually if your kernel is out of date." -echo -echo "After adding your Wacom tools into /etc/X11/xorg.conf, please restart X server or simply reboot your system to run the new Wacom X driver." - diff --git a/prebuilt/uninstall b/prebuilt/uninstall deleted file mode 100755 index fcc7924..0000000 --- a/prebuilt/uninstall +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash -#uninstall prebuilt wacom X driver and associated utilities - -# Make sure the script is running under root -if [ "$(id -u)" != "0" ]; then - echo "This script must be run as root" 1>&2 - exit -fi - -echo "Please remove linuxwacom package if your system has an existing one" - -echo "Removing Wacom X driver related utility programs...." -rm -f /usr/local/bin/xsetwacom -rm -f /usr/local/bin/wacdump -rm -f /usr/local/bin/xidump -rm -f /usr/bin/xsetwacom -rm -f /usr/bin/wacdump -rm -f /usr/bin/xidump -rm -f /usr/local/libexec/hal-setup-wacom -rm -f /usr/local/share/hal/fdi/policy/20thirdparty/10-linuxwacom.fdi -rm -f /usr/local/lib/libwacomcfg.la /usr/local/lib/libwacomcfg.so.0.0.1 /usr/local/lib/libwacomcfg.so.0 /usr/local/lib/libwacomcf.so /usr/local/lib/libwacomcfg.a -rm -f /usr/local/include/wacomcfg/wacomcfg.h -rm -f /usr/local/bin/wacomcpl -rm -f /usr/local/bin/wacomcpl-exec -rm -f /usr/local/lib/TkXInput/pkgIndex.tcl -rm -f /usr/local/lib/TkXInput/libwacomxi.la /usr/local/lib/TkXInput/libwacomxi.so.0.0.0 /usr/local/lib/TkXInput/libwacomxi.so.0 /usr/local/lib/TkXInput/libwacomxi.so /usr/local/lib/TkXInput/libwacomxi.a -rm -f /usr/libexec/hal-setup-wacom -rm -f /usr/share/hal/fdi/policy/20thirdparty/10-linuxwacom.fdi -rm -f /usr/lib/libwacomcfg.la /usr/lib/libwacomcfg.so.0.0.1 /usr/lib/libwacomcfg.so.0 /usr/lib/libwacomcf.so /usr/lib/libwacomcfg.a -rm -f /usr/include/wacomcfg/wacomcfg.h -rm -f /usr/bin/wacomcpl -rm -f /usr/bin/wacomcpl-exec -rm -f /usr/lib/TkXInput/pkgIndex.tcl -rm -f /usr/lib/TkXInput/libwacomxi.la /usr/lib/TkXInput/libwacomxi.so.0.0.0 /usr/lib/TkXInput/libwacomxi.so.0 /usr/lib/TkXInput/libwacomxi.so /usr/lib/TkXInput/libwacomxi.a -rm -f /etc/wacom.dat -rm -f /etc/X11/wcm.* -echo "Wacom X driver related utility programs have been removed" diff --git a/src/2.6.10/Makefile.in b/src/2.6.10/Makefile.in deleted file mode 100644 index 2657b92..0000000 --- a/src/2.6.10/Makefile.in +++ /dev/null @@ -1,101 +0,0 @@ -############################ 2.6 kernel compile ############################### -ifneq ($(KERNELRELEASE),) -# We were called by kbuild -# Do NOT indent stuff in this part! It has to be like this to make the -# $(error ... ) stuff work - -# only compile those modules which are enabled by global configure -ifeq ($(WCM_OPTION_HID),yes) - -# check if kernel was configured to have hid as an module -ifeq ($(CONFIG_USB_HID),m) - -# check if HID module should be usbhid.ko or hid.ko -NEWHID := $(shell test $(SUBLEVEL) -ge 6 && echo usb) - -$(NEWHID)hid-objs := hid-core.o - -# behave exactly as kernel config wants us to behave -ifeq ($(CONFIG_USB_HIDDEV),y) -$(NEWHID)hid-objs += hiddev.o -endif -ifeq ($(CONFIG_USB_HIDINPUT),y) -$(NEWHID)hid-objs += hid-input.o -endif -ifeq ($(CONFIG_HID_PID),y) -$(NEWHID)hid-objs += pid.o -endif -ifeq ($(CONFIG_LOGITECH_FF),y) -$(NEWHID)hid-objs += hid-lgff.o -endif -ifeq ($(CONFIG_THRUSTMASTER_FF),y) -$(NEWHID)hid-objs += hid-tmff.o -endif -ifeq ($(CONFIG_HID_FF),y) -$(NEWHID)hid-objs += hid-ff.o -endif - -obj-$(CONFIG_USB_HID) += $(NEWHID)hid.o - -else -ifeq ($(CONFIG_USB_HID),y) -$(error You requested to build hid with configure, but hid is configured as built-in in your kernel config) -endif - -$(error You requested to build hid with configure, but hid is not configured in your kernel config) -endif # CONFIG_USB_HID -endif # WCM_OPTION_HID not - -ifeq ($(WCM_OPTION_WACOM),yes) -ifneq ($(CONFIG_USB_WACOM),y) -obj-m += wacom.o -else -$(error You requested to build wacom with configure, but wacom is configured as built-in in your kernel config) -endif # CONFIG_USB_WACOM -endif # WCM_OPTION_WACOM - -else # We were called from command line -PWD := $(shell pwd) - -WCM_KERNEL_DIR := @WCM_KERNEL_DIR@ -WCM_OPTION_WACOM := @WCM_OPTION_WACOM@ -WCM_OPTION_HID := @WCM_OPTION_HID@ - -export WCM_OPTION_WACOM WCM_OPTION_HID - -COPY_FROM_KERNEL_TREE := hiddev.c hid.h hid-ff.c hid-input.c fixp-arith.h -COPY_FROM_KERNEL_TREE += hid-lgff.c hid-tmff.c pid.c pid.h - -all: -# Copy hid-stuff from kernel-dir to local dir -ifeq ($(WCM_OPTION_HID),yes) - @for i in $(COPY_FROM_KERNEL_TREE); do \ - if test ! -f "$$i" && test -f $(WCM_KERNEL_DIR)/drivers/usb/input/$$i ; then \ - cp $(WCM_KERNEL_DIR)/drivers/usb/input/$$i .; \ - fi; \ - done -endif - - @echo ' Building linuxwacom drivers for 2.6 kernel.' - @echo '***Note: Drivers not enabled as modules in your kernel config but requested through configure are NOT built' - $(MAKE) -C $(WCM_KERNEL_DIR) M=$(PWD) - -endif # End kbuild check - -######################### Version independent targets ########################## - -clean: - rm -rf *.o *.ko *.mod.* .[a-z]* core *.i - -# also remove copied stuff -distclean: clean - @for i in $(COPY_FROM_KERNEL_TREE); do \ - if test -f "$$i"; then \ - rm -f $$i ; \ - fi; \ - done - -EMPTY_AUTOMAKE_TARGETS = distdir install install-data install-exec uninstall install-info -EMPTY_AUTOMAKE_TARGETS += installdirs check dvi pdf ps info html tags ctags mostlyclean distclean maintainer-clean -.PHONY: $(EMPTY_AUTOMAKE_TARGETS) - $(EMPTY_AUTOMAKE_TARGETS): diff --git a/src/2.6.10/hid-core.c b/src/2.6.10/hid-core.c deleted file mode 100644 index 1c9bc73..0000000 --- a/src/2.6.10/hid-core.c +++ /dev/null @@ -1,1887 +0,0 @@ -/* - * USB HID support for Linux - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@suse.cz> - */ - -/* - * 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. - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/list.h> -#include <linux/mm.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/unaligned.h> -#include <asm/byteorder.h> -#include <linux/input.h> - -#undef DEBUG -#undef DEBUG_DATA - -#include <linux/usb.h> - -#include "hid.h" -#include <linux/hiddev.h> - -/* - * Version Information - */ - -#define DRIVER_VERSION "v2.0" -#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik" -#define DRIVER_DESC "USB HID core driver" -#define DRIVER_LICENSE "GPL" - -static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick", - "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"}; - -/* - * Register a new report for a device. - */ - -static struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id) -{ - struct hid_report_enum *report_enum = device->report_enum + type; - struct hid_report *report; - - if (report_enum->report_id_hash[id]) - return report_enum->report_id_hash[id]; - - if (!(report = kmalloc(sizeof(struct hid_report), GFP_KERNEL))) - return NULL; - memset(report, 0, sizeof(struct hid_report)); - - if (id != 0) - report_enum->numbered = 1; - - report->id = id; - report->type = type; - report->size = 0; - report->device = device; - report_enum->report_id_hash[id] = report; - - list_add_tail(&report->list, &report_enum->report_list); - - return report; -} - -/* - * Register a new field for this report. - */ - -static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) -{ - struct hid_field *field; - - if (report->maxfield == HID_MAX_FIELDS) { - dbg("too many fields in report"); - return NULL; - } - - if (!(field = kmalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) - + values * sizeof(unsigned), GFP_KERNEL))) return NULL; - - memset(field, 0, sizeof(struct hid_field) + usages * sizeof(struct hid_usage) - + values * sizeof(unsigned)); - - report->field[report->maxfield++] = field; - field->usage = (struct hid_usage *)(field + 1); - field->value = (unsigned *)(field->usage + usages); - field->report = report; - - return field; -} - -/* - * Open a collection. The type/usage is pushed on the stack. - */ - -static int open_collection(struct hid_parser *parser, unsigned type) -{ - struct hid_collection *collection; - unsigned usage; - - usage = parser->local.usage[0]; - - if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { - dbg("collection stack overflow"); - return -1; - } - - if (parser->device->maxcollection == parser->device->collection_size) { - collection = kmalloc(sizeof(struct hid_collection) * - parser->device->collection_size * 2, - GFP_KERNEL); - if (collection == NULL) { - dbg("failed to reallocate collection array"); - return -1; - } - memcpy(collection, parser->device->collection, - sizeof(struct hid_collection) * - parser->device->collection_size); - memset(collection + parser->device->collection_size, 0, - sizeof(struct hid_collection) * - parser->device->collection_size); - kfree(parser->device->collection); - parser->device->collection = collection; - parser->device->collection_size *= 2; - } - - parser->collection_stack[parser->collection_stack_ptr++] = - parser->device->maxcollection; - - collection = parser->device->collection + - parser->device->maxcollection++; - collection->type = type; - collection->usage = usage; - collection->level = parser->collection_stack_ptr - 1; - - if (type == HID_COLLECTION_APPLICATION) - parser->device->maxapplication++; - - return 0; -} - -/* - * Close a collection. - */ - -static int close_collection(struct hid_parser *parser) -{ - if (!parser->collection_stack_ptr) { - dbg("collection stack underflow"); - return -1; - } - parser->collection_stack_ptr--; - return 0; -} - -/* - * Climb up the stack, search for the specified collection type - * and return the usage. - */ - -static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) -{ - int n; - for (n = parser->collection_stack_ptr - 1; n >= 0; n--) - if (parser->device->collection[parser->collection_stack[n]].type == type) - return parser->device->collection[parser->collection_stack[n]].usage; - return 0; /* we know nothing about this usage type */ -} - -/* - * Add a usage to the temporary parser table. - */ - -static int hid_add_usage(struct hid_parser *parser, unsigned usage) -{ - if (parser->local.usage_index >= HID_MAX_USAGES) { - dbg("usage index exceeded"); - return -1; - } - parser->local.usage[parser->local.usage_index] = usage; - parser->local.collection_index[parser->local.usage_index] = - parser->collection_stack_ptr ? - parser->collection_stack[parser->collection_stack_ptr - 1] : 0; - parser->local.usage_index++; - return 0; -} - -/* - * Register a new field for this report. - */ - -static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags) -{ - struct hid_report *report; - struct hid_field *field; - int usages; - unsigned offset; - int i; - - if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { - dbg("hid_register_report failed"); - return -1; - } - - if (parser->global.logical_maximum < parser->global.logical_minimum) { - dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum); - return -1; - } - - if (!(usages = max_t(int, parser->local.usage_index, parser->global.report_count))) - return 0; /* Ignore padding fields */ - - offset = report->size; - report->size += parser->global.report_size * parser->global.report_count; - - if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL) - return 0; - - field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); - field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL); - field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); - - for (i = 0; i < usages; i++) { - int j = i; - /* Duplicate the last usage we parsed if we have excess values */ - if (i >= parser->local.usage_index) - j = parser->local.usage_index - 1; - field->usage[i].hid = parser->local.usage[j]; - field->usage[i].collection_index = - parser->local.collection_index[j]; - } - - field->maxusage = usages; - field->flags = flags; - field->report_offset = offset; - field->report_type = report_type; - field->report_size = parser->global.report_size; - field->report_count = parser->global.report_count; - field->logical_minimum = parser->global.logical_minimum; - field->logical_maximum = parser->global.logical_maximum; - field->physical_minimum = parser->global.physical_minimum; - field->physical_maximum = parser->global.physical_maximum; - field->unit_exponent = parser->global.unit_exponent; - field->unit = parser->global.unit; - - return 0; -} - -/* - * Read data value from item. - */ - -static __inline__ __u32 item_udata(struct hid_item *item) -{ - switch (item->size) { - case 1: return item->data.u8; - case 2: return item->data.u16; - case 4: return item->data.u32; - } - return 0; -} - -static __inline__ __s32 item_sdata(struct hid_item *item) -{ - switch (item->size) { - case 1: return item->data.s8; - case 2: return item->data.s16; - case 4: return item->data.s32; - } - return 0; -} - -/* - * Process a global item. - */ - -static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) -{ - switch (item->tag) { - - case HID_GLOBAL_ITEM_TAG_PUSH: - - if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { - dbg("global enviroment stack overflow"); - return -1; - } - - memcpy(parser->global_stack + parser->global_stack_ptr++, - &parser->global, sizeof(struct hid_global)); - return 0; - - case HID_GLOBAL_ITEM_TAG_POP: - - if (!parser->global_stack_ptr) { - dbg("global enviroment stack underflow"); - return -1; - } - - memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr, - sizeof(struct hid_global)); - return 0; - - case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: - parser->global.usage_page = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: - parser->global.logical_minimum = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: - if (parser->global.logical_minimum < 0) - parser->global.logical_maximum = item_sdata(item); - else - parser->global.logical_maximum = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: - parser->global.physical_minimum = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: - if (parser->global.physical_minimum < 0) - parser->global.physical_maximum = item_sdata(item); - else - parser->global.physical_maximum = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: - parser->global.unit_exponent = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_UNIT: - parser->global.unit = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: - if ((parser->global.report_size = item_udata(item)) > 32) { - dbg("invalid report_size %d", parser->global.report_size); - return -1; - } - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: - if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) { - dbg("invalid report_count %d", parser->global.report_count); - return -1; - } - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_ID: - if ((parser->global.report_id = item_udata(item)) == 0) { - dbg("report_id 0 is invalid"); - return -1; - } - return 0; - - default: - dbg("unknown global tag 0x%x", item->tag); - return -1; - } -} - -/* - * Process a local item. - */ - -static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) -{ - __u32 data; - unsigned n; - - if (item->size == 0) { - dbg("item data expected for local item"); - return -1; - } - - data = item_udata(item); - - switch (item->tag) { - - case HID_LOCAL_ITEM_TAG_DELIMITER: - - if (data) { - /* - * We treat items before the first delimiter - * as global to all usage sets (branch 0). - * In the moment we process only these global - * items and the first delimiter set. - */ - if (parser->local.delimiter_depth != 0) { - dbg("nested delimiters"); - return -1; - } - parser->local.delimiter_depth++; - parser->local.delimiter_branch++; - } else { - if (parser->local.delimiter_depth < 1) { - dbg("bogus close delimiter"); - return -1; - } - parser->local.delimiter_depth--; - } - return 1; - - case HID_LOCAL_ITEM_TAG_USAGE: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - return hid_add_usage(parser, data); - - case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - parser->local.usage_minimum = data; - return 0; - - case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - for (n = parser->local.usage_minimum; n <= data; n++) - if (hid_add_usage(parser, n)) { - dbg("hid_add_usage failed\n"); - return -1; - } - return 0; - - default: - - dbg("unknown local item tag 0x%x", item->tag); - return 0; - } - return 0; -} - -/* - * Process a main item. - */ - -static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) -{ - __u32 data; - int ret; - - data = item_udata(item); - - switch (item->tag) { - case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: - ret = open_collection(parser, data & 0xff); - break; - case HID_MAIN_ITEM_TAG_END_COLLECTION: - ret = close_collection(parser); - break; - case HID_MAIN_ITEM_TAG_INPUT: - ret = hid_add_field(parser, HID_INPUT_REPORT, data); - break; - case HID_MAIN_ITEM_TAG_OUTPUT: - ret = hid_add_field(parser, HID_OUTPUT_REPORT, data); - break; - case HID_MAIN_ITEM_TAG_FEATURE: - ret = hid_add_field(parser, HID_FEATURE_REPORT, data); - break; - default: - dbg("unknown main item tag 0x%x", item->tag); - ret = 0; - } - - memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */ - - return ret; -} - -/* - * Process a reserved item. - */ - -static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) -{ - dbg("reserved item type, tag 0x%x", item->tag); - return 0; -} - -/* - * Free a report and all registered fields. The field->usage and - * field->value table's are allocated behind the field, so we need - * only to free(field) itself. - */ - -static void hid_free_report(struct hid_report *report) -{ - unsigned n; - - for (n = 0; n < report->maxfield; n++) - kfree(report->field[n]); - kfree(report); -} - -/* - * Free a device structure, all reports, and all fields. - */ - -static void hid_free_device(struct hid_device *device) -{ - unsigned i,j; - - hid_ff_exit(device); - - for (i = 0; i < HID_REPORT_TYPES; i++) { - struct hid_report_enum *report_enum = device->report_enum + i; - - for (j = 0; j < 256; j++) { - struct hid_report *report = report_enum->report_id_hash[j]; - if (report) - hid_free_report(report); - } - } - - if (device->rdesc) - kfree(device->rdesc); - kfree(device); -} - -/* - * Fetch a report description item from the data stream. We support long - * items, though they are not used yet. - */ - -static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) -{ - u8 b; - - if ((end - start) <= 0) - return NULL; - - b = *start++; - - item->type = (b >> 2) & 3; - item->tag = (b >> 4) & 15; - - if (item->tag == HID_ITEM_TAG_LONG) { - - item->format = HID_ITEM_FORMAT_LONG; - - if ((end - start) < 2) - return NULL; - - item->size = *start++; - item->tag = *start++; - - if ((end - start) < item->size) - return NULL; - - item->data.longdata = start; - start += item->size; - return start; - } - - item->format = HID_ITEM_FORMAT_SHORT; - item->size = b & 3; - - switch (item->size) { - - case 0: - return start; - - case 1: - if ((end - start) < 1) - return NULL; - item->data.u8 = *start++; - return start; - - case 2: - if ((end - start) < 2) - return NULL; - item->data.u16 = le16_to_cpu(get_unaligned((__le16*)start)); - start = (__u8 *)((__le16 *)start + 1); - return start; - - case 3: - item->size++; - if ((end - start) < 4) - return NULL; - item->data.u32 = le32_to_cpu(get_unaligned((__le32*)start)); - start = (__u8 *)((__le32 *)start + 1); - return start; - } - - return NULL; -} - -/* - * Parse a report description into a hid_device structure. Reports are - * enumerated, fields are attached to these reports. - */ - -static struct hid_device *hid_parse_report(__u8 *start, unsigned size) -{ - struct hid_device *device; - struct hid_parser *parser; - struct hid_item item; - __u8 *end; - unsigned i; - static int (*dispatch_type[])(struct hid_parser *parser, - struct hid_item *item) = { - hid_parser_main, - hid_parser_global, - hid_parser_local, - hid_parser_reserved - }; - - if (!(device = kmalloc(sizeof(struct hid_device), GFP_KERNEL))) - return NULL; - memset(device, 0, sizeof(struct hid_device)); - - if (!(device->collection =kmalloc(sizeof(struct hid_collection) * - HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) { - kfree(device); - return NULL; - } - memset(device->collection, 0, sizeof(struct hid_collection) * - HID_DEFAULT_NUM_COLLECTIONS); - device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; - - for (i = 0; i < HID_REPORT_TYPES; i++) - INIT_LIST_HEAD(&device->report_enum[i].report_list); - - if (!(device->rdesc = (__u8 *)kmalloc(size, GFP_KERNEL))) { - kfree(device->collection); - kfree(device); - return NULL; - } - memcpy(device->rdesc, start, size); - device->rsize = size; - - if (!(parser = kmalloc(sizeof(struct hid_parser), GFP_KERNEL))) { - kfree(device->rdesc); - kfree(device->collection); - kfree(device); - return NULL; - } - memset(parser, 0, sizeof(struct hid_parser)); - parser->device = device; - - end = start + size; - while ((start = fetch_item(start, end, &item)) != 0) { - - if (item.format != HID_ITEM_FORMAT_SHORT) { - dbg("unexpected long global item"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - - if (dispatch_type[item.type](parser, &item)) { - dbg("item %u %u %u %u parsing failed\n", - item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - - if (start == end) { - if (parser->collection_stack_ptr) { - dbg("unbalanced collection at end of report description"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - if (parser->local.delimiter_depth) { - dbg("unbalanced delimiter at end of report description"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - kfree(parser); - return device; - } - } - - dbg("item fetching failed at offset %d\n", (int)(end - start)); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; -} - -/* - * Convert a signed n-bit integer to signed 32-bit integer. Common - * cases are done through the compiler, the screwed things has to be - * done by hand. - */ - -static __inline__ __s32 snto32(__u32 value, unsigned n) -{ - switch (n) { - case 8: return ((__s8)value); - case 16: return ((__s16)value); - case 32: return ((__s32)value); - } - return value & (1 << (n - 1)) ? value | (-1 << n) : value; -} - -/* - * Convert a signed 32-bit integer to a signed n-bit integer. - */ - -static __inline__ __u32 s32ton(__s32 value, unsigned n) -{ - __s32 a = value >> (n - 1); - if (a && a != -1) - return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; - return value & ((1 << n) - 1); -} - -/* - * Extract/implement a data field from/to a report. - */ - -static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) -{ - report += (offset >> 5) << 2; offset &= 31; - return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1 << n) - 1); -} - -static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) -{ - report += (offset >> 5) << 2; offset &= 31; - put_unaligned((get_unaligned((__le64*)report) - & cpu_to_le64(~((((__u64) 1 << n) - 1) << offset))) - | cpu_to_le64((__u64)value << offset), (__le64*)report); -} - -/* - * Search an array for a value. - */ - -static __inline__ int search(__s32 *array, __s32 value, unsigned n) -{ - while (n--) { - if (*array++ == value) - return 0; - } - return -1; -} - -static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) -{ - hid_dump_input(usage, value); - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_hid_event(hid, field, usage, value, regs); - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_hid_event(hid, field, usage, value, regs); -} - -/* - * Analyse a received field, and fetch the data from it. The field - * content is stored for next report processing (we do differential - * reporting to the layer). - */ - -static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, struct pt_regs *regs) -{ - unsigned n; - unsigned count = field->report_count; - unsigned offset = field->report_offset; - unsigned size = field->report_size; - __s32 min = field->logical_minimum; - __s32 max = field->logical_maximum; - __s32 *value; - - value = kmalloc(sizeof(__s32)*count, GFP_ATOMIC); - if (!value) - return; - - for (n = 0; n < count; n++) { - - value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : - extract(data, offset + n * size, size); - - if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */ - && value[n] >= min && value[n] <= max - && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) - goto exit; - } - - for (n = 0; n < count; n++) { - - if (HID_MAIN_ITEM_VARIABLE & field->flags) { - - if (field->flags & HID_MAIN_ITEM_RELATIVE) { - if (!value[n]) - continue; - } else { - if (value[n] == field->value[n]) - continue; - } - hid_process_event(hid, field, &field->usage[n], value[n], regs); - continue; - } - - if (field->value[n] >= min && field->value[n] <= max - && field->usage[field->value[n] - min].hid - && search(value, field->value[n], count)) - hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, regs); - - if (value[n] >= min && value[n] <= max - && field->usage[value[n] - min].hid - && search(field->value, value[n], count)) - hid_process_event(hid, field, &field->usage[value[n] - min], 1, regs); - } - - memcpy(field->value, value, count * sizeof(__s32)); -exit: - kfree(value); -} - -static int hid_input_report(int type, struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - struct hid_report_enum *report_enum = hid->report_enum + type; - u8 *data = urb->transfer_buffer; - int len = urb->actual_length; - struct hid_report *report; - int n, size; - - if (!len) { - dbg("empty report"); - return -1; - } - -#ifdef DEBUG_DATA - printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", len, report_enum->numbered ? "" : "un"); -#endif - - n = 0; /* Normally report number is 0 */ - if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */ - n = *data++; - len--; - } - -#ifdef DEBUG_DATA - { - int i; - printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, len); - for (i = 0; i < len; i++) - printk(" %02x", data[i]); - printk("\n"); - } -#endif - - if (!(report = report_enum->report_id_hash[n])) { - dbg("undefined report_id %d received", n); - return -1; - } - - size = ((report->size - 1) >> 3) + 1; - - if (len < size) { - dbg("report %d is too short, (%d < %d)", report->id, len, size); - return -1; - } - - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_report_event(hid, report); - - for (n = 0; n < report->maxfield; n++) - hid_input_field(hid, report->field[n], data, regs); - - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_report_event(hid, report); - - return 0; -} - -/* - * Input interrupt completion handler. - */ - -static void hid_irq_in(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - int status; - - switch (urb->status) { - case 0: /* success */ - hid_input_report(HID_INPUT_REPORT, urb, regs); - break; - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -ESHUTDOWN: - case -EPERM: - return; - case -ETIMEDOUT: /* NAK */ - break; - default: /* error */ - warn("input irq status %d received", urb->status); - } - - status = usb_submit_urb(urb, SLAB_ATOMIC); - if (status) - err("can't resubmit intr, %s-%s/input%d, status %d", - hid->dev->bus->bus_name, hid->dev->devpath, - hid->ifnum, status); -} - -/* - * Output the field into the report. - */ - -static void hid_output_field(struct hid_field *field, __u8 *data) -{ - unsigned count = field->report_count; - unsigned offset = field->report_offset; - unsigned size = field->report_size; - unsigned n; - - for (n = 0; n < count; n++) { - if (field->logical_minimum < 0) /* signed values */ - implement(data, offset + n * size, size, s32ton(field->value[n], size)); - else /* unsigned values */ - implement(data, offset + n * size, size, field->value[n]); - } -} - -/* - * Create a report. - */ - -static void hid_output_report(struct hid_report *report, __u8 *data) -{ - unsigned n; - - if (report->id > 0) - *data++ = report->id; - - for (n = 0; n < report->maxfield; n++) - hid_output_field(report->field[n], data); -} - -/* - * Set a field value. The report this field belongs to has to be - * created and transferred to the device, to set this value in the - * device. - */ - -int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) -{ - unsigned size = field->report_size; - - hid_dump_input(field->usage + offset, value); - - if (offset >= field->report_count) { - dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count); - hid_dump_field(field, 8); - return -1; - } - if (field->logical_minimum < 0) { - if (value != snto32(s32ton(value, size), size)) { - dbg("value %d is out of range", value); - return -1; - } - } - field->value[offset] = value; - return 0; -} - -int hid_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field) -{ - struct hid_report_enum *report_enum = hid->report_enum + HID_OUTPUT_REPORT; - struct list_head *list = report_enum->report_list.next; - int i, j; - - while (list != &report_enum->report_list) { - struct hid_report *report = (struct hid_report *) list; - list = list->next; - for (i = 0; i < report->maxfield; i++) { - *field = report->field[i]; - for (j = 0; j < (*field)->maxusage; j++) - if ((*field)->usage[j].type == type && (*field)->usage[j].code == code) - return j; - } - } - return -1; -} - -/* - * Find a report with a specified HID usage. - */ - -int hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, struct hid_report **report, int type) -{ - struct hid_report_enum *report_enum = hid->report_enum + type; - struct list_head *list = report_enum->report_list.next; - int i, j; - - while (list != &report_enum->report_list) { - *report = (struct hid_report *) list; - list = list->next; - for (i = 0; i < (*report)->maxfield; i++) { - struct hid_field *field = (*report)->field[i]; - for (j = 0; j < field->maxusage; j++) - if (field->logical == wanted_usage) - return j; - } - } - return -1; -} - -#if 0 -static int hid_find_field_in_report(struct hid_report *report, __u32 wanted_usage, struct hid_field **field) -{ - int i, j; - - for (i = 0; i < report->maxfield; i++) { - *field = report->field[i]; - for (j = 0; j < (*field)->maxusage; j++) - if ((*field)->usage[j].hid == wanted_usage) - return j; - } - - return -1; -} -#endif - -static int hid_submit_out(struct hid_device *hid) -{ - struct hid_report *report; - - report = hid->out[hid->outtail]; - - hid_output_report(report, hid->outbuf); - hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); - hid->urbout->dev = hid->dev; - - dbg("submitting out urb"); - - if (usb_submit_urb(hid->urbout, GFP_ATOMIC)) { - err("usb_submit_urb(out) failed"); - return -1; - } - - return 0; -} - -static int hid_submit_ctrl(struct hid_device *hid) -{ - struct hid_report *report; - unsigned char dir; - int len; - - report = hid->ctrl[hid->ctrltail].report; - dir = hid->ctrl[hid->ctrltail].dir; - - len = ((report->size - 1) >> 3) + 1 + (report->id > 0); - if (dir == USB_DIR_OUT) { - hid_output_report(report, hid->ctrlbuf); - hid->urbctrl->pipe = usb_sndctrlpipe(hid->dev, 0); - hid->urbctrl->transfer_buffer_length = len; - } else { - int maxpacket, padlen; - - hid->urbctrl->pipe = usb_rcvctrlpipe(hid->dev, 0); - maxpacket = usb_maxpacket(hid->dev, hid->urbctrl->pipe, 0); - if (maxpacket > 0) { - padlen = (len + maxpacket - 1) / maxpacket; - padlen *= maxpacket; - if (padlen > HID_BUFFER_SIZE) - padlen = HID_BUFFER_SIZE; - } else - padlen = 0; - hid->urbctrl->transfer_buffer_length = padlen; - } - hid->urbctrl->dev = hid->dev; - - hid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; - hid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; - hid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id); - hid->cr->wIndex = cpu_to_le16(hid->ifnum); - hid->cr->wLength = cpu_to_le16(len); - - dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u", - hid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", - hid->cr->wValue, hid->cr->wIndex, hid->cr->wLength); - - if (usb_submit_urb(hid->urbctrl, GFP_ATOMIC)) { - err("usb_submit_urb(ctrl) failed"); - return -1; - } - - return 0; -} - -/* - * Output interrupt completion handler. - */ - -static void hid_irq_out(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - unsigned long flags; - - switch (urb->status) { - case 0: /* success */ - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -ESHUTDOWN: - break; - default: /* error */ - warn("output irq status %d received", urb->status); - } - - spin_lock_irqsave(&hid->outlock, flags); - - hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); - - if (hid->outhead != hid->outtail) { - if (hid_submit_out(hid)) { - clear_bit(HID_OUT_RUNNING, &hid->iofl);; - wake_up(&hid->wait); - } - spin_unlock_irqrestore(&hid->outlock, flags); - return; - } - - clear_bit(HID_OUT_RUNNING, &hid->iofl); - spin_unlock_irqrestore(&hid->outlock, flags); - wake_up(&hid->wait); -} - -/* - * Control pipe completion handler. - */ - -static void hid_ctrl(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - unsigned long flags; - - spin_lock_irqsave(&hid->ctrllock, flags); - - switch (urb->status) { - case 0: /* success */ - if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) - hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, regs); - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -ESHUTDOWN: - case -EPIPE: /* report not available */ - break; - default: /* error */ - warn("ctrl urb status %d received", urb->status); - } - - hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); - - if (hid->ctrlhead != hid->ctrltail) { - if (hid_submit_ctrl(hid)) { - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - wake_up(&hid->wait); - } - spin_unlock_irqrestore(&hid->ctrllock, flags); - return; - } - - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - spin_unlock_irqrestore(&hid->ctrllock, flags); - wake_up(&hid->wait); -} - -void hid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) -{ - int head; - unsigned long flags; - - if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) - return; - - if (hid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { - - spin_lock_irqsave(&hid->outlock, flags); - - if ((head = (hid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == hid->outtail) { - spin_unlock_irqrestore(&hid->outlock, flags); - warn("output queue full"); - return; - } - - hid->out[hid->outhead] = report; - hid->outhead = head; - - if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl)) - if (hid_submit_out(hid)) - clear_bit(HID_OUT_RUNNING, &hid->iofl); - - spin_unlock_irqrestore(&hid->outlock, flags); - return; - } - - spin_lock_irqsave(&hid->ctrllock, flags); - - if ((head = (hid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == hid->ctrltail) { - spin_unlock_irqrestore(&hid->ctrllock, flags); - warn("control queue full"); - return; - } - - hid->ctrl[hid->ctrlhead].report = report; - hid->ctrl[hid->ctrlhead].dir = dir; - hid->ctrlhead = head; - - if (!test_and_set_bit(HID_CTRL_RUNNING, &hid->iofl)) - if (hid_submit_ctrl(hid)) - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - - spin_unlock_irqrestore(&hid->ctrllock, flags); -} - -int hid_wait_io(struct hid_device *hid) -{ - DECLARE_WAITQUEUE(wait, current); - int timeout = 10*HZ; - - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&hid->wait, &wait); - - while (timeout && (test_bit(HID_CTRL_RUNNING, &hid->iofl) || - test_bit(HID_OUT_RUNNING, &hid->iofl))) { - set_current_state(TASK_UNINTERRUPTIBLE); - timeout = schedule_timeout(timeout); - } - - set_current_state(TASK_RUNNING); - remove_wait_queue(&hid->wait, &wait); - - if (!timeout) { - dbg("timeout waiting for ctrl or out queue to clear"); - return -1; - } - - return 0; -} - -static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, - unsigned char type, void *buf, int size) -{ - return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, - (type << 8), ifnum, buf, size, HZ * USB_CTRL_GET_TIMEOUT); -} - -int hid_open(struct hid_device *hid) -{ - if (hid->open++) - return 0; - - hid->urbin->dev = hid->dev; - - if (usb_submit_urb(hid->urbin, GFP_KERNEL)) - return -EIO; - - return 0; -} - -void hid_close(struct hid_device *hid) -{ - if (!--hid->open) - usb_kill_urb(hid->urbin); -} - -/* - * Initialize all reports - */ - -void hid_init_reports(struct hid_device *hid) -{ - struct hid_report_enum *report_enum; - struct hid_report *report; - struct list_head *list; - int err, ret; - - /* - * The Set_Idle request is supposed to affect only the - * "Interrupt In" pipe. Unfortunately, buggy devices such as - * the BTC keyboard (ID 046e:5303) the request also affects - * Get_Report requests on the control pipe. In the worst - * case, if the device was put on idle for an indefinite - * amount of time (as we do below) and there are no input - * events to report, the Get_Report requests will just hang - * until we get a USB timeout. To avoid this, we temporarily - * establish a minimal idle time of 1ms. This shouldn't hurt - * bugfree devices and will cause a worst-case extra delay of - * 1ms for buggy ones. - */ - usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0), - HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (1 << 8), - hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); - - report_enum = hid->report_enum + HID_INPUT_REPORT; - list = report_enum->report_list.next; - while (list != &report_enum->report_list) { - report = (struct hid_report *) list; - hid_submit_report(hid, report, USB_DIR_IN); - list = list->next; - } - - report_enum = hid->report_enum + HID_FEATURE_REPORT; - list = report_enum->report_list.next; - while (list != &report_enum->report_list) { - report = (struct hid_report *) list; - hid_submit_report(hid, report, USB_DIR_IN); - list = list->next; - } - - err = 0; - ret = hid_wait_io(hid); - while (ret) { - err |= ret; - if (test_bit(HID_CTRL_RUNNING, &hid->iofl)) - usb_kill_urb(hid->urbctrl); - if (test_bit(HID_OUT_RUNNING, &hid->iofl)) - usb_kill_urb(hid->urbout); - ret = hid_wait_io(hid); - } - - if (err) - warn("timeout initializing reports\n"); - - report_enum = hid->report_enum + HID_INPUT_REPORT; - list = report_enum->report_list.next; - while (list != &report_enum->report_list) { - report = (struct hid_report *) list; - usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0), - HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, report->id, - hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); - list = list->next; - } -} - -#define USB_VENDOR_ID_WACOM 0x056a - -#define USB_VENDOR_ID_KBGEAR 0x084e -#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 - -#define USB_VENDOR_ID_AIPTEK 0x08ca -#define USB_DEVICE_ID_AIPTEK_01 0x0001 -#define USB_DEVICE_ID_AIPTEK_10 0x0010 -#define USB_DEVICE_ID_AIPTEK_20 0x0020 -#define USB_DEVICE_ID_AIPTEK_21 0x0021 -#define USB_DEVICE_ID_AIPTEK_22 0x0022 -#define USB_DEVICE_ID_AIPTEK_23 0x0023 -#define USB_DEVICE_ID_AIPTEK_24 0x0024 - -#define USB_VENDOR_ID_GRIFFIN 0x077d -#define USB_DEVICE_ID_POWERMATE 0x0410 -#define USB_DEVICE_ID_SOUNDKNOB 0x04AA - -#define USB_VENDOR_ID_ATEN 0x0557 -#define USB_DEVICE_ID_ATEN_UC100KM 0x2004 -#define USB_DEVICE_ID_ATEN_CS124U 0x2202 -#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204 -#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 -#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 - -#define USB_VENDOR_ID_TOPMAX 0x0663 -#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 - -#define USB_VENDOR_ID_HAPP 0x078b -#define USB_DEVICE_ID_UGCI_DRIVING 0x0010 -#define USB_DEVICE_ID_UGCI_FLYING 0x0020 -#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 - -#define USB_VENDOR_ID_MGE 0x0463 -#define USB_DEVICE_ID_MGE_UPS 0xffff -#define USB_DEVICE_ID_MGE_UPS1 0x0001 - -#define USB_VENDOR_ID_ONTRAK 0x0a07 -#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 - -#define USB_VENDOR_ID_TANGTOP 0x0d3d -#define USB_DEVICE_ID_TANGTOP_USBPS2 0x0001 - -#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f -#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 - -#define USB_VENDOR_ID_A4TECH 0x09DA -#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 - -#define USB_VENDOR_ID_CYPRESS 0x04b4 -#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 -#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 - -#define USB_VENDOR_ID_BERKSHIRE 0x0c98 -#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 - -#define USB_VENDOR_ID_ALPS 0x0433 -#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 - -#define USB_VENDOR_ID_SAITEK 0x06a3 -#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 - -#define USB_VENDOR_ID_NEC 0x073e -#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 - -#define USB_VENDOR_ID_CHIC 0x05fe -#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014 - -#define USB_VENDOR_ID_GLAB 0x06c2 -#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 -#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 -#define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045 -#define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040 -#define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053 - -#define USB_VENDOR_ID_WISEGROUP 0x0925 -#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 -#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 - -#define USB_VENDOR_ID_CODEMERCS 0x07c0 -#define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500 -#define USB_DEVICE_ID_CODEMERCS_IOW24 0x1501 -#define USB_DEVICE_ID_CODEMERCS_IOW48 0x1502 -#define USB_DEVICE_ID_CODEMERCS_IOW28 0x1503 - -#define USB_VENDOR_ID_DELORME 0x1163 -#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 - -static struct hid_blacklist { - __u16 idVendor; - __u16 idProduct; - unsigned quirks; -} hid_blacklist[] = { - - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, - - { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_BACK }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_EXTRA }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, - - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW48, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE }, - - { 0, 0 } -}; - -static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) -{ - if (!(hid->inbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->inbuf_dma))) - return -1; - if (!(hid->outbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->outbuf_dma))) - return -1; - if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma))) - return -1; - if (!(hid->ctrlbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->ctrlbuf_dma))) - return -1; - - return 0; -} - -static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) -{ - if (hid->inbuf) - usb_buffer_free(dev, HID_BUFFER_SIZE, hid->inbuf, hid->inbuf_dma); - if (hid->outbuf) - usb_buffer_free(dev, HID_BUFFER_SIZE, hid->outbuf, hid->outbuf_dma); - if (hid->cr) - usb_buffer_free(dev, sizeof(*(hid->cr)), hid->cr, hid->cr_dma); - if (hid->ctrlbuf) - usb_buffer_free(dev, HID_BUFFER_SIZE, hid->ctrlbuf, hid->ctrlbuf_dma); -} - -static struct hid_device *usb_hid_configure(struct usb_interface *intf) -{ - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_device *dev = interface_to_usbdev (intf); - struct hid_descriptor *hdesc; - struct hid_device *hid; - unsigned quirks = 0, rsize = 0; - char *buf, *rdesc; - int n; - - /* ignore all Wacom devices */ - if (dev->descriptor.idVendor == USB_VENDOR_ID_WACOM) - return NULL; - - for (n = 0; hid_blacklist[n].idVendor; n++) - if ((hid_blacklist[n].idVendor == dev->descriptor.idVendor) && - (hid_blacklist[n].idProduct == dev->descriptor.idProduct)) - quirks = hid_blacklist[n].quirks; - - if (quirks & HID_QUIRK_IGNORE) - return NULL; - - if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->desc.bNumEndpoints) || - usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { - dbg("class descriptor not present\n"); - return NULL; - } - - for (n = 0; n < hdesc->bNumDescriptors; n++) - if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) - rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); - - if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { - dbg("weird size of report descriptor (%u)", rsize); - return NULL; - } - - if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) { - dbg("couldn't allocate rdesc memory"); - return NULL; - } - - if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { - dbg("reading report descriptor failed"); - kfree(rdesc); - return NULL; - } - -#ifdef DEBUG_DATA - printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); - for (n = 0; n < rsize; n++) - printk(" %02x", (unsigned char) rdesc[n]); - printk("\n"); -#endif - - if (!(hid = hid_parse_report(rdesc, rsize))) { - dbg("parsing report descriptor failed"); - kfree(rdesc); - return NULL; - } - - kfree(rdesc); - hid->quirks = quirks; - - if (hid_alloc_buffers(dev, hid)) { - hid_free_buffers(dev, hid); - goto fail; - } - - for (n = 0; n < interface->desc.bNumEndpoints; n++) { - - struct usb_endpoint_descriptor *endpoint; - int pipe; - int interval; - - endpoint = &interface->endpoint[n].desc; - if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */ - continue; - - /* handle potential highspeed HID correctly */ - interval = endpoint->bInterval; - if (dev->speed == USB_SPEED_HIGH) - interval = 1 << (interval - 1); - - if (endpoint->bEndpointAddress & USB_DIR_IN) { - int len; - - if (hid->urbin) - continue; - if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) - goto fail; - pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); - len = usb_maxpacket(dev, pipe, 0); - if (len > HID_BUFFER_SIZE) - len = HID_BUFFER_SIZE; - usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, len, - hid_irq_in, hid, interval); - hid->urbin->transfer_dma = hid->inbuf_dma; - hid->urbin->transfer_flags |=(URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK); - } else { - if (hid->urbout) - continue; - if (!(hid->urbout = usb_alloc_urb(0, GFP_KERNEL))) - goto fail; - pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress); - usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0, - hid_irq_out, hid, interval); - hid->urbout->transfer_dma = hid->outbuf_dma; - hid->urbout->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK); - } - } - - if (!hid->urbin) { - err("couldn't find an input interrupt endpoint"); - goto fail; - } - - init_waitqueue_head(&hid->wait); - - spin_lock_init(&hid->outlock); - spin_lock_init(&hid->ctrllock); - - hid->version = le16_to_cpu(hdesc->bcdHID); - hid->country = hdesc->bCountryCode; - hid->dev = dev; - hid->intf = intf; - hid->ifnum = interface->desc.bInterfaceNumber; - - hid->name[0] = 0; - - if (!(buf = kmalloc(64, GFP_KERNEL))) - goto fail; - - if (usb_string(dev, dev->descriptor.iManufacturer, buf, 64) > 0) { - strcat(hid->name, buf); - if (usb_string(dev, dev->descriptor.iProduct, buf, 64) > 0) - snprintf(hid->name, 64, "%s %s", hid->name, buf); - } else if (usb_string(dev, dev->descriptor.iProduct, buf, 128) > 0) { - snprintf(hid->name, 128, "%s", buf); - } else - snprintf(hid->name, 128, "%04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct); - - usb_make_path(dev, buf, 64); - snprintf(hid->phys, 64, "%s/input%d", buf, - intf->altsetting[0].desc.bInterfaceNumber); - - if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) - hid->uniq[0] = 0; - - kfree(buf); - - hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); - if (!hid->urbctrl) - goto fail; - usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr, - hid->ctrlbuf, 1, hid_ctrl, hid); - hid->urbctrl->setup_dma = hid->cr_dma; - hid->urbctrl->transfer_dma = hid->ctrlbuf_dma; - hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | URB_ASYNC_UNLINK); - - return hid; - -fail: - - if (hid->urbin) - usb_free_urb(hid->urbin); - if (hid->urbout) - usb_free_urb(hid->urbout); - if (hid->urbctrl) - usb_free_urb(hid->urbctrl); - hid_free_buffers(dev, hid); - hid_free_device(hid); - - return NULL; -} - -static void hid_disconnect(struct usb_interface *intf) -{ - struct hid_device *hid = usb_get_intfdata (intf); - - if (!hid) - return; - - usb_set_intfdata(intf, NULL); - usb_kill_urb(hid->urbin); - usb_kill_urb(hid->urbout); - usb_kill_urb(hid->urbctrl); - - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_disconnect(hid); - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_disconnect(hid); - - usb_free_urb(hid->urbin); - usb_free_urb(hid->urbctrl); - if (hid->urbout) - usb_free_urb(hid->urbout); - - hid_free_buffers(hid->dev, hid); - hid_free_device(hid); -} - -static int hid_probe (struct usb_interface *intf, const struct usb_device_id *id) -{ - struct hid_device *hid; - char path[64]; - int i; - char *c; - - dbg("HID probe called for ifnum %d", - intf->altsetting->desc.bInterfaceNumber); - - if (!(hid = usb_hid_configure(intf))) - return -EIO; - - hid_init_reports(hid); - hid_dump_device(hid); - - if (!hidinput_connect(hid)) - hid->claimed |= HID_CLAIMED_INPUT; - if (!hiddev_connect(hid)) - hid->claimed |= HID_CLAIMED_HIDDEV; - - usb_set_intfdata(intf, hid); - - if (!hid->claimed) { - printk ("HID device not claimed by input or hiddev\n"); - hid_disconnect(intf); - return -EIO; - } - - printk(KERN_INFO); - - if (hid->claimed & HID_CLAIMED_INPUT) - printk("input"); - if (hid->claimed == (HID_CLAIMED_INPUT | HID_CLAIMED_HIDDEV)) - printk(","); - if (hid->claimed & HID_CLAIMED_HIDDEV) - printk("hiddev%d", hid->minor); - - c = "Device"; - for (i = 0; i < hid->maxcollection; i++) { - if (hid->collection[i].type == HID_COLLECTION_APPLICATION && - (hid->collection[i].usage & HID_USAGE_PAGE) == HID_UP_GENDESK && - (hid->collection[i].usage & 0xffff) < ARRAY_SIZE(hid_types)) { - c = hid_types[hid->collection[i].usage & 0xffff]; - break; - } - } - - usb_make_path(interface_to_usbdev(intf), path, 63); - - printk(": USB HID v%x.%02x %s [%s] on %s\n", - hid->version >> 8, hid->version & 0xff, c, hid->name, path); - - return 0; -} - -static int hid_suspend(struct usb_interface *intf, u32 state) -{ - struct hid_device *hid = usb_get_intfdata (intf); - - usb_kill_urb(hid->urbin); - intf->dev.power.power_state = state; - dev_dbg(&intf->dev, "suspend\n"); - return 0; -} - -static int hid_resume(struct usb_interface *intf) -{ - struct hid_device *hid = usb_get_intfdata (intf); - int status; - - intf->dev.power.power_state = PM_SUSPEND_ON; - if (hid->open) - status = usb_submit_urb(hid->urbin, GFP_NOIO); - else - status = 0; - dev_dbg(&intf->dev, "resume status %d\n", status); - return status; -} - -static struct usb_device_id hid_usb_ids [] = { - { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, - .bInterfaceClass = USB_INTERFACE_CLASS_HID }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE (usb, hid_usb_ids); - -static struct usb_driver hid_driver = { - .owner = THIS_MODULE, - .name = "usbhid", - .probe = hid_probe, - .disconnect = hid_disconnect, - .suspend = hid_suspend, - .resume = hid_resume, - .id_table = hid_usb_ids, -}; - -static int __init hid_init(void) -{ - int retval; - retval = hiddev_init(); - if (retval) - goto hiddev_init_fail; - retval = usb_register(&hid_driver); - if (retval) - goto usb_register_fail; - info(DRIVER_VERSION ":" DRIVER_DESC); - - return 0; -usb_register_fail: - hiddev_exit(); -hiddev_init_fail: - return retval; -} - -static void __exit hid_exit(void) -{ - usb_deregister(&hid_driver); - hiddev_exit(); -} - -module_init(hid_init); -module_exit(hid_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); diff --git a/src/2.6.10/wacom.c b/src/2.6.10/wacom.c deleted file mode 100644 index a064949..0000000 --- a/src/2.6.10/wacom.c +++ /dev/null @@ -1,1264 +0,0 @@ -/* - * USB Wacom Graphire and Wacom Intuos tablet support - * - * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz> - * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk> - * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at> - * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org> - * Copyright (c) 2000 James E. Blair <corvus@gnu.org> - * Copyright (c) 2000 Daniel Egger <egger@suse.de> - * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> - * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> - * Copyright (c) 2002-2009 Ping Cheng <pingc@wacom.com> - * - * ChangeLog: - * v0.1 (vp) - Initial release - * v0.2 (aba) - Support for all buttons / combinations - * v0.3 (vp) - Support for Intuos added - * v0.4 (sm) - Support for more Intuos models, menustrip - * relative mode, proximity. - * v0.5 (vp) - Big cleanup, nifty features removed, - * they belong in userspace - * v1.8 (vp) - Submit URB only when operating, moved to CVS, - * use input_report_key instead of report_btn and - * other cleanups - * v1.11 (vp) - Add URB ->dev setting for new kernels - * v1.11 (jb) - Add support for the 4D Mouse & Lens - * v1.12 (de) - Add support for two more inking pen IDs - * v1.14 (vp) - Use new USB device id probing scheme. - * Fix Wacom Graphire mouse wheel - * v1.18 (vp) - Fix mouse wheel direction - * Make mouse relative - * v1.20 (fl) - Report tool id for Intuos devices - * - Multi tools support - * - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...) - * - Add PL models support - * - Fix Wacom Graphire mouse wheel again - * v1.21 (vp) - Removed protocol descriptions - * - Added MISC_SERIAL for tool serial numbers - * (gb) - Identify version on module load. - * v1.21.1 (fl) - added Graphire2 support - * v1.21.2 (fl) - added Intuos2 support - * - added all the PL ids - * v1.21.3 (fl) - added another eraser id from Neil Okamoto - * - added smooth filter for Graphire from Peri Hankey - * - added PenPartner support from Olaf van Es - * - new tool ids from Ole Martin Bjoerndalen - * v1.29 (pc) - Add support for more tablets - * - Fix pressure reporting - * v1.30 (vp) - Merge 2.4 and 2.5 drivers - * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse - * - Cleanups here and there - * v1.30.1 (pi) - Added Graphire3 support - * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... - * - * WARNING: THIS IS NOT PART OF THE OFFICIAL KERNEL TREE - * THIS IS FOR TESTING PURPOSES - * - * v1.40-2.6.10-pc-0.1 - initial release based on 2.6.10 - * v1.40-2.6.10-pc-0.2 - fixed a Graphire bug - * v1.40-2.6.10-pc-0.3 - added Cintiq 21UX - * v1.40-2.6.10-pc-0.4 - Fixed an I3 bug - * v1.40-2.6.10-pc-0.5 - Fixed a Cintiq 21UX bug - * v1.40-2.6.10-pc-0.6 - Added G4, DTF720 and DTU710 - * v1.40-2.6.10-pc-0.7 - Added DTF 521, I3 12x12, and I3 12x19 - * v1.40-2.6.10-pc-0.8 - Support tablet buttons/keys - * v1.40-2.6.10-pc-0.9 - Support Intuos outbound tracking - * v1.40-2.6.10-pc-0.10 - Added Bamboo - * v1.40-2.6.10-pc-0.11 - added Bamboo1, Bamboo Fun, and Hummingbird - * v1.40-2.6.10-pc-0.12 - Added Cintiq 20WSX - * v1.40-2.6.10-pc-0.13 - Added Intuos4 - * v1.40-2.6.10-pc-0.14 - Fixed an expresskey bug - */ - -/* - * 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. - */ - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/input.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/usb.h> -#include <asm/unaligned.h> -#include <asm/byteorder.h> - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.40 - 2.6.10-pc-0.14" -#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" -#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" -#define DRIVER_LICENSE "GPL" - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); - -#define USB_VENDOR_ID_WACOM 0x056a -#define STYLUS_DEVICE_ID 0x02 -#define CURSOR_DEVICE_ID 0x06 -#define ERASER_DEVICE_ID 0x0A -#define PAD_DEVICE_ID 0x0F - -enum { - PENPARTNER = 0, - VOLITO1, - GRAPHIRE, - G4, - PL, - INTUOS, - INTUOS3S, - INTUOS3, - INTUOS3L, - CINTIQ, - INTUOS4S, - INTUOS4, - INTUOS4L, - MO, - BEE, - MAX_TYPE -}; - -struct wacom_features { - char *name; - int pktlen; - int x_max; - int y_max; - int pressure_max; - int distance_max; - int type; - usb_complete_t irq; -}; - -struct wacom { - unsigned char *data; - dma_addr_t data_dma; - struct input_dev dev; - struct usb_device *usbdev; - struct urb *irq; - struct wacom_features *features; - int tool[2]; - int id[2]; - int open; - __u32 serial[2]; - char phys[32]; -}; - -#define USB_REQ_GET_REPORT 0x01 -#define USB_REQ_SET_REPORT 0x09 -static int usb_set_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_sndctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, HZ); -} - -static int usb_get_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, HZ); -} - -static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) -{ - struct wacom *wacom = urb->context; - unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; - int prox, pressure; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - if (data[0] != 2) { - dbg("wacom_pl_irq: received unknown report #%d", data[0]); - goto exit; - } - - prox = data[1] & 0x40; - - input_regs(dev, regs); - - wacom->id[0] = ERASER_DEVICE_ID; - if (prox) { - - pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); - if (wacom->features->pressure_max > 255) - pressure = (pressure << 1) | ((data[4] >> 6) & 1); - pressure += (wacom->features->pressure_max + 1) / 2; - - /* - * if going from out of proximity into proximity select between the eraser - * and the pen based on the state of the stylus2 button, choose eraser if - * pressed else choose pen. if not a proximity change from out to in, send - * an out of proximity for previous tool then a in for new tool. - */ - if (!wacom->tool[0]) { - /* Eraser bit set for DTF */ - if (data[1] & 0x10) - wacom->tool[1] = BTN_TOOL_RUBBER; - else - /* Going into proximity select tool */ - wacom->tool[1] = (data[4] & 0x20)? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - } - else { - /* was entered with stylus2 pressed */ - if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) { - /* report out proximity for previous tool */ - input_report_key(dev, wacom->tool[1], 0); - input_sync(dev); - wacom->tool[1] = BTN_TOOL_PEN; - goto exit; - } - } - if (wacom->tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom->tool[1] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - } - input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */ - input_report_abs(dev, ABS_MISC, wacom->id[0]); /* report tool id */ - input_report_abs(dev, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); - input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); - input_report_abs(dev, ABS_PRESSURE, pressure); - - input_report_key(dev, BTN_TOUCH, data[4] & 0x08); - input_report_key(dev, BTN_STYLUS, data[4] & 0x10); - /* Only allow the stylus2 button to be reported for the pen tool. */ - input_report_key(dev, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20)); - } - else { - /* report proximity-out of a (valid) tool */ - if (wacom->tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom->tool[1] = BTN_TOOL_PEN; - } - input_report_key(dev, wacom->tool[1], prox); - input_report_abs(dev, ABS_MISC, 0); /* reset tool id */ - } - - wacom->tool[0] = prox; /* Save proximity state */ - input_sync(dev); - -exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs) -{ - struct wacom *wacom = urb->context; - unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - if (data[0] != 2) - { - printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); - goto exit; - } - - input_regs(dev, regs); - if (data[1] & 0x04) - { - input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20); - input_report_key(dev, BTN_TOUCH, data[1] & 0x08); - wacom->id[0] = ERASER_DEVICE_ID; - } - else - { - input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20); - input_report_key(dev, BTN_TOUCH, data[1] & 0x01); - wacom->id[0] = STYLUS_DEVICE_ID; - } - input_report_abs(dev, ABS_MISC, wacom->id[0]); /* report tool id */ - input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[2])); - input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[4])); - input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6])); - input_report_key(dev, BTN_STYLUS, data[1] & 0x02); - input_report_key(dev, BTN_STYLUS2, data[1] & 0x10); - - input_sync(dev); - -exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs) -{ - struct wacom *wacom = urb->context; - unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - switch (data[0]) { - case 1: - input_regs(dev, regs); - if (data[5] & 0x80) { - wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID; - input_report_key(dev, wacom->tool[0], 1); - input_report_abs(dev, ABS_MISC, wacom->id[0]); /* report tool id */ - input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[1])); - input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[3])); - input_report_abs(dev, ABS_PRESSURE, (signed char)data[6] + 127); - input_report_key(dev, BTN_TOUCH, ((signed char)data[6] > -127)); - input_report_key(dev, BTN_STYLUS, (data[5] & 0x40)); - } else { - input_report_key(dev, wacom->tool[0], 0); - input_report_abs(dev, ABS_MISC, 0); /* report tool id */ - input_report_abs(dev, ABS_PRESSURE, -1); - input_report_key(dev, BTN_TOUCH, 0); - } - input_sync(dev); - break; - case 2: - input_regs(dev, regs); - input_report_key(dev, BTN_TOOL_PEN, 1); - input_report_abs(dev, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */ - input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[1])); - input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[3])); - input_report_abs(dev, ABS_PRESSURE, (signed char)data[6] + 127); - input_report_key(dev, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20)); - input_report_key(dev, BTN_STYLUS, (data[5] & 0x40)); - input_sync(dev); - break; - default: - printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]); - goto exit; - } - -exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) -{ - struct wacom *wacom = urb->context; - unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; - int x, y, rw; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - /* 2 Volito1 and 2 users say this is wrong - if (data[0] == 99) return; */ - - if (data[0] != 2) { - dbg("wacom_graphire_irq: received unknown report #%d", data[0]); - goto exit; - } - - input_regs(dev, regs); - - if (data[1] & 0x80) { - /* in prox and not a pad data */ - - - switch ((data[1] >> 5) & 3) { - - case 0: /* Pen */ - wacom->id[0] = STYLUS_DEVICE_ID; - wacom->tool[0] = BTN_TOOL_PEN; - break; - - case 1: /* Rubber */ - wacom->tool[0] = BTN_TOOL_RUBBER; - wacom->id[0] = ERASER_DEVICE_ID; - break; - - case 2: /* Mouse with wheel */ - input_report_key(dev, BTN_MIDDLE, data[1] & 0x04); - if ( wacom->features->type == G4 || - wacom->features->type == MO ) { - rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : data[7] & 0x03; - input_report_rel(dev, REL_WHEEL, -rw); - else - input_report_rel(dev, REL_WHEEL, -(signed char) data[6]); - /* fall through */ - - case 3: /* Mouse without wheel */ - wacom->tool[0] = BTN_TOOL_MOUSE; - wacom->id[0] = CURSOR_DEVICE_ID; - input_report_key(dev, BTN_LEFT, data[1] & 0x01); - input_report_key(dev, BTN_RIGHT, data[1] & 0x02); - if ( wacom->features->type == G4 || - wacom->features->type == MO ) - input_report_abs(dev, ABS_DISTANCE, data[6]); - else - input_report_abs(dev, ABS_DISTANCE, data[7]); - break; - } - x = le16_to_cpu(*(__le16 *) &data[2]); - y = le16_to_cpu(*(__le16 *) &data[4]); - input_report_abs(dev, ABS_X, x); - input_report_abs(dev, ABS_Y, y); - - if (wacom->tool[0] != BTN_TOOL_MOUSE) { - input_report_abs(dev, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8)); - input_report_key(dev, BTN_TOUCH, data[1] & 0x01); - input_report_key(dev, BTN_STYLUS, data[1] & 0x02); - input_report_key(dev, BTN_STYLUS2, data[1] & 0x04); - } - input_report_abs(dev, ABS_MISC, wacom->id[0]); /* report tool id */ - input_report_key(dev, wacom->tool[0], 1); - } else if (wacom->id[0]) { - input_report_abs(dev, ABS_X, 0); - input_report_abs(dev, ABS_Y, 0); - if (wacom->tool[0] == BTN_TOOL_MOUSE) { - input_report_key(dev, BTN_LEFT, 0); - input_report_key(dev, BTN_RIGHT, 0); - input_report_abs(dev, ABS_DISTANCE, 0); - } else { - input_report_abs(dev, ABS_PRESSURE, 0); - input_report_key(dev, BTN_TOUCH, 0); - input_report_key(dev, BTN_STYLUS, 0); - input_report_key(dev, BTN_STYLUS2, 0); - } - wacom->id[0] = 0; - input_report_abs(dev, ABS_MISC, 0); /* reset tool id */ - input_report_key(dev, wacom->tool[0], 0); - } - input_sync(dev); - - /* send pad data */ - switch (wacom->features->type) { - case G4: - if (data[7] & 0xf8) { - wacom->id[1] = PAD_DEVICE_ID; - input_report_key(dev, BTN_0, (data[7] & 0x40)); - input_report_key(dev, BTN_4, (data[7] & 0x80)); - rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); - input_report_rel(dev, REL_WHEEL, rw); - input_report_key(dev, BTN_TOOL_FINGER, 0xf0); - input_report_abs(dev, ABS_MISC, wacom->id[1]); - input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); - } else if (wacom->id[1]) { - wacom->id[1] = 0; - input_report_key(dev, BTN_TOOL_FINGER, 0); - input_report_abs(dev, ABS_MISC, 0); - input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); - } - input_sync(dev); - break; - case MO: - if ((data[7] & 0xf8) || (data[8] & 0xff)) { - wacom->id[1] = PAD_DEVICE_ID; - input_report_key(dev, BTN_0, (data[7] & 0x08)); - input_report_key(dev, BTN_1, (data[7] & 0x20)); - input_report_key(dev, BTN_4, (data[7] & 0x10)); - input_report_key(dev, BTN_5, (data[7] & 0x40)); - input_report_abs(dev, ABS_WHEEL, (data[8] & 0x7f)); - input_report_key(dev, BTN_TOOL_FINGER, 0xf0); - input_report_abs(dev, ABS_MISC, wacom->id[1]); - input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); - } else if (wacom->id[1]) { - wacom->id[1] = 0; - input_report_key(dev, BTN_0, (data[7] & 0x08)); - input_report_key(dev, BTN_1, (data[7] & 0x20)); - input_report_key(dev, BTN_4, (data[7] & 0x10)); - input_report_key(dev, BTN_5, (data[7] & 0x40)); - input_report_abs(dev, ABS_WHEEL, (data[8] & 0x7f)); - input_report_key(dev, BTN_TOOL_FINGER, 0); - input_report_abs(dev, ABS_MISC, 0); - input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); - } - input_sync(dev); - break; - } - -exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -static int wacom_intuos_inout(struct urb *urb) -{ - struct wacom *wacom = urb->context; - unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; - int idx = 0; - - /* tool number */ - if (wacom->features->type == INTUOS) - idx = data[1] & 0x01; - - /* Enter report */ - if ((data[1] & 0xfc) == 0xc0) - { - /* serial number of the tool */ - wacom->serial[idx] = ((data[3] & 0x0f) << 28) + - (data[4] << 20) + ((__u32)data[5] << 12) + - (data[6] << 4) + (data[7] >> 4); - - wacom->id[idx] = (data[2] << 4) | (data[3] >> 4); - switch (wacom->id[idx]) { - case 0x812: /* Inking pen */ - case 0x801: /* Intuos3 Inking pen */ - case 0x20802: /* Intuos4 Inking Pen */ - case 0x012: - wacom->tool[idx] = BTN_TOOL_PENCIL; - break; - case 0x822: /* Pen */ - case 0x842: - case 0x852: - case 0x823: /* Intuos3 Grip Pen */ - case 0x813: /* Intuos3 Classic Pen */ - case 0x885: /* Intuos3 Marker Pen */ - case 0x802: /* Intuos4 Grip Pen Eraser */ - case 0x804: /* Intuos4 Marker Pen */ - case 0x40802: /* Intuos4 Classic Pen */ - case 0x022: - wacom->tool[idx] = BTN_TOOL_PEN; - break; - case 0x832: /* Stroke pen */ - case 0x032: - wacom->tool[idx] = BTN_TOOL_BRUSH; - break; - case 0x007: /* Mouse 4D and 2D */ - case 0x09c: - case 0x094: - case 0x806: /* Intuos4 Mouse */ - case 0x017: /* Intuos3 2D Mouse */ - wacom->tool[idx] = BTN_TOOL_MOUSE; - break; - case 0x096: /* Lens cursor */ - case 0x097: /* Intuos3 Lens cursor */ - case 0x006: /* Intuos4 Lens cursor */ - wacom->tool[idx] = BTN_TOOL_LENS; - break; - case 0x82a: /* Eraser */ - case 0x85a: - case 0x91a: - case 0xd1a: - case 0x0fa: - case 0x82b: /* Intuos3 Grip Pen Eraser */ - case 0x81b: /* Intuos3 Classic Pen Eraser */ - case 0x91b: /* Intuos3 Airbrush Eraser */ - case 0x80c: /* Intuos4 Marker Pen Eraser */ - case 0x80a: /* Intuos4 Grip Pen Eraser */ - case 0x4080a: /* Intuos4 Classic Pen Eraser */ - case 0x90a: /* Intuos4 Airbrush Eraser */ - wacom->tool[idx] = BTN_TOOL_RUBBER; - break; - case 0xd12: /* Airbrush */ - case 0x912: - case 0x112: - case 0x913: /* Intuos3 Airbrush */ - case 0x902: /* Intuos4 Airbrush */ - wacom->tool[idx] = BTN_TOOL_AIRBRUSH; - break; - default: /* Unknown tool */ - wacom->tool[idx] = BTN_TOOL_PEN; - } - return 1; - } - - /* Exit report */ - if ((data[1] & 0xfe) == 0x80) { - input_report_abs(dev, ABS_X, 0); - input_report_abs(dev, ABS_Y, 0); - input_report_abs(dev, ABS_DISTANCE, 0); - input_report_abs(dev, ABS_TILT_X, 0); - input_report_abs(dev, ABS_TILT_Y, 0); - if (wacom->tool[idx] >= BTN_TOOL_MOUSE) { - input_report_key(dev, BTN_LEFT, 0); - input_report_key(dev, BTN_MIDDLE, 0); - input_report_key(dev, BTN_RIGHT, 0); - input_report_key(dev, BTN_SIDE, 0); - input_report_key(dev, BTN_EXTRA, 0); - input_report_abs(dev, ABS_THROTTLE, 0); - input_report_abs(dev, ABS_RZ, 0); - } else { - input_report_abs(dev, ABS_PRESSURE, 0); - input_report_key(dev, BTN_STYLUS, 0); - input_report_key(dev, BTN_STYLUS2, 0); - input_report_key(dev, BTN_TOUCH, 0); - input_report_abs(dev, ABS_WHEEL, 0); - if(wacom->features->type >= INTUOS3S) - input_report_abs(dev, ABS_Z, 0); - } - input_report_key(dev, wacom->tool[idx], 0); - input_report_abs(dev, ABS_MISC, 0); /* reset tool id */ - input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); - input_sync(dev); - return 1; - } - return 0; -} - -static void wacom_intuos_general(struct urb *urb) -{ - struct wacom *wacom = urb->context; - unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; - unsigned int t; - - /* general pen packet */ - if ((data[1] & 0xb8) == 0xa0) - { - t = (data[6] << 2) | ((data[7] >> 6) & 3); - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) - t = (t << 1) | (data[1] & 1); - input_report_abs(dev, ABS_PRESSURE, t); - input_report_abs(dev, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); - input_report_key(dev, BTN_STYLUS, data[1] & 2); - input_report_key(dev, BTN_STYLUS2, data[1] & 4); - input_report_key(dev, BTN_TOUCH, t > 10); - } - - /* airbrush second packet */ - if ((data[1] & 0xbc) == 0xb4) - { - input_report_abs(dev, ABS_WHEEL, - (data[6] << 2) | ((data[7] >> 6) & 3)); - input_report_abs(dev, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); - } - return; -} - -static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) -{ - struct wacom *wacom = urb->context; - unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; - unsigned int t; - int idx = 0; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) { - dbg("wacom_intuos_irq: received unknown report #%d", data[0]); - goto exit; - } - - input_regs(dev, regs); - - /* tool number */ - if (wacom->features->type == INTUOS) - idx = data[1] & 0x01; - - /* pad packets. Works as a second tool */ - if (data[0] == 12) - { - /* initiate the pad as a device */ - if (wacom->tool[1] != BTN_TOOL_FINGER) - wacom->tool[1] = BTN_TOOL_FINGER; - - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { - input_report_key(dev, BTN_0, (data[2] & 0x01)); - input_report_key(dev, BTN_1, (data[3] & 0x01)); - input_report_key(dev, BTN_2, (data[3] & 0x02)); - input_report_key(dev, BTN_3, (data[3] & 0x04)); - input_report_key(dev, BTN_4, (data[3] & 0x08)); - input_report_key(dev, BTN_5, (data[3] & 0x10)); - input_report_key(dev, BTN_6, (data[3] & 0x20)); - if (data[1] & 0x80) { - input_report_abs(dev, ABS_WHEEL, (data[1] & 0x7f)); - } else { - /* Out of proximity, clear wheel value. */ - input_report_abs(dev, ABS_WHEEL, 0); - } - if (wacom->features->type != INTUOS4S) { - input_report_key(dev, BTN_7, (data[3] & 0x40)); - input_report_key(dev, BTN_8, (data[3] & 0x80)); - } - if (data[1] | (data[2] & 0x01) | data[3]) { - input_report_key(dev, wacom->tool[1], 1); - input_report_abs(dev, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_key(dev, wacom->tool[1], 0); - input_report_abs(dev, ABS_MISC, 0); - } - } else { - input_report_key(dev, BTN_0, (data[5] & 0x01)); - input_report_key(dev, BTN_1, (data[5] & 0x02)); - input_report_key(dev, BTN_2, (data[5] & 0x04)); - input_report_key(dev, BTN_3, (data[5] & 0x08)); - input_report_key(dev, BTN_4, (data[6] & 0x01)); - input_report_key(dev, BTN_5, (data[6] & 0x02)); - input_report_key(dev, BTN_6, (data[6] & 0x04)); - input_report_key(dev, BTN_7, (data[6] & 0x08)); - input_report_key(dev, BTN_8, (data[5] & 0x10)); - input_report_key(dev, BTN_9, (data[6] & 0x10)); - input_report_abs(dev, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); - input_report_abs(dev, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); - - if((data[5] & 0x1f) | (data[6] & 0x1f) | (data[1] & 0x1f) | - data[2] | (data[3] & 0x1f) | data[4]) { - input_report_key(dev, wacom->tool[1], 1); - input_report_abs(dev, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_key(dev, wacom->tool[1], 0); - input_report_abs(dev, ABS_MISC, 0); - } - } - input_event(dev, EV_MSC, MSC_SERIAL, 0xffffffff); - input_sync(dev); - goto exit; - } - - /* process in/out prox events */ - if (wacom_intuos_inout(urb)) goto exit; - - /* don't proceed if we don't know the ID */ - if (!wacom->id[idx]) goto exit; - - /* Only large Intuos support Lense Cursor */ - if((wacom->tool[idx] == BTN_TOOL_LENS) - && ((wacom->features->type == INTUOS3) - || (wacom->features->type == INTUOS3S) - || (wacom->features->type == INTUOS4) - || (wacom->features->type == INTUOS4S))) - goto exit; - - /* Cintiq doesn't send data when RDY bit isn't set */ - if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40)) goto exit; - - if(wacom->features->type >= INTUOS3S) - { - input_report_abs(dev, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); - input_report_abs(dev, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); - input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); - } - else - { - input_report_abs(dev, ABS_X, be16_to_cpu(*(__be16 *) &data[2])); - input_report_abs(dev, ABS_Y, be16_to_cpu(*(__be16 *) &data[4])); - input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); - } - - /* process general packets */ - wacom_intuos_general(urb); - - /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ - if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) { - /* Rotation packet */ - if (data[1] & 0x02) - { - if(wacom->features->type >= INTUOS3S) - { - /* I3 marker pen rotation */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : - ((t-1) / 2 + 450)) : (450 - t / 2) ; - input_report_abs(dev, ABS_Z, t); - } - else - { - /* 4D mouse rotation packet */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ? - ((t - 1) / 2) : -t / 2); - } - } - /* 4D mouse packets */ - else if ( !(data[1] & 0x10) && wacom->features->type < INTUOS3S) - { - input_report_key(dev, BTN_LEFT, data[8] & 0x01); - input_report_key(dev, BTN_MIDDLE, data[8] & 0x02); - input_report_key(dev, BTN_RIGHT, data[8] & 0x04); - - input_report_key(dev, BTN_SIDE, data[8] & 0x20); - input_report_key(dev, BTN_EXTRA, data[8] & 0x10); - t = (data[6] << 2) | ((data[7] >> 6) & 3); - input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); - } - else if (wacom->tool[idx] == BTN_TOOL_MOUSE) - { - /* I4 mouse */ - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { - input_report_key(dev, BTN_LEFT, data[6] & 0x01); - input_report_key(dev, BTN_MIDDLE, data[6] & 0x02); - input_report_key(dev, BTN_RIGHT, data[6] & 0x04); - input_report_rel(dev, REL_WHEEL, ((data[7] & 0x80) >> 7) - - ((data[7] & 0x40) >> 6)); - input_report_key(dev, BTN_SIDE, data[6] & 0x08); - input_report_key(dev, BTN_EXTRA, data[6] & 0x10); - - input_report_abs(dev, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); - } else { - /* 2D mouse packets */ - input_report_key(dev, BTN_LEFT, data[8] & 0x04); - input_report_key(dev, BTN_MIDDLE, data[8] & 0x08); - input_report_key(dev, BTN_RIGHT, data[8] & 0x10); - input_report_rel(dev, REL_WHEEL, (data[8] & 0x01) - - ((data[8] & 0x02) >> 1)); - - /* I3 2D mouse side buttons */ - if (wacom->features->type <= INTUOS3S && wacom->features->type >= INTUOS3L) - { - input_report_key(dev, BTN_SIDE, data[8] & 0x40); - input_report_key(dev, BTN_EXTRA, data[8] & 0x20); - } - } - } - /* Lens cursor packets */ - else if ((wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L || - wacom->features->type == INTUOS4L) && (wacom->tool[idx] == BTN_TOOL_LENS)) - { - input_report_key(dev, BTN_LEFT, data[8] & 0x01); - input_report_key(dev, BTN_MIDDLE, data[8] & 0x02); - input_report_key(dev, BTN_RIGHT, data[8] & 0x04); - input_report_key(dev, BTN_SIDE, data[8] & 0x10); - input_report_key(dev, BTN_EXTRA, data[8] & 0x08); - } - } - - input_report_abs(dev, ABS_MISC, wacom->id[idx]); /* report tool id */ - input_report_key(dev, wacom->tool[idx], 1); - input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); - input_sync(dev); - -exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -static struct wacom_features wacom_features[] = { - { "Wacom Penpartner", 7, 5040, 3780, 255, 0, PENPARTNER, wacom_penpartner_irq }, - { "Wacom Graphire", 8, 10206, 7422, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Graphire3 4x5", 8, 10208, 7424, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, G4, wacom_graphire_irq }, - { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, G4, wacom_graphire_irq }, - { "Wacom BambooFun 4x5", 9, 14760, 9225, 511, 63, MO, wacom_graphire_irq }, - { "Wacom BambooFun 6x8", 9, 21648, 13530, 511, 63, MO, wacom_graphire_irq }, - { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom PL400", 8, 5408, 4056, 255, 0, PL, wacom_pl_irq }, - { "Wacom PL500", 8, 6144, 4608, 255, 0, PL, wacom_pl_irq }, - { "Wacom PL600", 8, 6126, 4604, 255, 0, PL, wacom_pl_irq }, - { "Wacom PL600SX", 8, 6260, 5016, 255, 0, PL, wacom_pl_irq }, - { "Wacom PL550", 8, 6144, 4608, 511, 0, PL, wacom_pl_irq }, - { "Wacom PL800", 8, 7220, 5780, 511, 0, PL, wacom_pl_irq }, - { "Wacom PL700", 8, 6758, 5406, 511, 0, PL, wacom_pl_irq }, - { "Wacom PL510", 8, 6282, 4762, 511, 0, PL, wacom_pl_irq }, - { "Wacom DTU710", 8, 34080, 27660, 511, 0, PL, wacom_pl_irq }, - { "Wacom DTF521", 8, 6282, 4762, 511, 0, PL, wacom_pl_irq }, - { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Volito", 8, 5104, 3712, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom PenStation2", 8, 3250, 2320, 255, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom PenPartner2", 8, 3250, 2320, 255, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Bamboo", 9, 14760, 9225, 511, 63, MO, wacom_graphire_irq }, - { "Wacom Bamboo1", 8, 5104, 3712, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Cintiq Partner",8, 20480, 15360, 511, 0, PL, wacom_ptu_irq }, - { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 63, INTUOS3S, wacom_intuos_irq }, - { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 63, INTUOS3, wacom_intuos_irq }, - { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 63, INTUOS3, wacom_intuos_irq }, - { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L, wacom_intuos_irq }, - { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L, wacom_intuos_irq }, - { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3, wacom_intuos_irq }, - { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S, wacom_intuos_irq }, - { "Wacom Intuos4 4x6", 10, 31496, 19685, 2047, 63, INTUOS4S, wacom_intuos_irq }, - { "Wacom Intuos4 6x9", 10, 44704, 27940, 2047, 63, INTUOS4, wacom_intuos_irq }, - { "Wacom Intuos4 8x13", 10, 65024, 40640, 2047, 63, INTUOS4L, wacom_intuos_irq }, - { "Wacom Intuos4 12x19", 10, 97536, 60960, 2047, 63, INTUOS4L, wacom_intuos_irq }, - { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ, wacom_intuos_irq }, - { "Wacom DTF720", 8, 6858, 5506, 511, 0, PL, wacom_pl_irq }, - { "Wacom Cintiq 20WSX", 10, 86680, 54180, 1023, 63, BEE, wacom_intuos_irq }, - { "Wacom Cintiq 12WX", 10, 53020, 33440, 1023, 63, BEE, wacom_intuos_irq }, - { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS, wacom_intuos_irq }, - { } -}; - -static struct usb_device_id wacom_ids[] = { - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x00) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x11) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x17) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x18) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x30) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x32) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x69) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB8) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB9) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBA) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBB) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC4) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, - { } -}; - -MODULE_DEVICE_TABLE(usb, wacom_ids); - -static int wacom_open(struct input_dev *dev) -{ - struct wacom *wacom = dev->private; - - if (wacom->open++) - return 0; - - wacom->irq->dev = wacom->usbdev; - if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { - wacom->open--; - return -EIO; - } - - return 0; -} - -static void wacom_close(struct input_dev *dev) -{ - struct wacom *wacom = dev->private; - - if (!--wacom->open) - usb_kill_urb(wacom->irq); -} - -static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); - struct usb_endpoint_descriptor *endpoint; - char rep_data[2], limit = 0; - struct wacom *wacom; - char path[64]; - - if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) - return -ENOMEM; - memset(wacom, 0, sizeof(struct wacom)); - - wacom->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); - if (!wacom->data) { - kfree(wacom); - return -ENOMEM; - } - - wacom->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!wacom->irq) { - usb_buffer_free(dev, 10, wacom->data, wacom->data_dma); - kfree(wacom); - return -ENOMEM; - } - - wacom->features = wacom_features + (id - wacom_ids); - - wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); - wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); - wacom->dev.absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC); - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS); - - switch (wacom->features->type) { - case MO: - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_1) | BIT(BTN_5); - wacom->dev.absbit[0] |= BIT(ABS_WHEEL); - wacom->dev.absmax[ABS_WHEEL] = 71; - - case G4: - wacom->dev.evbit[0] |= BIT(EV_MSC); - wacom->dev.mscbit[0] |= BIT(MSC_SERIAL); - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_4); - /* fall through */ - - case GRAPHIRE: - wacom->dev.evbit[0] |= BIT(EV_REL); - wacom->dev.relbit[0] |= BIT(REL_WHEEL); - wacom->dev.absbit[0] |= BIT(ABS_DISTANCE); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); - break; - - case INTUOS3: - case INTUOS3L: - case CINTIQ: - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); - wacom->dev.absbit[0] |= BIT(ABS_RY); - wacom->dev.absmax[ABS_RY] = 4096; - /* fall through */ - - case INTUOS3S: - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); - wacom->dev.absbit[0] |= BIT(ABS_RX); - wacom->dev.absmax[ABS_RX] = 4096; - /* fall through */ - - case INTUOS: - wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); - wacom->dev.mscbit[0] |= BIT(MSC_SERIAL); - wacom->dev.relbit[0] |= BIT(REL_WHEEL); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) - | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); - wacom->dev.absbit[0] |= BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE); - break; - - case INTUOS4: - case INTUOS4L: - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_7) | BIT(BTN_8); - /* fall through */ - - case INTUOS4S: - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6); - wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); - wacom->dev.mscbit[0] |= BIT(MSC_SERIAL); - wacom->dev.relbit[0] |= BIT(REL_WHEEL); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) - | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); - wacom->dev.absbit[0] |= BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE); - break; - - case PL: - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER); - break; - - case PENPARTNER: - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER); - break; - } - - wacom->dev.absmax[ABS_X] = wacom->features->x_max; - wacom->dev.absmax[ABS_Y] = wacom->features->y_max; - wacom->dev.absmax[ABS_PRESSURE] = wacom->features->pressure_max; - wacom->dev.absmax[ABS_DISTANCE] = wacom->features->distance_max; - wacom->dev.absmax[ABS_TILT_X] = 127; - wacom->dev.absmax[ABS_TILT_Y] = 127; - wacom->dev.absmax[ABS_WHEEL] = 1023; - - wacom->dev.absmin[ABS_RZ] = -900; - wacom->dev.absmax[ABS_RZ] = 899; - wacom->dev.absmin[ABS_Z] = -900; - wacom->dev.absmax[ABS_Z] = 899; - wacom->dev.absmin[ABS_THROTTLE] = -1023; - wacom->dev.absmax[ABS_THROTTLE] = 1023; - - wacom->dev.absfuzz[ABS_X] = 4; - wacom->dev.absfuzz[ABS_Y] = 4; - - wacom->dev.private = wacom; - wacom->dev.open = wacom_open; - wacom->dev.close = wacom_close; - - usb_make_path(dev, path, 64); - sprintf(wacom->phys, "%s/input0", path); - - wacom->dev.name = wacom->features->name; - wacom->dev.phys = wacom->phys; - wacom->dev.id.bustype = BUS_USB; - wacom->dev.id.vendor = dev->descriptor.idVendor; - wacom->dev.id.product = dev->descriptor.idProduct; - wacom->dev.id.version = dev->descriptor.bcdDevice; - wacom->dev.dev = &intf->dev; - wacom->usbdev = dev; - - endpoint = &intf->cur_altsetting->endpoint[0].desc; - - if (wacom->features->pktlen > 10) - BUG(); - - usb_fill_int_urb(wacom->irq, dev, - usb_rcvintpipe(dev, endpoint->bEndpointAddress), - wacom->data, wacom->features->pktlen, - wacom->features->irq, wacom, endpoint->bInterval); - wacom->irq->transfer_dma = wacom->data_dma; - wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - input_register_device(&wacom->dev); - - /* ask the tablet to report tablet data. repeats until it succeeds*/ - do { - rep_data[0] = 2; - rep_data[1] = 2; - usb_set_report(intf, 3, 2, rep_data, 2); - usb_get_report(intf, 3, 2, rep_data, 2); - } while (rep_data[1] != 2 && limit++ < 5); - - printk(KERN_INFO "input: %s on %s\n", wacom->features->name, path); - - usb_set_intfdata(intf, wacom); - - return 0; -} - -static void wacom_disconnect(struct usb_interface *intf) -{ - struct wacom *wacom = usb_get_intfdata (intf); - - usb_set_intfdata(intf, NULL); - if (wacom) { - usb_kill_urb(wacom->irq); - input_unregister_device(&wacom->dev); - usb_free_urb(wacom->irq); - usb_buffer_free(interface_to_usbdev(intf), 10, wacom->data, wacom->data_dma); - kfree(wacom); - } -} - -static struct usb_driver wacom_driver = { - .owner = THIS_MODULE, - .name = "wacom", - .probe = wacom_probe, - .disconnect = wacom_disconnect, - .id_table = wacom_ids, -}; - -static int __init wacom_init(void) -{ - int result = usb_register(&wacom_driver); - if (result == 0) - info(DRIVER_VERSION ":" DRIVER_DESC); - return result; -} - -static void __exit wacom_exit(void) -{ - usb_deregister(&wacom_driver); -} - -module_init(wacom_init); -module_exit(wacom_exit); diff --git a/src/2.6.11/Makefile.in b/src/2.6.11/Makefile.in deleted file mode 100644 index fe4d249..0000000 --- a/src/2.6.11/Makefile.in +++ /dev/null @@ -1,107 +0,0 @@ -############################ 2.6 kernel compile ############################### -ifneq ($(KERNELRELEASE),) -# We were called by kbuild -# Do NOT indent stuff in this part! It has to be like this to make the -# $(error ... ) stuff work - -# only compile those modules which are enabled by global configure -ifeq ($(WCM_OPTION_HID),yes) - -# check if kernel was configured to have hid as an module -ifeq ($(CONFIG_USB_HID),m) - -# check if HID module should be usbhid.ko or hid.ko -NEWHID := $(shell test $(SUBLEVEL) -ge 6 && echo usb) - -$(NEWHID)hid-objs := hid-core.o - -# behave exactly as kernel config wants us to behave -ifeq ($(CONFIG_USB_HIDDEV),y) -$(NEWHID)hid-objs += hiddev.o -endif -ifeq ($(CONFIG_USB_HIDINPUT),y) -$(NEWHID)hid-objs += hid-input.o -endif -ifeq ($(CONFIG_HID_PID),y) -$(NEWHID)hid-objs += pid.o -endif -ifeq ($(CONFIG_LOGITECH_FF),y) -$(NEWHID)hid-objs += hid-lgff.o -endif -ifeq ($(CONFIG_THRUSTMASTER_FF),y) -$(NEWHID)hid-objs += hid-tmff.o -endif -ifeq ($(CONFIG_HID_FF),y) -$(NEWHID)hid-objs += hid-ff.o -endif - -obj-$(CONFIG_USB_HID) += $(NEWHID)hid.o - -else -ifeq ($(CONFIG_USB_HID),y) -$(error You requested to build hid with configure, but hid is configured as built-in in your kernel config) -endif - -$(error You requested to build hid with configure, but hid is not configured in your kernel config) -endif # CONFIG_USB_HID -endif # WCM_OPTION_HID not - -ifeq ($(WCM_OPTION_WACOM),yes) -ifneq ($(CONFIG_USB_WACOM),y) -wacom-objs := wacom_wac.o wacom_sys.o -obj-m += wacom.o -else -$(error You requested to build wacom with configure, but wacom is configured as built-in in your kernel config) -endif # CONFIG_USB_WACOM -endif # WCM_OPTION_WACOM - -else # We were called from command line -PWD := $(shell pwd) - -WCM_KERNEL_DIR := @WCM_KERNEL_DIR@ -WCM_OPTION_WACOM := @WCM_OPTION_WACOM@ -WCM_OPTION_HID := @WCM_OPTION_HID@ - -export WCM_OPTION_WACOM WCM_OPTION_HID - -COPY_FROM_KERNEL_TREE := hiddev.c hid.h hid-ff.c hid-input.c fixp-arith.h -COPY_FROM_KERNEL_TREE += hid-lgff.c hid-tmff.c pid.c pid.h - -all: -# Copy hid-stuff from kernel-dir to local dir -ifeq ($(WCM_OPTION_HID),yes) - @for i in $(COPY_FROM_KERNEL_TREE); do \ - if test ! -f "$$i" && test -f $(WCM_KERNEL_DIR)/drivers/usb/input/$$i ; then \ - cp $(WCM_KERNEL_DIR)/drivers/usb/input/$$i .; \ - fi; \ - done -endif - -# Copy Wacom specific code which is common to all kernel releases -ifeq ($(WCM_OPTION_WACOM),yes) - cp -f ../2.6.16/wacom_wac.c . - cp -f ../2.6.16/wacom_wac.h . -endif - @echo ' Building linuxwacom drivers for 2.6 kernel.' - @echo '***Note: Drivers not enabled as modules in your kernel config but requested through configure are NOT built' - $(MAKE) -C $(WCM_KERNEL_DIR) M=$(PWD) - -endif # End kbuild check - -######################### Version independent targets ########################## - -clean: - rm -rf *.o *.ko *.mod.* .[a-z]* core *.i - -# also remove copied stuff -distclean: clean - @for i in $(COPY_FROM_KERNEL_TREE); do \ - if test -f "$$i"; then \ - rm -f $$i ; \ - fi; \ - done - -EMPTY_AUTOMAKE_TARGETS = distdir install install-data install-exec uninstall install-info -EMPTY_AUTOMAKE_TARGETS += installdirs check dvi pdf ps info html tags ctags mostlyclean distclean maintainer-clean -.PHONY: $(EMPTY_AUTOMAKE_TARGETS) - $(EMPTY_AUTOMAKE_TARGETS): diff --git a/src/2.6.11/hid-core.c b/src/2.6.11/hid-core.c deleted file mode 100644 index 679c77c..0000000 --- a/src/2.6.11/hid-core.c +++ /dev/null @@ -1,1912 +0,0 @@ -/* - * USB HID support for Linux - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@suse.cz> - */ - -/* - * 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. - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/list.h> -#include <linux/mm.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/unaligned.h> -#include <asm/byteorder.h> -#include <linux/input.h> - -#undef DEBUG -#undef DEBUG_DATA - -#include <linux/usb.h> - -#include "hid.h" -#include <linux/hiddev.h> - -/* - * Version Information - */ - -#define DRIVER_VERSION "v2.0 - 2.6.11.3-pc-0.2" -#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik" -#define DRIVER_DESC "USB HID core driver" -#define DRIVER_LICENSE "GPL" - -static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick", - "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"}; - -/* - * Register a new report for a device. - */ - -static struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id) -{ - struct hid_report_enum *report_enum = device->report_enum + type; - struct hid_report *report; - - if (report_enum->report_id_hash[id]) - return report_enum->report_id_hash[id]; - - if (!(report = kmalloc(sizeof(struct hid_report), GFP_KERNEL))) - return NULL; - memset(report, 0, sizeof(struct hid_report)); - - if (id != 0) - report_enum->numbered = 1; - - report->id = id; - report->type = type; - report->size = 0; - report->device = device; - report_enum->report_id_hash[id] = report; - - list_add_tail(&report->list, &report_enum->report_list); - - return report; -} - -/* - * Register a new field for this report. - */ - -static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) -{ - struct hid_field *field; - - if (report->maxfield == HID_MAX_FIELDS) { - dbg("too many fields in report"); - return NULL; - } - - if (!(field = kmalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) - + values * sizeof(unsigned), GFP_KERNEL))) return NULL; - - memset(field, 0, sizeof(struct hid_field) + usages * sizeof(struct hid_usage) - + values * sizeof(unsigned)); - - field->index = report->maxfield++; - report->field[field->index] = field; - field->usage = (struct hid_usage *)(field + 1); - field->value = (unsigned *)(field->usage + usages); - field->report = report; - - return field; -} - -/* - * Open a collection. The type/usage is pushed on the stack. - */ - -static int open_collection(struct hid_parser *parser, unsigned type) -{ - struct hid_collection *collection; - unsigned usage; - - usage = parser->local.usage[0]; - - if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { - dbg("collection stack overflow"); - return -1; - } - - if (parser->device->maxcollection == parser->device->collection_size) { - collection = kmalloc(sizeof(struct hid_collection) * - parser->device->collection_size * 2, - GFP_KERNEL); - if (collection == NULL) { - dbg("failed to reallocate collection array"); - return -1; - } - memcpy(collection, parser->device->collection, - sizeof(struct hid_collection) * - parser->device->collection_size); - memset(collection + parser->device->collection_size, 0, - sizeof(struct hid_collection) * - parser->device->collection_size); - kfree(parser->device->collection); - parser->device->collection = collection; - parser->device->collection_size *= 2; - } - - parser->collection_stack[parser->collection_stack_ptr++] = - parser->device->maxcollection; - - collection = parser->device->collection + - parser->device->maxcollection++; - collection->type = type; - collection->usage = usage; - collection->level = parser->collection_stack_ptr - 1; - - if (type == HID_COLLECTION_APPLICATION) - parser->device->maxapplication++; - - return 0; -} - -/* - * Close a collection. - */ - -static int close_collection(struct hid_parser *parser) -{ - if (!parser->collection_stack_ptr) { - dbg("collection stack underflow"); - return -1; - } - parser->collection_stack_ptr--; - return 0; -} - -/* - * Climb up the stack, search for the specified collection type - * and return the usage. - */ - -static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) -{ - int n; - for (n = parser->collection_stack_ptr - 1; n >= 0; n--) - if (parser->device->collection[parser->collection_stack[n]].type == type) - return parser->device->collection[parser->collection_stack[n]].usage; - return 0; /* we know nothing about this usage type */ -} - -/* - * Add a usage to the temporary parser table. - */ - -static int hid_add_usage(struct hid_parser *parser, unsigned usage) -{ - if (parser->local.usage_index >= HID_MAX_USAGES) { - dbg("usage index exceeded"); - return -1; - } - parser->local.usage[parser->local.usage_index] = usage; - parser->local.collection_index[parser->local.usage_index] = - parser->collection_stack_ptr ? - parser->collection_stack[parser->collection_stack_ptr - 1] : 0; - parser->local.usage_index++; - return 0; -} - -/* - * Register a new field for this report. - */ - -static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags) -{ - struct hid_report *report; - struct hid_field *field; - int usages; - unsigned offset; - int i; - - if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { - dbg("hid_register_report failed"); - return -1; - } - - if (parser->global.logical_maximum < parser->global.logical_minimum) { - dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum); - return -1; - } - - if (!(usages = max_t(int, parser->local.usage_index, parser->global.report_count))) - return 0; /* Ignore padding fields */ - - offset = report->size; - report->size += parser->global.report_size * parser->global.report_count; - - if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL) - return 0; - - field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); - field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL); - field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); - - for (i = 0; i < usages; i++) { - int j = i; - /* Duplicate the last usage we parsed if we have excess values */ - if (i >= parser->local.usage_index) - j = parser->local.usage_index - 1; - field->usage[i].hid = parser->local.usage[j]; - field->usage[i].collection_index = - parser->local.collection_index[j]; - } - - field->maxusage = usages; - field->flags = flags; - field->report_offset = offset; - field->report_type = report_type; - field->report_size = parser->global.report_size; - field->report_count = parser->global.report_count; - field->logical_minimum = parser->global.logical_minimum; - field->logical_maximum = parser->global.logical_maximum; - field->physical_minimum = parser->global.physical_minimum; - field->physical_maximum = parser->global.physical_maximum; - field->unit_exponent = parser->global.unit_exponent; - field->unit = parser->global.unit; - - return 0; -} - -/* - * Read data value from item. - */ - -static __inline__ __u32 item_udata(struct hid_item *item) -{ - switch (item->size) { - case 1: return item->data.u8; - case 2: return item->data.u16; - case 4: return item->data.u32; - } - return 0; -} - -static __inline__ __s32 item_sdata(struct hid_item *item) -{ - switch (item->size) { - case 1: return item->data.s8; - case 2: return item->data.s16; - case 4: return item->data.s32; - } - return 0; -} - -/* - * Process a global item. - */ - -static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) -{ - switch (item->tag) { - - case HID_GLOBAL_ITEM_TAG_PUSH: - - if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { - dbg("global enviroment stack overflow"); - return -1; - } - - memcpy(parser->global_stack + parser->global_stack_ptr++, - &parser->global, sizeof(struct hid_global)); - return 0; - - case HID_GLOBAL_ITEM_TAG_POP: - - if (!parser->global_stack_ptr) { - dbg("global enviroment stack underflow"); - return -1; - } - - memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr, - sizeof(struct hid_global)); - return 0; - - case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: - parser->global.usage_page = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: - parser->global.logical_minimum = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: - if (parser->global.logical_minimum < 0) - parser->global.logical_maximum = item_sdata(item); - else - parser->global.logical_maximum = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: - parser->global.physical_minimum = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: - if (parser->global.physical_minimum < 0) - parser->global.physical_maximum = item_sdata(item); - else - parser->global.physical_maximum = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: - parser->global.unit_exponent = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_UNIT: - parser->global.unit = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: - if ((parser->global.report_size = item_udata(item)) > 32) { - dbg("invalid report_size %d", parser->global.report_size); - return -1; - } - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: - if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) { - dbg("invalid report_count %d", parser->global.report_count); - return -1; - } - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_ID: - if ((parser->global.report_id = item_udata(item)) == 0) { - dbg("report_id 0 is invalid"); - return -1; - } - return 0; - - default: - dbg("unknown global tag 0x%x", item->tag); - return -1; - } -} - -/* - * Process a local item. - */ - -static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) -{ - __u32 data; - unsigned n; - - if (item->size == 0) { - dbg("item data expected for local item"); - return -1; - } - - data = item_udata(item); - - switch (item->tag) { - - case HID_LOCAL_ITEM_TAG_DELIMITER: - - if (data) { - /* - * We treat items before the first delimiter - * as global to all usage sets (branch 0). - * In the moment we process only these global - * items and the first delimiter set. - */ - if (parser->local.delimiter_depth != 0) { - dbg("nested delimiters"); - return -1; - } - parser->local.delimiter_depth++; - parser->local.delimiter_branch++; - } else { - if (parser->local.delimiter_depth < 1) { - dbg("bogus close delimiter"); - return -1; - } - parser->local.delimiter_depth--; - } - return 1; - - case HID_LOCAL_ITEM_TAG_USAGE: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - return hid_add_usage(parser, data); - - case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - parser->local.usage_minimum = data; - return 0; - - case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - for (n = parser->local.usage_minimum; n <= data; n++) - if (hid_add_usage(parser, n)) { - dbg("hid_add_usage failed\n"); - return -1; - } - return 0; - - default: - - dbg("unknown local item tag 0x%x", item->tag); - return 0; - } - return 0; -} - -/* - * Process a main item. - */ - -static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) -{ - __u32 data; - int ret; - - data = item_udata(item); - - switch (item->tag) { - case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: - ret = open_collection(parser, data & 0xff); - break; - case HID_MAIN_ITEM_TAG_END_COLLECTION: - ret = close_collection(parser); - break; - case HID_MAIN_ITEM_TAG_INPUT: - ret = hid_add_field(parser, HID_INPUT_REPORT, data); - break; - case HID_MAIN_ITEM_TAG_OUTPUT: - ret = hid_add_field(parser, HID_OUTPUT_REPORT, data); - break; - case HID_MAIN_ITEM_TAG_FEATURE: - ret = hid_add_field(parser, HID_FEATURE_REPORT, data); - break; - default: - dbg("unknown main item tag 0x%x", item->tag); - ret = 0; - } - - memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */ - - return ret; -} - -/* - * Process a reserved item. - */ - -static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) -{ - dbg("reserved item type, tag 0x%x", item->tag); - return 0; -} - -/* - * Free a report and all registered fields. The field->usage and - * field->value table's are allocated behind the field, so we need - * only to free(field) itself. - */ - -static void hid_free_report(struct hid_report *report) -{ - unsigned n; - - for (n = 0; n < report->maxfield; n++) - kfree(report->field[n]); - kfree(report); -} - -/* - * Free a device structure, all reports, and all fields. - */ - -static void hid_free_device(struct hid_device *device) -{ - unsigned i,j; - - hid_ff_exit(device); - - for (i = 0; i < HID_REPORT_TYPES; i++) { - struct hid_report_enum *report_enum = device->report_enum + i; - - for (j = 0; j < 256; j++) { - struct hid_report *report = report_enum->report_id_hash[j]; - if (report) - hid_free_report(report); - } - } - - if (device->rdesc) - kfree(device->rdesc); - kfree(device); -} - -/* - * Fetch a report description item from the data stream. We support long - * items, though they are not used yet. - */ - -static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) -{ - u8 b; - - if ((end - start) <= 0) - return NULL; - - b = *start++; - - item->type = (b >> 2) & 3; - item->tag = (b >> 4) & 15; - - if (item->tag == HID_ITEM_TAG_LONG) { - - item->format = HID_ITEM_FORMAT_LONG; - - if ((end - start) < 2) - return NULL; - - item->size = *start++; - item->tag = *start++; - - if ((end - start) < item->size) - return NULL; - - item->data.longdata = start; - start += item->size; - return start; - } - - item->format = HID_ITEM_FORMAT_SHORT; - item->size = b & 3; - - switch (item->size) { - - case 0: - return start; - - case 1: - if ((end - start) < 1) - return NULL; - item->data.u8 = *start++; - return start; - - case 2: - if ((end - start) < 2) - return NULL; - item->data.u16 = le16_to_cpu(get_unaligned((__le16*)start)); - start = (__u8 *)((__le16 *)start + 1); - return start; - - case 3: - item->size++; - if ((end - start) < 4) - return NULL; - item->data.u32 = le32_to_cpu(get_unaligned((__le32*)start)); - start = (__u8 *)((__le32 *)start + 1); - return start; - } - - return NULL; -} - -/* - * Parse a report description into a hid_device structure. Reports are - * enumerated, fields are attached to these reports. - */ - -static struct hid_device *hid_parse_report(__u8 *start, unsigned size) -{ - struct hid_device *device; - struct hid_parser *parser; - struct hid_item item; - __u8 *end; - unsigned i; - static int (*dispatch_type[])(struct hid_parser *parser, - struct hid_item *item) = { - hid_parser_main, - hid_parser_global, - hid_parser_local, - hid_parser_reserved - }; - - if (!(device = kmalloc(sizeof(struct hid_device), GFP_KERNEL))) - return NULL; - memset(device, 0, sizeof(struct hid_device)); - - if (!(device->collection =kmalloc(sizeof(struct hid_collection) * - HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) { - kfree(device); - return NULL; - } - memset(device->collection, 0, sizeof(struct hid_collection) * - HID_DEFAULT_NUM_COLLECTIONS); - device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; - - for (i = 0; i < HID_REPORT_TYPES; i++) - INIT_LIST_HEAD(&device->report_enum[i].report_list); - - if (!(device->rdesc = (__u8 *)kmalloc(size, GFP_KERNEL))) { - kfree(device->collection); - kfree(device); - return NULL; - } - memcpy(device->rdesc, start, size); - device->rsize = size; - - if (!(parser = kmalloc(sizeof(struct hid_parser), GFP_KERNEL))) { - kfree(device->rdesc); - kfree(device->collection); - kfree(device); - return NULL; - } - memset(parser, 0, sizeof(struct hid_parser)); - parser->device = device; - - end = start + size; - while ((start = fetch_item(start, end, &item)) != NULL) { - - if (item.format != HID_ITEM_FORMAT_SHORT) { - dbg("unexpected long global item"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - - if (dispatch_type[item.type](parser, &item)) { - dbg("item %u %u %u %u parsing failed\n", - item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - - if (start == end) { - if (parser->collection_stack_ptr) { - dbg("unbalanced collection at end of report description"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - if (parser->local.delimiter_depth) { - dbg("unbalanced delimiter at end of report description"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - kfree(parser); - return device; - } - } - - dbg("item fetching failed at offset %d\n", (int)(end - start)); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; -} - -/* - * Convert a signed n-bit integer to signed 32-bit integer. Common - * cases are done through the compiler, the screwed things has to be - * done by hand. - */ - -static __inline__ __s32 snto32(__u32 value, unsigned n) -{ - switch (n) { - case 8: return ((__s8)value); - case 16: return ((__s16)value); - case 32: return ((__s32)value); - } - return value & (1 << (n - 1)) ? value | (-1 << n) : value; -} - -/* - * Convert a signed 32-bit integer to a signed n-bit integer. - */ - -static __inline__ __u32 s32ton(__s32 value, unsigned n) -{ - __s32 a = value >> (n - 1); - if (a && a != -1) - return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; - return value & ((1 << n) - 1); -} - -/* - * Extract/implement a data field from/to a report. - */ - -static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) -{ - report += (offset >> 5) << 2; offset &= 31; - return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1 << n) - 1); -} - -static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) -{ - report += (offset >> 5) << 2; offset &= 31; - put_unaligned((get_unaligned((__le64*)report) - & cpu_to_le64(~((((__u64) 1 << n) - 1) << offset))) - | cpu_to_le64((__u64)value << offset), (__le64*)report); -} - -/* - * Search an array for a value. - */ - -static __inline__ int search(__s32 *array, __s32 value, unsigned n) -{ - while (n--) { - if (*array++ == value) - return 0; - } - return -1; -} - -static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) -{ - hid_dump_input(usage, value); - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_hid_event(hid, field, usage, value, regs); - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_hid_event(hid, field, usage, value, regs); -} - -/* - * Analyse a received field, and fetch the data from it. The field - * content is stored for next report processing (we do differential - * reporting to the layer). - */ - -static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, struct pt_regs *regs) -{ - unsigned n; - unsigned count = field->report_count; - unsigned offset = field->report_offset; - unsigned size = field->report_size; - __s32 min = field->logical_minimum; - __s32 max = field->logical_maximum; - __s32 *value; - - value = kmalloc(sizeof(__s32)*count, GFP_ATOMIC); - if (!value) - return; - - for (n = 0; n < count; n++) { - - value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : - extract(data, offset + n * size, size); - - if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */ - && value[n] >= min && value[n] <= max - && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) - goto exit; - } - - for (n = 0; n < count; n++) { - - if (HID_MAIN_ITEM_VARIABLE & field->flags) { - - if (field->flags & HID_MAIN_ITEM_RELATIVE) { - if (!value[n]) - continue; - } else { - if (value[n] == field->value[n]) - continue; - } - hid_process_event(hid, field, &field->usage[n], value[n], regs); - continue; - } - - if (field->value[n] >= min && field->value[n] <= max - && field->usage[field->value[n] - min].hid - && search(value, field->value[n], count)) - hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, regs); - - if (value[n] >= min && value[n] <= max - && field->usage[value[n] - min].hid - && search(field->value, value[n], count)) - hid_process_event(hid, field, &field->usage[value[n] - min], 1, regs); - } - - memcpy(field->value, value, count * sizeof(__s32)); -exit: - kfree(value); -} - -static int hid_input_report(int type, struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - struct hid_report_enum *report_enum = hid->report_enum + type; - u8 *data = urb->transfer_buffer; - int len = urb->actual_length; - struct hid_report *report; - int n, size; - - if (!len) { - dbg("empty report"); - return -1; - } - -#ifdef DEBUG_DATA - printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", len, report_enum->numbered ? "" : "un"); -#endif - - n = 0; /* Normally report number is 0 */ - if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */ - n = *data++; - len--; - } - -#ifdef DEBUG_DATA - { - int i; - printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, len); - for (i = 0; i < len; i++) - printk(" %02x", data[i]); - printk("\n"); - } -#endif - - if (!(report = report_enum->report_id_hash[n])) { - dbg("undefined report_id %d received", n); - return -1; - } - - size = ((report->size - 1) >> 3) + 1; - - if (len < size) { - dbg("report %d is too short, (%d < %d)", report->id, len, size); - return -1; - } - - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_report_event(hid, report); - - for (n = 0; n < report->maxfield; n++) - hid_input_field(hid, report->field[n], data, regs); - - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_report_event(hid, report); - - return 0; -} - -/* - * Input interrupt completion handler. - */ - -static void hid_irq_in(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - int status; - - switch (urb->status) { - case 0: /* success */ - hid_input_report(HID_INPUT_REPORT, urb, regs); - break; - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -EPERM: - case -ESHUTDOWN: /* unplug */ - case -EILSEQ: /* unplug timeout on uhci */ - return; - case -ETIMEDOUT: /* NAK */ - break; - default: /* error */ - warn("input irq status %d received", urb->status); - } - - status = usb_submit_urb(urb, SLAB_ATOMIC); - if (status) - err("can't resubmit intr, %s-%s/input%d, status %d", - hid->dev->bus->bus_name, hid->dev->devpath, - hid->ifnum, status); -} - -/* - * Output the field into the report. - */ - -static void hid_output_field(struct hid_field *field, __u8 *data) -{ - unsigned count = field->report_count; - unsigned offset = field->report_offset; - unsigned size = field->report_size; - unsigned n; - - for (n = 0; n < count; n++) { - if (field->logical_minimum < 0) /* signed values */ - implement(data, offset + n * size, size, s32ton(field->value[n], size)); - else /* unsigned values */ - implement(data, offset + n * size, size, field->value[n]); - } -} - -/* - * Create a report. - */ - -static void hid_output_report(struct hid_report *report, __u8 *data) -{ - unsigned n; - - if (report->id > 0) - *data++ = report->id; - - for (n = 0; n < report->maxfield; n++) - hid_output_field(report->field[n], data); -} - -/* - * Set a field value. The report this field belongs to has to be - * created and transferred to the device, to set this value in the - * device. - */ - -int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) -{ - unsigned size = field->report_size; - - hid_dump_input(field->usage + offset, value); - - if (offset >= field->report_count) { - dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count); - hid_dump_field(field, 8); - return -1; - } - if (field->logical_minimum < 0) { - if (value != snto32(s32ton(value, size), size)) { - dbg("value %d is out of range", value); - return -1; - } - } - field->value[offset] = value; - return 0; -} - -int hid_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field) -{ - struct hid_report_enum *report_enum = hid->report_enum + HID_OUTPUT_REPORT; - struct list_head *list = report_enum->report_list.next; - int i, j; - - while (list != &report_enum->report_list) { - struct hid_report *report = (struct hid_report *) list; - list = list->next; - for (i = 0; i < report->maxfield; i++) { - *field = report->field[i]; - for (j = 0; j < (*field)->maxusage; j++) - if ((*field)->usage[j].type == type && (*field)->usage[j].code == code) - return j; - } - } - return -1; -} - -/* - * Find a report with a specified HID usage. - */ - -int hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, struct hid_report **report, int type) -{ - struct hid_report_enum *report_enum = hid->report_enum + type; - struct list_head *list = report_enum->report_list.next; - int i, j; - - while (list != &report_enum->report_list) { - *report = (struct hid_report *) list; - list = list->next; - for (i = 0; i < (*report)->maxfield; i++) { - struct hid_field *field = (*report)->field[i]; - for (j = 0; j < field->maxusage; j++) - if (field->logical == wanted_usage) - return j; - } - } - return -1; -} - -#if 0 -static int hid_find_field_in_report(struct hid_report *report, __u32 wanted_usage, struct hid_field **field) -{ - int i, j; - - for (i = 0; i < report->maxfield; i++) { - *field = report->field[i]; - for (j = 0; j < (*field)->maxusage; j++) - if ((*field)->usage[j].hid == wanted_usage) - return j; - } - - return -1; -} -#endif - -static int hid_submit_out(struct hid_device *hid) -{ - struct hid_report *report; - - report = hid->out[hid->outtail]; - - hid_output_report(report, hid->outbuf); - hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); - hid->urbout->dev = hid->dev; - - dbg("submitting out urb"); - - if (usb_submit_urb(hid->urbout, GFP_ATOMIC)) { - err("usb_submit_urb(out) failed"); - return -1; - } - - return 0; -} - -static int hid_submit_ctrl(struct hid_device *hid) -{ - struct hid_report *report; - unsigned char dir; - int len; - - report = hid->ctrl[hid->ctrltail].report; - dir = hid->ctrl[hid->ctrltail].dir; - - len = ((report->size - 1) >> 3) + 1 + (report->id > 0); - if (dir == USB_DIR_OUT) { - hid_output_report(report, hid->ctrlbuf); - hid->urbctrl->pipe = usb_sndctrlpipe(hid->dev, 0); - hid->urbctrl->transfer_buffer_length = len; - } else { - int maxpacket, padlen; - - hid->urbctrl->pipe = usb_rcvctrlpipe(hid->dev, 0); - maxpacket = usb_maxpacket(hid->dev, hid->urbctrl->pipe, 0); - if (maxpacket > 0) { - padlen = (len + maxpacket - 1) / maxpacket; - padlen *= maxpacket; - if (padlen > HID_BUFFER_SIZE) - padlen = HID_BUFFER_SIZE; - } else - padlen = 0; - hid->urbctrl->transfer_buffer_length = padlen; - } - hid->urbctrl->dev = hid->dev; - - hid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; - hid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; - hid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id); - hid->cr->wIndex = cpu_to_le16(hid->ifnum); - hid->cr->wLength = cpu_to_le16(len); - - dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u", - hid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", - hid->cr->wValue, hid->cr->wIndex, hid->cr->wLength); - - if (usb_submit_urb(hid->urbctrl, GFP_ATOMIC)) { - err("usb_submit_urb(ctrl) failed"); - return -1; - } - - return 0; -} - -/* - * Output interrupt completion handler. - */ - -static void hid_irq_out(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - unsigned long flags; - int unplug = 0; - - switch (urb->status) { - case 0: /* success */ - case -ESHUTDOWN: /* unplug */ - case -EILSEQ: /* unplug timeout on uhci */ - unplug = 1; - case -ECONNRESET: /* unlink */ - case -ENOENT: - break; - default: /* error */ - warn("output irq status %d received", urb->status); - } - - spin_lock_irqsave(&hid->outlock, flags); - - if (unplug) - hid->outtail = hid->outhead; - else - hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); - - if (hid->outhead != hid->outtail) { - if (hid_submit_out(hid)) { - clear_bit(HID_OUT_RUNNING, &hid->iofl);; - wake_up(&hid->wait); - } - spin_unlock_irqrestore(&hid->outlock, flags); - return; - } - - clear_bit(HID_OUT_RUNNING, &hid->iofl); - spin_unlock_irqrestore(&hid->outlock, flags); - wake_up(&hid->wait); -} - -/* - * Control pipe completion handler. - */ - -static void hid_ctrl(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - unsigned long flags; - int unplug = 0; - - spin_lock_irqsave(&hid->ctrllock, flags); - - switch (urb->status) { - case 0: /* success */ - if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) - hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, regs); - case -ESHUTDOWN: /* unplug */ - case -EILSEQ: /* unplug timectrl on uhci */ - unplug = 1; - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -EPIPE: /* report not available */ - break; - default: /* error */ - warn("ctrl urb status %d received", urb->status); - } - - if (unplug) - hid->ctrltail = hid->ctrlhead; - else - hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); - - if (hid->ctrlhead != hid->ctrltail) { - if (hid_submit_ctrl(hid)) { - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - wake_up(&hid->wait); - } - spin_unlock_irqrestore(&hid->ctrllock, flags); - return; - } - - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - spin_unlock_irqrestore(&hid->ctrllock, flags); - wake_up(&hid->wait); -} - -void hid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) -{ - int head; - unsigned long flags; - - if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) - return; - - if (hid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { - - spin_lock_irqsave(&hid->outlock, flags); - - if ((head = (hid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == hid->outtail) { - spin_unlock_irqrestore(&hid->outlock, flags); - warn("output queue full"); - return; - } - - hid->out[hid->outhead] = report; - hid->outhead = head; - - if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl)) - if (hid_submit_out(hid)) - clear_bit(HID_OUT_RUNNING, &hid->iofl); - - spin_unlock_irqrestore(&hid->outlock, flags); - return; - } - - spin_lock_irqsave(&hid->ctrllock, flags); - - if ((head = (hid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == hid->ctrltail) { - spin_unlock_irqrestore(&hid->ctrllock, flags); - warn("control queue full"); - return; - } - - hid->ctrl[hid->ctrlhead].report = report; - hid->ctrl[hid->ctrlhead].dir = dir; - hid->ctrlhead = head; - - if (!test_and_set_bit(HID_CTRL_RUNNING, &hid->iofl)) - if (hid_submit_ctrl(hid)) - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - - spin_unlock_irqrestore(&hid->ctrllock, flags); -} - -int hid_wait_io(struct hid_device *hid) -{ - DECLARE_WAITQUEUE(wait, current); - int timeout = 10*HZ; - - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&hid->wait, &wait); - - while (timeout && (test_bit(HID_CTRL_RUNNING, &hid->iofl) || - test_bit(HID_OUT_RUNNING, &hid->iofl))) { - set_current_state(TASK_UNINTERRUPTIBLE); - timeout = schedule_timeout(timeout); - } - - set_current_state(TASK_RUNNING); - remove_wait_queue(&hid->wait, &wait); - - if (!timeout) { - dbg("timeout waiting for ctrl or out queue to clear"); - return -1; - } - - return 0; -} - -static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, - unsigned char type, void *buf, int size) -{ - int result, retries = 4; - - memset(buf,0,size); // Make sure we parse really received data - - do { - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, - (type << 8), ifnum, buf, size, HZ * USB_CTRL_GET_TIMEOUT); - retries--; - } while (result < size && retries); - return result; -} - -int hid_open(struct hid_device *hid) -{ - if (hid->open++) - return 0; - - hid->urbin->dev = hid->dev; - - if (usb_submit_urb(hid->urbin, GFP_KERNEL)) - return -EIO; - - return 0; -} - -void hid_close(struct hid_device *hid) -{ - if (!--hid->open) - usb_kill_urb(hid->urbin); -} - -/* - * Initialize all reports - */ - -void hid_init_reports(struct hid_device *hid) -{ - struct hid_report_enum *report_enum; - struct hid_report *report; - struct list_head *list; - int err, ret, size; - - /* - * The Set_Idle request is supposed to affect only the - * "Interrupt In" pipe. Unfortunately, buggy devices such as - * the BTC keyboard (ID 046e:5303) the request also affects - * Get_Report requests on the control pipe. In the worst - * case, if the device was put on idle for an indefinite - * amount of time (as we do below) and there are no input - * events to report, the Get_Report requests will just hang - * until we get a USB timeout. To avoid this, we temporarily - * establish a minimal idle time of 1ms. This shouldn't hurt - * bugfree devices and will cause a worst-case extra delay of - * 1ms for buggy ones. - */ - usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0), - HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (1 << 8), - hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); - - report_enum = hid->report_enum + HID_INPUT_REPORT; - list = report_enum->report_list.next; - while (list != &report_enum->report_list) { - report = (struct hid_report *) list; - size = ((report->size - 1) >> 3) + 1 + report_enum->numbered; - if (size > HID_BUFFER_SIZE) size = HID_BUFFER_SIZE; - if (size > hid->urbin->transfer_buffer_length) - hid->urbin->transfer_buffer_length = size; - hid_submit_report(hid, report, USB_DIR_IN); - list = list->next; - } - - report_enum = hid->report_enum + HID_FEATURE_REPORT; - list = report_enum->report_list.next; - while (list != &report_enum->report_list) { - report = (struct hid_report *) list; - hid_submit_report(hid, report, USB_DIR_IN); - list = list->next; - } - - err = 0; - ret = hid_wait_io(hid); - while (ret) { - err |= ret; - if (test_bit(HID_CTRL_RUNNING, &hid->iofl)) - usb_kill_urb(hid->urbctrl); - if (test_bit(HID_OUT_RUNNING, &hid->iofl)) - usb_kill_urb(hid->urbout); - ret = hid_wait_io(hid); - } - - if (err) - warn("timeout initializing reports\n"); - - report_enum = hid->report_enum + HID_INPUT_REPORT; - list = report_enum->report_list.next; - while (list != &report_enum->report_list) { - report = (struct hid_report *) list; - usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0), - HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, report->id, - hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); - list = list->next; - } -} - -#define USB_VENDOR_ID_WACOM 0x056a - -#define USB_VENDOR_ID_KBGEAR 0x084e -#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 - -#define USB_VENDOR_ID_AIPTEK 0x08ca -#define USB_DEVICE_ID_AIPTEK_01 0x0001 -#define USB_DEVICE_ID_AIPTEK_10 0x0010 -#define USB_DEVICE_ID_AIPTEK_20 0x0020 -#define USB_DEVICE_ID_AIPTEK_21 0x0021 -#define USB_DEVICE_ID_AIPTEK_22 0x0022 -#define USB_DEVICE_ID_AIPTEK_23 0x0023 -#define USB_DEVICE_ID_AIPTEK_24 0x0024 - -#define USB_VENDOR_ID_GRIFFIN 0x077d -#define USB_DEVICE_ID_POWERMATE 0x0410 -#define USB_DEVICE_ID_SOUNDKNOB 0x04AA - -#define USB_VENDOR_ID_ATEN 0x0557 -#define USB_DEVICE_ID_ATEN_UC100KM 0x2004 -#define USB_DEVICE_ID_ATEN_CS124U 0x2202 -#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204 -#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 -#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 - -#define USB_VENDOR_ID_TOPMAX 0x0663 -#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 - -#define USB_VENDOR_ID_HAPP 0x078b -#define USB_DEVICE_ID_UGCI_DRIVING 0x0010 -#define USB_DEVICE_ID_UGCI_FLYING 0x0020 -#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 - -#define USB_VENDOR_ID_MGE 0x0463 -#define USB_DEVICE_ID_MGE_UPS 0xffff -#define USB_DEVICE_ID_MGE_UPS1 0x0001 - -#define USB_VENDOR_ID_ONTRAK 0x0a07 -#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 - -#define USB_VENDOR_ID_TANGTOP 0x0d3d -#define USB_DEVICE_ID_TANGTOP_USBPS2 0x0001 - -#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f -#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 - -#define USB_VENDOR_ID_A4TECH 0x09DA -#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 - -#define USB_VENDOR_ID_CYPRESS 0x04b4 -#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 -#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 - -#define USB_VENDOR_ID_BERKSHIRE 0x0c98 -#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 - -#define USB_VENDOR_ID_ALPS 0x0433 -#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 - -#define USB_VENDOR_ID_SAITEK 0x06a3 -#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 - -#define USB_VENDOR_ID_NEC 0x073e -#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 - -#define USB_VENDOR_ID_CHIC 0x05fe -#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014 - -#define USB_VENDOR_ID_GLAB 0x06c2 -#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 -#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 -#define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045 -#define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040 -#define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053 - -#define USB_VENDOR_ID_WISEGROUP 0x0925 -#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 -#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 - -#define USB_VENDOR_ID_CODEMERCS 0x07c0 -#define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500 -#define USB_DEVICE_ID_CODEMERCS_IOW24 0x1501 -#define USB_DEVICE_ID_CODEMERCS_IOW48 0x1502 -#define USB_DEVICE_ID_CODEMERCS_IOW28 0x1503 - -#define USB_VENDOR_ID_DELORME 0x1163 -#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 - -static struct hid_blacklist { - __u16 idVendor; - __u16 idProduct; - unsigned quirks; -} hid_blacklist[] = { - - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW48, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, - - - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, - - { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, - - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW48, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE }, - - { 0, 0 } -}; - -static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) -{ - if (!(hid->inbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->inbuf_dma))) - return -1; - if (!(hid->outbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->outbuf_dma))) - return -1; - if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma))) - return -1; - if (!(hid->ctrlbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->ctrlbuf_dma))) - return -1; - - return 0; -} - -static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) -{ - if (hid->inbuf) - usb_buffer_free(dev, HID_BUFFER_SIZE, hid->inbuf, hid->inbuf_dma); - if (hid->outbuf) - usb_buffer_free(dev, HID_BUFFER_SIZE, hid->outbuf, hid->outbuf_dma); - if (hid->cr) - usb_buffer_free(dev, sizeof(*(hid->cr)), hid->cr, hid->cr_dma); - if (hid->ctrlbuf) - usb_buffer_free(dev, HID_BUFFER_SIZE, hid->ctrlbuf, hid->ctrlbuf_dma); -} - -static struct hid_device *usb_hid_configure(struct usb_interface *intf) -{ - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_device *dev = interface_to_usbdev (intf); - struct hid_descriptor *hdesc; - struct hid_device *hid; - unsigned quirks = 0, rsize = 0; - char *buf, *rdesc; - int n; - - /* ignore all Wacom devices */ - if (dev->descriptor.idVendor == USB_VENDOR_ID_WACOM) - return NULL; - - for (n = 0; hid_blacklist[n].idVendor; n++) - if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) && - (hid_blacklist[n].idProduct == le16_to_cpu(dev->descriptor.idProduct))) - quirks = hid_blacklist[n].quirks; - - if (quirks & HID_QUIRK_IGNORE) - return NULL; - - if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->desc.bNumEndpoints) || - usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { - dbg("class descriptor not present\n"); - return NULL; - } - - for (n = 0; n < hdesc->bNumDescriptors; n++) - if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) - rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); - - if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { - dbg("weird size of report descriptor (%u)", rsize); - return NULL; - } - - if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) { - dbg("couldn't allocate rdesc memory"); - return NULL; - } - - if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { - dbg("reading report descriptor failed"); - kfree(rdesc); - return NULL; - } - -#ifdef DEBUG_DATA - printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); - for (n = 0; n < rsize; n++) - printk(" %02x", (unsigned char) rdesc[n]); - printk("\n"); -#endif - - if (!(hid = hid_parse_report(rdesc, n))) { - dbg("parsing report descriptor failed"); - kfree(rdesc); - return NULL; - } - - kfree(rdesc); - hid->quirks = quirks; - - if (hid_alloc_buffers(dev, hid)) { - hid_free_buffers(dev, hid); - goto fail; - } - - for (n = 0; n < interface->desc.bNumEndpoints; n++) { - - struct usb_endpoint_descriptor *endpoint; - int pipe; - int interval; - - endpoint = &interface->endpoint[n].desc; - if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */ - continue; - - /* handle potential highspeed HID correctly */ - interval = endpoint->bInterval; - if (dev->speed == USB_SPEED_HIGH) - interval = 1 << (interval - 1); - - if (endpoint->bEndpointAddress & USB_DIR_IN) { - if (hid->urbin) - continue; - if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) - goto fail; - pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); - usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0, - hid_irq_in, hid, interval); - hid->urbin->transfer_dma = hid->inbuf_dma; - hid->urbin->transfer_flags |=(URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK); - } else { - if (hid->urbout) - continue; - if (!(hid->urbout = usb_alloc_urb(0, GFP_KERNEL))) - goto fail; - pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress); - usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0, - hid_irq_out, hid, interval); - hid->urbout->transfer_dma = hid->outbuf_dma; - hid->urbout->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK); - } - } - - if (!hid->urbin) { - err("couldn't find an input interrupt endpoint"); - goto fail; - } - - init_waitqueue_head(&hid->wait); - - spin_lock_init(&hid->outlock); - spin_lock_init(&hid->ctrllock); - - hid->version = le16_to_cpu(hdesc->bcdHID); - hid->country = hdesc->bCountryCode; - hid->dev = dev; - hid->intf = intf; - hid->ifnum = interface->desc.bInterfaceNumber; - - hid->name[0] = 0; - - if (!(buf = kmalloc(64, GFP_KERNEL))) - goto fail; - - if (usb_string(dev, dev->descriptor.iManufacturer, buf, 64) > 0) { - strcat(hid->name, buf); - if (usb_string(dev, dev->descriptor.iProduct, buf, 64) > 0) - snprintf(hid->name, 64, "%s %s", hid->name, buf); - } else if (usb_string(dev, dev->descriptor.iProduct, buf, 64) > 0) { - snprintf(hid->name, 128, "%s", buf); - } else - snprintf(hid->name, 128, "%04x:%04x", - le16_to_cpu(dev->descriptor.idVendor), - le16_to_cpu(dev->descriptor.idProduct)); - - usb_make_path(dev, buf, 64); - snprintf(hid->phys, 64, "%s/input%d", buf, - intf->altsetting[0].desc.bInterfaceNumber); - - if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) - hid->uniq[0] = 0; - - kfree(buf); - - hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); - if (!hid->urbctrl) - goto fail; - usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr, - hid->ctrlbuf, 1, hid_ctrl, hid); - hid->urbctrl->setup_dma = hid->cr_dma; - hid->urbctrl->transfer_dma = hid->ctrlbuf_dma; - hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | URB_ASYNC_UNLINK); - - return hid; - -fail: - - if (hid->urbin) - usb_free_urb(hid->urbin); - if (hid->urbout) - usb_free_urb(hid->urbout); - if (hid->urbctrl) - usb_free_urb(hid->urbctrl); - hid_free_buffers(dev, hid); - hid_free_device(hid); - - return NULL; -} - -static void hid_disconnect(struct usb_interface *intf) -{ - struct hid_device *hid = usb_get_intfdata (intf); - - if (!hid) - return; - - usb_set_intfdata(intf, NULL); - usb_kill_urb(hid->urbin); - usb_kill_urb(hid->urbout); - usb_kill_urb(hid->urbctrl); - - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_disconnect(hid); - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_disconnect(hid); - - usb_free_urb(hid->urbin); - usb_free_urb(hid->urbctrl); - if (hid->urbout) - usb_free_urb(hid->urbout); - - hid_free_buffers(hid->dev, hid); - hid_free_device(hid); -} - -static int hid_probe (struct usb_interface *intf, const struct usb_device_id *id) -{ - struct hid_device *hid; - char path[64]; - int i; - char *c; - - dbg("HID probe called for ifnum %d", - intf->altsetting->desc.bInterfaceNumber); - - if (!(hid = usb_hid_configure(intf))) - return -EIO; - - hid_init_reports(hid); - hid_dump_device(hid); - - if (!hidinput_connect(hid)) - hid->claimed |= HID_CLAIMED_INPUT; - if (!hiddev_connect(hid)) - hid->claimed |= HID_CLAIMED_HIDDEV; - - usb_set_intfdata(intf, hid); - - if (!hid->claimed) { - printk ("HID device not claimed by input or hiddev\n"); - hid_disconnect(intf); - return -EIO; - } - - printk(KERN_INFO); - - if (hid->claimed & HID_CLAIMED_INPUT) - printk("input"); - if (hid->claimed == (HID_CLAIMED_INPUT | HID_CLAIMED_HIDDEV)) - printk(","); - if (hid->claimed & HID_CLAIMED_HIDDEV) - printk("hiddev%d", hid->minor); - - c = "Device"; - for (i = 0; i < hid->maxcollection; i++) { - if (hid->collection[i].type == HID_COLLECTION_APPLICATION && - (hid->collection[i].usage & HID_USAGE_PAGE) == HID_UP_GENDESK && - (hid->collection[i].usage & 0xffff) < ARRAY_SIZE(hid_types)) { - c = hid_types[hid->collection[i].usage & 0xffff]; - break; - } - } - - usb_make_path(interface_to_usbdev(intf), path, 63); - - printk(": USB HID v%x.%02x %s [%s] on %s\n", - hid->version >> 8, hid->version & 0xff, c, hid->name, path); - - return 0; -} - -static int hid_suspend(struct usb_interface *intf, u32 state) -{ - struct hid_device *hid = usb_get_intfdata (intf); - - usb_kill_urb(hid->urbin); - intf->dev.power.power_state = state; - dev_dbg(&intf->dev, "suspend\n"); - return 0; -} - -static int hid_resume(struct usb_interface *intf) -{ - struct hid_device *hid = usb_get_intfdata (intf); - int status; - - intf->dev.power.power_state = PM_SUSPEND_ON; - if (hid->open) - status = usb_submit_urb(hid->urbin, GFP_NOIO); - else - status = 0; - dev_dbg(&intf->dev, "resume status %d\n", status); - return status; -} - -static struct usb_device_id hid_usb_ids [] = { - { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, - .bInterfaceClass = USB_INTERFACE_CLASS_HID }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE (usb, hid_usb_ids); - -static struct usb_driver hid_driver = { - .owner = THIS_MODULE, - .name = "usbhid", - .probe = hid_probe, - .disconnect = hid_disconnect, - .suspend = hid_suspend, - .resume = hid_resume, - .id_table = hid_usb_ids, -}; - -static int __init hid_init(void) -{ - int retval; - retval = hiddev_init(); - if (retval) - goto hiddev_init_fail; - retval = usb_register(&hid_driver); - if (retval) - goto usb_register_fail; - info(DRIVER_VERSION ":" DRIVER_DESC); - - return 0; -usb_register_fail: - hiddev_exit(); -hiddev_init_fail: - return retval; -} - -static void __exit hid_exit(void) -{ - usb_deregister(&hid_driver); - hiddev_exit(); -} - -module_init(hid_init); -module_exit(hid_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); diff --git a/src/2.6.11/wacom.h b/src/2.6.11/wacom.h deleted file mode 100755 index 900ce81..0000000 --- a/src/2.6.11/wacom.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * drivers/usb/input/wacom.h - * - * USB Wacom Graphire and Wacom Intuos tablet support - * - * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz> - * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk> - * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at> - * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org> - * Copyright (c) 2000 James E. Blair <corvus@gnu.org> - * Copyright (c) 2000 Daniel Egger <egger@suse.de> - * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> - * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> - * Copyright (c) 2002-2009 Ping Cheng <pingc@wacom.com> - * - * ChangeLog: - * v0.1 (vp) - Initial release - * v0.2 (aba) - Support for all buttons / combinations - * v0.3 (vp) - Support for Intuos added - * v0.4 (sm) - Support for more Intuos models, menustrip - * relative mode, proximity. - * v0.5 (vp) - Big cleanup, nifty features removed, - * they belong in userspace - * v1.8 (vp) - Submit URB only when operating, moved to CVS, - * use input_report_key instead of report_btn and - * other cleanups - * v1.11 (vp) - Add URB ->dev setting for new kernels - * v1.11 (jb) - Add support for the 4D Mouse & Lens - * v1.12 (de) - Add support for two more inking pen IDs - * v1.14 (vp) - Use new USB device id probing scheme. - * Fix Wacom Graphire mouse wheel - * v1.18 (vp) - Fix mouse wheel direction - * Make mouse relative - * v1.20 (fl) - Report tool id for Intuos devices - * - Multi tools support - * - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...) - * - Add PL models support - * - Fix Wacom Graphire mouse wheel again - * v1.21 (vp) - Removed protocol descriptions - * - Added MISC_SERIAL for tool serial numbers - * (gb) - Identify version on module load. - * v1.21.1 (fl) - added Graphire2 support - * v1.21.2 (fl) - added Intuos2 support - * - added all the PL ids - * v1.21.3 (fl) - added another eraser id from Neil Okamoto - * - added smooth filter for Graphire from Peri Hankey - * - added PenPartner support from Olaf van Es - * - new tool ids from Ole Martin Bjoerndalen - * v1.29 (pc) - Add support for more tablets - * - Fix pressure reporting - * v1.30 (vp) - Merge 2.4 and 2.5 drivers - * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse - * - Cleanups here and there - * v1.30.1 (pi) - Added Graphire3 support - * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... - * v1.43 (pc) - Added support for Cintiq 21UX - * - Fixed a Graphire bug - * - Merged wacom_intuos3_irq into wacom_intuos_irq - * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc. - * - Report Device IDs - * v1.45 (pc) - Added support for DTF 521, Intuos3 12x12 and 12x19 - * - Minor data report fix - * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c, - * - where wacom_sys.c deals with system specific code, - * - and wacom_wac.c deals with Wacom specific code - */ - -/* - * 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. - */ -#ifndef WACOM_H -#define WACOM_H -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/input.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/usb.h> -#include <asm/unaligned.h> -#include <asm/byteorder.h> - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.46-pc0.5" -#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" -#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" -#define DRIVER_LICENSE "GPL" - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); - -#define USB_VENDOR_ID_WACOM 0x056a - -struct wacom { - dma_addr_t data_dma; - struct input_dev dev; - struct usb_device *usbdev; - struct urb *irq; - struct wacom_wac * wacom_wac; - int open; - char phys[32]; -}; - -struct wacom_combo { - struct wacom * wacom; - struct urb * urb; - struct pt_regs *regs; -}; - -extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo); -extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data); -extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data); -extern void wacom_report_key(void *wcombo, unsigned int key_type, int key_data); -extern void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value); -extern void wacom_input_regs(void *wcombo); -extern void wacom_input_sync(void *wcombo); -extern void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern __u16 wacom_le16_to_cpu(unsigned char *data); -extern __u16 wacom_be16_to_cpu(unsigned char *data); -extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id); -extern const struct usb_device_id * get_device_table(void); - -#endif diff --git a/src/2.6.11/wacom_sys.c b/src/2.6.11/wacom_sys.c deleted file mode 100755 index 9c78833..0000000 --- a/src/2.6.11/wacom_sys.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * drivers/usb/input/wacom_sys.c - * - * USB Wacom Graphire and Wacom Intuos tablet support - system specific code - */ - -/* - * 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. - */ - -#include "wacom.h" -#include "wacom_wac.h" - -/* defines to get HID report descriptor */ -#define HID_DEVICET_HID (USB_TYPE_CLASS | 0x01) -#define HID_DEVICET_REPORT (USB_TYPE_CLASS | 0x02) -#define HID_USAGE_UNDEFINED 0x00 -#define HID_USAGE_PAGE 0x05 -#define HID_USAGE_PAGE_DIGITIZER 0x0d -#define HID_USAGE_PAGE_DESKTOP 0x01 -#define HID_USAGE 0x09 -#define HID_USAGE_X 0x30 -#define HID_USAGE_Y 0x31 -#define HID_USAGE_X_TILT 0x3d -#define HID_USAGE_Y_TILT 0x3e -#define HID_USAGE_FINGER 0x22 -#define HID_USAGE_STYLUS 0x20 -#define HID_COLLECTION 0xc0 -#define HID_USAGE_PAGE_VDEFINED 0xff - -enum { - WCM_UNDEFINED = 0, - WCM_DESKTOP, - WCM_DIGITIZER, - MAX_USAGE_PAGE -}; - -struct hid_descriptor -{ - struct usb_descriptor_header header; - __le16 bcdHID; - u8 bCountryCode; - u8 bNumDescriptors; - u8 bDescriptorType; - __le16 wDescriptorLength; -} __attribute__ ((packed)); - -/* defines to get/set USB message */ -#define USB_REQ_GET_REPORT 0x01 -#define USB_REQ_SET_REPORT 0x09 -#define WAC_HID_FEATURE_REPORT 0x03 - -static int usb_get_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 100); -} - -static int usb_set_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_sndctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 1000); -} - -static struct input_dev * get_input_dev(struct wacom_combo *wcombo) -{ - return &(wcombo->wacom->dev); -} - -static void wacom_sys_irq(struct urb *urb, struct pt_regs *regs) -{ - struct wacom *wacom = urb->context; - struct wacom_combo wcombo; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - wcombo.wacom = wacom; - wcombo.urb = urb; - wcombo.regs = regs; - - if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo)) - input_sync(get_input_dev(&wcombo)); - - exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) -{ - input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); - return; -} - -void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data) -{ - input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data); - return; -} - -void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data) -{ - input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data); - return; -} - -void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value) -{ - input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value); - return; -} - -__u16 wacom_be16_to_cpu(unsigned char *data) -{ - __u16 value; - value = be16_to_cpu(*(__be16 *) data); - return value; -} - -__u16 wacom_le16_to_cpu(unsigned char *data) -{ - __u16 value; - value = le16_to_cpu(*(__le16 *) data); - return value; -} - -void wacom_input_regs(void *wcombo) -{ - input_regs(get_input_dev((struct wacom_combo *)wcombo), ((struct wacom_combo *)wcombo)->regs); - return; -} - -void wacom_input_sync(void *wcombo) -{ - input_sync(get_input_dev((struct wacom_combo *)wcombo)); - return; -} - -static int wacom_open(struct input_dev *dev) -{ - struct wacom *wacom = dev->private; - - if (wacom->open++) - return 0; - - wacom->irq->dev = wacom->usbdev; - if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { - wacom->open--; - return -EIO; - } - - return 0; -} - -static void wacom_close(struct input_dev *dev) -{ - struct wacom *wacom = dev->private; - - if (!--wacom->open) - usb_kill_urb(wacom->irq); -} - -void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_1) | BIT(BTN_5); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); -} - -void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_MSC); - input_dev->mscbit[0] |= BIT(MSC_SERIAL); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_4); -} - -void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_REL); - input_dev->relbit[0] |= BIT(REL_WHEEL); - input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); -} - -void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); - input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); - input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); -} - -void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_7) | BIT(BTN_8); -} - -void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_8) | BIT(BTN_9); -} - -void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); - input_dev->mscbit[0] |= BIT(MSC_SERIAL); - input_dev->relbit[0] |= BIT(REL_WHEEL); - input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) - | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); - input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); -} - -void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2); -} - -void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER); -} - -static void wacom_paser_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, - struct wacom_wac *wacom_wac, char *report) -{ - struct usb_device *dev = interface_to_usbdev(intf); - char limit = 0, result = 0; - int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; - - /* retrive report descriptors */ - do { - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, - USB_RECIP_INTERFACE | USB_DIR_IN, - HID_DEVICET_REPORT << 8, - intf->altsetting[0].desc.bInterfaceNumber, /* interface */ - report, - hid_desc->wDescriptorLength, - 5000); /* 5 secs */ - } while (limit++ < 5); - - for (i=0; i<hid_desc->wDescriptorLength; i++) { - if ((unsigned short)report[i] == HID_USAGE_PAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_PAGE_DIGITIZER: - usage = WCM_DIGITIZER; - i++; - continue; - case HID_USAGE_PAGE_DESKTOP: - usage = WCM_DESKTOP; - i++; - continue; - } - } - - if ((unsigned short)report[i] == HID_USAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_X: - if (usage == WCM_DESKTOP) { - if (finger) { - wacom_wac->features->touch_x_max = - wacom_wac->features->touch_y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+6])); - i += 7; - } else if (pen) { - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - i += 4; - } - } else if (usage == WCM_DIGITIZER) { - /* max pressure isn't reported - wacom_wac->features->pressure_max = (unsigned short) - (report[i+4] << 8 | report[i+3]); - */ - wacom_wac->features->pressure_max = 255; - i += 4; - } - break; - case HID_USAGE_Y: - if (usage == WCM_DESKTOP) { - wacom_wac->features->y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - case HID_USAGE_FINGER: - finger = 1; - i++; - break; - case HID_USAGE_STYLUS: - pen = 1; - i++; - break; - case HID_USAGE_UNDEFINED: - if (usage == WCM_DESKTOP && finger) { /* capacity */ - wacom_wac->features->pressure_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - } - } - - if ((unsigned short)report[i] == HID_COLLECTION) { - /* reset UsagePage ans Finger */ - finger = usage = 0; - } - } -} - -static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_endpoint_descriptor *endpoint; - struct wacom *wacom; - struct wacom_wac *wacom_wac; - char rep_data[2], limit = 0, mode = 2, *report = NULL; - struct hid_descriptor *hid_desc; - char path[64]; - - if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) - return -ENOMEM; - memset(wacom, 0, sizeof(struct wacom)); - - if (!(wacom_wac = kmalloc(sizeof(struct wacom_wac), GFP_KERNEL))) { - kfree(wacom); - return -ENOMEM; - } - memset(wacom_wac, 0, sizeof(struct wacom_wac)); - - wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); - if (!wacom_wac->data) { - kfree(wacom); - kfree(wacom_wac); - return -ENOMEM; - } - - wacom->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!wacom->irq) { - usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); - kfree(wacom); - kfree(wacom_wac); - return -ENOMEM; - } - - wacom->usbdev = dev; - usb_make_path(dev, path, 64); - sprintf(wacom->phys, "%s/input0", path); - - wacom_wac->features = get_wacom_feature(id); - BUG_ON(wacom_wac->features->pktlen > 10); - - endpoint = &intf->cur_altsetting->endpoint[0].desc; - - /* Initialize touch_x_max and touch_y_max in case it is not defined */ - if (wacom_wac->features->type == TABLETPC) { - wacom_wac->features->touch_x_max = 1023; - wacom_wac->features->touch_y_max = 1023; - } else { - wacom_wac->features->touch_x_max = 0; - wacom_wac->features->touch_y_max = 0; - } - - /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ - if (wacom_wac->features->type == TABLETPC) { - if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { - if (usb_get_extra_descriptor(&interface->endpoint[0], - HID_DEVICET_REPORT, &hid_desc)) { - printk("wacom: can not retrive extra class descriptor\n"); - usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); - kfree(wacom); - kfree(wacom_wac); - return -ENOMEM; - } - } - report = kmalloc(hid_desc->wDescriptorLength, GFP_KERNEL); - if (!report) { - usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); - kfree(wacom); - kfree(wacom_wac); - return -ENOMEM; - } - wacom_paser_hid(intf, hid_desc, wacom_wac, report); - } - - wacom->dev.name = wacom_wac->features->name; - wacom->wacom_wac = wacom_wac; - wacom->dev.phys = wacom->phys; - wacom->dev.id.bustype = BUS_USB; - wacom->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); - wacom->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); - wacom->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); - wacom->dev.dev = &intf->dev; - wacom->dev.private = wacom; - wacom->dev.open = wacom_open; - wacom->dev.close = wacom_close; - - wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_STYLUS) | BIT(BTN_TOUCH); - input_set_abs_params(&wacom->dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0); - input_set_abs_params(&wacom->dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0); - input_set_abs_params(&wacom->dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0); - if (wacom_wac->features->type == TABLETPC) { - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_DOUBLETAP); - input_set_abs_params(&wacom->dev, ABS_RX, 0, wacom_wac->features->touch_x_max, 4, 0); - input_set_abs_params(&wacom->dev, ABS_RY, 0, wacom_wac->features->touch_y_max, 4, 0); - } - wacom->dev.absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC); - - wacom_init_input_dev(&wacom->dev, wacom_wac); - - usb_fill_int_urb(wacom->irq, dev, - usb_rcvintpipe(dev, endpoint->bEndpointAddress), - wacom_wac->data, wacom_wac->features->pktlen, - wacom_sys_irq, wacom, endpoint->bInterval); - wacom->irq->transfer_dma = wacom->data_dma; - wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - input_register_device(&wacom->dev); - - /* Ask the tablet to report tablet data if it is not a Tablet PC. - * Repeat until it succeeds - */ - if (wacom_wac->features->type != TABLETPC) { - do { - rep_data[0] = 2; - rep_data[1] = mode; - usb_set_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); - usb_get_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); - } while (rep_data[1] != mode && limit++ < 5); - } - - usb_set_intfdata(intf, wacom); - kfree(report); - return 0; -} - -static void wacom_disconnect(struct usb_interface *intf) -{ - struct wacom *wacom = usb_get_intfdata (intf); - - usb_set_intfdata(intf, NULL); - if (wacom) { - usb_kill_urb(wacom->irq); - input_unregister_device(&wacom->dev); - usb_free_urb(wacom->irq); - usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); - kfree(wacom->wacom_wac); - kfree(wacom); - } -} - -static struct usb_driver wacom_driver = { - .owner = THIS_MODULE, - .name = "wacom", - .probe = wacom_probe, - .disconnect = wacom_disconnect, -}; - -static int __init wacom_init(void) -{ - int result; - wacom_driver.id_table = get_device_table(); - result = usb_register(&wacom_driver); - if (result == 0) - info(DRIVER_VERSION ":" DRIVER_DESC); - return result; -} - -static void __exit wacom_exit(void) -{ - usb_deregister(&wacom_driver); -} - -module_init(wacom_init); -module_exit(wacom_exit); diff --git a/src/2.6.13/Makefile.in b/src/2.6.13/Makefile.in deleted file mode 100644 index fe4d249..0000000 --- a/src/2.6.13/Makefile.in +++ /dev/null @@ -1,107 +0,0 @@ -############################ 2.6 kernel compile ############################### -ifneq ($(KERNELRELEASE),) -# We were called by kbuild -# Do NOT indent stuff in this part! It has to be like this to make the -# $(error ... ) stuff work - -# only compile those modules which are enabled by global configure -ifeq ($(WCM_OPTION_HID),yes) - -# check if kernel was configured to have hid as an module -ifeq ($(CONFIG_USB_HID),m) - -# check if HID module should be usbhid.ko or hid.ko -NEWHID := $(shell test $(SUBLEVEL) -ge 6 && echo usb) - -$(NEWHID)hid-objs := hid-core.o - -# behave exactly as kernel config wants us to behave -ifeq ($(CONFIG_USB_HIDDEV),y) -$(NEWHID)hid-objs += hiddev.o -endif -ifeq ($(CONFIG_USB_HIDINPUT),y) -$(NEWHID)hid-objs += hid-input.o -endif -ifeq ($(CONFIG_HID_PID),y) -$(NEWHID)hid-objs += pid.o -endif -ifeq ($(CONFIG_LOGITECH_FF),y) -$(NEWHID)hid-objs += hid-lgff.o -endif -ifeq ($(CONFIG_THRUSTMASTER_FF),y) -$(NEWHID)hid-objs += hid-tmff.o -endif -ifeq ($(CONFIG_HID_FF),y) -$(NEWHID)hid-objs += hid-ff.o -endif - -obj-$(CONFIG_USB_HID) += $(NEWHID)hid.o - -else -ifeq ($(CONFIG_USB_HID),y) -$(error You requested to build hid with configure, but hid is configured as built-in in your kernel config) -endif - -$(error You requested to build hid with configure, but hid is not configured in your kernel config) -endif # CONFIG_USB_HID -endif # WCM_OPTION_HID not - -ifeq ($(WCM_OPTION_WACOM),yes) -ifneq ($(CONFIG_USB_WACOM),y) -wacom-objs := wacom_wac.o wacom_sys.o -obj-m += wacom.o -else -$(error You requested to build wacom with configure, but wacom is configured as built-in in your kernel config) -endif # CONFIG_USB_WACOM -endif # WCM_OPTION_WACOM - -else # We were called from command line -PWD := $(shell pwd) - -WCM_KERNEL_DIR := @WCM_KERNEL_DIR@ -WCM_OPTION_WACOM := @WCM_OPTION_WACOM@ -WCM_OPTION_HID := @WCM_OPTION_HID@ - -export WCM_OPTION_WACOM WCM_OPTION_HID - -COPY_FROM_KERNEL_TREE := hiddev.c hid.h hid-ff.c hid-input.c fixp-arith.h -COPY_FROM_KERNEL_TREE += hid-lgff.c hid-tmff.c pid.c pid.h - -all: -# Copy hid-stuff from kernel-dir to local dir -ifeq ($(WCM_OPTION_HID),yes) - @for i in $(COPY_FROM_KERNEL_TREE); do \ - if test ! -f "$$i" && test -f $(WCM_KERNEL_DIR)/drivers/usb/input/$$i ; then \ - cp $(WCM_KERNEL_DIR)/drivers/usb/input/$$i .; \ - fi; \ - done -endif - -# Copy Wacom specific code which is common to all kernel releases -ifeq ($(WCM_OPTION_WACOM),yes) - cp -f ../2.6.16/wacom_wac.c . - cp -f ../2.6.16/wacom_wac.h . -endif - @echo ' Building linuxwacom drivers for 2.6 kernel.' - @echo '***Note: Drivers not enabled as modules in your kernel config but requested through configure are NOT built' - $(MAKE) -C $(WCM_KERNEL_DIR) M=$(PWD) - -endif # End kbuild check - -######################### Version independent targets ########################## - -clean: - rm -rf *.o *.ko *.mod.* .[a-z]* core *.i - -# also remove copied stuff -distclean: clean - @for i in $(COPY_FROM_KERNEL_TREE); do \ - if test -f "$$i"; then \ - rm -f $$i ; \ - fi; \ - done - -EMPTY_AUTOMAKE_TARGETS = distdir install install-data install-exec uninstall install-info -EMPTY_AUTOMAKE_TARGETS += installdirs check dvi pdf ps info html tags ctags mostlyclean distclean maintainer-clean -.PHONY: $(EMPTY_AUTOMAKE_TARGETS) - $(EMPTY_AUTOMAKE_TARGETS): diff --git a/src/2.6.13/hid-core.c b/src/2.6.13/hid-core.c deleted file mode 100644 index 7e1572e..0000000 --- a/src/2.6.13/hid-core.c +++ /dev/null @@ -1,1887 +0,0 @@ -/* - * USB HID support for Linux - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@suse.cz> - */ - -/* - * 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. - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/list.h> -#include <linux/mm.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/unaligned.h> -#include <asm/byteorder.h> -#include <linux/input.h> -#include <linux/wait.h> - -#undef DEBUG -#undef DEBUG_DATA - -#include <linux/usb.h> - -#include "hid.h" -#include <linux/hiddev.h> - -/* - * Version Information - */ - -#define DRIVER_VERSION "v2.01" -#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik" -#define DRIVER_DESC "USB HID core driver" -#define DRIVER_LICENSE "GPL" - -static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick", - "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"}; -/* - * Module parameters. - */ - -static unsigned int hid_mousepoll_interval; -module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); -MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); - -/* - * Register a new report for a device. - */ - -static struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id) -{ - struct hid_report_enum *report_enum = device->report_enum + type; - struct hid_report *report; - - if (report_enum->report_id_hash[id]) - return report_enum->report_id_hash[id]; - - if (!(report = kmalloc(sizeof(struct hid_report), GFP_KERNEL))) - return NULL; - memset(report, 0, sizeof(struct hid_report)); - - if (id != 0) - report_enum->numbered = 1; - - report->id = id; - report->type = type; - report->size = 0; - report->device = device; - report_enum->report_id_hash[id] = report; - - list_add_tail(&report->list, &report_enum->report_list); - - return report; -} - -/* - * Register a new field for this report. - */ - -static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) -{ - struct hid_field *field; - - if (report->maxfield == HID_MAX_FIELDS) { - dbg("too many fields in report"); - return NULL; - } - - if (!(field = kmalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) - + values * sizeof(unsigned), GFP_KERNEL))) return NULL; - - memset(field, 0, sizeof(struct hid_field) + usages * sizeof(struct hid_usage) - + values * sizeof(unsigned)); - - field->index = report->maxfield++; - report->field[field->index] = field; - field->usage = (struct hid_usage *)(field + 1); - field->value = (unsigned *)(field->usage + usages); - field->report = report; - - return field; -} - -/* - * Open a collection. The type/usage is pushed on the stack. - */ - -static int open_collection(struct hid_parser *parser, unsigned type) -{ - struct hid_collection *collection; - unsigned usage; - - usage = parser->local.usage[0]; - - if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { - dbg("collection stack overflow"); - return -1; - } - - if (parser->device->maxcollection == parser->device->collection_size) { - collection = kmalloc(sizeof(struct hid_collection) * - parser->device->collection_size * 2, GFP_KERNEL); - if (collection == NULL) { - dbg("failed to reallocate collection array"); - return -1; - } - memcpy(collection, parser->device->collection, - sizeof(struct hid_collection) * - parser->device->collection_size); - memset(collection + parser->device->collection_size, 0, - sizeof(struct hid_collection) * - parser->device->collection_size); - kfree(parser->device->collection); - parser->device->collection = collection; - parser->device->collection_size *= 2; - } - - parser->collection_stack[parser->collection_stack_ptr++] = - parser->device->maxcollection; - - collection = parser->device->collection + - parser->device->maxcollection++; - collection->type = type; - collection->usage = usage; - collection->level = parser->collection_stack_ptr - 1; - - if (type == HID_COLLECTION_APPLICATION) - parser->device->maxapplication++; - - return 0; -} - -/* - * Close a collection. - */ - -static int close_collection(struct hid_parser *parser) -{ - if (!parser->collection_stack_ptr) { - dbg("collection stack underflow"); - return -1; - } - parser->collection_stack_ptr--; - return 0; -} - -/* - * Climb up the stack, search for the specified collection type - * and return the usage. - */ - -static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) -{ - int n; - for (n = parser->collection_stack_ptr - 1; n >= 0; n--) - if (parser->device->collection[parser->collection_stack[n]].type == type) - return parser->device->collection[parser->collection_stack[n]].usage; - return 0; /* we know nothing about this usage type */ -} - -/* - * Add a usage to the temporary parser table. - */ - -static int hid_add_usage(struct hid_parser *parser, unsigned usage) -{ - if (parser->local.usage_index >= HID_MAX_USAGES) { - dbg("usage index exceeded"); - return -1; - } - parser->local.usage[parser->local.usage_index] = usage; - parser->local.collection_index[parser->local.usage_index] = - parser->collection_stack_ptr ? - parser->collection_stack[parser->collection_stack_ptr - 1] : 0; - parser->local.usage_index++; - return 0; -} - -/* - * Register a new field for this report. - */ - -static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags) -{ - struct hid_report *report; - struct hid_field *field; - int usages; - unsigned offset; - int i; - - if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { - dbg("hid_register_report failed"); - return -1; - } - - if (parser->global.logical_maximum < parser->global.logical_minimum) { - dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum); - return -1; - } - - offset = report->size; - report->size += parser->global.report_size * parser->global.report_count; - - if (!parser->local.usage_index) /* Ignore padding fields */ - return 0; - - usages = max_t(int, parser->local.usage_index, parser->global.report_count); - - if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL) - return 0; - - field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); - field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL); - field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); - - for (i = 0; i < usages; i++) { - int j = i; - /* Duplicate the last usage we parsed if we have excess values */ - if (i >= parser->local.usage_index) - j = parser->local.usage_index - 1; - field->usage[i].hid = parser->local.usage[j]; - field->usage[i].collection_index = - parser->local.collection_index[j]; - } - - field->maxusage = usages; - field->flags = flags; - field->report_offset = offset; - field->report_type = report_type; - field->report_size = parser->global.report_size; - field->report_count = parser->global.report_count; - field->logical_minimum = parser->global.logical_minimum; - field->logical_maximum = parser->global.logical_maximum; - field->physical_minimum = parser->global.physical_minimum; - field->physical_maximum = parser->global.physical_maximum; - field->unit_exponent = parser->global.unit_exponent; - field->unit = parser->global.unit; - - return 0; -} - -/* - * Read data value from item. - */ - -static __inline__ __u32 item_udata(struct hid_item *item) -{ - switch (item->size) { - case 1: return item->data.u8; - case 2: return item->data.u16; - case 4: return item->data.u32; - } - return 0; -} - -static __inline__ __s32 item_sdata(struct hid_item *item) -{ - switch (item->size) { - case 1: return item->data.s8; - case 2: return item->data.s16; - case 4: return item->data.s32; - } - return 0; -} - -/* - * Process a global item. - */ - -static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) -{ - switch (item->tag) { - - case HID_GLOBAL_ITEM_TAG_PUSH: - - if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { - dbg("global enviroment stack overflow"); - return -1; - } - - memcpy(parser->global_stack + parser->global_stack_ptr++, - &parser->global, sizeof(struct hid_global)); - return 0; - - case HID_GLOBAL_ITEM_TAG_POP: - - if (!parser->global_stack_ptr) { - dbg("global enviroment stack underflow"); - return -1; - } - - memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr, - sizeof(struct hid_global)); - return 0; - - case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: - parser->global.usage_page = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: - parser->global.logical_minimum = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: - if (parser->global.logical_minimum < 0) - parser->global.logical_maximum = item_sdata(item); - else - parser->global.logical_maximum = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: - parser->global.physical_minimum = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: - if (parser->global.physical_minimum < 0) - parser->global.physical_maximum = item_sdata(item); - else - parser->global.physical_maximum = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: - parser->global.unit_exponent = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_UNIT: - parser->global.unit = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: - if ((parser->global.report_size = item_udata(item)) > 32) { - dbg("invalid report_size %d", parser->global.report_size); - return -1; - } - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: - if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) { - dbg("invalid report_count %d", parser->global.report_count); - return -1; - } - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_ID: - if ((parser->global.report_id = item_udata(item)) == 0) { - dbg("report_id 0 is invalid"); - return -1; - } - return 0; - - default: - dbg("unknown global tag 0x%x", item->tag); - return -1; - } -} - -/* - * Process a local item. - */ - -static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) -{ - __u32 data; - unsigned n; - - if (item->size == 0) { - dbg("item data expected for local item"); - return -1; - } - - data = item_udata(item); - - switch (item->tag) { - - case HID_LOCAL_ITEM_TAG_DELIMITER: - - if (data) { - /* - * We treat items before the first delimiter - * as global to all usage sets (branch 0). - * In the moment we process only these global - * items and the first delimiter set. - */ - if (parser->local.delimiter_depth != 0) { - dbg("nested delimiters"); - return -1; - } - parser->local.delimiter_depth++; - parser->local.delimiter_branch++; - } else { - if (parser->local.delimiter_depth < 1) { - dbg("bogus close delimiter"); - return -1; - } - parser->local.delimiter_depth--; - } - return 1; - - case HID_LOCAL_ITEM_TAG_USAGE: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - return hid_add_usage(parser, data); - - case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - parser->local.usage_minimum = data; - return 0; - - case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - for (n = parser->local.usage_minimum; n <= data; n++) - if (hid_add_usage(parser, n)) { - dbg("hid_add_usage failed\n"); - return -1; - } - return 0; - - default: - - dbg("unknown local item tag 0x%x", item->tag); - return 0; - } - return 0; -} - -/* - * Process a main item. - */ - -static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) -{ - __u32 data; - int ret; - - data = item_udata(item); - - switch (item->tag) { - case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: - ret = open_collection(parser, data & 0xff); - break; - case HID_MAIN_ITEM_TAG_END_COLLECTION: - ret = close_collection(parser); - break; - case HID_MAIN_ITEM_TAG_INPUT: - ret = hid_add_field(parser, HID_INPUT_REPORT, data); - break; - case HID_MAIN_ITEM_TAG_OUTPUT: - ret = hid_add_field(parser, HID_OUTPUT_REPORT, data); - break; - case HID_MAIN_ITEM_TAG_FEATURE: - ret = hid_add_field(parser, HID_FEATURE_REPORT, data); - break; - default: - dbg("unknown main item tag 0x%x", item->tag); - ret = 0; - } - - memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */ - - return ret; -} - -/* - * Process a reserved item. - */ - -static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) -{ - dbg("reserved item type, tag 0x%x", item->tag); - return 0; -} - -/* - * Free a report and all registered fields. The field->usage and - * field->value table's are allocated behind the field, so we need - * only to free(field) itself. - */ - -static void hid_free_report(struct hid_report *report) -{ - unsigned n; - - for (n = 0; n < report->maxfield; n++) - kfree(report->field[n]); - kfree(report); -} - -/* - * Free a device structure, all reports, and all fields. - */ - -static void hid_free_device(struct hid_device *device) -{ - unsigned i,j; - - hid_ff_exit(device); - - for (i = 0; i < HID_REPORT_TYPES; i++) { - struct hid_report_enum *report_enum = device->report_enum + i; - - for (j = 0; j < 256; j++) { - struct hid_report *report = report_enum->report_id_hash[j]; - if (report) - hid_free_report(report); - } - } - - kfree(device->rdesc); - kfree(device); -} - -/* - * Fetch a report description item from the data stream. We support long - * items, though they are not used yet. - */ - -static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) -{ - u8 b; - - if ((end - start) <= 0) - return NULL; - - b = *start++; - - item->type = (b >> 2) & 3; - item->tag = (b >> 4) & 15; - - if (item->tag == HID_ITEM_TAG_LONG) { - - item->format = HID_ITEM_FORMAT_LONG; - - if ((end - start) < 2) - return NULL; - - item->size = *start++; - item->tag = *start++; - - if ((end - start) < item->size) - return NULL; - - item->data.longdata = start; - start += item->size; - return start; - } - - item->format = HID_ITEM_FORMAT_SHORT; - item->size = b & 3; - - switch (item->size) { - - case 0: - return start; - - case 1: - if ((end - start) < 1) - return NULL; - item->data.u8 = *start++; - return start; - - case 2: - if ((end - start) < 2) - return NULL; - item->data.u16 = le16_to_cpu(get_unaligned((__le16*)start)); - start = (__u8 *)((__le16 *)start + 1); - return start; - - case 3: - item->size++; - if ((end - start) < 4) - return NULL; - item->data.u32 = le32_to_cpu(get_unaligned((__le32*)start)); - start = (__u8 *)((__le32 *)start + 1); - return start; - } - - return NULL; -} - -/* - * Parse a report description into a hid_device structure. Reports are - * enumerated, fields are attached to these reports. - */ - -static struct hid_device *hid_parse_report(__u8 *start, unsigned size) -{ - struct hid_device *device; - struct hid_parser *parser; - struct hid_item item; - __u8 *end; - unsigned i; - static int (*dispatch_type[])(struct hid_parser *parser, - struct hid_item *item) = { - hid_parser_main, - hid_parser_global, - hid_parser_local, - hid_parser_reserved - }; - - if (!(device = kmalloc(sizeof(struct hid_device), GFP_KERNEL))) - return NULL; - memset(device, 0, sizeof(struct hid_device)); - - if (!(device->collection = kmalloc(sizeof(struct hid_collection) * - HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) { - kfree(device); - return NULL; - } - memset(device->collection, 0, sizeof(struct hid_collection) * - HID_DEFAULT_NUM_COLLECTIONS); - device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; - - for (i = 0; i < HID_REPORT_TYPES; i++) - INIT_LIST_HEAD(&device->report_enum[i].report_list); - - if (!(device->rdesc = (__u8 *)kmalloc(size, GFP_KERNEL))) { - kfree(device->collection); - kfree(device); - return NULL; - } - memcpy(device->rdesc, start, size); - device->rsize = size; - - if (!(parser = kmalloc(sizeof(struct hid_parser), GFP_KERNEL))) { - kfree(device->rdesc); - kfree(device->collection); - kfree(device); - return NULL; - } - memset(parser, 0, sizeof(struct hid_parser)); - parser->device = device; - - end = start + size; - while ((start = fetch_item(start, end, &item)) != NULL) { - - if (item.format != HID_ITEM_FORMAT_SHORT) { - dbg("unexpected long global item"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - - if (dispatch_type[item.type](parser, &item)) { - dbg("item %u %u %u %u parsing failed\n", - item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - - if (start == end) { - if (parser->collection_stack_ptr) { - dbg("unbalanced collection at end of report description"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - if (parser->local.delimiter_depth) { - dbg("unbalanced delimiter at end of report description"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - kfree(parser); - return device; - } - } - - dbg("item fetching failed at offset %d\n", (int)(end - start)); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; -} - -/* - * Convert a signed n-bit integer to signed 32-bit integer. Common - * cases are done through the compiler, the screwed things has to be - * done by hand. - */ - -static __inline__ __s32 snto32(__u32 value, unsigned n) -{ - switch (n) { - case 8: return ((__s8)value); - case 16: return ((__s16)value); - case 32: return ((__s32)value); - } - return value & (1 << (n - 1)) ? value | (-1 << n) : value; -} - -/* - * Convert a signed 32-bit integer to a signed n-bit integer. - */ - -static __inline__ __u32 s32ton(__s32 value, unsigned n) -{ - __s32 a = value >> (n - 1); - if (a && a != -1) - return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; - return value & ((1 << n) - 1); -} - -/* - * Extract/implement a data field from/to a report. - */ - -static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) -{ - report += (offset >> 5) << 2; offset &= 31; - return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1ULL << n) - 1); -} - -static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) -{ - report += (offset >> 5) << 2; offset &= 31; - put_unaligned((get_unaligned((__le64*)report) - & cpu_to_le64(~((((__u64) 1 << n) - 1) << offset))) - | cpu_to_le64((__u64)value << offset), (__le64*)report); -} - -/* - * Search an array for a value. - */ - -static __inline__ int search(__s32 *array, __s32 value, unsigned n) -{ - while (n--) { - if (*array++ == value) - return 0; - } - return -1; -} - -static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt, struct pt_regs *regs) -{ - hid_dump_input(usage, value); - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_hid_event(hid, field, usage, value, regs); - if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt) - hiddev_hid_event(hid, field, usage, value, regs); -} - -/* - * Analyse a received field, and fetch the data from it. The field - * content is stored for next report processing (we do differential - * reporting to the layer). - */ - -static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt, struct pt_regs *regs) -{ - unsigned n; - unsigned count = field->report_count; - unsigned offset = field->report_offset; - unsigned size = field->report_size; - __s32 min = field->logical_minimum; - __s32 max = field->logical_maximum; - __s32 *value; - - if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC))) - return; - - for (n = 0; n < count; n++) { - - value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : - extract(data, offset + n * size, size); - - if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */ - && value[n] >= min && value[n] <= max - && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) - goto exit; - } - - for (n = 0; n < count; n++) { - - if (HID_MAIN_ITEM_VARIABLE & field->flags) { - hid_process_event(hid, field, &field->usage[n], value[n], interrupt, regs); - continue; - } - - if (field->value[n] >= min && field->value[n] <= max - && field->usage[field->value[n] - min].hid - && search(value, field->value[n], count)) - hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt, regs); - - if (value[n] >= min && value[n] <= max - && field->usage[value[n] - min].hid - && search(field->value, value[n], count)) - hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt, regs); - } - - memcpy(field->value, value, count * sizeof(__s32)); -exit: - kfree(value); -} - -static int hid_input_report(int type, struct urb *urb, int interrupt, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - struct hid_report_enum *report_enum = hid->report_enum + type; - u8 *data = urb->transfer_buffer; - int len = urb->actual_length; - struct hid_report *report; - int n, size; - - if (!len) { - dbg("empty report"); - return -1; - } - -#ifdef DEBUG_DATA - printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", len, report_enum->numbered ? "" : "un"); -#endif - - n = 0; /* Normally report number is 0 */ - if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */ - n = *data++; - len--; - } - -#ifdef DEBUG_DATA - { - int i; - printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, len); - for (i = 0; i < len; i++) - printk(" %02x", data[i]); - printk("\n"); - } -#endif - - if (!(report = report_enum->report_id_hash[n])) { - dbg("undefined report_id %d received", n); - return -1; - } - - size = ((report->size - 1) >> 3) + 1; - - if (len < size) - dbg("report %d is too short, (%d < %d)", report->id, len, size); - - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_report_event(hid, report); - - for (n = 0; n < report->maxfield; n++) - hid_input_field(hid, report->field[n], data, interrupt, regs); - - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_report_event(hid, report); - - return 0; -} - -/* - * Input interrupt completion handler. - */ - -static void hid_irq_in(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - int status; - - switch (urb->status) { - case 0: /* success */ - hid_input_report(HID_INPUT_REPORT, urb, 1, regs); - break; - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -EPERM: - case -ESHUTDOWN: /* unplug */ - case -EILSEQ: /* unplug timeout on uhci */ - return; - case -ETIMEDOUT: /* NAK */ - break; - default: /* error */ - warn("input irq status %d received", urb->status); - } - - status = usb_submit_urb(urb, SLAB_ATOMIC); - if (status) - err("can't resubmit intr, %s-%s/input%d, status %d", - hid->dev->bus->bus_name, hid->dev->devpath, - hid->ifnum, status); -} - -/* - * Output the field into the report. - */ - -static void hid_output_field(struct hid_field *field, __u8 *data) -{ - unsigned count = field->report_count; - unsigned offset = field->report_offset; - unsigned size = field->report_size; - unsigned n; - - for (n = 0; n < count; n++) { - if (field->logical_minimum < 0) /* signed values */ - implement(data, offset + n * size, size, s32ton(field->value[n], size)); - else /* unsigned values */ - implement(data, offset + n * size, size, field->value[n]); - } -} - -/* - * Create a report. - */ - -static void hid_output_report(struct hid_report *report, __u8 *data) -{ - unsigned n; - - if (report->id > 0) - *data++ = report->id; - - for (n = 0; n < report->maxfield; n++) - hid_output_field(report->field[n], data); -} - -/* - * Set a field value. The report this field belongs to has to be - * created and transferred to the device, to set this value in the - * device. - */ - -int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) -{ - unsigned size = field->report_size; - - hid_dump_input(field->usage + offset, value); - - if (offset >= field->report_count) { - dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count); - hid_dump_field(field, 8); - return -1; - } - if (field->logical_minimum < 0) { - if (value != snto32(s32ton(value, size), size)) { - dbg("value %d is out of range", value); - return -1; - } - } - field->value[offset] = value; - return 0; -} - -/* - * Find a report field with a specified HID usage. - */ - -struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_usage, int type) -{ - struct hid_report *report; - int i; - - list_for_each_entry(report, &hid->report_enum[type].report_list, list) - for (i = 0; i < report->maxfield; i++) - if (report->field[i]->logical == wanted_usage) - return report->field[i]; - return NULL; -} - -static int hid_submit_out(struct hid_device *hid) -{ - struct hid_report *report; - - report = hid->out[hid->outtail]; - - hid_output_report(report, hid->outbuf); - hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); - hid->urbout->dev = hid->dev; - - dbg("submitting out urb"); - - if (usb_submit_urb(hid->urbout, GFP_ATOMIC)) { - err("usb_submit_urb(out) failed"); - return -1; - } - - return 0; -} - -static int hid_submit_ctrl(struct hid_device *hid) -{ - struct hid_report *report; - unsigned char dir; - int len; - - report = hid->ctrl[hid->ctrltail].report; - dir = hid->ctrl[hid->ctrltail].dir; - - len = ((report->size - 1) >> 3) + 1 + (report->id > 0); - if (dir == USB_DIR_OUT) { - hid_output_report(report, hid->ctrlbuf); - hid->urbctrl->pipe = usb_sndctrlpipe(hid->dev, 0); - hid->urbctrl->transfer_buffer_length = len; - } else { - int maxpacket, padlen; - - hid->urbctrl->pipe = usb_rcvctrlpipe(hid->dev, 0); - maxpacket = usb_maxpacket(hid->dev, hid->urbctrl->pipe, 0); - if (maxpacket > 0) { - padlen = (len + maxpacket - 1) / maxpacket; - padlen *= maxpacket; - if (padlen > HID_BUFFER_SIZE) - padlen = HID_BUFFER_SIZE; - } else - padlen = 0; - hid->urbctrl->transfer_buffer_length = padlen; - } - hid->urbctrl->dev = hid->dev; - - hid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; - hid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; - hid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id); - hid->cr->wIndex = cpu_to_le16(hid->ifnum); - hid->cr->wLength = cpu_to_le16(len); - - dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u", - hid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", - hid->cr->wValue, hid->cr->wIndex, hid->cr->wLength); - - if (usb_submit_urb(hid->urbctrl, GFP_ATOMIC)) { - err("usb_submit_urb(ctrl) failed"); - return -1; - } - - return 0; -} - -/* - * Output interrupt completion handler. - */ - -static void hid_irq_out(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - unsigned long flags; - int unplug = 0; - - switch (urb->status) { - case 0: /* success */ - case -ESHUTDOWN: /* unplug */ - case -EILSEQ: /* unplug timeout on uhci */ - unplug = 1; - case -ECONNRESET: /* unlink */ - case -ENOENT: - break; - default: /* error */ - warn("output irq status %d received", urb->status); - } - - spin_lock_irqsave(&hid->outlock, flags); - - if (unplug) - hid->outtail = hid->outhead; - else - hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); - - if (hid->outhead != hid->outtail) { - if (hid_submit_out(hid)) { - clear_bit(HID_OUT_RUNNING, &hid->iofl);; - wake_up(&hid->wait); - } - spin_unlock_irqrestore(&hid->outlock, flags); - return; - } - - clear_bit(HID_OUT_RUNNING, &hid->iofl); - spin_unlock_irqrestore(&hid->outlock, flags); - wake_up(&hid->wait); -} - -/* - * Control pipe completion handler. - */ - -static void hid_ctrl(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - unsigned long flags; - int unplug = 0; - - spin_lock_irqsave(&hid->ctrllock, flags); - - switch (urb->status) { - case 0: /* success */ - if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) - hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs); - case -ESHUTDOWN: /* unplug */ - case -EILSEQ: /* unplug timectrl on uhci */ - unplug = 1; - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -EPIPE: /* report not available */ - break; - default: /* error */ - warn("ctrl urb status %d received", urb->status); - } - - if (unplug) - hid->ctrltail = hid->ctrlhead; - else - hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); - - if (hid->ctrlhead != hid->ctrltail) { - if (hid_submit_ctrl(hid)) { - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - wake_up(&hid->wait); - } - spin_unlock_irqrestore(&hid->ctrllock, flags); - return; - } - - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - spin_unlock_irqrestore(&hid->ctrllock, flags); - wake_up(&hid->wait); -} - -void hid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) -{ - int head; - unsigned long flags; - - if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) - return; - - if (hid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { - - spin_lock_irqsave(&hid->outlock, flags); - - if ((head = (hid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == hid->outtail) { - spin_unlock_irqrestore(&hid->outlock, flags); - warn("output queue full"); - return; - } - - hid->out[hid->outhead] = report; - hid->outhead = head; - - if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl)) - if (hid_submit_out(hid)) - clear_bit(HID_OUT_RUNNING, &hid->iofl); - - spin_unlock_irqrestore(&hid->outlock, flags); - return; - } - - spin_lock_irqsave(&hid->ctrllock, flags); - - if ((head = (hid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == hid->ctrltail) { - spin_unlock_irqrestore(&hid->ctrllock, flags); - warn("control queue full"); - return; - } - - hid->ctrl[hid->ctrlhead].report = report; - hid->ctrl[hid->ctrlhead].dir = dir; - hid->ctrlhead = head; - - if (!test_and_set_bit(HID_CTRL_RUNNING, &hid->iofl)) - if (hid_submit_ctrl(hid)) - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - - spin_unlock_irqrestore(&hid->ctrllock, flags); -} - -int hid_wait_io(struct hid_device *hid) -{ - if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &hid->iofl) && - !test_bit(HID_OUT_RUNNING, &hid->iofl)), - 10*HZ)) { - dbg("timeout waiting for ctrl or out queue to clear"); - return -1; - } - - return 0; -} - -static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle) -{ - return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (idle << 8) | report, - ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT); -} - -static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, - unsigned char type, void *buf, int size) -{ - int result, retries = 4; - - memset(buf,0,size); // Make sure we parse really received data - - do { - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, - (type << 8), ifnum, buf, size, USB_CTRL_GET_TIMEOUT); - retries--; - } while (result < size && retries); - return result; -} - -int hid_open(struct hid_device *hid) -{ - if (hid->open++) - return 0; - - hid->urbin->dev = hid->dev; - - if (usb_submit_urb(hid->urbin, GFP_KERNEL)) - return -EIO; - - return 0; -} - -void hid_close(struct hid_device *hid) -{ - if (!--hid->open) - usb_kill_urb(hid->urbin); -} - -/* - * Initialize all reports - */ - -void hid_init_reports(struct hid_device *hid) -{ - struct hid_report *report; - int err, ret; - - list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) { - int size = ((report->size - 1) >> 3) + 1 + hid->report_enum[HID_INPUT_REPORT].numbered; - if (size > HID_BUFFER_SIZE) size = HID_BUFFER_SIZE; - if (size > hid->urbin->transfer_buffer_length) - hid->urbin->transfer_buffer_length = size; - hid_submit_report(hid, report, USB_DIR_IN); - } - - list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) - hid_submit_report(hid, report, USB_DIR_IN); - - err = 0; - ret = hid_wait_io(hid); - while (ret) { - err |= ret; - if (test_bit(HID_CTRL_RUNNING, &hid->iofl)) - usb_kill_urb(hid->urbctrl); - if (test_bit(HID_OUT_RUNNING, &hid->iofl)) - usb_kill_urb(hid->urbout); - ret = hid_wait_io(hid); - } - - if (err) - warn("timeout initializing reports\n"); -} - -#define USB_VENDOR_ID_WACOM 0x056a - -#define USB_VENDOR_ID_ACECAD 0x0460 -#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 -#define USB_DEVICE_ID_ACECAD_302 0x0008 - -#define USB_VENDOR_ID_KBGEAR 0x084e -#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 - -#define USB_VENDOR_ID_AIPTEK 0x08ca -#define USB_DEVICE_ID_AIPTEK_01 0x0001 -#define USB_DEVICE_ID_AIPTEK_10 0x0010 -#define USB_DEVICE_ID_AIPTEK_20 0x0020 -#define USB_DEVICE_ID_AIPTEK_21 0x0021 -#define USB_DEVICE_ID_AIPTEK_22 0x0022 -#define USB_DEVICE_ID_AIPTEK_23 0x0023 -#define USB_DEVICE_ID_AIPTEK_24 0x0024 - -#define USB_VENDOR_ID_GRIFFIN 0x077d -#define USB_DEVICE_ID_POWERMATE 0x0410 -#define USB_DEVICE_ID_SOUNDKNOB 0x04AA - -#define USB_VENDOR_ID_ATEN 0x0557 -#define USB_DEVICE_ID_ATEN_UC100KM 0x2004 -#define USB_DEVICE_ID_ATEN_CS124U 0x2202 -#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204 -#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 -#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 - -#define USB_VENDOR_ID_TOPMAX 0x0663 -#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 - -#define USB_VENDOR_ID_HAPP 0x078b -#define USB_DEVICE_ID_UGCI_DRIVING 0x0010 -#define USB_DEVICE_ID_UGCI_FLYING 0x0020 -#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 - -#define USB_VENDOR_ID_MGE 0x0463 -#define USB_DEVICE_ID_MGE_UPS 0xffff -#define USB_DEVICE_ID_MGE_UPS1 0x0001 - -#define USB_VENDOR_ID_ONTRAK 0x0a07 -#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 - -#define USB_VENDOR_ID_TANGTOP 0x0d3d -#define USB_DEVICE_ID_TANGTOP_USBPS2 0x0001 - -#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f -#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 - -#define USB_VENDOR_ID_A4TECH 0x09da -#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 - -#define USB_VENDOR_ID_AASHIMA 0x06D6 -#define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 - -#define USB_VENDOR_ID_CYPRESS 0x04b4 -#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 -#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 - -#define USB_VENDOR_ID_BERKSHIRE 0x0c98 -#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 - -#define USB_VENDOR_ID_ALPS 0x0433 -#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 - -#define USB_VENDOR_ID_SAITEK 0x06a3 -#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 - -#define USB_VENDOR_ID_NEC 0x073e -#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 - -#define USB_VENDOR_ID_CHIC 0x05fe -#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014 - -#define USB_VENDOR_ID_GLAB 0x06c2 -#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 -#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 -#define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045 -#define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040 -#define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053 - -#define USB_VENDOR_ID_WISEGROUP 0x0925 -#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 -#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 - -#define USB_VENDOR_ID_CODEMERCS 0x07c0 -#define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500 -#define USB_DEVICE_ID_CODEMERCS_IOW24 0x1501 -#define USB_DEVICE_ID_CODEMERCS_IOW48 0x1502 -#define USB_DEVICE_ID_CODEMERCS_IOW28 0x1503 - -#define USB_VENDOR_ID_DELORME 0x1163 -#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 -#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 - -#define USB_VENDOR_ID_MCC 0x09db -#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 -#define USB_DEVICE_ID_MCC_PMD1208LS 0x007a - -#define USB_VENDOR_ID_CHICONY 0x04f2 -#define USB_DEVICE_ID_CHICONY_USBHUB_KB 0x0100 - -#define USB_VENDOR_ID_BTC 0x046e -#define USB_DEVICE_ID_BTC_KEYBOARD 0x5303 - -#define USB_VENDOR_ID_VERNIER 0x08f7 -#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 -#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 -#define USB_DEVICE_ID_VERNIER_SKIP 0x0003 -#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 - -#define USB_VENDOR_ID_LD 0x0f11 -#define USB_DEVICE_ID_CASSY 0x1000 -#define USB_DEVICE_ID_POCKETCASSY 0x1010 -#define USB_DEVICE_ID_MOBILECASSY 0x1020 -#define USB_DEVICE_ID_JWM 0x1080 -#define USB_DEVICE_ID_DMMP 0x1081 -#define USB_DEVICE_ID_UMIP 0x1090 -#define USB_DEVICE_ID_VIDEOCOM 0x1200 -#define USB_DEVICE_ID_COM3LAB 0x2000 -#define USB_DEVICE_ID_TELEPORT 0x2010 -#define USB_DEVICE_ID_NETWORKANALYSER 0x2020 -#define USB_DEVICE_ID_POWERCONTROL 0x2030 - - -/* - * Alphabetically sorted blacklist by quirk type. - */ - -static struct hid_blacklist { - __u16 idVendor; - __u16 idProduct; - unsigned quirks; -} hid_blacklist[] = { - - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW48, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_CASSY, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_POCKETCASSY, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_MOBILECASSY, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_JWM, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_DMMP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_UMIP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_VIDEOCOM, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_COM3LAB, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_TELEPORT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_NETWORKANALYSER, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_POWERCONTROL, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_KEYBOARD, HID_QUIRK_NOGET}, - { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET}, - { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, - - { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, - - { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, - - { 0, 0 } -}; - -static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) -{ - if (!(hid->inbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->inbuf_dma))) - return -1; - if (!(hid->outbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->outbuf_dma))) - return -1; - if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma))) - return -1; - if (!(hid->ctrlbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->ctrlbuf_dma))) - return -1; - - return 0; -} - -static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) -{ - if (hid->inbuf) - usb_buffer_free(dev, HID_BUFFER_SIZE, hid->inbuf, hid->inbuf_dma); - if (hid->outbuf) - usb_buffer_free(dev, HID_BUFFER_SIZE, hid->outbuf, hid->outbuf_dma); - if (hid->cr) - usb_buffer_free(dev, sizeof(*(hid->cr)), hid->cr, hid->cr_dma); - if (hid->ctrlbuf) - usb_buffer_free(dev, HID_BUFFER_SIZE, hid->ctrlbuf, hid->ctrlbuf_dma); -} - -static struct hid_device *usb_hid_configure(struct usb_interface *intf) -{ - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_device *dev = interface_to_usbdev (intf); - struct hid_descriptor *hdesc; - struct hid_device *hid; - unsigned quirks = 0, rsize = 0; - char *buf, *rdesc; - int n; - - /* ignore all Wacom devices */ - if (dev->descriptor.idVendor == USB_VENDOR_ID_WACOM) - return NULL; - - for (n = 0; hid_blacklist[n].idVendor; n++) - if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) && - (hid_blacklist[n].idProduct == le16_to_cpu(dev->descriptor.idProduct))) - quirks = hid_blacklist[n].quirks; - - if (quirks & HID_QUIRK_IGNORE) - return NULL; - - if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->desc.bNumEndpoints) || - usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { - dbg("class descriptor not present\n"); - return NULL; - } - - for (n = 0; n < hdesc->bNumDescriptors; n++) - if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) - rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); - - if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { - dbg("weird size of report descriptor (%u)", rsize); - return NULL; - } - - if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) { - dbg("couldn't allocate rdesc memory"); - return NULL; - } - - hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0); - - if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { - dbg("reading report descriptor failed"); - kfree(rdesc); - return NULL; - } - -#ifdef DEBUG_DATA - printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); - for (n = 0; n < rsize; n++) - printk(" %02x", (unsigned char) rdesc[n]); - printk("\n"); -#endif - - if (!(hid = hid_parse_report(rdesc, n))) { - dbg("parsing report descriptor failed"); - kfree(rdesc); - return NULL; - } - - kfree(rdesc); - hid->quirks = quirks; - - if (hid_alloc_buffers(dev, hid)) { - hid_free_buffers(dev, hid); - goto fail; - } - - for (n = 0; n < interface->desc.bNumEndpoints; n++) { - - struct usb_endpoint_descriptor *endpoint; - int pipe; - int interval; - - endpoint = &interface->endpoint[n].desc; - if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */ - continue; - - /* handle potential highspeed HID correctly */ - interval = endpoint->bInterval; - if (dev->speed == USB_SPEED_HIGH) - interval = 1 << (interval - 1); - - /* Change the polling interval of mice. */ - if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) - interval = hid_mousepoll_interval; - - if (endpoint->bEndpointAddress & USB_DIR_IN) { - if (hid->urbin) - continue; - if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) - goto fail; - pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); - usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0, - hid_irq_in, hid, interval); - hid->urbin->transfer_dma = hid->inbuf_dma; - hid->urbin->transfer_flags |=(URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK); - } else { - if (hid->urbout) - continue; - if (!(hid->urbout = usb_alloc_urb(0, GFP_KERNEL))) - goto fail; - pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress); - usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0, - hid_irq_out, hid, interval); - hid->urbout->transfer_dma = hid->outbuf_dma; - hid->urbout->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK); - } - } - - if (!hid->urbin) { - err("couldn't find an input interrupt endpoint"); - goto fail; - } - - init_waitqueue_head(&hid->wait); - - spin_lock_init(&hid->outlock); - spin_lock_init(&hid->ctrllock); - - hid->version = le16_to_cpu(hdesc->bcdHID); - hid->country = hdesc->bCountryCode; - hid->dev = dev; - hid->intf = intf; - hid->ifnum = interface->desc.bInterfaceNumber; - - hid->name[0] = 0; - - if (!(buf = kmalloc(64, GFP_KERNEL))) - goto fail; - - if (dev->manufacturer) { - strcat(hid->name, dev->manufacturer); - if (dev->product) - snprintf(hid->name, 64, "%s %s", hid->name, dev->product); - } else if (dev->product) { - snprintf(hid->name, 128, "%s", dev->product); - } else - snprintf(hid->name, 128, "%04x:%04x", - le16_to_cpu(dev->descriptor.idVendor), - le16_to_cpu(dev->descriptor.idProduct)); - - usb_make_path(dev, buf, 64); - snprintf(hid->phys, 64, "%s/input%d", buf, - intf->altsetting[0].desc.bInterfaceNumber); - - if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) - hid->uniq[0] = 0; - - kfree(buf); - - hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); - if (!hid->urbctrl) - goto fail; - usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr, - hid->ctrlbuf, 1, hid_ctrl, hid); - hid->urbctrl->setup_dma = hid->cr_dma; - hid->urbctrl->transfer_dma = hid->ctrlbuf_dma; - hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | URB_ASYNC_UNLINK); - - return hid; - -fail: - - if (hid->urbin) - usb_free_urb(hid->urbin); - if (hid->urbout) - usb_free_urb(hid->urbout); - if (hid->urbctrl) - usb_free_urb(hid->urbctrl); - hid_free_buffers(dev, hid); - hid_free_device(hid); - - return NULL; -} - -static void hid_disconnect(struct usb_interface *intf) -{ - struct hid_device *hid = usb_get_intfdata (intf); - - if (!hid) - return; - - usb_set_intfdata(intf, NULL); - usb_kill_urb(hid->urbin); - usb_kill_urb(hid->urbout); - usb_kill_urb(hid->urbctrl); - - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_disconnect(hid); - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_disconnect(hid); - - usb_free_urb(hid->urbin); - usb_free_urb(hid->urbctrl); - if (hid->urbout) - usb_free_urb(hid->urbout); - - hid_free_buffers(hid->dev, hid); - hid_free_device(hid); -} - -static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct hid_device *hid; - char path[64]; - int i; - char *c; - - dbg("HID probe called for ifnum %d", - intf->altsetting->desc.bInterfaceNumber); - - if (!(hid = usb_hid_configure(intf))) - return -ENODEV; - - hid_init_reports(hid); - hid_dump_device(hid); - - if (!hidinput_connect(hid)) - hid->claimed |= HID_CLAIMED_INPUT; - if (!hiddev_connect(hid)) - hid->claimed |= HID_CLAIMED_HIDDEV; - - usb_set_intfdata(intf, hid); - - if (!hid->claimed) { - printk ("HID device not claimed by input or hiddev\n"); - hid_disconnect(intf); - return -ENODEV; - } - - printk(KERN_INFO); - - if (hid->claimed & HID_CLAIMED_INPUT) - printk("input"); - if (hid->claimed == (HID_CLAIMED_INPUT | HID_CLAIMED_HIDDEV)) - printk(","); - if (hid->claimed & HID_CLAIMED_HIDDEV) - printk("hiddev%d", hid->minor); - - c = "Device"; - for (i = 0; i < hid->maxcollection; i++) { - if (hid->collection[i].type == HID_COLLECTION_APPLICATION && - (hid->collection[i].usage & HID_USAGE_PAGE) == HID_UP_GENDESK && - (hid->collection[i].usage & 0xffff) < ARRAY_SIZE(hid_types)) { - c = hid_types[hid->collection[i].usage & 0xffff]; - break; - } - } - - usb_make_path(interface_to_usbdev(intf), path, 63); - - printk(": USB HID v%x.%02x %s [%s] on %s\n", - hid->version >> 8, hid->version & 0xff, c, hid->name, path); - - return 0; -} - -static int hid_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct hid_device *hid = usb_get_intfdata (intf); - - usb_kill_urb(hid->urbin); - intf->dev.power.power_state = PMSG_SUSPEND; - dev_dbg(&intf->dev, "suspend\n"); - return 0; -} - -static int hid_resume(struct usb_interface *intf) -{ - struct hid_device *hid = usb_get_intfdata (intf); - int status; - - intf->dev.power.power_state = PMSG_ON; - if (hid->open) - status = usb_submit_urb(hid->urbin, GFP_NOIO); - else - status = 0; - dev_dbg(&intf->dev, "resume status %d\n", status); - return status; -} - -static struct usb_device_id hid_usb_ids [] = { - { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, - .bInterfaceClass = USB_INTERFACE_CLASS_HID }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE (usb, hid_usb_ids); - -static struct usb_driver hid_driver = { - .owner = THIS_MODULE, - .name = "usbhid", - .probe = hid_probe, - .disconnect = hid_disconnect, - .suspend = hid_suspend, - .resume = hid_resume, - .id_table = hid_usb_ids, -}; - -static int __init hid_init(void) -{ - int retval; - retval = hiddev_init(); - if (retval) - goto hiddev_init_fail; - retval = usb_register(&hid_driver); - if (retval) - goto usb_register_fail; - info(DRIVER_VERSION ":" DRIVER_DESC); - - return 0; -usb_register_fail: - hiddev_exit(); -hiddev_init_fail: - return retval; -} - -static void __exit hid_exit(void) -{ - usb_deregister(&hid_driver); - hiddev_exit(); -} - -module_init(hid_init); -module_exit(hid_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); diff --git a/src/2.6.13/wacom.h b/src/2.6.13/wacom.h deleted file mode 100755 index cd34ff1..0000000 --- a/src/2.6.13/wacom.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * drivers/usb/input/wacom.h - * - * USB Wacom Graphire and Wacom Intuos tablet support - * - * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz> - * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk> - * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at> - * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org> - * Copyright (c) 2000 James E. Blair <corvus@gnu.org> - * Copyright (c) 2000 Daniel Egger <egger@suse.de> - * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> - * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> - * Copyright (c) 2002-2009 Ping Cheng <pingc@wacom.com> - * - * ChangeLog: - * v0.1 (vp) - Initial release - * v0.2 (aba) - Support for all buttons / combinations - * v0.3 (vp) - Support for Intuos added - * v0.4 (sm) - Support for more Intuos models, menustrip - * relative mode, proximity. - * v0.5 (vp) - Big cleanup, nifty features removed, - * they belong in userspace - * v1.8 (vp) - Submit URB only when operating, moved to CVS, - * use input_report_key instead of report_btn and - * other cleanups - * v1.11 (vp) - Add URB ->dev setting for new kernels - * v1.11 (jb) - Add support for the 4D Mouse & Lens - * v1.12 (de) - Add support for two more inking pen IDs - * v1.14 (vp) - Use new USB device id probing scheme. - * Fix Wacom Graphire mouse wheel - * v1.18 (vp) - Fix mouse wheel direction - * Make mouse relative - * v1.20 (fl) - Report tool id for Intuos devices - * - Multi tools support - * - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...) - * - Add PL models support - * - Fix Wacom Graphire mouse wheel again - * v1.21 (vp) - Removed protocol descriptions - * - Added MISC_SERIAL for tool serial numbers - * (gb) - Identify version on module load. - * v1.21.1 (fl) - added Graphire2 support - * v1.21.2 (fl) - added Intuos2 support - * - added all the PL ids - * v1.21.3 (fl) - added another eraser id from Neil Okamoto - * - added smooth filter for Graphire from Peri Hankey - * - added PenPartner support from Olaf van Es - * - new tool ids from Ole Martin Bjoerndalen - * v1.29 (pc) - Add support for more tablets - * - Fix pressure reporting - * v1.30 (vp) - Merge 2.4 and 2.5 drivers - * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse - * - Cleanups here and there - * v1.30.1 (pi) - Added Graphire3 support - * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... - * v1.43 (pc) - Added support for Cintiq 21UX - * - Fixed a Graphire bug - * - Merged wacom_intuos3_irq into wacom_intuos_irq - * - * - * WARNING: THIS IS NOT PART OF THE OFFICIAL KERNEL TREE - * THIS IS FOR TESTING PURPOSES - * - * v1.43-2.6.13.1-pc-0.1 - initial release based on 2.6.13.1 - * v1.43-2.6.13.1-pc-0.2 - added DTF 521, I3 12x12, and I3 12x19 - * v1.43-2.6.13.1-pc-0.3 - Support tablet buttons/keys - * v1.43-2.6.13.1-pc-0.4 - Split wacom.c into 4 files - * v1.43-2.6.13.1-pc-0.5 - added Bamboo - * v1.43-2.6.13.1-pc-0.6 - Added BambooFun and Hummingbird - * v1.43-2.6.13.1-pc-0.7 - Added USB Tablet PC - */ - -/* - * 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. - */ -#ifndef WACOM_H -#define WACOM_H -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/input.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/usb.h> -#include <linux/usb_input.h> -#include <asm/unaligned.h> -#include <asm/byteorder.h> - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.43-2.6.13.1-pc-0.9" -#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" -#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" -#define DRIVER_LICENSE "GPL" - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); - -#define USB_VENDOR_ID_WACOM 0x056a - -struct wacom { - dma_addr_t data_dma; - struct input_dev dev; - struct usb_device *usbdev; - struct urb *irq; - struct wacom_wac * wacom_wac; - int open; - char phys[32]; -}; - -struct wacom_combo { - struct wacom * wacom; - struct urb * urb; - struct pt_regs *regs; -}; - -extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo); -extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data); -extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data); -extern void wacom_report_key(void *wcombo, unsigned int key_type, int key_data); -extern void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value); -extern void wacom_input_regs(void *wcombo); -extern void wacom_input_sync(void *wcombo); -extern void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern __u16 wacom_le16_to_cpu(unsigned char *data); -extern __u16 wacom_be16_to_cpu(unsigned char *data); -extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id); -extern const struct usb_device_id * get_device_table(void); - -#endif diff --git a/src/2.6.13/wacom_sys.c b/src/2.6.13/wacom_sys.c deleted file mode 100755 index 8c1f3fe..0000000 --- a/src/2.6.13/wacom_sys.c +++ /dev/null @@ -1,523 +0,0 @@ -/* - * drivers/usb/input/wacom_sys.c - * - * USB Wacom Graphire and Wacom Intuos tablet support - system specific code - */ - -/* - * 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. - */ - -#include "wacom.h" -#include "wacom_wac.h" - -/* defines to get HID report descriptor */ -#define HID_DEVICET_HID (USB_TYPE_CLASS | 0x01) -#define HID_DEVICET_REPORT (USB_TYPE_CLASS | 0x02) -#define HID_USAGE_UNDEFINED 0x00 -#define HID_USAGE_PAGE 0x05 -#define HID_USAGE_PAGE_DIGITIZER 0x0d -#define HID_USAGE_PAGE_DESKTOP 0x01 -#define HID_USAGE 0x09 -#define HID_USAGE_X 0x30 -#define HID_USAGE_Y 0x31 -#define HID_USAGE_X_TILT 0x3d -#define HID_USAGE_Y_TILT 0x3e -#define HID_USAGE_FINGER 0x22 -#define HID_USAGE_STYLUS 0x20 -#define HID_COLLECTION 0xc0 - -enum { - WCM_UNDEFINED = 0, - WCM_DESKTOP, - WCM_DIGITIZER, - MAX_USAGE_PAGE -}; - -struct hid_descriptor -{ - struct usb_descriptor_header header; - __le16 bcdHID; - u8 bCountryCode; - u8 bNumDescriptors; - u8 bDescriptorType; - __le16 wDescriptorLength; -} __attribute__ ((packed)); - -/* defines to get/set USB message */ -#define USB_REQ_GET_REPORT 0x01 -#define USB_REQ_SET_REPORT 0x09 -#define WAC_HID_FEATURE_REPORT 0x03 - -static int usb_get_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 100); -} - -static int usb_set_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_sndctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 1000); -} - -static struct input_dev * get_input_dev(struct wacom_combo *wcombo) -{ - return &(wcombo->wacom->dev); -} - -static void wacom_sys_irq(struct urb *urb, struct pt_regs *regs) -{ - struct wacom *wacom = urb->context; - struct wacom_combo wcombo; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - wcombo.wacom = wacom; - wcombo.urb = urb; - wcombo.regs = regs; - - if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo)) - input_sync(get_input_dev(&wcombo)); - - exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) -{ - input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); - return; -} - -void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data) -{ - input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data); - return; -} - -void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data) -{ - input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data); - return; -} - -void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value) -{ - input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value); - return; -} - -__u16 wacom_be16_to_cpu(unsigned char *data) -{ - __u16 value; - value = be16_to_cpu(*(__be16 *) data); - return value; -} - -__u16 wacom_le16_to_cpu(unsigned char *data) -{ - __u16 value; - value = le16_to_cpu(*(__le16 *) data); - return value; -} - -void wacom_input_regs(void *wcombo) -{ - input_regs(get_input_dev((struct wacom_combo *)wcombo), ((struct wacom_combo *)wcombo)->regs); - return; -} - -void wacom_input_sync(void *wcombo) -{ - input_sync(get_input_dev((struct wacom_combo *)wcombo)); - return; -} - -static int wacom_open(struct input_dev *dev) -{ - struct wacom *wacom = dev->private; - - if (wacom->open++) - return 0; - - wacom->irq->dev = wacom->usbdev; - if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { - wacom->open--; - return -EIO; - } - - return 0; -} - -static void wacom_close(struct input_dev *dev) -{ - struct wacom *wacom = dev->private; - - if (!--wacom->open) - usb_kill_urb(wacom->irq); -} - -void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_1) | BIT(BTN_5); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); -} - -void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_MSC); - input_dev->mscbit[0] |= BIT(MSC_SERIAL); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_4); -} - -void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_REL); - input_dev->relbit[0] |= BIT(REL_WHEEL); - input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); -} - -void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); - input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); - input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); -} - -void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_7) | BIT(BTN_8); -} - -void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_8) | BIT(BTN_9); -} - -void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); - input_dev->mscbit[0] |= BIT(MSC_SERIAL); - input_dev->relbit[0] |= BIT(REL_WHEEL); - input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) - | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); - input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); -} - -void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2); -} - -void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER); -} - -static void wacom_paser_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, - struct wacom_wac *wacom_wac, char *report) -{ - struct usb_device *dev = interface_to_usbdev(intf); - char limit = 0, result = 0; - int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; - - /* retrive report descriptors */ - do { - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, - USB_RECIP_INTERFACE | USB_DIR_IN, - HID_DEVICET_REPORT << 8, - intf->altsetting[0].desc.bInterfaceNumber, /* interface */ - report, - hid_desc->wDescriptorLength, - 5000); /* 5 secs */ - } while (limit++ < 5); - - for (i=0; i<hid_desc->wDescriptorLength; i++) { - if ((unsigned short)report[i] == HID_USAGE_PAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_PAGE_DIGITIZER: - usage = WCM_DIGITIZER; - i++; - continue; - case HID_USAGE_PAGE_DESKTOP: - usage = WCM_DESKTOP; - i++; - continue; - } - } - - if ((unsigned short)report[i] == HID_USAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_X: - if (usage == WCM_DESKTOP) { - if (finger) { - wacom_wac->features->touch_x_max = - wacom_wac->features->touch_y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+6])); - i += 7; - } else if (pen) { - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - i += 4; - } - } else if (usage == WCM_DIGITIZER) { - /* max pressure isn't reported - wacom_wac->features->pressure_max = (unsigned short) - (report[i+4] << 8 | report[i+3]); - */ - wacom_wac->features->pressure_max = 255; - i += 4; - } - break; - case HID_USAGE_Y: - if (usage == WCM_DESKTOP) { - wacom_wac->features->y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - case HID_USAGE_FINGER: - finger = 1; - i++; - break; - case HID_USAGE_STYLUS: - pen = 1; - i++; - break; - case HID_USAGE_UNDEFINED: - if (usage == WCM_DESKTOP && finger) { /* capacity */ - wacom_wac->features->pressure_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - } - } - - if ((unsigned short)report[i] == HID_COLLECTION) { - /* reset UsagePage ans Finger */ - finger = usage = 0; - } - } -} - -static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); - struct usb_endpoint_descriptor *endpoint; - struct usb_host_interface *interface = intf->cur_altsetting; - struct wacom *wacom; - struct wacom_wac *wacom_wac; - char rep_data[2], limit = 0, mode = 2, *report = NULL; - struct hid_descriptor *hid_desc; - char path[64]; - - if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) - return -ENOMEM; - memset(wacom, 0, sizeof(struct wacom)); - - if (!(wacom_wac = kmalloc(sizeof(struct wacom_wac), GFP_KERNEL))) { - kfree(wacom); - return -ENOMEM; - } - memset(wacom_wac, 0, sizeof(struct wacom_wac)); - - wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); - if (!wacom_wac->data) { - kfree(wacom); - kfree(wacom_wac); - return -ENOMEM; - } - - wacom->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!wacom->irq) { - usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); - kfree(wacom); - kfree(wacom_wac); - return -ENOMEM; - } - - wacom->usbdev = dev; - usb_make_path(dev, path, 64); - sprintf(wacom->phys, "%s/input0", path); - - wacom_wac->features = get_wacom_feature(id); - BUG_ON(wacom_wac->features->pktlen > 10); - - endpoint = &intf->cur_altsetting->endpoint[0].desc; - - /* Initialize touch_x_max and touch_y_max in case it is not defined */ - if (wacom_wac->features->type == TABLETPC) { - wacom_wac->features->touch_x_max = 1023; - wacom_wac->features->touch_y_max = 1023; - } else { - wacom_wac->features->touch_x_max = 0; - wacom_wac->features->touch_y_max = 0; - } - - /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ - if (wacom_wac->features->type == TABLETPC) { - if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { - if (usb_get_extra_descriptor(&interface->endpoint[0], - HID_DEVICET_REPORT, &hid_desc)) { - printk("wacom: can not retrive extra class descriptor\n"); - usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); - kfree(wacom); - kfree(wacom_wac); - return -ENOMEM; - } - } - report = kmalloc(hid_desc->wDescriptorLength, GFP_KERNEL); - if (!report) { - usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); - kfree(wacom); - kfree(wacom_wac); - return -ENOMEM; - } - wacom_paser_hid(intf, hid_desc, wacom_wac, report); - } - - wacom->dev.name = wacom_wac->features->name; - wacom->wacom_wac = wacom_wac; - wacom->dev.phys = wacom->phys; - usb_to_input_id(dev, &wacom->dev.id); - wacom->dev.dev = &intf->dev; - wacom->dev.private = wacom; - wacom->dev.open = wacom_open; - wacom->dev.close = wacom_close; - - wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_STYLUS) | BIT(BTN_TOUCH); - input_set_abs_params(&wacom->dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0); - input_set_abs_params(&wacom->dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0); - input_set_abs_params(&wacom->dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0); - if (wacom_wac->features->type == TABLETPC) { - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_DOUBLETAP); - input_set_abs_params(&wacom->dev, ABS_RX, 0, wacom_wac->features->touch_x_max, 4, 0); - input_set_abs_params(&wacom->dev, ABS_RY, 0, wacom_wac->features->touch_y_max, 4, 0); - } - wacom->dev.absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC); - - wacom_init_input_dev(&wacom->dev, wacom_wac); - - usb_fill_int_urb(wacom->irq, dev, - usb_rcvintpipe(dev, endpoint->bEndpointAddress), - wacom_wac->data, wacom_wac->features->pktlen, - wacom_sys_irq, wacom, endpoint->bInterval); - wacom->irq->transfer_dma = wacom->data_dma; - wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - input_register_device(&wacom->dev); - - /* Ask the tablet to report tablet data if it is not a Tablet PC. - * Repeat until it succeeds - */ - if (wacom_wac->features->type != TABLETPC) { - do { - rep_data[0] = 2; - rep_data[1] = mode; - usb_set_report(intf, USB_DT_STRING, 2, rep_data, 2); - usb_get_report(intf, USB_DT_STRING, 2, rep_data, 2); - } while (rep_data[1] != mode && limit++ < 5); - } - - usb_set_intfdata(intf, wacom); - kfree(report); - return 0; -} - -static void wacom_disconnect(struct usb_interface *intf) -{ - struct wacom *wacom = usb_get_intfdata (intf); - - usb_set_intfdata(intf, NULL); - if (wacom) { - usb_kill_urb(wacom->irq); - input_unregister_device(&wacom->dev); - usb_free_urb(wacom->irq); - usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); - kfree(wacom->wacom_wac); - kfree(wacom); - } -} - -static struct usb_driver wacom_driver = { - .owner = THIS_MODULE, - .name = "wacom", - .probe = wacom_probe, - .disconnect = wacom_disconnect, -}; - -static int __init wacom_init(void) -{ - int result; - wacom_driver.id_table = get_device_table(); - result = usb_register(&wacom_driver); - if (result == 0) - info(DRIVER_VERSION ":" DRIVER_DESC); - return result; -} - -static void __exit wacom_exit(void) -{ - usb_deregister(&wacom_driver); -} - -module_init(wacom_init); -module_exit(wacom_exit); diff --git a/src/2.6.14/Makefile.in b/src/2.6.14/Makefile.in deleted file mode 100644 index 432f8e8..0000000 --- a/src/2.6.14/Makefile.in +++ /dev/null @@ -1,109 +0,0 @@ -############################ 2.6 kernel compile ############################### -ifneq ($(KERNELRELEASE),) -# We were called by kbuild -# Do NOT indent stuff in this part! It has to be like this to make the -# $(error ... ) stuff work - -# only compile those modules which are enabled by global configure -ifeq ($(WCM_OPTION_HID),yes) - -# check if kernel was configured to have hid as an module -ifeq ($(CONFIG_USB_HID),m) - -# check if HID module should be usbhid.ko or hid.ko -NEWHID := $(shell test $(SUBLEVEL) -ge 6 && echo usb) - -$(NEWHID)hid-objs := hid-core.o - -# behave exactly as kernel config wants us to behave -ifeq ($(CONFIG_USB_HIDDEV),y) -$(NEWHID)hid-objs += hiddev.o -endif -ifeq ($(CONFIG_USB_HIDINPUT),y) -$(NEWHID)hid-objs += hid-input.o -endif -ifeq ($(CONFIG_HID_PID),y) -$(NEWHID)hid-objs += pid.o -endif -ifeq ($(CONFIG_LOGITECH_FF),y) -$(NEWHID)hid-objs += hid-lgff.o -endif -ifeq ($(CONFIG_THRUSTMASTER_FF),y) -$(NEWHID)hid-objs += hid-tmff.o -endif -ifeq ($(CONFIG_HID_FF),y) -$(NEWHID)hid-objs += hid-ff.o -endif - -obj-$(CONFIG_USB_HID) += $(NEWHID)hid.o - -else -ifeq ($(CONFIG_USB_HID),y) -$(error You requested to build hid with configure, but hid is configured as built-in in your kernel config) -endif - -$(error You requested to build hid with configure, but hid is not configured in your kernel config) -endif # CONFIG_USB_HID -endif # WCM_OPTION_HID not - -ifeq ($(WCM_OPTION_WACOM),yes) -ifneq ($(CONFIG_USB_WACOM),y) -wacom-objs := wacom_wac.o wacom_sys.o -obj-m += wacom.o -else -$(error You requested to build wacom with configure, but wacom is configured as built-in in your kernel config) -endif # CONFIG_USB_WACOM -endif # WCM_OPTION_WACOM - -else # We were called from command line -PWD := $(shell pwd) - -WCM_KERNEL_DIR := @WCM_KERNEL_DIR@ -WCM_OPTION_WACOM := @WCM_OPTION_WACOM@ -WCM_OPTION_HID := @WCM_OPTION_HID@ - -export WCM_OPTION_WACOM WCM_OPTION_HID - -COPY_FROM_KERNEL_TREE := hiddev.c hid.h hid-ff.c hid-input.c fixp-arith.h -COPY_FROM_KERNEL_TREE += hid-lgff.c hid-tmff.c pid.c pid.h - -all: -# Copy hid-stuff from kernel-dir to local dir -ifeq ($(WCM_OPTION_HID),yes) - @for i in $(COPY_FROM_KERNEL_TREE); do \ - if test ! -f "$$i" && test -f $(WCM_KERNEL_DIR)/drivers/usb/input/$$i ; then \ - cp $(WCM_KERNEL_DIR)/drivers/usb/input/$$i .; \ - fi; \ - done -endif - -# Copy Wacom specific code which is common to all kernel releases -ifeq ($(WCM_OPTION_WACOM),yes) - cp -f ../2.6.16/wacom_wac.c . - cp -f ../2.6.16/wacom_wac.h . - cp -f ../2.6.13/wacom.h . - cp -f ../2.6.13/wacom_sys.c . -endif - @echo ' Building linuxwacom drivers for 2.6 kernel.' - @echo '***Note: Drivers not enabled as modules in your kernel config but requested through configure are NOT built' - $(MAKE) -C $(WCM_KERNEL_DIR) M=$(PWD) - -endif # End kbuild check - -######################### Version independent targets ########################## - -clean: - rm -rf *.o *.ko *.mod.* .[a-z]* core *.i - -# also remove copied stuff -distclean: clean - @for i in $(COPY_FROM_KERNEL_TREE); do \ - if test -f "$$i"; then \ - rm -f $$i ; \ - fi; \ - done - -EMPTY_AUTOMAKE_TARGETS = distdir install install-data install-exec uninstall install-info -EMPTY_AUTOMAKE_TARGETS += installdirs check dvi pdf ps info html tags ctags mostlyclean distclean maintainer-clean -.PHONY: $(EMPTY_AUTOMAKE_TARGETS) - $(EMPTY_AUTOMAKE_TARGETS): diff --git a/src/2.6.14/hid-core.c b/src/2.6.14/hid-core.c deleted file mode 100644 index df4de38..0000000 --- a/src/2.6.14/hid-core.c +++ /dev/null @@ -1,1926 +0,0 @@ -/* - * USB HID support for Linux - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> - * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc - * - * WARNING: THIS IS NOT PART OF THE OFFICIAL KERNEL TREE - * THIS IS FOR TESTING PURPOSES - * - * v2.6-2.6.14-pc-0.1 - initial release based on 2.6.14 - * - */ - -/* - * 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. - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/list.h> -#include <linux/mm.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/unaligned.h> -#include <asm/byteorder.h> -#include <linux/input.h> -#include <linux/wait.h> - -#undef DEBUG -#undef DEBUG_DATA - -#include <linux/usb.h> - -#include "hid.h" -#include <linux/hiddev.h> - -/* - * Version Information - */ - -#define DRIVER_VERSION "v2.6" -#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik" -#define DRIVER_DESC "USB HID core driver" -#define DRIVER_LICENSE "GPL" - -static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick", - "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"}; -/* - * Module parameters. - */ - -static unsigned int hid_mousepoll_interval; -module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); -MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); - -/* - * Register a new report for a device. - */ - -static struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id) -{ - struct hid_report_enum *report_enum = device->report_enum + type; - struct hid_report *report; - - if (report_enum->report_id_hash[id]) - return report_enum->report_id_hash[id]; - - if (!(report = kmalloc(sizeof(struct hid_report), GFP_KERNEL))) - return NULL; - memset(report, 0, sizeof(struct hid_report)); - - if (id != 0) - report_enum->numbered = 1; - - report->id = id; - report->type = type; - report->size = 0; - report->device = device; - report_enum->report_id_hash[id] = report; - - list_add_tail(&report->list, &report_enum->report_list); - - return report; -} - -/* - * Register a new field for this report. - */ - -static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) -{ - struct hid_field *field; - - if (report->maxfield == HID_MAX_FIELDS) { - dbg("too many fields in report"); - return NULL; - } - - if (!(field = kmalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) - + values * sizeof(unsigned), GFP_KERNEL))) return NULL; - - memset(field, 0, sizeof(struct hid_field) + usages * sizeof(struct hid_usage) - + values * sizeof(unsigned)); - - field->index = report->maxfield++; - report->field[field->index] = field; - field->usage = (struct hid_usage *)(field + 1); - field->value = (unsigned *)(field->usage + usages); - field->report = report; - - return field; -} - -/* - * Open a collection. The type/usage is pushed on the stack. - */ - -static int open_collection(struct hid_parser *parser, unsigned type) -{ - struct hid_collection *collection; - unsigned usage; - - usage = parser->local.usage[0]; - - if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { - dbg("collection stack overflow"); - return -1; - } - - if (parser->device->maxcollection == parser->device->collection_size) { - collection = kmalloc(sizeof(struct hid_collection) * - parser->device->collection_size * 2, GFP_KERNEL); - if (collection == NULL) { - dbg("failed to reallocate collection array"); - return -1; - } - memcpy(collection, parser->device->collection, - sizeof(struct hid_collection) * - parser->device->collection_size); - memset(collection + parser->device->collection_size, 0, - sizeof(struct hid_collection) * - parser->device->collection_size); - kfree(parser->device->collection); - parser->device->collection = collection; - parser->device->collection_size *= 2; - } - - parser->collection_stack[parser->collection_stack_ptr++] = - parser->device->maxcollection; - - collection = parser->device->collection + - parser->device->maxcollection++; - collection->type = type; - collection->usage = usage; - collection->level = parser->collection_stack_ptr - 1; - - if (type == HID_COLLECTION_APPLICATION) - parser->device->maxapplication++; - - return 0; -} - -/* - * Close a collection. - */ - -static int close_collection(struct hid_parser *parser) -{ - if (!parser->collection_stack_ptr) { - dbg("collection stack underflow"); - return -1; - } - parser->collection_stack_ptr--; - return 0; -} - -/* - * Climb up the stack, search for the specified collection type - * and return the usage. - */ - -static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) -{ - int n; - for (n = parser->collection_stack_ptr - 1; n >= 0; n--) - if (parser->device->collection[parser->collection_stack[n]].type == type) - return parser->device->collection[parser->collection_stack[n]].usage; - return 0; /* we know nothing about this usage type */ -} - -/* - * Add a usage to the temporary parser table. - */ - -static int hid_add_usage(struct hid_parser *parser, unsigned usage) -{ - if (parser->local.usage_index >= HID_MAX_USAGES) { - dbg("usage index exceeded"); - return -1; - } - parser->local.usage[parser->local.usage_index] = usage; - parser->local.collection_index[parser->local.usage_index] = - parser->collection_stack_ptr ? - parser->collection_stack[parser->collection_stack_ptr - 1] : 0; - parser->local.usage_index++; - return 0; -} - -/* - * Register a new field for this report. - */ - -static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags) -{ - struct hid_report *report; - struct hid_field *field; - int usages; - unsigned offset; - int i; - - if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { - dbg("hid_register_report failed"); - return -1; - } - - if (parser->global.logical_maximum < parser->global.logical_minimum) { - dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum); - return -1; - } - - offset = report->size; - report->size += parser->global.report_size * parser->global.report_count; - - if (!parser->local.usage_index) /* Ignore padding fields */ - return 0; - - usages = max_t(int, parser->local.usage_index, parser->global.report_count); - - if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL) - return 0; - - field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); - field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL); - field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); - - for (i = 0; i < usages; i++) { - int j = i; - /* Duplicate the last usage we parsed if we have excess values */ - if (i >= parser->local.usage_index) - j = parser->local.usage_index - 1; - field->usage[i].hid = parser->local.usage[j]; - field->usage[i].collection_index = - parser->local.collection_index[j]; - } - - field->maxusage = usages; - field->flags = flags; - field->report_offset = offset; - field->report_type = report_type; - field->report_size = parser->global.report_size; - field->report_count = parser->global.report_count; - field->logical_minimum = parser->global.logical_minimum; - field->logical_maximum = parser->global.logical_maximum; - field->physical_minimum = parser->global.physical_minimum; - field->physical_maximum = parser->global.physical_maximum; - field->unit_exponent = parser->global.unit_exponent; - field->unit = parser->global.unit; - - return 0; -} - -/* - * Read data value from item. - */ - -static __inline__ __u32 item_udata(struct hid_item *item) -{ - switch (item->size) { - case 1: return item->data.u8; - case 2: return item->data.u16; - case 4: return item->data.u32; - } - return 0; -} - -static __inline__ __s32 item_sdata(struct hid_item *item) -{ - switch (item->size) { - case 1: return item->data.s8; - case 2: return item->data.s16; - case 4: return item->data.s32; - } - return 0; -} - -/* - * Process a global item. - */ - -static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) -{ - switch (item->tag) { - - case HID_GLOBAL_ITEM_TAG_PUSH: - - if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { - dbg("global enviroment stack overflow"); - return -1; - } - - memcpy(parser->global_stack + parser->global_stack_ptr++, - &parser->global, sizeof(struct hid_global)); - return 0; - - case HID_GLOBAL_ITEM_TAG_POP: - - if (!parser->global_stack_ptr) { - dbg("global enviroment stack underflow"); - return -1; - } - - memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr, - sizeof(struct hid_global)); - return 0; - - case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: - parser->global.usage_page = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: - parser->global.logical_minimum = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: - if (parser->global.logical_minimum < 0) - parser->global.logical_maximum = item_sdata(item); - else - parser->global.logical_maximum = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: - parser->global.physical_minimum = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: - if (parser->global.physical_minimum < 0) - parser->global.physical_maximum = item_sdata(item); - else - parser->global.physical_maximum = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: - parser->global.unit_exponent = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_UNIT: - parser->global.unit = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: - if ((parser->global.report_size = item_udata(item)) > 32) { - dbg("invalid report_size %d", parser->global.report_size); - return -1; - } - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: - if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) { - dbg("invalid report_count %d", parser->global.report_count); - return -1; - } - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_ID: - if ((parser->global.report_id = item_udata(item)) == 0) { - dbg("report_id 0 is invalid"); - return -1; - } - return 0; - - default: - dbg("unknown global tag 0x%x", item->tag); - return -1; - } -} - -/* - * Process a local item. - */ - -static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) -{ - __u32 data; - unsigned n; - - if (item->size == 0) { - dbg("item data expected for local item"); - return -1; - } - - data = item_udata(item); - - switch (item->tag) { - - case HID_LOCAL_ITEM_TAG_DELIMITER: - - if (data) { - /* - * We treat items before the first delimiter - * as global to all usage sets (branch 0). - * In the moment we process only these global - * items and the first delimiter set. - */ - if (parser->local.delimiter_depth != 0) { - dbg("nested delimiters"); - return -1; - } - parser->local.delimiter_depth++; - parser->local.delimiter_branch++; - } else { - if (parser->local.delimiter_depth < 1) { - dbg("bogus close delimiter"); - return -1; - } - parser->local.delimiter_depth--; - } - return 1; - - case HID_LOCAL_ITEM_TAG_USAGE: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - return hid_add_usage(parser, data); - - case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - parser->local.usage_minimum = data; - return 0; - - case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - for (n = parser->local.usage_minimum; n <= data; n++) - if (hid_add_usage(parser, n)) { - dbg("hid_add_usage failed\n"); - return -1; - } - return 0; - - default: - - dbg("unknown local item tag 0x%x", item->tag); - return 0; - } - return 0; -} - -/* - * Process a main item. - */ - -static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) -{ - __u32 data; - int ret; - - data = item_udata(item); - - switch (item->tag) { - case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: - ret = open_collection(parser, data & 0xff); - break; - case HID_MAIN_ITEM_TAG_END_COLLECTION: - ret = close_collection(parser); - break; - case HID_MAIN_ITEM_TAG_INPUT: - ret = hid_add_field(parser, HID_INPUT_REPORT, data); - break; - case HID_MAIN_ITEM_TAG_OUTPUT: - ret = hid_add_field(parser, HID_OUTPUT_REPORT, data); - break; - case HID_MAIN_ITEM_TAG_FEATURE: - ret = hid_add_field(parser, HID_FEATURE_REPORT, data); - break; - default: - dbg("unknown main item tag 0x%x", item->tag); - ret = 0; - } - - memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */ - - return ret; -} - -/* - * Process a reserved item. - */ - -static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) -{ - dbg("reserved item type, tag 0x%x", item->tag); - return 0; -} - -/* - * Free a report and all registered fields. The field->usage and - * field->value table's are allocated behind the field, so we need - * only to free(field) itself. - */ - -static void hid_free_report(struct hid_report *report) -{ - unsigned n; - - for (n = 0; n < report->maxfield; n++) - kfree(report->field[n]); - kfree(report); -} - -/* - * Free a device structure, all reports, and all fields. - */ - -static void hid_free_device(struct hid_device *device) -{ - unsigned i,j; - - hid_ff_exit(device); - - for (i = 0; i < HID_REPORT_TYPES; i++) { - struct hid_report_enum *report_enum = device->report_enum + i; - - for (j = 0; j < 256; j++) { - struct hid_report *report = report_enum->report_id_hash[j]; - if (report) - hid_free_report(report); - } - } - - kfree(device->rdesc); - kfree(device); -} - -/* - * Fetch a report description item from the data stream. We support long - * items, though they are not used yet. - */ - -static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) -{ - u8 b; - - if ((end - start) <= 0) - return NULL; - - b = *start++; - - item->type = (b >> 2) & 3; - item->tag = (b >> 4) & 15; - - if (item->tag == HID_ITEM_TAG_LONG) { - - item->format = HID_ITEM_FORMAT_LONG; - - if ((end - start) < 2) - return NULL; - - item->size = *start++; - item->tag = *start++; - - if ((end - start) < item->size) - return NULL; - - item->data.longdata = start; - start += item->size; - return start; - } - - item->format = HID_ITEM_FORMAT_SHORT; - item->size = b & 3; - - switch (item->size) { - - case 0: - return start; - - case 1: - if ((end - start) < 1) - return NULL; - item->data.u8 = *start++; - return start; - - case 2: - if ((end - start) < 2) - return NULL; - item->data.u16 = le16_to_cpu(get_unaligned((__le16*)start)); - start = (__u8 *)((__le16 *)start + 1); - return start; - - case 3: - item->size++; - if ((end - start) < 4) - return NULL; - item->data.u32 = le32_to_cpu(get_unaligned((__le32*)start)); - start = (__u8 *)((__le32 *)start + 1); - return start; - } - - return NULL; -} - -/* - * Parse a report description into a hid_device structure. Reports are - * enumerated, fields are attached to these reports. - */ - -static struct hid_device *hid_parse_report(__u8 *start, unsigned size) -{ - struct hid_device *device; - struct hid_parser *parser; - struct hid_item item; - __u8 *end; - unsigned i; - static int (*dispatch_type[])(struct hid_parser *parser, - struct hid_item *item) = { - hid_parser_main, - hid_parser_global, - hid_parser_local, - hid_parser_reserved - }; - - if (!(device = kmalloc(sizeof(struct hid_device), GFP_KERNEL))) - return NULL; - memset(device, 0, sizeof(struct hid_device)); - - if (!(device->collection = kmalloc(sizeof(struct hid_collection) * - HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) { - kfree(device); - return NULL; - } - memset(device->collection, 0, sizeof(struct hid_collection) * - HID_DEFAULT_NUM_COLLECTIONS); - device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; - - for (i = 0; i < HID_REPORT_TYPES; i++) - INIT_LIST_HEAD(&device->report_enum[i].report_list); - - if (!(device->rdesc = (__u8 *)kmalloc(size, GFP_KERNEL))) { - kfree(device->collection); - kfree(device); - return NULL; - } - memcpy(device->rdesc, start, size); - device->rsize = size; - - if (!(parser = kmalloc(sizeof(struct hid_parser), GFP_KERNEL))) { - kfree(device->rdesc); - kfree(device->collection); - kfree(device); - return NULL; - } - memset(parser, 0, sizeof(struct hid_parser)); - parser->device = device; - - end = start + size; - while ((start = fetch_item(start, end, &item)) != NULL) { - - if (item.format != HID_ITEM_FORMAT_SHORT) { - dbg("unexpected long global item"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - - if (dispatch_type[item.type](parser, &item)) { - dbg("item %u %u %u %u parsing failed\n", - item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - - if (start == end) { - if (parser->collection_stack_ptr) { - dbg("unbalanced collection at end of report description"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - if (parser->local.delimiter_depth) { - dbg("unbalanced delimiter at end of report description"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - kfree(parser); - return device; - } - } - - dbg("item fetching failed at offset %d\n", (int)(end - start)); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; -} - -/* - * Convert a signed n-bit integer to signed 32-bit integer. Common - * cases are done through the compiler, the screwed things has to be - * done by hand. - */ - -static __inline__ __s32 snto32(__u32 value, unsigned n) -{ - switch (n) { - case 8: return ((__s8)value); - case 16: return ((__s16)value); - case 32: return ((__s32)value); - } - return value & (1 << (n - 1)) ? value | (-1 << n) : value; -} - -/* - * Convert a signed 32-bit integer to a signed n-bit integer. - */ - -static __inline__ __u32 s32ton(__s32 value, unsigned n) -{ - __s32 a = value >> (n - 1); - if (a && a != -1) - return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; - return value & ((1 << n) - 1); -} - -/* - * Extract/implement a data field from/to a report. - */ - -static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) -{ - report += (offset >> 5) << 2; offset &= 31; - return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1ULL << n) - 1); -} - -static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) -{ - report += (offset >> 5) << 2; offset &= 31; - put_unaligned((get_unaligned((__le64*)report) - & cpu_to_le64(~((((__u64) 1 << n) - 1) << offset))) - | cpu_to_le64((__u64)value << offset), (__le64*)report); -} - -/* - * Search an array for a value. - */ - -static __inline__ int search(__s32 *array, __s32 value, unsigned n) -{ - while (n--) { - if (*array++ == value) - return 0; - } - return -1; -} - -static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt, struct pt_regs *regs) -{ - hid_dump_input(usage, value); - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_hid_event(hid, field, usage, value, regs); - if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt) - hiddev_hid_event(hid, field, usage, value, regs); -} - -/* - * Analyse a received field, and fetch the data from it. The field - * content is stored for next report processing (we do differential - * reporting to the layer). - */ - -static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt, struct pt_regs *regs) -{ - unsigned n; - unsigned count = field->report_count; - unsigned offset = field->report_offset; - unsigned size = field->report_size; - __s32 min = field->logical_minimum; - __s32 max = field->logical_maximum; - __s32 *value; - - if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC))) - return; - - for (n = 0; n < count; n++) { - - value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : - extract(data, offset + n * size, size); - - if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */ - && value[n] >= min && value[n] <= max - && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) - goto exit; - } - - for (n = 0; n < count; n++) { - - if (HID_MAIN_ITEM_VARIABLE & field->flags) { - hid_process_event(hid, field, &field->usage[n], value[n], interrupt, regs); - continue; - } - - if (field->value[n] >= min && field->value[n] <= max - && field->usage[field->value[n] - min].hid - && search(value, field->value[n], count)) - hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt, regs); - - if (value[n] >= min && value[n] <= max - && field->usage[value[n] - min].hid - && search(field->value, value[n], count)) - hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt, regs); - } - - memcpy(field->value, value, count * sizeof(__s32)); -exit: - kfree(value); -} - -static int hid_input_report(int type, struct urb *urb, int interrupt, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - struct hid_report_enum *report_enum = hid->report_enum + type; - u8 *data = urb->transfer_buffer; - int len = urb->actual_length; - struct hid_report *report; - int n, size; - - if (!len) { - dbg("empty report"); - return -1; - } - -#ifdef DEBUG_DATA - printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", len, report_enum->numbered ? "" : "un"); -#endif - - n = 0; /* Normally report number is 0 */ - if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */ - n = *data++; - len--; - } - -#ifdef DEBUG_DATA - { - int i; - printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, len); - for (i = 0; i < len; i++) - printk(" %02x", data[i]); - printk("\n"); - } -#endif - - if (!(report = report_enum->report_id_hash[n])) { - dbg("undefined report_id %d received", n); - return -1; - } - - size = ((report->size - 1) >> 3) + 1; - - if (len < size) - dbg("report %d is too short, (%d < %d)", report->id, len, size); - - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_report_event(hid, report); - - for (n = 0; n < report->maxfield; n++) - hid_input_field(hid, report->field[n], data, interrupt, regs); - - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_report_event(hid, report); - - return 0; -} - -/* - * Input interrupt completion handler. - */ - -static void hid_irq_in(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - int status; - - switch (urb->status) { - case 0: /* success */ - hid_input_report(HID_INPUT_REPORT, urb, 1, regs); - break; - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -EPERM: - case -ESHUTDOWN: /* unplug */ - case -EILSEQ: /* unplug timeout on uhci */ - return; - case -ETIMEDOUT: /* NAK */ - break; - default: /* error */ - warn("input irq status %d received", urb->status); - } - - status = usb_submit_urb(urb, SLAB_ATOMIC); - if (status) - err("can't resubmit intr, %s-%s/input%d, status %d", - hid->dev->bus->bus_name, hid->dev->devpath, - hid->ifnum, status); -} - -/* - * Output the field into the report. - */ - -static void hid_output_field(struct hid_field *field, __u8 *data) -{ - unsigned count = field->report_count; - unsigned offset = field->report_offset; - unsigned size = field->report_size; - unsigned n; - - for (n = 0; n < count; n++) { - if (field->logical_minimum < 0) /* signed values */ - implement(data, offset + n * size, size, s32ton(field->value[n], size)); - else /* unsigned values */ - implement(data, offset + n * size, size, field->value[n]); - } -} - -/* - * Create a report. - */ - -static void hid_output_report(struct hid_report *report, __u8 *data) -{ - unsigned n; - - if (report->id > 0) - *data++ = report->id; - - for (n = 0; n < report->maxfield; n++) - hid_output_field(report->field[n], data); -} - -/* - * Set a field value. The report this field belongs to has to be - * created and transferred to the device, to set this value in the - * device. - */ - -int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) -{ - unsigned size = field->report_size; - - hid_dump_input(field->usage + offset, value); - - if (offset >= field->report_count) { - dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count); - hid_dump_field(field, 8); - return -1; - } - if (field->logical_minimum < 0) { - if (value != snto32(s32ton(value, size), size)) { - dbg("value %d is out of range", value); - return -1; - } - } - field->value[offset] = value; - return 0; -} - -/* - * Find a report field with a specified HID usage. - */ - -struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_usage, int type) -{ - struct hid_report *report; - int i; - - list_for_each_entry(report, &hid->report_enum[type].report_list, list) - for (i = 0; i < report->maxfield; i++) - if (report->field[i]->logical == wanted_usage) - return report->field[i]; - return NULL; -} - -static int hid_submit_out(struct hid_device *hid) -{ - struct hid_report *report; - - report = hid->out[hid->outtail]; - - hid_output_report(report, hid->outbuf); - hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); - hid->urbout->dev = hid->dev; - - dbg("submitting out urb"); - - if (usb_submit_urb(hid->urbout, GFP_ATOMIC)) { - err("usb_submit_urb(out) failed"); - return -1; - } - - return 0; -} - -static int hid_submit_ctrl(struct hid_device *hid) -{ - struct hid_report *report; - unsigned char dir; - int len; - - report = hid->ctrl[hid->ctrltail].report; - dir = hid->ctrl[hid->ctrltail].dir; - - len = ((report->size - 1) >> 3) + 1 + (report->id > 0); - if (dir == USB_DIR_OUT) { - hid_output_report(report, hid->ctrlbuf); - hid->urbctrl->pipe = usb_sndctrlpipe(hid->dev, 0); - hid->urbctrl->transfer_buffer_length = len; - } else { - int maxpacket, padlen; - - hid->urbctrl->pipe = usb_rcvctrlpipe(hid->dev, 0); - maxpacket = usb_maxpacket(hid->dev, hid->urbctrl->pipe, 0); - if (maxpacket > 0) { - padlen = (len + maxpacket - 1) / maxpacket; - padlen *= maxpacket; - if (padlen > hid->bufsize) - padlen = hid->bufsize; - } else - padlen = 0; - hid->urbctrl->transfer_buffer_length = padlen; - } - hid->urbctrl->dev = hid->dev; - - hid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; - hid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; - hid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id); - hid->cr->wIndex = cpu_to_le16(hid->ifnum); - hid->cr->wLength = cpu_to_le16(len); - - dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u", - hid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", - hid->cr->wValue, hid->cr->wIndex, hid->cr->wLength); - - if (usb_submit_urb(hid->urbctrl, GFP_ATOMIC)) { - err("usb_submit_urb(ctrl) failed"); - return -1; - } - - return 0; -} - -/* - * Output interrupt completion handler. - */ - -static void hid_irq_out(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - unsigned long flags; - int unplug = 0; - - switch (urb->status) { - case 0: /* success */ - break; - case -ESHUTDOWN: /* unplug */ - case -EILSEQ: /* unplug timeout on uhci */ - unplug = 1; - case -ECONNRESET: /* unlink */ - case -ENOENT: - break; - default: /* error */ - warn("output irq status %d received", urb->status); - } - - spin_lock_irqsave(&hid->outlock, flags); - - if (unplug) - hid->outtail = hid->outhead; - else - hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); - - if (hid->outhead != hid->outtail) { - if (hid_submit_out(hid)) { - clear_bit(HID_OUT_RUNNING, &hid->iofl);; - wake_up(&hid->wait); - } - spin_unlock_irqrestore(&hid->outlock, flags); - return; - } - - clear_bit(HID_OUT_RUNNING, &hid->iofl); - spin_unlock_irqrestore(&hid->outlock, flags); - wake_up(&hid->wait); -} - -/* - * Control pipe completion handler. - */ - -static void hid_ctrl(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - unsigned long flags; - int unplug = 0; - - spin_lock_irqsave(&hid->ctrllock, flags); - - switch (urb->status) { - case 0: /* success */ - if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) - hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs); - break; - case -ESHUTDOWN: /* unplug */ - case -EILSEQ: /* unplug timectrl on uhci */ - unplug = 1; - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -EPIPE: /* report not available */ - break; - default: /* error */ - warn("ctrl urb status %d received", urb->status); - } - - if (unplug) - hid->ctrltail = hid->ctrlhead; - else - hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); - - if (hid->ctrlhead != hid->ctrltail) { - if (hid_submit_ctrl(hid)) { - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - wake_up(&hid->wait); - } - spin_unlock_irqrestore(&hid->ctrllock, flags); - return; - } - - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - spin_unlock_irqrestore(&hid->ctrllock, flags); - wake_up(&hid->wait); -} - -void hid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) -{ - int head; - unsigned long flags; - - if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) - return; - - if (hid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { - - spin_lock_irqsave(&hid->outlock, flags); - - if ((head = (hid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == hid->outtail) { - spin_unlock_irqrestore(&hid->outlock, flags); - warn("output queue full"); - return; - } - - hid->out[hid->outhead] = report; - hid->outhead = head; - - if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl)) - if (hid_submit_out(hid)) - clear_bit(HID_OUT_RUNNING, &hid->iofl); - - spin_unlock_irqrestore(&hid->outlock, flags); - return; - } - - spin_lock_irqsave(&hid->ctrllock, flags); - - if ((head = (hid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == hid->ctrltail) { - spin_unlock_irqrestore(&hid->ctrllock, flags); - warn("control queue full"); - return; - } - - hid->ctrl[hid->ctrlhead].report = report; - hid->ctrl[hid->ctrlhead].dir = dir; - hid->ctrlhead = head; - - if (!test_and_set_bit(HID_CTRL_RUNNING, &hid->iofl)) - if (hid_submit_ctrl(hid)) - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - - spin_unlock_irqrestore(&hid->ctrllock, flags); -} - -int hid_wait_io(struct hid_device *hid) -{ - if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &hid->iofl) && - !test_bit(HID_OUT_RUNNING, &hid->iofl)), - 10*HZ)) { - dbg("timeout waiting for ctrl or out queue to clear"); - return -1; - } - - return 0; -} - -static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle) -{ - return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (idle << 8) | report, - ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT); -} - -static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, - unsigned char type, void *buf, int size) -{ - int result, retries = 4; - - memset(buf,0,size); // Make sure we parse really received data - - do { - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, - (type << 8), ifnum, buf, size, USB_CTRL_GET_TIMEOUT); - retries--; - } while (result < size && retries); - return result; -} - -int hid_open(struct hid_device *hid) -{ - if (hid->open++) - return 0; - - hid->urbin->dev = hid->dev; - - if (usb_submit_urb(hid->urbin, GFP_KERNEL)) - return -EIO; - - return 0; -} - -void hid_close(struct hid_device *hid) -{ - if (!--hid->open) - usb_kill_urb(hid->urbin); -} - -/* - * Initialize all reports - */ - -void hid_init_reports(struct hid_device *hid) -{ - struct hid_report *report; - int err, ret; - - list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) - hid_submit_report(hid, report, USB_DIR_IN); - - list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) - hid_submit_report(hid, report, USB_DIR_IN); - - err = 0; - ret = hid_wait_io(hid); - while (ret) { - err |= ret; - if (test_bit(HID_CTRL_RUNNING, &hid->iofl)) - usb_kill_urb(hid->urbctrl); - if (test_bit(HID_OUT_RUNNING, &hid->iofl)) - usb_kill_urb(hid->urbout); - ret = hid_wait_io(hid); - } - - if (err) - warn("timeout initializing reports\n"); -} - -#define USB_VENDOR_ID_WACOM 0x056a - -#define USB_VENDOR_ID_ACECAD 0x0460 -#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 -#define USB_DEVICE_ID_ACECAD_302 0x0008 - -#define USB_VENDOR_ID_KBGEAR 0x084e -#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 - -#define USB_VENDOR_ID_AIPTEK 0x08ca -#define USB_DEVICE_ID_AIPTEK_01 0x0001 -#define USB_DEVICE_ID_AIPTEK_10 0x0010 -#define USB_DEVICE_ID_AIPTEK_20 0x0020 -#define USB_DEVICE_ID_AIPTEK_21 0x0021 -#define USB_DEVICE_ID_AIPTEK_22 0x0022 -#define USB_DEVICE_ID_AIPTEK_23 0x0023 -#define USB_DEVICE_ID_AIPTEK_24 0x0024 - -#define USB_VENDOR_ID_GRIFFIN 0x077d -#define USB_DEVICE_ID_POWERMATE 0x0410 -#define USB_DEVICE_ID_SOUNDKNOB 0x04AA - -#define USB_VENDOR_ID_ATEN 0x0557 -#define USB_DEVICE_ID_ATEN_UC100KM 0x2004 -#define USB_DEVICE_ID_ATEN_CS124U 0x2202 -#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204 -#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 -#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 - -#define USB_VENDOR_ID_TOPMAX 0x0663 -#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 - -#define USB_VENDOR_ID_HAPP 0x078b -#define USB_DEVICE_ID_UGCI_DRIVING 0x0010 -#define USB_DEVICE_ID_UGCI_FLYING 0x0020 -#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 - -#define USB_VENDOR_ID_MGE 0x0463 -#define USB_DEVICE_ID_MGE_UPS 0xffff -#define USB_DEVICE_ID_MGE_UPS1 0x0001 - -#define USB_VENDOR_ID_ONTRAK 0x0a07 -#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 - -#define USB_VENDOR_ID_TANGTOP 0x0d3d -#define USB_DEVICE_ID_TANGTOP_USBPS2 0x0001 - -#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f -#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 - -#define USB_VENDOR_ID_A4TECH 0x09da -#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 - -#define USB_VENDOR_ID_AASHIMA 0x06d6 -#define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 -#define USB_DEVICE_ID_AASHIMA_PREDATOR 0x0026 - -#define USB_VENDOR_ID_CYPRESS 0x04b4 -#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 -#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 -#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417 - -#define USB_VENDOR_ID_BERKSHIRE 0x0c98 -#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 - -#define USB_VENDOR_ID_ALPS 0x0433 -#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 - -#define USB_VENDOR_ID_SAITEK 0x06a3 -#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 - -#define USB_VENDOR_ID_NEC 0x073e -#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 - -#define USB_VENDOR_ID_CHIC 0x05fe -#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014 - -#define USB_VENDOR_ID_GLAB 0x06c2 -#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 -#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 -#define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045 -#define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040 -#define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053 - -#define USB_VENDOR_ID_WISEGROUP 0x0925 -#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 -#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 - -#define USB_VENDOR_ID_CODEMERCS 0x07c0 -#define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500 -#define USB_DEVICE_ID_CODEMERCS_IOW24 0x1501 -#define USB_DEVICE_ID_CODEMERCS_IOW48 0x1502 -#define USB_DEVICE_ID_CODEMERCS_IOW28 0x1503 - -#define USB_VENDOR_ID_DELORME 0x1163 -#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 -#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 - -#define USB_VENDOR_ID_MCC 0x09db -#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 -#define USB_DEVICE_ID_MCC_PMD1208LS 0x007a - -#define USB_VENDOR_ID_CHICONY 0x04f2 -#define USB_DEVICE_ID_CHICONY_USBHUB_KB 0x0100 - -#define USB_VENDOR_ID_BTC 0x046e -#define USB_DEVICE_ID_BTC_KEYBOARD 0x5303 - -#define USB_VENDOR_ID_VERNIER 0x08f7 -#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 -#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 -#define USB_DEVICE_ID_VERNIER_SKIP 0x0003 -#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 - -#define USB_VENDOR_ID_LD 0x0f11 -#define USB_DEVICE_ID_CASSY 0x1000 -#define USB_DEVICE_ID_POCKETCASSY 0x1010 -#define USB_DEVICE_ID_MOBILECASSY 0x1020 -#define USB_DEVICE_ID_JWM 0x1080 -#define USB_DEVICE_ID_DMMP 0x1081 -#define USB_DEVICE_ID_UMIP 0x1090 -#define USB_DEVICE_ID_VIDEOCOM 0x1200 -#define USB_DEVICE_ID_COM3LAB 0x2000 -#define USB_DEVICE_ID_TELEPORT 0x2010 -#define USB_DEVICE_ID_NETWORKANALYSER 0x2020 -#define USB_DEVICE_ID_POWERCONTROL 0x2030 - -#define USB_VENDOR_ID_APPLE 0x05ac -#define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304 - -/* - * Alphabetically sorted blacklist by quirk type. - */ - -static struct hid_blacklist { - __u16 idVendor; - __u16 idProduct; - unsigned quirks; -} hid_blacklist[] = { - - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW48, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_CASSY, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_POCKETCASSY, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_MOBILECASSY, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_JWM, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_DMMP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_UMIP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_VIDEOCOM, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_COM3LAB, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_TELEPORT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_NETWORKANALYSER, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_POWERCONTROL, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_KEYBOARD, HID_QUIRK_NOGET}, - { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET}, - { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, - - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE }, - { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, - - { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, - - { 0, 0 } -}; - -/* - * Traverse the supplied list of reports and find the longest - */ -static void hid_find_max_report(struct hid_device *hid, unsigned int type, int *max) -{ - struct hid_report *report; - int size; - - list_for_each_entry(report, &hid->report_enum[type].report_list, list) { - size = ((report->size - 1) >> 3) + 1; - if (type == HID_INPUT_REPORT && hid->report_enum[type].numbered) - size++; - if (*max < size) - *max = size; - } -} - -static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) -{ - if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->inbuf_dma))) - return -1; - if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->outbuf_dma))) - return -1; - if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma))) - return -1; - if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->ctrlbuf_dma))) - return -1; - - return 0; -} - -static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) -{ - if (hid->inbuf) - usb_buffer_free(dev, hid->bufsize, hid->inbuf, hid->inbuf_dma); - if (hid->outbuf) - usb_buffer_free(dev, hid->bufsize, hid->outbuf, hid->outbuf_dma); - if (hid->cr) - usb_buffer_free(dev, sizeof(*(hid->cr)), hid->cr, hid->cr_dma); - if (hid->ctrlbuf) - usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma); -} - -static struct hid_device *usb_hid_configure(struct usb_interface *intf) -{ - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_device *dev = interface_to_usbdev (intf); - struct hid_descriptor *hdesc; - struct hid_device *hid; - unsigned quirks = 0, rsize = 0; - char *buf, *rdesc; - int n, insize = 0; - - /* ignore all Wacom devices */ - if (dev->descriptor.idVendor == USB_VENDOR_ID_WACOM) - return NULL; - - for (n = 0; hid_blacklist[n].idVendor; n++) - if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) && - (hid_blacklist[n].idProduct == le16_to_cpu(dev->descriptor.idProduct))) - quirks = hid_blacklist[n].quirks; - - if (quirks & HID_QUIRK_IGNORE) - return NULL; - - if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->desc.bNumEndpoints) || - usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { - dbg("class descriptor not present\n"); - return NULL; - } - - for (n = 0; n < hdesc->bNumDescriptors; n++) - if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) - rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); - - if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { - dbg("weird size of report descriptor (%u)", rsize); - return NULL; - } - - if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) { - dbg("couldn't allocate rdesc memory"); - return NULL; - } - - hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0); - - if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { - dbg("reading report descriptor failed"); - kfree(rdesc); - return NULL; - } - -#ifdef DEBUG_DATA - printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); - for (n = 0; n < rsize; n++) - printk(" %02x", (unsigned char) rdesc[n]); - printk("\n"); -#endif - - if (!(hid = hid_parse_report(rdesc, n))) { - dbg("parsing report descriptor failed"); - kfree(rdesc); - return NULL; - } - - kfree(rdesc); - hid->quirks = quirks; - - hid->bufsize = HID_MIN_BUFFER_SIZE; - hid_find_max_report(hid, HID_INPUT_REPORT, &hid->bufsize); - hid_find_max_report(hid, HID_OUTPUT_REPORT, &hid->bufsize); - hid_find_max_report(hid, HID_FEATURE_REPORT, &hid->bufsize); - - if (hid->bufsize > HID_MAX_BUFFER_SIZE) - hid->bufsize = HID_MAX_BUFFER_SIZE; - - hid_find_max_report(hid, HID_INPUT_REPORT, &insize); - - if (insize > HID_MAX_BUFFER_SIZE) - insize = HID_MAX_BUFFER_SIZE; - - if (hid_alloc_buffers(dev, hid)) { - hid_free_buffers(dev, hid); - goto fail; - } - - for (n = 0; n < interface->desc.bNumEndpoints; n++) { - - struct usb_endpoint_descriptor *endpoint; - int pipe; - int interval; - - endpoint = &interface->endpoint[n].desc; - if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */ - continue; - - interval = endpoint->bInterval; - - /* Change the polling interval of mice. */ - if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) - interval = hid_mousepoll_interval; - - if (endpoint->bEndpointAddress & USB_DIR_IN) { - if (hid->urbin) - continue; - if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) - goto fail; - pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); - usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, insize, - hid_irq_in, hid, interval); - hid->urbin->transfer_dma = hid->inbuf_dma; - hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - } else { - if (hid->urbout) - continue; - if (!(hid->urbout = usb_alloc_urb(0, GFP_KERNEL))) - goto fail; - pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress); - usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0, - hid_irq_out, hid, interval); - hid->urbout->transfer_dma = hid->outbuf_dma; - hid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - } - } - - if (!hid->urbin) { - err("couldn't find an input interrupt endpoint"); - goto fail; - } - - init_waitqueue_head(&hid->wait); - - spin_lock_init(&hid->outlock); - spin_lock_init(&hid->ctrllock); - - hid->version = le16_to_cpu(hdesc->bcdHID); - hid->country = hdesc->bCountryCode; - hid->dev = dev; - hid->intf = intf; - hid->ifnum = interface->desc.bInterfaceNumber; - - hid->name[0] = 0; - - if (!(buf = kmalloc(64, GFP_KERNEL))) - goto fail; - - if (dev->manufacturer) { - strcat(hid->name, dev->manufacturer); - if (dev->product) - snprintf(hid->name, 64, "%s %s", hid->name, dev->product); - } else if (dev->product) { - snprintf(hid->name, 128, "%s", dev->product); - } else - snprintf(hid->name, 128, "%04x:%04x", - le16_to_cpu(dev->descriptor.idVendor), - le16_to_cpu(dev->descriptor.idProduct)); - - usb_make_path(dev, buf, 64); - snprintf(hid->phys, 64, "%s/input%d", buf, - intf->altsetting[0].desc.bInterfaceNumber); - - if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) - hid->uniq[0] = 0; - - kfree(buf); - - hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); - if (!hid->urbctrl) - goto fail; - usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr, - hid->ctrlbuf, 1, hid_ctrl, hid); - hid->urbctrl->setup_dma = hid->cr_dma; - hid->urbctrl->transfer_dma = hid->ctrlbuf_dma; - hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); - - return hid; - -fail: - - if (hid->urbin) - usb_free_urb(hid->urbin); - if (hid->urbout) - usb_free_urb(hid->urbout); - if (hid->urbctrl) - usb_free_urb(hid->urbctrl); - hid_free_buffers(dev, hid); - hid_free_device(hid); - - return NULL; -} - -static void hid_disconnect(struct usb_interface *intf) -{ - struct hid_device *hid = usb_get_intfdata (intf); - - if (!hid) - return; - - usb_set_intfdata(intf, NULL); - usb_kill_urb(hid->urbin); - usb_kill_urb(hid->urbout); - usb_kill_urb(hid->urbctrl); - - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_disconnect(hid); - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_disconnect(hid); - - usb_free_urb(hid->urbin); - usb_free_urb(hid->urbctrl); - if (hid->urbout) - usb_free_urb(hid->urbout); - - hid_free_buffers(hid->dev, hid); - hid_free_device(hid); -} - -static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct hid_device *hid; - char path[64]; - int i; - char *c; - - dbg("HID probe called for ifnum %d", - intf->altsetting->desc.bInterfaceNumber); - - if (!(hid = usb_hid_configure(intf))) - return -ENODEV; - - hid_init_reports(hid); - hid_dump_device(hid); - - if (!hidinput_connect(hid)) - hid->claimed |= HID_CLAIMED_INPUT; - if (!hiddev_connect(hid)) - hid->claimed |= HID_CLAIMED_HIDDEV; - - usb_set_intfdata(intf, hid); - - if (!hid->claimed) { - printk ("HID device not claimed by input or hiddev\n"); - hid_disconnect(intf); - return -ENODEV; - } - - printk(KERN_INFO); - - if (hid->claimed & HID_CLAIMED_INPUT) - printk("input"); - if (hid->claimed == (HID_CLAIMED_INPUT | HID_CLAIMED_HIDDEV)) - printk(","); - if (hid->claimed & HID_CLAIMED_HIDDEV) - printk("hiddev%d", hid->minor); - - c = "Device"; - for (i = 0; i < hid->maxcollection; i++) { - if (hid->collection[i].type == HID_COLLECTION_APPLICATION && - (hid->collection[i].usage & HID_USAGE_PAGE) == HID_UP_GENDESK && - (hid->collection[i].usage & 0xffff) < ARRAY_SIZE(hid_types)) { - c = hid_types[hid->collection[i].usage & 0xffff]; - break; - } - } - - usb_make_path(interface_to_usbdev(intf), path, 63); - - printk(": USB HID v%x.%02x %s [%s] on %s\n", - hid->version >> 8, hid->version & 0xff, c, hid->name, path); - - return 0; -} - -static int hid_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct hid_device *hid = usb_get_intfdata (intf); - - usb_kill_urb(hid->urbin); - intf->dev.power.power_state = PMSG_SUSPEND; - dev_dbg(&intf->dev, "suspend\n"); - return 0; -} - -static int hid_resume(struct usb_interface *intf) -{ - struct hid_device *hid = usb_get_intfdata (intf); - int status; - - intf->dev.power.power_state = PMSG_ON; - if (hid->open) - status = usb_submit_urb(hid->urbin, GFP_NOIO); - else - status = 0; - dev_dbg(&intf->dev, "resume status %d\n", status); - return status; -} - -static struct usb_device_id hid_usb_ids [] = { - { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, - .bInterfaceClass = USB_INTERFACE_CLASS_HID }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE (usb, hid_usb_ids); - -static struct usb_driver hid_driver = { - .owner = THIS_MODULE, - .name = "usbhid", - .probe = hid_probe, - .disconnect = hid_disconnect, - .suspend = hid_suspend, - .resume = hid_resume, - .id_table = hid_usb_ids, -}; - -static int __init hid_init(void) -{ - int retval; - retval = hiddev_init(); - if (retval) - goto hiddev_init_fail; - retval = usb_register(&hid_driver); - if (retval) - goto usb_register_fail; - info(DRIVER_VERSION ":" DRIVER_DESC); - - return 0; -usb_register_fail: - hiddev_exit(); -hiddev_init_fail: - return retval; -} - -static void __exit hid_exit(void) -{ - usb_deregister(&hid_driver); - hiddev_exit(); -} - -module_init(hid_init); -module_exit(hid_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); diff --git a/src/2.6.15/Makefile.in b/src/2.6.15/Makefile.in deleted file mode 100644 index c46dc7d..0000000 --- a/src/2.6.15/Makefile.in +++ /dev/null @@ -1,108 +0,0 @@ -############################ 2.6 kernel compile ############################### -ifneq ($(KERNELRELEASE),) -# We were called by kbuild -# Do NOT indent stuff in this part! It has to be like this to make the -# $(error ... ) stuff work - -# only compile those modules which are enabled by global configure -ifeq ($(WCM_OPTION_HID),yes) - -# check if kernel was configured to have hid as an module -ifeq ($(CONFIG_USB_HID),m) - -# check if HID module should be usbhid.ko or hid.ko -NEWHID := $(shell test $(SUBLEVEL) -ge 6 && echo usb) - -$(NEWHID)hid-objs := hid-core.o - -# behave exactly as kernel config wants us to behave -ifeq ($(CONFIG_USB_HIDDEV),y) -$(NEWHID)hid-objs += hiddev.o -endif -ifeq ($(CONFIG_USB_HIDINPUT),y) -$(NEWHID)hid-objs += hid-input.o -endif -ifeq ($(CONFIG_HID_PID),y) -$(NEWHID)hid-objs += pid.o -endif -ifeq ($(CONFIG_LOGITECH_FF),y) -$(NEWHID)hid-objs += hid-lgff.o -endif -ifeq ($(CONFIG_THRUSTMASTER_FF),y) -$(NEWHID)hid-objs += hid-tmff.o -endif -ifeq ($(CONFIG_HID_FF),y) -$(NEWHID)hid-objs += hid-ff.o -endif - -obj-$(CONFIG_USB_HID) += $(NEWHID)hid.o - -else -ifeq ($(CONFIG_USB_HID),y) -$(error You requested to build hid with configure, but hid is configured as built-in in your kernel config) -endif - -$(error You requested to build hid with configure, but hid is not configured in your kernel config) -endif # CONFIG_USB_HID -endif # WCM_OPTION_HID not - -ifeq ($(WCM_OPTION_WACOM),yes) -ifneq ($(CONFIG_USB_WACOM),y) -wacom-objs := wacom_wac.o wacom_sys.o -obj-m += wacom.o -else -$(error You requested to build wacom with configure, but wacom is configured as built-in in your kernel config) -endif # CONFIG_USB_WACOM -endif # WCM_OPTION_WACOM - -else # We were called from command line -PWD := $(shell pwd) - -WCM_KERNEL_DIR := @WCM_KERNEL_DIR@ -WCM_OPTION_WACOM := @WCM_OPTION_WACOM@ -WCM_OPTION_HID := @WCM_OPTION_HID@ - -export WCM_OPTION_WACOM WCM_OPTION_HID - -COPY_FROM_KERNEL_TREE := hiddev.c hid.h hid-ff.c hid-input.c fixp-arith.h -COPY_FROM_KERNEL_TREE += hid-lgff.c hid-tmff.c pid.c pid.h - -all: -# Copy hid-stuff from kernel-dir to local dir -ifeq ($(WCM_OPTION_HID),yes) - @for i in $(COPY_FROM_KERNEL_TREE); do \ - if test ! -f "$$i" && test -f $(WCM_KERNEL_DIR)/drivers/usb/input/$$i ; then \ - cp $(WCM_KERNEL_DIR)/drivers/usb/input/$$i .; \ - fi; \ - done -endif - -# Copy Wacom specific code which is common to all kernel releases -ifeq ($(WCM_OPTION_WACOM),yes) - cp -f ../2.6.16/wacom_wac.c . - cp -f ../2.6.16/wacom_wac.h . - cp -f ../2.6.16/wacom.h . -endif - @echo ' Building linuxwacom drivers for 2.6 kernel.' - @echo '***Note: Drivers not enabled as modules in your kernel config but requested through configure are NOT built' - $(MAKE) -C $(WCM_KERNEL_DIR) M=$(PWD) - -endif # End kbuild check - -######################### Version independent targets ########################## - -clean: - rm -rf *.o *.ko *.mod.* .[a-z]* core *.i - -# also remove copied stuff -distclean: clean - @for i in $(COPY_FROM_KERNEL_TREE); do \ - if test -f "$$i"; then \ - rm -f $$i ; \ - fi; \ - done - -EMPTY_AUTOMAKE_TARGETS = distdir install install-data install-exec uninstall install-info -EMPTY_AUTOMAKE_TARGETS += installdirs check dvi pdf ps info html tags ctags mostlyclean distclean maintainer-clean -.PHONY: $(EMPTY_AUTOMAKE_TARGETS) - $(EMPTY_AUTOMAKE_TARGETS): diff --git a/src/2.6.15/hid-core.c b/src/2.6.15/hid-core.c deleted file mode 100644 index bf142c3..0000000 --- a/src/2.6.15/hid-core.c +++ /dev/null @@ -1,1932 +0,0 @@ -/* - * USB HID support for Linux - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> - * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc - * - * WARNING: THIS IS NOT PART OF THE OFFICIAL KERNEL TREE - * THIS IS FOR TESTING PURPOSES - * - * v2.6-2.6.15.4-pc-0.1 - initial release based on 2.6.15.4 - * v2.6-2.6.15.4-pc-0.2 - Added DTF521, I3 12x12, and I3 12x19 - * - */ - -/* - * 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. - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/list.h> -#include <linux/mm.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/unaligned.h> -#include <asm/byteorder.h> -#include <linux/input.h> -#include <linux/wait.h> - -#undef DEBUG -#undef DEBUG_DATA - -#include <linux/usb.h> - -#include "hid.h" -#include <linux/hiddev.h> - -/* - * Version Information - */ - -#define DRIVER_VERSION "v2.6.15.4-pc-0.1" -#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik" -#define DRIVER_DESC "USB HID core driver" -#define DRIVER_LICENSE "GPL" - -static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick", - "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"}; -/* - * Module parameters. - */ - -static unsigned int hid_mousepoll_interval; -module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); -MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); - -/* - * Register a new report for a device. - */ - -static struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id) -{ - struct hid_report_enum *report_enum = device->report_enum + type; - struct hid_report *report; - - if (report_enum->report_id_hash[id]) - return report_enum->report_id_hash[id]; - - if (!(report = kmalloc(sizeof(struct hid_report), GFP_KERNEL))) - return NULL; - memset(report, 0, sizeof(struct hid_report)); - - if (id != 0) - report_enum->numbered = 1; - - report->id = id; - report->type = type; - report->size = 0; - report->device = device; - report_enum->report_id_hash[id] = report; - - list_add_tail(&report->list, &report_enum->report_list); - - return report; -} - -/* - * Register a new field for this report. - */ - -static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) -{ - struct hid_field *field; - - if (report->maxfield == HID_MAX_FIELDS) { - dbg("too many fields in report"); - return NULL; - } - - if (!(field = kmalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) - + values * sizeof(unsigned), GFP_KERNEL))) return NULL; - - memset(field, 0, sizeof(struct hid_field) + usages * sizeof(struct hid_usage) - + values * sizeof(unsigned)); - - field->index = report->maxfield++; - report->field[field->index] = field; - field->usage = (struct hid_usage *)(field + 1); - field->value = (unsigned *)(field->usage + usages); - field->report = report; - - return field; -} - -/* - * Open a collection. The type/usage is pushed on the stack. - */ - -static int open_collection(struct hid_parser *parser, unsigned type) -{ - struct hid_collection *collection; - unsigned usage; - - usage = parser->local.usage[0]; - - if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { - dbg("collection stack overflow"); - return -1; - } - - if (parser->device->maxcollection == parser->device->collection_size) { - collection = kmalloc(sizeof(struct hid_collection) * - parser->device->collection_size * 2, GFP_KERNEL); - if (collection == NULL) { - dbg("failed to reallocate collection array"); - return -1; - } - memcpy(collection, parser->device->collection, - sizeof(struct hid_collection) * - parser->device->collection_size); - memset(collection + parser->device->collection_size, 0, - sizeof(struct hid_collection) * - parser->device->collection_size); - kfree(parser->device->collection); - parser->device->collection = collection; - parser->device->collection_size *= 2; - } - - parser->collection_stack[parser->collection_stack_ptr++] = - parser->device->maxcollection; - - collection = parser->device->collection + - parser->device->maxcollection++; - collection->type = type; - collection->usage = usage; - collection->level = parser->collection_stack_ptr - 1; - - if (type == HID_COLLECTION_APPLICATION) - parser->device->maxapplication++; - - return 0; -} - -/* - * Close a collection. - */ - -static int close_collection(struct hid_parser *parser) -{ - if (!parser->collection_stack_ptr) { - dbg("collection stack underflow"); - return -1; - } - parser->collection_stack_ptr--; - return 0; -} - -/* - * Climb up the stack, search for the specified collection type - * and return the usage. - */ - -static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) -{ - int n; - for (n = parser->collection_stack_ptr - 1; n >= 0; n--) - if (parser->device->collection[parser->collection_stack[n]].type == type) - return parser->device->collection[parser->collection_stack[n]].usage; - return 0; /* we know nothing about this usage type */ -} - -/* - * Add a usage to the temporary parser table. - */ - -static int hid_add_usage(struct hid_parser *parser, unsigned usage) -{ - if (parser->local.usage_index >= HID_MAX_USAGES) { - dbg("usage index exceeded"); - return -1; - } - parser->local.usage[parser->local.usage_index] = usage; - parser->local.collection_index[parser->local.usage_index] = - parser->collection_stack_ptr ? - parser->collection_stack[parser->collection_stack_ptr - 1] : 0; - parser->local.usage_index++; - return 0; -} - -/* - * Register a new field for this report. - */ - -static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags) -{ - struct hid_report *report; - struct hid_field *field; - int usages; - unsigned offset; - int i; - - if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { - dbg("hid_register_report failed"); - return -1; - } - - if (parser->global.logical_maximum < parser->global.logical_minimum) { - dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum); - return -1; - } - - offset = report->size; - report->size += parser->global.report_size * parser->global.report_count; - - if (!parser->local.usage_index) /* Ignore padding fields */ - return 0; - - usages = max_t(int, parser->local.usage_index, parser->global.report_count); - - if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL) - return 0; - - field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); - field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL); - field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); - - for (i = 0; i < usages; i++) { - int j = i; - /* Duplicate the last usage we parsed if we have excess values */ - if (i >= parser->local.usage_index) - j = parser->local.usage_index - 1; - field->usage[i].hid = parser->local.usage[j]; - field->usage[i].collection_index = - parser->local.collection_index[j]; - } - - field->maxusage = usages; - field->flags = flags; - field->report_offset = offset; - field->report_type = report_type; - field->report_size = parser->global.report_size; - field->report_count = parser->global.report_count; - field->logical_minimum = parser->global.logical_minimum; - field->logical_maximum = parser->global.logical_maximum; - field->physical_minimum = parser->global.physical_minimum; - field->physical_maximum = parser->global.physical_maximum; - field->unit_exponent = parser->global.unit_exponent; - field->unit = parser->global.unit; - - return 0; -} - -/* - * Read data value from item. - */ - -static __inline__ __u32 item_udata(struct hid_item *item) -{ - switch (item->size) { - case 1: return item->data.u8; - case 2: return item->data.u16; - case 4: return item->data.u32; - } - return 0; -} - -static __inline__ __s32 item_sdata(struct hid_item *item) -{ - switch (item->size) { - case 1: return item->data.s8; - case 2: return item->data.s16; - case 4: return item->data.s32; - } - return 0; -} - -/* - * Process a global item. - */ - -static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) -{ - switch (item->tag) { - - case HID_GLOBAL_ITEM_TAG_PUSH: - - if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { - dbg("global enviroment stack overflow"); - return -1; - } - - memcpy(parser->global_stack + parser->global_stack_ptr++, - &parser->global, sizeof(struct hid_global)); - return 0; - - case HID_GLOBAL_ITEM_TAG_POP: - - if (!parser->global_stack_ptr) { - dbg("global enviroment stack underflow"); - return -1; - } - - memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr, - sizeof(struct hid_global)); - return 0; - - case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: - parser->global.usage_page = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: - parser->global.logical_minimum = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: - if (parser->global.logical_minimum < 0) - parser->global.logical_maximum = item_sdata(item); - else - parser->global.logical_maximum = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: - parser->global.physical_minimum = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: - if (parser->global.physical_minimum < 0) - parser->global.physical_maximum = item_sdata(item); - else - parser->global.physical_maximum = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: - parser->global.unit_exponent = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_UNIT: - parser->global.unit = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: - if ((parser->global.report_size = item_udata(item)) > 32) { - dbg("invalid report_size %d", parser->global.report_size); - return -1; - } - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: - if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) { - dbg("invalid report_count %d", parser->global.report_count); - return -1; - } - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_ID: - if ((parser->global.report_id = item_udata(item)) == 0) { - dbg("report_id 0 is invalid"); - return -1; - } - return 0; - - default: - dbg("unknown global tag 0x%x", item->tag); - return -1; - } -} - -/* - * Process a local item. - */ - -static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) -{ - __u32 data; - unsigned n; - - if (item->size == 0) { - dbg("item data expected for local item"); - return -1; - } - - data = item_udata(item); - - switch (item->tag) { - - case HID_LOCAL_ITEM_TAG_DELIMITER: - - if (data) { - /* - * We treat items before the first delimiter - * as global to all usage sets (branch 0). - * In the moment we process only these global - * items and the first delimiter set. - */ - if (parser->local.delimiter_depth != 0) { - dbg("nested delimiters"); - return -1; - } - parser->local.delimiter_depth++; - parser->local.delimiter_branch++; - } else { - if (parser->local.delimiter_depth < 1) { - dbg("bogus close delimiter"); - return -1; - } - parser->local.delimiter_depth--; - } - return 1; - - case HID_LOCAL_ITEM_TAG_USAGE: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - return hid_add_usage(parser, data); - - case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - parser->local.usage_minimum = data; - return 0; - - case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - for (n = parser->local.usage_minimum; n <= data; n++) - if (hid_add_usage(parser, n)) { - dbg("hid_add_usage failed\n"); - return -1; - } - return 0; - - default: - - dbg("unknown local item tag 0x%x", item->tag); - return 0; - } - return 0; -} - -/* - * Process a main item. - */ - -static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) -{ - __u32 data; - int ret; - - data = item_udata(item); - - switch (item->tag) { - case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: - ret = open_collection(parser, data & 0xff); - break; - case HID_MAIN_ITEM_TAG_END_COLLECTION: - ret = close_collection(parser); - break; - case HID_MAIN_ITEM_TAG_INPUT: - ret = hid_add_field(parser, HID_INPUT_REPORT, data); - break; - case HID_MAIN_ITEM_TAG_OUTPUT: - ret = hid_add_field(parser, HID_OUTPUT_REPORT, data); - break; - case HID_MAIN_ITEM_TAG_FEATURE: - ret = hid_add_field(parser, HID_FEATURE_REPORT, data); - break; - default: - dbg("unknown main item tag 0x%x", item->tag); - ret = 0; - } - - memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */ - - return ret; -} - -/* - * Process a reserved item. - */ - -static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) -{ - dbg("reserved item type, tag 0x%x", item->tag); - return 0; -} - -/* - * Free a report and all registered fields. The field->usage and - * field->value table's are allocated behind the field, so we need - * only to free(field) itself. - */ - -static void hid_free_report(struct hid_report *report) -{ - unsigned n; - - for (n = 0; n < report->maxfield; n++) - kfree(report->field[n]); - kfree(report); -} - -/* - * Free a device structure, all reports, and all fields. - */ - -static void hid_free_device(struct hid_device *device) -{ - unsigned i,j; - - hid_ff_exit(device); - - for (i = 0; i < HID_REPORT_TYPES; i++) { - struct hid_report_enum *report_enum = device->report_enum + i; - - for (j = 0; j < 256; j++) { - struct hid_report *report = report_enum->report_id_hash[j]; - if (report) - hid_free_report(report); - } - } - - kfree(device->rdesc); - kfree(device); -} - -/* - * Fetch a report description item from the data stream. We support long - * items, though they are not used yet. - */ - -static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) -{ - u8 b; - - if ((end - start) <= 0) - return NULL; - - b = *start++; - - item->type = (b >> 2) & 3; - item->tag = (b >> 4) & 15; - - if (item->tag == HID_ITEM_TAG_LONG) { - - item->format = HID_ITEM_FORMAT_LONG; - - if ((end - start) < 2) - return NULL; - - item->size = *start++; - item->tag = *start++; - - if ((end - start) < item->size) - return NULL; - - item->data.longdata = start; - start += item->size; - return start; - } - - item->format = HID_ITEM_FORMAT_SHORT; - item->size = b & 3; - - switch (item->size) { - - case 0: - return start; - - case 1: - if ((end - start) < 1) - return NULL; - item->data.u8 = *start++; - return start; - - case 2: - if ((end - start) < 2) - return NULL; - item->data.u16 = le16_to_cpu(get_unaligned((__le16*)start)); - start = (__u8 *)((__le16 *)start + 1); - return start; - - case 3: - item->size++; - if ((end - start) < 4) - return NULL; - item->data.u32 = le32_to_cpu(get_unaligned((__le32*)start)); - start = (__u8 *)((__le32 *)start + 1); - return start; - } - - return NULL; -} - -/* - * Parse a report description into a hid_device structure. Reports are - * enumerated, fields are attached to these reports. - */ - -static struct hid_device *hid_parse_report(__u8 *start, unsigned size) -{ - struct hid_device *device; - struct hid_parser *parser; - struct hid_item item; - __u8 *end; - unsigned i; - static int (*dispatch_type[])(struct hid_parser *parser, - struct hid_item *item) = { - hid_parser_main, - hid_parser_global, - hid_parser_local, - hid_parser_reserved - }; - - if (!(device = kmalloc(sizeof(struct hid_device), GFP_KERNEL))) - return NULL; - memset(device, 0, sizeof(struct hid_device)); - - if (!(device->collection = kmalloc(sizeof(struct hid_collection) * - HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) { - kfree(device); - return NULL; - } - memset(device->collection, 0, sizeof(struct hid_collection) * - HID_DEFAULT_NUM_COLLECTIONS); - device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; - - for (i = 0; i < HID_REPORT_TYPES; i++) - INIT_LIST_HEAD(&device->report_enum[i].report_list); - - if (!(device->rdesc = (__u8 *)kmalloc(size, GFP_KERNEL))) { - kfree(device->collection); - kfree(device); - return NULL; - } - memcpy(device->rdesc, start, size); - device->rsize = size; - - if (!(parser = kmalloc(sizeof(struct hid_parser), GFP_KERNEL))) { - kfree(device->rdesc); - kfree(device->collection); - kfree(device); - return NULL; - } - memset(parser, 0, sizeof(struct hid_parser)); - parser->device = device; - - end = start + size; - while ((start = fetch_item(start, end, &item)) != NULL) { - - if (item.format != HID_ITEM_FORMAT_SHORT) { - dbg("unexpected long global item"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - - if (dispatch_type[item.type](parser, &item)) { - dbg("item %u %u %u %u parsing failed\n", - item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - - if (start == end) { - if (parser->collection_stack_ptr) { - dbg("unbalanced collection at end of report description"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - if (parser->local.delimiter_depth) { - dbg("unbalanced delimiter at end of report description"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - kfree(parser); - return device; - } - } - - dbg("item fetching failed at offset %d\n", (int)(end - start)); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; -} - -/* - * Convert a signed n-bit integer to signed 32-bit integer. Common - * cases are done through the compiler, the screwed things has to be - * done by hand. - */ - -static __inline__ __s32 snto32(__u32 value, unsigned n) -{ - switch (n) { - case 8: return ((__s8)value); - case 16: return ((__s16)value); - case 32: return ((__s32)value); - } - return value & (1 << (n - 1)) ? value | (-1 << n) : value; -} - -/* - * Convert a signed 32-bit integer to a signed n-bit integer. - */ - -static __inline__ __u32 s32ton(__s32 value, unsigned n) -{ - __s32 a = value >> (n - 1); - if (a && a != -1) - return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; - return value & ((1 << n) - 1); -} - -/* - * Extract/implement a data field from/to a report. - */ - -static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) -{ - report += (offset >> 5) << 2; offset &= 31; - return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1ULL << n) - 1); -} - -static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) -{ - report += (offset >> 5) << 2; offset &= 31; - put_unaligned((get_unaligned((__le64*)report) - & cpu_to_le64(~((((__u64) 1 << n) - 1) << offset))) - | cpu_to_le64((__u64)value << offset), (__le64*)report); -} - -/* - * Search an array for a value. - */ - -static __inline__ int search(__s32 *array, __s32 value, unsigned n) -{ - while (n--) { - if (*array++ == value) - return 0; - } - return -1; -} - -static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt, struct pt_regs *regs) -{ - hid_dump_input(usage, value); - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_hid_event(hid, field, usage, value, regs); - if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt) - hiddev_hid_event(hid, field, usage, value, regs); -} - -/* - * Analyse a received field, and fetch the data from it. The field - * content is stored for next report processing (we do differential - * reporting to the layer). - */ - -static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt, struct pt_regs *regs) -{ - unsigned n; - unsigned count = field->report_count; - unsigned offset = field->report_offset; - unsigned size = field->report_size; - __s32 min = field->logical_minimum; - __s32 max = field->logical_maximum; - __s32 *value; - - if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC))) - return; - - for (n = 0; n < count; n++) { - - value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : - extract(data, offset + n * size, size); - - if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */ - && value[n] >= min && value[n] <= max - && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) - goto exit; - } - - for (n = 0; n < count; n++) { - - if (HID_MAIN_ITEM_VARIABLE & field->flags) { - hid_process_event(hid, field, &field->usage[n], value[n], interrupt, regs); - continue; - } - - if (field->value[n] >= min && field->value[n] <= max - && field->usage[field->value[n] - min].hid - && search(value, field->value[n], count)) - hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt, regs); - - if (value[n] >= min && value[n] <= max - && field->usage[value[n] - min].hid - && search(field->value, value[n], count)) - hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt, regs); - } - - memcpy(field->value, value, count * sizeof(__s32)); -exit: - kfree(value); -} - -static int hid_input_report(int type, struct urb *urb, int interrupt, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - struct hid_report_enum *report_enum = hid->report_enum + type; - u8 *data = urb->transfer_buffer; - int len = urb->actual_length; - struct hid_report *report; - int n, size; - - if (!len) { - dbg("empty report"); - return -1; - } - -#ifdef DEBUG_DATA - printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", len, report_enum->numbered ? "" : "un"); -#endif - - n = 0; /* Normally report number is 0 */ - if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */ - n = *data++; - len--; - } - -#ifdef DEBUG_DATA - { - int i; - printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, len); - for (i = 0; i < len; i++) - printk(" %02x", data[i]); - printk("\n"); - } -#endif - - if (!(report = report_enum->report_id_hash[n])) { - dbg("undefined report_id %d received", n); - return -1; - } - - size = ((report->size - 1) >> 3) + 1; - - if (len < size) { - dbg("report %d is too short, (%d < %d)", report->id, len, size); - memset(data + len, 0, size - len); - } - - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_report_event(hid, report); - - for (n = 0; n < report->maxfield; n++) - hid_input_field(hid, report->field[n], data, interrupt, regs); - - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_report_event(hid, report); - - return 0; -} - -/* - * Input interrupt completion handler. - */ - -static void hid_irq_in(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - int status; - - switch (urb->status) { - case 0: /* success */ - hid_input_report(HID_INPUT_REPORT, urb, 1, regs); - break; - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -EPERM: - case -ESHUTDOWN: /* unplug */ - case -EILSEQ: /* unplug timeout on uhci */ - return; - case -ETIMEDOUT: /* NAK */ - break; - default: /* error */ - warn("input irq status %d received", urb->status); - } - - status = usb_submit_urb(urb, SLAB_ATOMIC); - if (status) - err("can't resubmit intr, %s-%s/input%d, status %d", - hid->dev->bus->bus_name, hid->dev->devpath, - hid->ifnum, status); -} - -/* - * Output the field into the report. - */ - -static void hid_output_field(struct hid_field *field, __u8 *data) -{ - unsigned count = field->report_count; - unsigned offset = field->report_offset; - unsigned size = field->report_size; - unsigned n; - - for (n = 0; n < count; n++) { - if (field->logical_minimum < 0) /* signed values */ - implement(data, offset + n * size, size, s32ton(field->value[n], size)); - else /* unsigned values */ - implement(data, offset + n * size, size, field->value[n]); - } -} - -/* - * Create a report. - */ - -static void hid_output_report(struct hid_report *report, __u8 *data) -{ - unsigned n; - - if (report->id > 0) - *data++ = report->id; - - for (n = 0; n < report->maxfield; n++) - hid_output_field(report->field[n], data); -} - -/* - * Set a field value. The report this field belongs to has to be - * created and transferred to the device, to set this value in the - * device. - */ - -int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) -{ - unsigned size = field->report_size; - - hid_dump_input(field->usage + offset, value); - - if (offset >= field->report_count) { - dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count); - hid_dump_field(field, 8); - return -1; - } - if (field->logical_minimum < 0) { - if (value != snto32(s32ton(value, size), size)) { - dbg("value %d is out of range", value); - return -1; - } - } - field->value[offset] = value; - return 0; -} - -/* - * Find a report field with a specified HID usage. - */ - -struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_usage, int type) -{ - struct hid_report *report; - int i; - - list_for_each_entry(report, &hid->report_enum[type].report_list, list) - for (i = 0; i < report->maxfield; i++) - if (report->field[i]->logical == wanted_usage) - return report->field[i]; - return NULL; -} - -static int hid_submit_out(struct hid_device *hid) -{ - struct hid_report *report; - - report = hid->out[hid->outtail]; - - hid_output_report(report, hid->outbuf); - hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); - hid->urbout->dev = hid->dev; - - dbg("submitting out urb"); - - if (usb_submit_urb(hid->urbout, GFP_ATOMIC)) { - err("usb_submit_urb(out) failed"); - return -1; - } - - return 0; -} - -static int hid_submit_ctrl(struct hid_device *hid) -{ - struct hid_report *report; - unsigned char dir; - int len; - - report = hid->ctrl[hid->ctrltail].report; - dir = hid->ctrl[hid->ctrltail].dir; - - len = ((report->size - 1) >> 3) + 1 + (report->id > 0); - if (dir == USB_DIR_OUT) { - hid_output_report(report, hid->ctrlbuf); - hid->urbctrl->pipe = usb_sndctrlpipe(hid->dev, 0); - hid->urbctrl->transfer_buffer_length = len; - } else { - int maxpacket, padlen; - - hid->urbctrl->pipe = usb_rcvctrlpipe(hid->dev, 0); - maxpacket = usb_maxpacket(hid->dev, hid->urbctrl->pipe, 0); - if (maxpacket > 0) { - padlen = (len + maxpacket - 1) / maxpacket; - padlen *= maxpacket; - if (padlen > hid->bufsize) - padlen = hid->bufsize; - } else - padlen = 0; - hid->urbctrl->transfer_buffer_length = padlen; - } - hid->urbctrl->dev = hid->dev; - - hid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; - hid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; - hid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id); - hid->cr->wIndex = cpu_to_le16(hid->ifnum); - hid->cr->wLength = cpu_to_le16(len); - - dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u", - hid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", - hid->cr->wValue, hid->cr->wIndex, hid->cr->wLength); - - if (usb_submit_urb(hid->urbctrl, GFP_ATOMIC)) { - err("usb_submit_urb(ctrl) failed"); - return -1; - } - - return 0; -} - -/* - * Output interrupt completion handler. - */ - -static void hid_irq_out(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - unsigned long flags; - int unplug = 0; - - switch (urb->status) { - case 0: /* success */ - break; - case -ESHUTDOWN: /* unplug */ - case -EILSEQ: /* unplug timeout on uhci */ - unplug = 1; - case -ECONNRESET: /* unlink */ - case -ENOENT: - break; - default: /* error */ - warn("output irq status %d received", urb->status); - } - - spin_lock_irqsave(&hid->outlock, flags); - - if (unplug) - hid->outtail = hid->outhead; - else - hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); - - if (hid->outhead != hid->outtail) { - if (hid_submit_out(hid)) { - clear_bit(HID_OUT_RUNNING, &hid->iofl);; - wake_up(&hid->wait); - } - spin_unlock_irqrestore(&hid->outlock, flags); - return; - } - - clear_bit(HID_OUT_RUNNING, &hid->iofl); - spin_unlock_irqrestore(&hid->outlock, flags); - wake_up(&hid->wait); -} - -/* - * Control pipe completion handler. - */ - -static void hid_ctrl(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - unsigned long flags; - int unplug = 0; - - spin_lock_irqsave(&hid->ctrllock, flags); - - switch (urb->status) { - case 0: /* success */ - if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) - hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs); - break; - case -ESHUTDOWN: /* unplug */ - case -EILSEQ: /* unplug timectrl on uhci */ - unplug = 1; - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -EPIPE: /* report not available */ - break; - default: /* error */ - warn("ctrl urb status %d received", urb->status); - } - - if (unplug) - hid->ctrltail = hid->ctrlhead; - else - hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); - - if (hid->ctrlhead != hid->ctrltail) { - if (hid_submit_ctrl(hid)) { - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - wake_up(&hid->wait); - } - spin_unlock_irqrestore(&hid->ctrllock, flags); - return; - } - - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - spin_unlock_irqrestore(&hid->ctrllock, flags); - wake_up(&hid->wait); -} - -void hid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) -{ - int head; - unsigned long flags; - - if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) - return; - - if (hid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { - - spin_lock_irqsave(&hid->outlock, flags); - - if ((head = (hid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == hid->outtail) { - spin_unlock_irqrestore(&hid->outlock, flags); - warn("output queue full"); - return; - } - - hid->out[hid->outhead] = report; - hid->outhead = head; - - if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl)) - if (hid_submit_out(hid)) - clear_bit(HID_OUT_RUNNING, &hid->iofl); - - spin_unlock_irqrestore(&hid->outlock, flags); - return; - } - - spin_lock_irqsave(&hid->ctrllock, flags); - - if ((head = (hid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == hid->ctrltail) { - spin_unlock_irqrestore(&hid->ctrllock, flags); - warn("control queue full"); - return; - } - - hid->ctrl[hid->ctrlhead].report = report; - hid->ctrl[hid->ctrlhead].dir = dir; - hid->ctrlhead = head; - - if (!test_and_set_bit(HID_CTRL_RUNNING, &hid->iofl)) - if (hid_submit_ctrl(hid)) - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - - spin_unlock_irqrestore(&hid->ctrllock, flags); -} - -int hid_wait_io(struct hid_device *hid) -{ - if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &hid->iofl) && - !test_bit(HID_OUT_RUNNING, &hid->iofl)), - 10*HZ)) { - dbg("timeout waiting for ctrl or out queue to clear"); - return -1; - } - - return 0; -} - -static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle) -{ - return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (idle << 8) | report, - ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT); -} - -static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, - unsigned char type, void *buf, int size) -{ - int result, retries = 4; - - memset(buf,0,size); // Make sure we parse really received data - - do { - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, - (type << 8), ifnum, buf, size, USB_CTRL_GET_TIMEOUT); - retries--; - } while (result < size && retries); - return result; -} - -int hid_open(struct hid_device *hid) -{ - if (hid->open++) - return 0; - - hid->urbin->dev = hid->dev; - - if (usb_submit_urb(hid->urbin, GFP_KERNEL)) - return -EIO; - - return 0; -} - -void hid_close(struct hid_device *hid) -{ - if (!--hid->open) - usb_kill_urb(hid->urbin); -} - -/* - * Initialize all reports - */ - -void hid_init_reports(struct hid_device *hid) -{ - struct hid_report *report; - int err, ret; - - list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) - hid_submit_report(hid, report, USB_DIR_IN); - - list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) - hid_submit_report(hid, report, USB_DIR_IN); - - err = 0; - ret = hid_wait_io(hid); - while (ret) { - err |= ret; - if (test_bit(HID_CTRL_RUNNING, &hid->iofl)) - usb_kill_urb(hid->urbctrl); - if (test_bit(HID_OUT_RUNNING, &hid->iofl)) - usb_kill_urb(hid->urbout); - ret = hid_wait_io(hid); - } - - if (err) - warn("timeout initializing reports\n"); -} - -#define USB_VENDOR_ID_WACOM 0x056a - -#define USB_VENDOR_ID_ACECAD 0x0460 -#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 -#define USB_DEVICE_ID_ACECAD_302 0x0008 - -#define USB_VENDOR_ID_KBGEAR 0x084e -#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 - -#define USB_VENDOR_ID_AIPTEK 0x08ca -#define USB_DEVICE_ID_AIPTEK_01 0x0001 -#define USB_DEVICE_ID_AIPTEK_10 0x0010 -#define USB_DEVICE_ID_AIPTEK_20 0x0020 -#define USB_DEVICE_ID_AIPTEK_21 0x0021 -#define USB_DEVICE_ID_AIPTEK_22 0x0022 -#define USB_DEVICE_ID_AIPTEK_23 0x0023 -#define USB_DEVICE_ID_AIPTEK_24 0x0024 - -#define USB_VENDOR_ID_GRIFFIN 0x077d -#define USB_DEVICE_ID_POWERMATE 0x0410 -#define USB_DEVICE_ID_SOUNDKNOB 0x04AA - -#define USB_VENDOR_ID_ATEN 0x0557 -#define USB_DEVICE_ID_ATEN_UC100KM 0x2004 -#define USB_DEVICE_ID_ATEN_CS124U 0x2202 -#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204 -#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 -#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 - -#define USB_VENDOR_ID_TOPMAX 0x0663 -#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 - -#define USB_VENDOR_ID_HAPP 0x078b -#define USB_DEVICE_ID_UGCI_DRIVING 0x0010 -#define USB_DEVICE_ID_UGCI_FLYING 0x0020 -#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 - -#define USB_VENDOR_ID_MGE 0x0463 -#define USB_DEVICE_ID_MGE_UPS 0xffff -#define USB_DEVICE_ID_MGE_UPS1 0x0001 - -#define USB_VENDOR_ID_ONTRAK 0x0a07 -#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 - -#define USB_VENDOR_ID_TANGTOP 0x0d3d -#define USB_DEVICE_ID_TANGTOP_USBPS2 0x0001 - -#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f -#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 - -#define USB_VENDOR_ID_A4TECH 0x09da -#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 - -#define USB_VENDOR_ID_AASHIMA 0x06d6 -#define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 -#define USB_DEVICE_ID_AASHIMA_PREDATOR 0x0026 - -#define USB_VENDOR_ID_CYPRESS 0x04b4 -#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 -#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 -#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417 - -#define USB_VENDOR_ID_BERKSHIRE 0x0c98 -#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 - -#define USB_VENDOR_ID_ALPS 0x0433 -#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 - -#define USB_VENDOR_ID_SAITEK 0x06a3 -#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 - -#define USB_VENDOR_ID_NEC 0x073e -#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 - -#define USB_VENDOR_ID_CHIC 0x05fe -#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014 - -#define USB_VENDOR_ID_GLAB 0x06c2 -#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 -#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 -#define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045 -#define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040 -#define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053 - -#define USB_VENDOR_ID_WISEGROUP 0x0925 -#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 -#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 - -#define USB_VENDOR_ID_CODEMERCS 0x07c0 -#define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500 -#define USB_DEVICE_ID_CODEMERCS_IOW24 0x1501 -#define USB_DEVICE_ID_CODEMERCS_IOW48 0x1502 -#define USB_DEVICE_ID_CODEMERCS_IOW28 0x1503 - -#define USB_VENDOR_ID_DELORME 0x1163 -#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 -#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 - -#define USB_VENDOR_ID_MCC 0x09db -#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 -#define USB_DEVICE_ID_MCC_PMD1208LS 0x007a - -#define USB_VENDOR_ID_CHICONY 0x04f2 -#define USB_DEVICE_ID_CHICONY_USBHUB_KB 0x0100 - -#define USB_VENDOR_ID_BTC 0x046e -#define USB_DEVICE_ID_BTC_KEYBOARD 0x5303 - -#define USB_VENDOR_ID_VERNIER 0x08f7 -#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 -#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 -#define USB_DEVICE_ID_VERNIER_SKIP 0x0003 -#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 - -#define USB_VENDOR_ID_LD 0x0f11 -#define USB_DEVICE_ID_CASSY 0x1000 -#define USB_DEVICE_ID_POCKETCASSY 0x1010 -#define USB_DEVICE_ID_MOBILECASSY 0x1020 -#define USB_DEVICE_ID_JWM 0x1080 -#define USB_DEVICE_ID_DMMP 0x1081 -#define USB_DEVICE_ID_UMIP 0x1090 -#define USB_DEVICE_ID_VIDEOCOM 0x1200 -#define USB_DEVICE_ID_COM3LAB 0x2000 -#define USB_DEVICE_ID_TELEPORT 0x2010 -#define USB_DEVICE_ID_NETWORKANALYSER 0x2020 -#define USB_DEVICE_ID_POWERCONTROL 0x2030 - -#define USB_VENDOR_ID_APPLE 0x05ac -#define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304 - -/* - * Alphabetically sorted blacklist by quirk type. - */ - -static struct hid_blacklist { - __u16 idVendor; - __u16 idProduct; - unsigned quirks; -} hid_blacklist[] = { - - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW48, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_CASSY, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_POCKETCASSY, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_MOBILECASSY, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_JWM, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_DMMP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_UMIP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_VIDEOCOM, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_COM3LAB, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_TELEPORT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_NETWORKANALYSER, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_POWERCONTROL, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_KEYBOARD, HID_QUIRK_NOGET}, - { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET}, - { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, - - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE }, - { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, - - { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, - - { 0, 0 } -}; - -/* - * Traverse the supplied list of reports and find the longest - */ -static void hid_find_max_report(struct hid_device *hid, unsigned int type, int *max) -{ - struct hid_report *report; - int size; - - list_for_each_entry(report, &hid->report_enum[type].report_list, list) { - size = ((report->size - 1) >> 3) + 1; - if (type == HID_INPUT_REPORT && hid->report_enum[type].numbered) - size++; - if (*max < size) - *max = size; - } -} - -static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) -{ - if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->inbuf_dma))) - return -1; - if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->outbuf_dma))) - return -1; - if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma))) - return -1; - if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->ctrlbuf_dma))) - return -1; - - return 0; -} - -static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) -{ - if (hid->inbuf) - usb_buffer_free(dev, hid->bufsize, hid->inbuf, hid->inbuf_dma); - if (hid->outbuf) - usb_buffer_free(dev, hid->bufsize, hid->outbuf, hid->outbuf_dma); - if (hid->cr) - usb_buffer_free(dev, sizeof(*(hid->cr)), hid->cr, hid->cr_dma); - if (hid->ctrlbuf) - usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma); -} - -static struct hid_device *usb_hid_configure(struct usb_interface *intf) -{ - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_device *dev = interface_to_usbdev (intf); - struct hid_descriptor *hdesc; - struct hid_device *hid; - unsigned quirks = 0, rsize = 0; - char *rdesc; - int n, len, insize = 0; - - /* ignore all Wacom devices */ - if (dev->descriptor.idVendor == USB_VENDOR_ID_WACOM) - return NULL; - - for (n = 0; hid_blacklist[n].idVendor; n++) - if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) && - (hid_blacklist[n].idProduct == le16_to_cpu(dev->descriptor.idProduct))) - quirks = hid_blacklist[n].quirks; - - if (quirks & HID_QUIRK_IGNORE) - return NULL; - - if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && - (!interface->desc.bNumEndpoints || - usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { - dbg("class descriptor not present\n"); - return NULL; - } - - for (n = 0; n < hdesc->bNumDescriptors; n++) - if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) - rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); - - if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { - dbg("weird size of report descriptor (%u)", rsize); - return NULL; - } - - if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) { - dbg("couldn't allocate rdesc memory"); - return NULL; - } - - hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0); - - if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { - dbg("reading report descriptor failed"); - kfree(rdesc); - return NULL; - } - -#ifdef DEBUG_DATA - printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); - for (n = 0; n < rsize; n++) - printk(" %02x", (unsigned char) rdesc[n]); - printk("\n"); -#endif - - if (!(hid = hid_parse_report(rdesc, n))) { - dbg("parsing report descriptor failed"); - kfree(rdesc); - return NULL; - } - - kfree(rdesc); - hid->quirks = quirks; - - hid->bufsize = HID_MIN_BUFFER_SIZE; - hid_find_max_report(hid, HID_INPUT_REPORT, &hid->bufsize); - hid_find_max_report(hid, HID_OUTPUT_REPORT, &hid->bufsize); - hid_find_max_report(hid, HID_FEATURE_REPORT, &hid->bufsize); - - if (hid->bufsize > HID_MAX_BUFFER_SIZE) - hid->bufsize = HID_MAX_BUFFER_SIZE; - - hid_find_max_report(hid, HID_INPUT_REPORT, &insize); - - if (insize > HID_MAX_BUFFER_SIZE) - insize = HID_MAX_BUFFER_SIZE; - - if (hid_alloc_buffers(dev, hid)) { - hid_free_buffers(dev, hid); - goto fail; - } - - for (n = 0; n < interface->desc.bNumEndpoints; n++) { - - struct usb_endpoint_descriptor *endpoint; - int pipe; - int interval; - - endpoint = &interface->endpoint[n].desc; - if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */ - continue; - - interval = endpoint->bInterval; - - /* Change the polling interval of mice. */ - if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) - interval = hid_mousepoll_interval; - - if (endpoint->bEndpointAddress & USB_DIR_IN) { - if (hid->urbin) - continue; - if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) - goto fail; - pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); - usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, insize, - hid_irq_in, hid, interval); - hid->urbin->transfer_dma = hid->inbuf_dma; - hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - } else { - if (hid->urbout) - continue; - if (!(hid->urbout = usb_alloc_urb(0, GFP_KERNEL))) - goto fail; - pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress); - usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0, - hid_irq_out, hid, interval); - hid->urbout->transfer_dma = hid->outbuf_dma; - hid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - } - } - - if (!hid->urbin) { - err("couldn't find an input interrupt endpoint"); - goto fail; - } - - init_waitqueue_head(&hid->wait); - - spin_lock_init(&hid->outlock); - spin_lock_init(&hid->ctrllock); - - hid->version = le16_to_cpu(hdesc->bcdHID); - hid->country = hdesc->bCountryCode; - hid->dev = dev; - hid->intf = intf; - hid->ifnum = interface->desc.bInterfaceNumber; - - hid->name[0] = 0; - - if (dev->manufacturer) - strlcpy(hid->name, dev->manufacturer, sizeof(hid->name)); - - if (dev->product) { - if (dev->manufacturer) - strlcat(hid->name, " ", sizeof(hid->name)); - strlcat(hid->name, dev->product, sizeof(hid->name)); - } - - if (!strlen(hid->name)) - snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x", - le16_to_cpu(dev->descriptor.idVendor), - le16_to_cpu(dev->descriptor.idProduct)); - - usb_make_path(dev, hid->phys, sizeof(hid->phys)); - strlcat(hid->phys, "/input", sizeof(hid->phys)); - len = strlen(hid->phys); - if (len < sizeof(hid->phys) - 1) - snprintf(hid->phys + len, sizeof(hid->phys) - len, - "%d", intf->altsetting[0].desc.bInterfaceNumber); - - if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) - hid->uniq[0] = 0; - - hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); - if (!hid->urbctrl) - goto fail; - - usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr, - hid->ctrlbuf, 1, hid_ctrl, hid); - hid->urbctrl->setup_dma = hid->cr_dma; - hid->urbctrl->transfer_dma = hid->ctrlbuf_dma; - hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); - - /* May be needed for some devices */ - usb_clear_halt(hid->dev, hid->urbin->pipe); - - return hid; - -fail: - - if (hid->urbin) - usb_free_urb(hid->urbin); - if (hid->urbout) - usb_free_urb(hid->urbout); - if (hid->urbctrl) - usb_free_urb(hid->urbctrl); - hid_free_buffers(dev, hid); - hid_free_device(hid); - - return NULL; -} - -static void hid_disconnect(struct usb_interface *intf) -{ - struct hid_device *hid = usb_get_intfdata (intf); - - if (!hid) - return; - - usb_set_intfdata(intf, NULL); - usb_kill_urb(hid->urbin); - usb_kill_urb(hid->urbout); - usb_kill_urb(hid->urbctrl); - - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_disconnect(hid); - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_disconnect(hid); - - usb_free_urb(hid->urbin); - usb_free_urb(hid->urbctrl); - if (hid->urbout) - usb_free_urb(hid->urbout); - - hid_free_buffers(hid->dev, hid); - hid_free_device(hid); -} - -static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct hid_device *hid; - char path[64]; - int i; - char *c; - - dbg("HID probe called for ifnum %d", - intf->altsetting->desc.bInterfaceNumber); - - if (!(hid = usb_hid_configure(intf))) - return -ENODEV; - - hid_init_reports(hid); - hid_dump_device(hid); - - if (!hidinput_connect(hid)) - hid->claimed |= HID_CLAIMED_INPUT; - if (!hiddev_connect(hid)) - hid->claimed |= HID_CLAIMED_HIDDEV; - - usb_set_intfdata(intf, hid); - - if (!hid->claimed) { - printk ("HID device not claimed by input or hiddev\n"); - hid_disconnect(intf); - return -ENODEV; - } - - printk(KERN_INFO); - - if (hid->claimed & HID_CLAIMED_INPUT) - printk("input"); - if (hid->claimed == (HID_CLAIMED_INPUT | HID_CLAIMED_HIDDEV)) - printk(","); - if (hid->claimed & HID_CLAIMED_HIDDEV) - printk("hiddev%d", hid->minor); - - c = "Device"; - for (i = 0; i < hid->maxcollection; i++) { - if (hid->collection[i].type == HID_COLLECTION_APPLICATION && - (hid->collection[i].usage & HID_USAGE_PAGE) == HID_UP_GENDESK && - (hid->collection[i].usage & 0xffff) < ARRAY_SIZE(hid_types)) { - c = hid_types[hid->collection[i].usage & 0xffff]; - break; - } - } - - usb_make_path(interface_to_usbdev(intf), path, 63); - - printk(": USB HID v%x.%02x %s [%s] on %s\n", - hid->version >> 8, hid->version & 0xff, c, hid->name, path); - - return 0; -} - -static int hid_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct hid_device *hid = usb_get_intfdata (intf); - - usb_kill_urb(hid->urbin); - dev_dbg(&intf->dev, "suspend\n"); - return 0; -} - -static int hid_resume(struct usb_interface *intf) -{ - struct hid_device *hid = usb_get_intfdata (intf); - int status; - - if (hid->open) - status = usb_submit_urb(hid->urbin, GFP_NOIO); - else - status = 0; - dev_dbg(&intf->dev, "resume status %d\n", status); - return status; -} - -static struct usb_device_id hid_usb_ids [] = { - { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, - .bInterfaceClass = USB_INTERFACE_CLASS_HID }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE (usb, hid_usb_ids); - -static struct usb_driver hid_driver = { - .owner = THIS_MODULE, - .name = "usbhid", - .probe = hid_probe, - .disconnect = hid_disconnect, - .suspend = hid_suspend, - .resume = hid_resume, - .id_table = hid_usb_ids, -}; - -static int __init hid_init(void) -{ - int retval; - retval = hiddev_init(); - if (retval) - goto hiddev_init_fail; - retval = usb_register(&hid_driver); - if (retval) - goto usb_register_fail; - info(DRIVER_VERSION ":" DRIVER_DESC); - - return 0; -usb_register_fail: - hiddev_exit(); -hiddev_init_fail: - return retval; -} - -static void __exit hid_exit(void) -{ - usb_deregister(&hid_driver); - hiddev_exit(); -} - -module_init(hid_init); -module_exit(hid_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); diff --git a/src/2.6.15/wacom_sys.c b/src/2.6.15/wacom_sys.c deleted file mode 100755 index 64f45ef..0000000 --- a/src/2.6.15/wacom_sys.c +++ /dev/null @@ -1,506 +0,0 @@ -/* - * drivers/usb/input/wacom_sys.c - * - * USB Wacom Graphire and Wacom Intuos tablet support - system specific code - */ - -/* - * 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. - */ - -#include "wacom.h" -#include "wacom_wac.h" - -/* defines to get HID report descriptor */ -#define HID_DEVICET_HID (USB_TYPE_CLASS | 0x01) -#define HID_DEVICET_REPORT (USB_TYPE_CLASS | 0x02) -#define HID_USAGE_UNDEFINED 0x00 -#define HID_USAGE_PAGE 0x05 -#define HID_USAGE_PAGE_DIGITIZER 0x0d -#define HID_USAGE_PAGE_DESKTOP 0x01 -#define HID_USAGE 0x09 -#define HID_USAGE_X 0x30 -#define HID_USAGE_Y 0x31 -#define HID_USAGE_X_TILT 0x3d -#define HID_USAGE_Y_TILT 0x3e -#define HID_USAGE_FINGER 0x22 -#define HID_USAGE_STYLUS 0x20 -#define HID_COLLECTION 0xc0 -#define HID_USAGE_PAGE_VDEFINED 0xff - -enum { - WCM_UNDEFINED = 0, - WCM_DESKTOP, - WCM_DIGITIZER, - MAX_USAGE_PAGE -}; - -struct hid_descriptor -{ - struct usb_descriptor_header header; - __le16 bcdHID; - u8 bCountryCode; - u8 bNumDescriptors; - u8 bDescriptorType; - __le16 wDescriptorLength; -} __attribute__ ((packed)); - -/* defines to get/set USB message */ -#define USB_REQ_GET_REPORT 0x01 -#define USB_REQ_SET_REPORT 0x09 -#define WAC_HID_FEATURE_REPORT 0x03 - -static int usb_get_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 100); -} - -static int usb_set_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_sndctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 1000); -} - -static struct input_dev * get_input_dev(struct wacom_combo *wcombo) -{ - return wcombo->wacom->dev; -} - -static void wacom_sys_irq(struct urb *urb, struct pt_regs *regs) -{ - struct wacom *wacom = urb->context; - struct wacom_combo wcombo; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - wcombo.wacom = wacom; - wcombo.urb = urb; - wcombo.regs = regs; - - if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo)) - input_sync(get_input_dev(&wcombo)); - - exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) -{ - input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); - return; -} - -void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data) -{ - input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data); - return; -} - -void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data) -{ - input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data); - return; -} - -void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value) -{ - input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value); - return; -} - -__u16 wacom_be16_to_cpu(unsigned char *data) -{ - __u16 value; - value = be16_to_cpu(*(__be16 *) data); - return value; -} - -__u16 wacom_le16_to_cpu(unsigned char *data) -{ - __u16 value; - value = le16_to_cpu(*(__le16 *) data); - return value; -} - -void wacom_input_regs(void *wcombo) -{ - input_regs(get_input_dev((struct wacom_combo *)wcombo), ((struct wacom_combo *)wcombo)->regs); - return; -} - -void wacom_input_sync(void *wcombo) -{ - input_sync(get_input_dev((struct wacom_combo *)wcombo)); - return; -} - -static int wacom_open(struct input_dev *dev) -{ - struct wacom *wacom = dev->private; - - wacom->irq->dev = wacom->usbdev; - if (usb_submit_urb(wacom->irq, GFP_KERNEL)) - return -EIO; - - return 0; -} - -static void wacom_close(struct input_dev *dev) -{ - struct wacom *wacom = dev->private; - - usb_kill_urb(wacom->irq); -} - -void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_1) | BIT(BTN_5); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); -} - -void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_MSC); - input_dev->mscbit[0] |= BIT(MSC_SERIAL); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_4); -} - -void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_REL); - input_dev->relbit[0] |= BIT(REL_WHEEL); - input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); -} - -void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); - input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); - input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); -} - -void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_7) | BIT(BTN_8); -} - -void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_8) | BIT(BTN_9); -} - -void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); - input_dev->mscbit[0] |= BIT(MSC_SERIAL); - input_dev->relbit[0] |= BIT(REL_WHEEL); - input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) - | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); - input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); -} - -void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2); -} - -void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER); -} - -static void wacom_paser_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, - struct wacom_wac *wacom_wac, char *report) -{ - struct usb_device *dev = interface_to_usbdev(intf); - char limit = 0, result = 0; - int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; - - /* retrive report descriptors */ - do { - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, - USB_RECIP_INTERFACE | USB_DIR_IN, - HID_DEVICET_REPORT << 8, - intf->altsetting[0].desc.bInterfaceNumber, /* interface */ - report, - hid_desc->wDescriptorLength, - 5000); /* 5 secs */ - } while (limit++ < 5); - - for (i=0; i<hid_desc->wDescriptorLength; i++) { - if (report[i] == HID_USAGE_PAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_PAGE_DIGITIZER: - usage = WCM_DIGITIZER; - i++; - continue; - case HID_USAGE_PAGE_DESKTOP: - usage = WCM_DESKTOP; - i++; - continue; - } - } - - if ((unsigned short)report[i] == HID_USAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_X: - if (usage == WCM_DESKTOP) { - if (finger) { - wacom_wac->features->touch_x_max = - wacom_wac->features->touch_y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+6])); - i += 7; - } else if (pen) { - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - i += 4; - } - } else if (usage == WCM_DIGITIZER) { - /* max pressure isn't reported - wacom_wac->features->pressure_max = (unsigned short) - (report[i+4] << 8 | report[i+3]); - */ - wacom_wac->features->pressure_max = 255; - i += 4; - } - break; - case HID_USAGE_Y: - if (usage == WCM_DESKTOP) { - wacom_wac->features->y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - case HID_USAGE_FINGER: - finger = 1; - i++; - break; - case HID_USAGE_STYLUS: - pen = 1; - i++; - break; - case HID_USAGE_UNDEFINED: - if (usage == WCM_DESKTOP && finger) { /* capacity */ - wacom_wac->features->pressure_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - } - } - - if ((unsigned short)report[i] == HID_COLLECTION) { - /* reset UsagePage ans Finger */ - finger = usage = 0; - } - } -} - -static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_endpoint_descriptor *endpoint; - struct wacom *wacom; - struct wacom_wac *wacom_wac; - struct input_dev *input_dev; - char rep_data[2], limit = 0, mode = 2, *report = NULL; - struct hid_descriptor *hid_desc; - - wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); - wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!wacom || !input_dev || !wacom_wac) - goto fail1; - - wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); - if (!wacom_wac->data) - goto fail1; - - wacom->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!wacom->irq) - goto fail2; - - wacom->usbdev = dev; - wacom->dev = input_dev; - usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); - strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); - - wacom_wac->features = get_wacom_feature(id); - BUG_ON(wacom_wac->features->pktlen > 10); - - input_dev->name = wacom_wac->features->name; - wacom->wacom_wac = wacom_wac; - usb_to_input_id(dev, &input_dev->id); - - input_dev->cdev.dev = &intf->dev; - input_dev->private = wacom; - input_dev->open = wacom_open; - input_dev->close = wacom_close; - - endpoint = &intf->cur_altsetting->endpoint[0].desc; - - /* Initialize touch_x_max and touch_y_max in case it is not defined */ - if (wacom_wac->features->type == TABLETPC) { - wacom_wac->features->touch_x_max = 1023; - wacom_wac->features->touch_y_max = 1023; - } else { - wacom_wac->features->touch_x_max = 0; - wacom_wac->features->touch_y_max = 0; - } - - /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ - if (wacom_wac->features->type == TABLETPC) { - if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { - if (usb_get_extra_descriptor(&interface->endpoint[0], - HID_DEVICET_REPORT, &hid_desc)) { - printk("wacom: can not retrive extra class descriptor\n"); - goto fail2; - } - } - report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); - if (!report) { - goto fail2; - } - wacom_paser_hid(intf, hid_desc, wacom_wac, report); - } - - input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_STYLUS) | BIT(BTN_TOUCH); - input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0); - input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0); - if (wacom_wac->features->type == TABLETPC) { - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_DOUBLETAP); - input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->touch_x_max, 4, 0); - input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->touch_y_max, 4, 0); - } - input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0); - input_dev->absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC); - - wacom_init_input_dev(input_dev, wacom_wac); - - usb_fill_int_urb(wacom->irq, dev, - usb_rcvintpipe(dev, endpoint->bEndpointAddress), - wacom_wac->data, wacom_wac->features->pktlen, - wacom_sys_irq, wacom, endpoint->bInterval); - wacom->irq->transfer_dma = wacom->data_dma; - wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - input_register_device(wacom->dev); - - /* Ask the tablet to report tablet data if it is not a Tablet PC. - * Repeat until it succeeds - */ - if (wacom_wac->features->type != TABLETPC) { - do { - rep_data[0] = 2; - rep_data[1] = mode; - usb_set_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); - usb_get_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); - } while (rep_data[1] != mode && limit++ < 5); - } - - usb_set_intfdata(intf, wacom); - return 0; - -fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); -fail1: input_free_device(input_dev); - kfree(wacom); - kfree(wacom_wac); - return -ENOMEM; -} - -static void wacom_disconnect(struct usb_interface *intf) -{ - struct wacom *wacom = usb_get_intfdata (intf); - - usb_set_intfdata(intf, NULL); - if (wacom) { - usb_kill_urb(wacom->irq); - input_unregister_device(wacom->dev); - usb_free_urb(wacom->irq); - usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); - kfree(wacom->wacom_wac); - kfree(wacom); - } -} - -static struct usb_driver wacom_driver = { - .name = "wacom", - .probe = wacom_probe, - .disconnect = wacom_disconnect, -}; - -static int __init wacom_init(void) -{ - int result; - wacom_driver.id_table = get_device_table(); - result = usb_register(&wacom_driver); - if (result == 0) - info(DRIVER_VERSION ":" DRIVER_DESC); - return result; -} - -static void __exit wacom_exit(void) -{ - usb_deregister(&wacom_driver); -} - -module_init(wacom_init); -module_exit(wacom_exit); diff --git a/src/2.6.16/Makefile.in b/src/2.6.16/Makefile.in deleted file mode 100644 index 8a3da2f..0000000 --- a/src/2.6.16/Makefile.in +++ /dev/null @@ -1,102 +0,0 @@ -############################ 2.6 kernel compile ############################### -ifneq ($(KERNELRELEASE),) -# We were called by kbuild -# Do NOT indent stuff in this part! It has to be like this to make the -# $(error ... ) stuff work - -# only compile those modules which are enabled by global configure -ifeq ($(WCM_OPTION_HID),yes) - -# check if kernel was configured to have hid as an module -ifeq ($(CONFIG_USB_HID),m) - -# check if HID module should be usbhid.ko or hid.ko -NEWHID := $(shell test $(SUBLEVEL) -ge 6 && echo usb) - -$(NEWHID)hid-objs := hid-core.o - -# behave exactly as kernel config wants us to behave -ifeq ($(CONFIG_USB_HIDDEV),y) -$(NEWHID)hid-objs += hiddev.o -endif -ifeq ($(CONFIG_USB_HIDINPUT),y) -$(NEWHID)hid-objs += hid-input.o -endif -ifeq ($(CONFIG_HID_PID),y) -$(NEWHID)hid-objs += pid.o -endif -ifeq ($(CONFIG_LOGITECH_FF),y) -$(NEWHID)hid-objs += hid-lgff.o -endif -ifeq ($(CONFIG_THRUSTMASTER_FF),y) -$(NEWHID)hid-objs += hid-tmff.o -endif -ifeq ($(CONFIG_HID_FF),y) -$(NEWHID)hid-objs += hid-ff.o -endif - -obj-$(CONFIG_USB_HID) += $(NEWHID)hid.o - -else -ifeq ($(CONFIG_USB_HID),y) -$(error You requested to build hid with configure, but hid is configured as built-in in your kernel config) -endif - -$(error You requested to build hid with configure, but hid is not configured in your kernel config) -endif # CONFIG_USB_HID -endif # WCM_OPTION_HID not - -ifeq ($(WCM_OPTION_WACOM),yes) -ifneq ($(CONFIG_USB_WACOM),y) -wacom-objs := wacom_wac.o wacom_sys.o -obj-m += wacom.o -else -$(error You requested to build wacom with configure, but wacom is configured as built-in in your kernel config) -endif # CONFIG_USB_WACOM -endif # WCM_OPTION_WACOM - -else # We were called from command line -PWD := $(shell pwd) - -WCM_KERNEL_DIR := @WCM_KERNEL_DIR@ -WCM_OPTION_WACOM := @WCM_OPTION_WACOM@ -WCM_OPTION_HID := @WCM_OPTION_HID@ - -export WCM_OPTION_WACOM WCM_OPTION_HID - -COPY_FROM_KERNEL_TREE := hiddev.c hid.h hid-ff.c hid-input.c fixp-arith.h -COPY_FROM_KERNEL_TREE += hid-lgff.c hid-tmff.c pid.c pid.h - -all: -# Copy hid-stuff from kernel-dir to local dir -ifeq ($(WCM_OPTION_HID),yes) - @for i in $(COPY_FROM_KERNEL_TREE); do \ - if test ! -f "$$i" && test -f $(WCM_KERNEL_DIR)/drivers/usb/input/$$i ; then \ - cp $(WCM_KERNEL_DIR)/drivers/usb/input/$$i .; \ - fi; \ - done -endif - - @echo ' Building linuxwacom drivers for 2.6 kernel.' - @echo '***Note: Drivers not enabled as modules in your kernel config but requested through configure are NOT built' - $(MAKE) -C $(WCM_KERNEL_DIR) M=$(PWD) - -endif # End kbuild check - -######################### Version independent targets ########################## - -clean: - rm -rf *.o *.ko *.mod.* .[a-z]* core *.i - -# also remove copied stuff -distclean: clean - @for i in $(COPY_FROM_KERNEL_TREE); do \ - if test -f "$$i"; then \ - rm -f $$i ; \ - fi; \ - done - -EMPTY_AUTOMAKE_TARGETS = distdir install install-data install-exec uninstall install-info -EMPTY_AUTOMAKE_TARGETS += installdirs check dvi pdf ps info html tags ctags mostlyclean distclean maintainer-clean -.PHONY: $(EMPTY_AUTOMAKE_TARGETS) - $(EMPTY_AUTOMAKE_TARGETS): diff --git a/src/2.6.16/hid-core.c b/src/2.6.16/hid-core.c deleted file mode 100644 index d1878c8..0000000 --- a/src/2.6.16/hid-core.c +++ /dev/null @@ -1,1972 +0,0 @@ -/* - * USB HID support for Linux - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> - * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc - * - * WARNING: THIS IS NOT PART OF THE OFFICIAL KERNEL TREE - * THIS IS FOR TESTING PURPOSES - * - * v2.6-2.6.16-pc-0.1 - initial release based on 2.6.16 - * v2.6-2.6.16-pc-0.2 - Added DTF 521, I3 12x12, and I3 12x19 - * v2.6-2.6.16-pc-0.3 - Make all Wacom devices into hid_blacklist - */ - -/* - * 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. - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/list.h> -#include <linux/mm.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/unaligned.h> -#include <asm/byteorder.h> -#include <linux/input.h> -#include <linux/wait.h> - -#undef DEBUG -#undef DEBUG_DATA - -#include <linux/usb.h> - -#include "hid.h" -#include <linux/hiddev.h> - -/* - * Version Information - */ - -#define DRIVER_VERSION "v2.6-2.6.16-pc-0.2" -#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik" -#define DRIVER_DESC "USB HID core driver" -#define DRIVER_LICENSE "GPL" - -static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick", - "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"}; -/* - * Module parameters. - */ - -static unsigned int hid_mousepoll_interval; -module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); -MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); - -/* - * Register a new report for a device. - */ - -static struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id) -{ - struct hid_report_enum *report_enum = device->report_enum + type; - struct hid_report *report; - - if (report_enum->report_id_hash[id]) - return report_enum->report_id_hash[id]; - - if (!(report = kmalloc(sizeof(struct hid_report), GFP_KERNEL))) - return NULL; - memset(report, 0, sizeof(struct hid_report)); - - if (id != 0) - report_enum->numbered = 1; - - report->id = id; - report->type = type; - report->size = 0; - report->device = device; - report_enum->report_id_hash[id] = report; - - list_add_tail(&report->list, &report_enum->report_list); - - return report; -} - -/* - * Register a new field for this report. - */ - -static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) -{ - struct hid_field *field; - - if (report->maxfield == HID_MAX_FIELDS) { - dbg("too many fields in report"); - return NULL; - } - - if (!(field = kmalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) - + values * sizeof(unsigned), GFP_KERNEL))) return NULL; - - memset(field, 0, sizeof(struct hid_field) + usages * sizeof(struct hid_usage) - + values * sizeof(unsigned)); - - field->index = report->maxfield++; - report->field[field->index] = field; - field->usage = (struct hid_usage *)(field + 1); - field->value = (unsigned *)(field->usage + usages); - field->report = report; - - return field; -} - -/* - * Open a collection. The type/usage is pushed on the stack. - */ - -static int open_collection(struct hid_parser *parser, unsigned type) -{ - struct hid_collection *collection; - unsigned usage; - - usage = parser->local.usage[0]; - - if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { - dbg("collection stack overflow"); - return -1; - } - - if (parser->device->maxcollection == parser->device->collection_size) { - collection = kmalloc(sizeof(struct hid_collection) * - parser->device->collection_size * 2, GFP_KERNEL); - if (collection == NULL) { - dbg("failed to reallocate collection array"); - return -1; - } - memcpy(collection, parser->device->collection, - sizeof(struct hid_collection) * - parser->device->collection_size); - memset(collection + parser->device->collection_size, 0, - sizeof(struct hid_collection) * - parser->device->collection_size); - kfree(parser->device->collection); - parser->device->collection = collection; - parser->device->collection_size *= 2; - } - - parser->collection_stack[parser->collection_stack_ptr++] = - parser->device->maxcollection; - - collection = parser->device->collection + - parser->device->maxcollection++; - collection->type = type; - collection->usage = usage; - collection->level = parser->collection_stack_ptr - 1; - - if (type == HID_COLLECTION_APPLICATION) - parser->device->maxapplication++; - - return 0; -} - -/* - * Close a collection. - */ - -static int close_collection(struct hid_parser *parser) -{ - if (!parser->collection_stack_ptr) { - dbg("collection stack underflow"); - return -1; - } - parser->collection_stack_ptr--; - return 0; -} - -/* - * Climb up the stack, search for the specified collection type - * and return the usage. - */ - -static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) -{ - int n; - for (n = parser->collection_stack_ptr - 1; n >= 0; n--) - if (parser->device->collection[parser->collection_stack[n]].type == type) - return parser->device->collection[parser->collection_stack[n]].usage; - return 0; /* we know nothing about this usage type */ -} - -/* - * Add a usage to the temporary parser table. - */ - -static int hid_add_usage(struct hid_parser *parser, unsigned usage) -{ - if (parser->local.usage_index >= HID_MAX_USAGES) { - dbg("usage index exceeded"); - return -1; - } - parser->local.usage[parser->local.usage_index] = usage; - parser->local.collection_index[parser->local.usage_index] = - parser->collection_stack_ptr ? - parser->collection_stack[parser->collection_stack_ptr - 1] : 0; - parser->local.usage_index++; - return 0; -} - -/* - * Register a new field for this report. - */ - -static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags) -{ - struct hid_report *report; - struct hid_field *field; - int usages; - unsigned offset; - int i; - - if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { - dbg("hid_register_report failed"); - return -1; - } - - if (parser->global.logical_maximum < parser->global.logical_minimum) { - dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum); - return -1; - } - - offset = report->size; - report->size += parser->global.report_size * parser->global.report_count; - - if (!parser->local.usage_index) /* Ignore padding fields */ - return 0; - - usages = max_t(int, parser->local.usage_index, parser->global.report_count); - - if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL) - return 0; - - field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); - field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL); - field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); - - for (i = 0; i < usages; i++) { - int j = i; - /* Duplicate the last usage we parsed if we have excess values */ - if (i >= parser->local.usage_index) - j = parser->local.usage_index - 1; - field->usage[i].hid = parser->local.usage[j]; - field->usage[i].collection_index = - parser->local.collection_index[j]; - } - - field->maxusage = usages; - field->flags = flags; - field->report_offset = offset; - field->report_type = report_type; - field->report_size = parser->global.report_size; - field->report_count = parser->global.report_count; - field->logical_minimum = parser->global.logical_minimum; - field->logical_maximum = parser->global.logical_maximum; - field->physical_minimum = parser->global.physical_minimum; - field->physical_maximum = parser->global.physical_maximum; - field->unit_exponent = parser->global.unit_exponent; - field->unit = parser->global.unit; - - return 0; -} - -/* - * Read data value from item. - */ - -static __inline__ __u32 item_udata(struct hid_item *item) -{ - switch (item->size) { - case 1: return item->data.u8; - case 2: return item->data.u16; - case 4: return item->data.u32; - } - return 0; -} - -static __inline__ __s32 item_sdata(struct hid_item *item) -{ - switch (item->size) { - case 1: return item->data.s8; - case 2: return item->data.s16; - case 4: return item->data.s32; - } - return 0; -} - -/* - * Process a global item. - */ - -static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) -{ - switch (item->tag) { - - case HID_GLOBAL_ITEM_TAG_PUSH: - - if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { - dbg("global enviroment stack overflow"); - return -1; - } - - memcpy(parser->global_stack + parser->global_stack_ptr++, - &parser->global, sizeof(struct hid_global)); - return 0; - - case HID_GLOBAL_ITEM_TAG_POP: - - if (!parser->global_stack_ptr) { - dbg("global enviroment stack underflow"); - return -1; - } - - memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr, - sizeof(struct hid_global)); - return 0; - - case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: - parser->global.usage_page = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: - parser->global.logical_minimum = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: - if (parser->global.logical_minimum < 0) - parser->global.logical_maximum = item_sdata(item); - else - parser->global.logical_maximum = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: - parser->global.physical_minimum = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: - if (parser->global.physical_minimum < 0) - parser->global.physical_maximum = item_sdata(item); - else - parser->global.physical_maximum = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: - parser->global.unit_exponent = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_UNIT: - parser->global.unit = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: - if ((parser->global.report_size = item_udata(item)) > 32) { - dbg("invalid report_size %d", parser->global.report_size); - return -1; - } - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: - if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) { - dbg("invalid report_count %d", parser->global.report_count); - return -1; - } - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_ID: - if ((parser->global.report_id = item_udata(item)) == 0) { - dbg("report_id 0 is invalid"); - return -1; - } - return 0; - - default: - dbg("unknown global tag 0x%x", item->tag); - return -1; - } -} - -/* - * Process a local item. - */ - -static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) -{ - __u32 data; - unsigned n; - - if (item->size == 0) { - dbg("item data expected for local item"); - return -1; - } - - data = item_udata(item); - - switch (item->tag) { - - case HID_LOCAL_ITEM_TAG_DELIMITER: - - if (data) { - /* - * We treat items before the first delimiter - * as global to all usage sets (branch 0). - * In the moment we process only these global - * items and the first delimiter set. - */ - if (parser->local.delimiter_depth != 0) { - dbg("nested delimiters"); - return -1; - } - parser->local.delimiter_depth++; - parser->local.delimiter_branch++; - } else { - if (parser->local.delimiter_depth < 1) { - dbg("bogus close delimiter"); - return -1; - } - parser->local.delimiter_depth--; - } - return 1; - - case HID_LOCAL_ITEM_TAG_USAGE: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - return hid_add_usage(parser, data); - - case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - parser->local.usage_minimum = data; - return 0; - - case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - for (n = parser->local.usage_minimum; n <= data; n++) - if (hid_add_usage(parser, n)) { - dbg("hid_add_usage failed\n"); - return -1; - } - return 0; - - default: - - dbg("unknown local item tag 0x%x", item->tag); - return 0; - } - return 0; -} - -/* - * Process a main item. - */ - -static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) -{ - __u32 data; - int ret; - - data = item_udata(item); - - switch (item->tag) { - case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: - ret = open_collection(parser, data & 0xff); - break; - case HID_MAIN_ITEM_TAG_END_COLLECTION: - ret = close_collection(parser); - break; - case HID_MAIN_ITEM_TAG_INPUT: - ret = hid_add_field(parser, HID_INPUT_REPORT, data); - break; - case HID_MAIN_ITEM_TAG_OUTPUT: - ret = hid_add_field(parser, HID_OUTPUT_REPORT, data); - break; - case HID_MAIN_ITEM_TAG_FEATURE: - ret = hid_add_field(parser, HID_FEATURE_REPORT, data); - break; - default: - dbg("unknown main item tag 0x%x", item->tag); - ret = 0; - } - - memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */ - - return ret; -} - -/* - * Process a reserved item. - */ - -static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) -{ - dbg("reserved item type, tag 0x%x", item->tag); - return 0; -} - -/* - * Free a report and all registered fields. The field->usage and - * field->value table's are allocated behind the field, so we need - * only to free(field) itself. - */ - -static void hid_free_report(struct hid_report *report) -{ - unsigned n; - - for (n = 0; n < report->maxfield; n++) - kfree(report->field[n]); - kfree(report); -} - -/* - * Free a device structure, all reports, and all fields. - */ - -static void hid_free_device(struct hid_device *device) -{ - unsigned i,j; - - hid_ff_exit(device); - - for (i = 0; i < HID_REPORT_TYPES; i++) { - struct hid_report_enum *report_enum = device->report_enum + i; - - for (j = 0; j < 256; j++) { - struct hid_report *report = report_enum->report_id_hash[j]; - if (report) - hid_free_report(report); - } - } - - kfree(device->rdesc); - kfree(device); -} - -/* - * Fetch a report description item from the data stream. We support long - * items, though they are not used yet. - */ - -static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) -{ - u8 b; - - if ((end - start) <= 0) - return NULL; - - b = *start++; - - item->type = (b >> 2) & 3; - item->tag = (b >> 4) & 15; - - if (item->tag == HID_ITEM_TAG_LONG) { - - item->format = HID_ITEM_FORMAT_LONG; - - if ((end - start) < 2) - return NULL; - - item->size = *start++; - item->tag = *start++; - - if ((end - start) < item->size) - return NULL; - - item->data.longdata = start; - start += item->size; - return start; - } - - item->format = HID_ITEM_FORMAT_SHORT; - item->size = b & 3; - - switch (item->size) { - - case 0: - return start; - - case 1: - if ((end - start) < 1) - return NULL; - item->data.u8 = *start++; - return start; - - case 2: - if ((end - start) < 2) - return NULL; - item->data.u16 = le16_to_cpu(get_unaligned((__le16*)start)); - start = (__u8 *)((__le16 *)start + 1); - return start; - - case 3: - item->size++; - if ((end - start) < 4) - return NULL; - item->data.u32 = le32_to_cpu(get_unaligned((__le32*)start)); - start = (__u8 *)((__le32 *)start + 1); - return start; - } - - return NULL; -} - -/* - * Parse a report description into a hid_device structure. Reports are - * enumerated, fields are attached to these reports. - */ - -static struct hid_device *hid_parse_report(__u8 *start, unsigned size) -{ - struct hid_device *device; - struct hid_parser *parser; - struct hid_item item; - __u8 *end; - unsigned i; - static int (*dispatch_type[])(struct hid_parser *parser, - struct hid_item *item) = { - hid_parser_main, - hid_parser_global, - hid_parser_local, - hid_parser_reserved - }; - - if (!(device = kmalloc(sizeof(struct hid_device), GFP_KERNEL))) - return NULL; - memset(device, 0, sizeof(struct hid_device)); - - if (!(device->collection = kmalloc(sizeof(struct hid_collection) * - HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) { - kfree(device); - return NULL; - } - memset(device->collection, 0, sizeof(struct hid_collection) * - HID_DEFAULT_NUM_COLLECTIONS); - device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; - - for (i = 0; i < HID_REPORT_TYPES; i++) - INIT_LIST_HEAD(&device->report_enum[i].report_list); - - if (!(device->rdesc = (__u8 *)kmalloc(size, GFP_KERNEL))) { - kfree(device->collection); - kfree(device); - return NULL; - } - memcpy(device->rdesc, start, size); - device->rsize = size; - - if (!(parser = kmalloc(sizeof(struct hid_parser), GFP_KERNEL))) { - kfree(device->rdesc); - kfree(device->collection); - kfree(device); - return NULL; - } - memset(parser, 0, sizeof(struct hid_parser)); - parser->device = device; - - end = start + size; - while ((start = fetch_item(start, end, &item)) != NULL) { - - if (item.format != HID_ITEM_FORMAT_SHORT) { - dbg("unexpected long global item"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - - if (dispatch_type[item.type](parser, &item)) { - dbg("item %u %u %u %u parsing failed\n", - item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - - if (start == end) { - if (parser->collection_stack_ptr) { - dbg("unbalanced collection at end of report description"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - if (parser->local.delimiter_depth) { - dbg("unbalanced delimiter at end of report description"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - kfree(parser); - return device; - } - } - - dbg("item fetching failed at offset %d\n", (int)(end - start)); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; -} - -/* - * Convert a signed n-bit integer to signed 32-bit integer. Common - * cases are done through the compiler, the screwed things has to be - * done by hand. - */ - -static __inline__ __s32 snto32(__u32 value, unsigned n) -{ - switch (n) { - case 8: return ((__s8)value); - case 16: return ((__s16)value); - case 32: return ((__s32)value); - } - return value & (1 << (n - 1)) ? value | (-1 << n) : value; -} - -/* - * Convert a signed 32-bit integer to a signed n-bit integer. - */ - -static __inline__ __u32 s32ton(__s32 value, unsigned n) -{ - __s32 a = value >> (n - 1); - if (a && a != -1) - return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; - return value & ((1 << n) - 1); -} - -/* - * Extract/implement a data field from/to a report. - */ - -static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) -{ - report += (offset >> 5) << 2; offset &= 31; - return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1ULL << n) - 1); -} - -static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) -{ - report += (offset >> 5) << 2; offset &= 31; - put_unaligned((get_unaligned((__le64*)report) - & cpu_to_le64(~((((__u64) 1 << n) - 1) << offset))) - | cpu_to_le64((__u64)value << offset), (__le64*)report); -} - -/* - * Search an array for a value. - */ - -static __inline__ int search(__s32 *array, __s32 value, unsigned n) -{ - while (n--) { - if (*array++ == value) - return 0; - } - return -1; -} - -static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt, struct pt_regs *regs) -{ - hid_dump_input(usage, value); - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_hid_event(hid, field, usage, value, regs); - if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt) - hiddev_hid_event(hid, field, usage, value, regs); -} - -/* - * Analyse a received field, and fetch the data from it. The field - * content is stored for next report processing (we do differential - * reporting to the layer). - */ - -static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt, struct pt_regs *regs) -{ - unsigned n; - unsigned count = field->report_count; - unsigned offset = field->report_offset; - unsigned size = field->report_size; - __s32 min = field->logical_minimum; - __s32 max = field->logical_maximum; - __s32 *value; - - if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC))) - return; - - for (n = 0; n < count; n++) { - - value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : - extract(data, offset + n * size, size); - - if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */ - && value[n] >= min && value[n] <= max - && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) - goto exit; - } - - for (n = 0; n < count; n++) { - - if (HID_MAIN_ITEM_VARIABLE & field->flags) { - hid_process_event(hid, field, &field->usage[n], value[n], interrupt, regs); - continue; - } - - if (field->value[n] >= min && field->value[n] <= max - && field->usage[field->value[n] - min].hid - && search(value, field->value[n], count)) - hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt, regs); - - if (value[n] >= min && value[n] <= max - && field->usage[value[n] - min].hid - && search(field->value, value[n], count)) - hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt, regs); - } - - memcpy(field->value, value, count * sizeof(__s32)); -exit: - kfree(value); -} - -static int hid_input_report(int type, struct urb *urb, int interrupt, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - struct hid_report_enum *report_enum = hid->report_enum + type; - u8 *data = urb->transfer_buffer; - int len = urb->actual_length; - struct hid_report *report; - int n, size; - - if (!len) { - dbg("empty report"); - return -1; - } - -#ifdef DEBUG_DATA - printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", len, report_enum->numbered ? "" : "un"); -#endif - - n = 0; /* Normally report number is 0 */ - if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */ - n = *data++; - len--; - } - -#ifdef DEBUG_DATA - { - int i; - printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, len); - for (i = 0; i < len; i++) - printk(" %02x", data[i]); - printk("\n"); - } -#endif - - if (!(report = report_enum->report_id_hash[n])) { - dbg("undefined report_id %d received", n); - return -1; - } - - size = ((report->size - 1) >> 3) + 1; - - if (len < size) { - dbg("report %d is too short, (%d < %d)", report->id, len, size); - memset(data + len, 0, size - len); - } - - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_report_event(hid, report); - - for (n = 0; n < report->maxfield; n++) - hid_input_field(hid, report->field[n], data, interrupt, regs); - - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_report_event(hid, report); - - return 0; -} - -/* - * Input interrupt completion handler. - */ - -static void hid_irq_in(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - int status; - - switch (urb->status) { - case 0: /* success */ - hid_input_report(HID_INPUT_REPORT, urb, 1, regs); - break; - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -EPERM: - case -ESHUTDOWN: /* unplug */ - case -EILSEQ: /* unplug timeout on uhci */ - return; - case -ETIMEDOUT: /* NAK */ - break; - default: /* error */ - warn("input irq status %d received", urb->status); - } - - status = usb_submit_urb(urb, SLAB_ATOMIC); - if (status) - err("can't resubmit intr, %s-%s/input%d, status %d", - hid->dev->bus->bus_name, hid->dev->devpath, - hid->ifnum, status); -} - -/* - * Output the field into the report. - */ - -static void hid_output_field(struct hid_field *field, __u8 *data) -{ - unsigned count = field->report_count; - unsigned offset = field->report_offset; - unsigned size = field->report_size; - unsigned n; - - for (n = 0; n < count; n++) { - if (field->logical_minimum < 0) /* signed values */ - implement(data, offset + n * size, size, s32ton(field->value[n], size)); - else /* unsigned values */ - implement(data, offset + n * size, size, field->value[n]); - } -} - -/* - * Create a report. - */ - -static void hid_output_report(struct hid_report *report, __u8 *data) -{ - unsigned n; - - if (report->id > 0) - *data++ = report->id; - - for (n = 0; n < report->maxfield; n++) - hid_output_field(report->field[n], data); -} - -/* - * Set a field value. The report this field belongs to has to be - * created and transferred to the device, to set this value in the - * device. - */ - -int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) -{ - unsigned size = field->report_size; - - hid_dump_input(field->usage + offset, value); - - if (offset >= field->report_count) { - dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count); - hid_dump_field(field, 8); - return -1; - } - if (field->logical_minimum < 0) { - if (value != snto32(s32ton(value, size), size)) { - dbg("value %d is out of range", value); - return -1; - } - } - field->value[offset] = value; - return 0; -} - -/* - * Find a report field with a specified HID usage. - */ - -struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_usage, int type) -{ - struct hid_report *report; - int i; - - list_for_each_entry(report, &hid->report_enum[type].report_list, list) - for (i = 0; i < report->maxfield; i++) - if (report->field[i]->logical == wanted_usage) - return report->field[i]; - return NULL; -} - -static int hid_submit_out(struct hid_device *hid) -{ - struct hid_report *report; - - report = hid->out[hid->outtail]; - - hid_output_report(report, hid->outbuf); - hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); - hid->urbout->dev = hid->dev; - - dbg("submitting out urb"); - - if (usb_submit_urb(hid->urbout, GFP_ATOMIC)) { - err("usb_submit_urb(out) failed"); - return -1; - } - - return 0; -} - -static int hid_submit_ctrl(struct hid_device *hid) -{ - struct hid_report *report; - unsigned char dir; - int len; - - report = hid->ctrl[hid->ctrltail].report; - dir = hid->ctrl[hid->ctrltail].dir; - - len = ((report->size - 1) >> 3) + 1 + (report->id > 0); - if (dir == USB_DIR_OUT) { - hid_output_report(report, hid->ctrlbuf); - hid->urbctrl->pipe = usb_sndctrlpipe(hid->dev, 0); - hid->urbctrl->transfer_buffer_length = len; - } else { - int maxpacket, padlen; - - hid->urbctrl->pipe = usb_rcvctrlpipe(hid->dev, 0); - maxpacket = usb_maxpacket(hid->dev, hid->urbctrl->pipe, 0); - if (maxpacket > 0) { - padlen = (len + maxpacket - 1) / maxpacket; - padlen *= maxpacket; - if (padlen > hid->bufsize) - padlen = hid->bufsize; - } else - padlen = 0; - hid->urbctrl->transfer_buffer_length = padlen; - } - hid->urbctrl->dev = hid->dev; - - hid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; - hid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; - hid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id); - hid->cr->wIndex = cpu_to_le16(hid->ifnum); - hid->cr->wLength = cpu_to_le16(len); - - dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u", - hid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", - hid->cr->wValue, hid->cr->wIndex, hid->cr->wLength); - - if (usb_submit_urb(hid->urbctrl, GFP_ATOMIC)) { - err("usb_submit_urb(ctrl) failed"); - return -1; - } - - return 0; -} - -/* - * Output interrupt completion handler. - */ - -static void hid_irq_out(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - unsigned long flags; - int unplug = 0; - - switch (urb->status) { - case 0: /* success */ - break; - case -ESHUTDOWN: /* unplug */ - case -EILSEQ: /* unplug timeout on uhci */ - unplug = 1; - case -ECONNRESET: /* unlink */ - case -ENOENT: - break; - default: /* error */ - warn("output irq status %d received", urb->status); - } - - spin_lock_irqsave(&hid->outlock, flags); - - if (unplug) - hid->outtail = hid->outhead; - else - hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); - - if (hid->outhead != hid->outtail) { - if (hid_submit_out(hid)) { - clear_bit(HID_OUT_RUNNING, &hid->iofl);; - wake_up(&hid->wait); - } - spin_unlock_irqrestore(&hid->outlock, flags); - return; - } - - clear_bit(HID_OUT_RUNNING, &hid->iofl); - spin_unlock_irqrestore(&hid->outlock, flags); - wake_up(&hid->wait); -} - -/* - * Control pipe completion handler. - */ - -static void hid_ctrl(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - unsigned long flags; - int unplug = 0; - - spin_lock_irqsave(&hid->ctrllock, flags); - - switch (urb->status) { - case 0: /* success */ - if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) - hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs); - break; - case -ESHUTDOWN: /* unplug */ - case -EILSEQ: /* unplug timectrl on uhci */ - unplug = 1; - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -EPIPE: /* report not available */ - break; - default: /* error */ - warn("ctrl urb status %d received", urb->status); - } - - if (unplug) - hid->ctrltail = hid->ctrlhead; - else - hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); - - if (hid->ctrlhead != hid->ctrltail) { - if (hid_submit_ctrl(hid)) { - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - wake_up(&hid->wait); - } - spin_unlock_irqrestore(&hid->ctrllock, flags); - return; - } - - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - spin_unlock_irqrestore(&hid->ctrllock, flags); - wake_up(&hid->wait); -} - -void hid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) -{ - int head; - unsigned long flags; - - if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) - return; - - if (hid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { - - spin_lock_irqsave(&hid->outlock, flags); - - if ((head = (hid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == hid->outtail) { - spin_unlock_irqrestore(&hid->outlock, flags); - warn("output queue full"); - return; - } - - hid->out[hid->outhead] = report; - hid->outhead = head; - - if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl)) - if (hid_submit_out(hid)) - clear_bit(HID_OUT_RUNNING, &hid->iofl); - - spin_unlock_irqrestore(&hid->outlock, flags); - return; - } - - spin_lock_irqsave(&hid->ctrllock, flags); - - if ((head = (hid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == hid->ctrltail) { - spin_unlock_irqrestore(&hid->ctrllock, flags); - warn("control queue full"); - return; - } - - hid->ctrl[hid->ctrlhead].report = report; - hid->ctrl[hid->ctrlhead].dir = dir; - hid->ctrlhead = head; - - if (!test_and_set_bit(HID_CTRL_RUNNING, &hid->iofl)) - if (hid_submit_ctrl(hid)) - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - - spin_unlock_irqrestore(&hid->ctrllock, flags); -} - -int hid_wait_io(struct hid_device *hid) -{ - if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &hid->iofl) && - !test_bit(HID_OUT_RUNNING, &hid->iofl)), - 10*HZ)) { - dbg("timeout waiting for ctrl or out queue to clear"); - return -1; - } - - return 0; -} - -static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle) -{ - return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (idle << 8) | report, - ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT); -} - -static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, - unsigned char type, void *buf, int size) -{ - int result, retries = 4; - - memset(buf,0,size); // Make sure we parse really received data - - do { - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, - (type << 8), ifnum, buf, size, USB_CTRL_GET_TIMEOUT); - retries--; - } while (result < size && retries); - return result; -} - -int hid_open(struct hid_device *hid) -{ - if (hid->open++) - return 0; - - hid->urbin->dev = hid->dev; - - if (usb_submit_urb(hid->urbin, GFP_KERNEL)) - return -EIO; - - return 0; -} - -void hid_close(struct hid_device *hid) -{ - if (!--hid->open) - usb_kill_urb(hid->urbin); -} - -/* - * Initialize all reports - */ - -void hid_init_reports(struct hid_device *hid) -{ - struct hid_report *report; - int err, ret; - - list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) - hid_submit_report(hid, report, USB_DIR_IN); - - list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) - hid_submit_report(hid, report, USB_DIR_IN); - - err = 0; - ret = hid_wait_io(hid); - while (ret) { - err |= ret; - if (test_bit(HID_CTRL_RUNNING, &hid->iofl)) - usb_kill_urb(hid->urbctrl); - if (test_bit(HID_OUT_RUNNING, &hid->iofl)) - usb_kill_urb(hid->urbout); - ret = hid_wait_io(hid); - } - - if (err) - warn("timeout initializing reports"); -} - -#define USB_VENDOR_ID_WACOM 0x056a - -#define USB_VENDOR_ID_ACECAD 0x0460 -#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 -#define USB_DEVICE_ID_ACECAD_302 0x0008 - -#define USB_VENDOR_ID_KBGEAR 0x084e -#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 - -#define USB_VENDOR_ID_AIPTEK 0x08ca -#define USB_DEVICE_ID_AIPTEK_01 0x0001 -#define USB_DEVICE_ID_AIPTEK_10 0x0010 -#define USB_DEVICE_ID_AIPTEK_20 0x0020 -#define USB_DEVICE_ID_AIPTEK_21 0x0021 -#define USB_DEVICE_ID_AIPTEK_22 0x0022 -#define USB_DEVICE_ID_AIPTEK_23 0x0023 -#define USB_DEVICE_ID_AIPTEK_24 0x0024 - -#define USB_VENDOR_ID_GRIFFIN 0x077d -#define USB_DEVICE_ID_POWERMATE 0x0410 -#define USB_DEVICE_ID_SOUNDKNOB 0x04AA - -#define USB_VENDOR_ID_ATEN 0x0557 -#define USB_DEVICE_ID_ATEN_UC100KM 0x2004 -#define USB_DEVICE_ID_ATEN_CS124U 0x2202 -#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204 -#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 -#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 - -#define USB_VENDOR_ID_TOPMAX 0x0663 -#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 - -#define USB_VENDOR_ID_HAPP 0x078b -#define USB_DEVICE_ID_UGCI_DRIVING 0x0010 -#define USB_DEVICE_ID_UGCI_FLYING 0x0020 -#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 - -#define USB_VENDOR_ID_MGE 0x0463 -#define USB_DEVICE_ID_MGE_UPS 0xffff -#define USB_DEVICE_ID_MGE_UPS1 0x0001 - -#define USB_VENDOR_ID_ONTRAK 0x0a07 -#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 - -#define USB_VENDOR_ID_TANGTOP 0x0d3d -#define USB_DEVICE_ID_TANGTOP_USBPS2 0x0001 - -#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f -#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 - -#define USB_VENDOR_ID_A4TECH 0x09da -#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 - -#define USB_VENDOR_ID_AASHIMA 0x06d6 -#define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 -#define USB_DEVICE_ID_AASHIMA_PREDATOR 0x0026 - -#define USB_VENDOR_ID_CYPRESS 0x04b4 -#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 -#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 -#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417 - -#define USB_VENDOR_ID_BERKSHIRE 0x0c98 -#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 - -#define USB_VENDOR_ID_ALPS 0x0433 -#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 - -#define USB_VENDOR_ID_SAITEK 0x06a3 -#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 - -#define USB_VENDOR_ID_NEC 0x073e -#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 - -#define USB_VENDOR_ID_CHIC 0x05fe -#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014 - -#define USB_VENDOR_ID_GLAB 0x06c2 -#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 -#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 -#define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045 -#define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040 -#define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053 - -#define USB_VENDOR_ID_WISEGROUP 0x0925 -#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 -#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 -#define USB_DEVICE_ID_DUAL_USB_JOYPAD 0x8866 - -#define USB_VENDOR_ID_CODEMERCS 0x07c0 -#define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500 -#define USB_DEVICE_ID_CODEMERCS_IOW24 0x1501 -#define USB_DEVICE_ID_CODEMERCS_IOW48 0x1502 -#define USB_DEVICE_ID_CODEMERCS_IOW28 0x1503 - -#define USB_VENDOR_ID_DELORME 0x1163 -#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 -#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 - -#define USB_VENDOR_ID_MCC 0x09db -#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 -#define USB_DEVICE_ID_MCC_PMD1208LS 0x007a - -#define USB_VENDOR_ID_CHICONY 0x04f2 -#define USB_DEVICE_ID_CHICONY_USBHUB_KB 0x0100 - -#define USB_VENDOR_ID_BTC 0x046e -#define USB_DEVICE_ID_BTC_KEYBOARD 0x5303 - -#define USB_VENDOR_ID_VERNIER 0x08f7 -#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 -#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 -#define USB_DEVICE_ID_VERNIER_SKIP 0x0003 -#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 - -#define USB_VENDOR_ID_LD 0x0f11 -#define USB_DEVICE_ID_LD_CASSY 0x1000 -#define USB_DEVICE_ID_LD_POCKETCASSY 0x1010 -#define USB_DEVICE_ID_LD_MOBILECASSY 0x1020 -#define USB_DEVICE_ID_LD_JWM 0x1080 -#define USB_DEVICE_ID_LD_DMMP 0x1081 -#define USB_DEVICE_ID_LD_UMIP 0x1090 -#define USB_DEVICE_ID_LD_XRAY1 0x1100 -#define USB_DEVICE_ID_LD_XRAY2 0x1101 -#define USB_DEVICE_ID_LD_VIDEOCOM 0x1200 -#define USB_DEVICE_ID_LD_COM3LAB 0x2000 -#define USB_DEVICE_ID_LD_TELEPORT 0x2010 -#define USB_DEVICE_ID_LD_NETWORKANALYSER 0x2020 -#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030 -#define USB_DEVICE_ID_LD_MACHINETEST 0x2040 - -#define USB_VENDOR_ID_APPLE 0x05ac -#define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304 - -#define USB_VENDOR_ID_CHERRY 0x046a -#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 - -#define USB_VENDOR_ID_HP 0x03f0 -#define USB_DEVICE_ID_HP_USBHUB_KB 0x020c - -/* - * Alphabetically sorted blacklist by quirk type. - */ - -static const struct hid_blacklist { - __u16 idVendor; - __u16 idProduct; - unsigned quirks; -} hid_blacklist[] = { - - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW48, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY1, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY2, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_VIDEOCOM, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_COM3LAB, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_TELEPORT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_KEYBOARD, HID_QUIRK_NOGET}, - { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET}, - { USB_VENDOR_ID_HP, USB_DEVICE_ID_HP_USBHUB_KB, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, - - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE }, - { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, - - { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, - - { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION }, - - { USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN }, - - { 0, 0 } -}; - -/* - * Traverse the supplied list of reports and find the longest - */ -static void hid_find_max_report(struct hid_device *hid, unsigned int type, int *max) -{ - struct hid_report *report; - int size; - - list_for_each_entry(report, &hid->report_enum[type].report_list, list) { - size = ((report->size - 1) >> 3) + 1; - if (type == HID_INPUT_REPORT && hid->report_enum[type].numbered) - size++; - if (*max < size) - *max = size; - } -} - -static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) -{ - if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->inbuf_dma))) - return -1; - if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->outbuf_dma))) - return -1; - if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma))) - return -1; - if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->ctrlbuf_dma))) - return -1; - - return 0; -} - -static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) -{ - if (hid->inbuf) - usb_buffer_free(dev, hid->bufsize, hid->inbuf, hid->inbuf_dma); - if (hid->outbuf) - usb_buffer_free(dev, hid->bufsize, hid->outbuf, hid->outbuf_dma); - if (hid->cr) - usb_buffer_free(dev, sizeof(*(hid->cr)), hid->cr, hid->cr_dma); - if (hid->ctrlbuf) - usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma); -} - -/* - * Cherry Cymotion keyboard have an invalid HID report descriptor, - * that needs fixing before we can parse it. - */ - -static void hid_fixup_cymotion_descriptor(char *rdesc, int rsize) -{ - if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { - info("Fixing up Cherry Cymotion report descriptor"); - rdesc[11] = rdesc[16] = 0xff; - rdesc[12] = rdesc[17] = 0x03; - } -} - -static struct hid_device *usb_hid_configure(struct usb_interface *intf) -{ - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_device *dev = interface_to_usbdev (intf); - struct hid_descriptor *hdesc; - struct hid_device *hid; - unsigned quirks = 0, rsize = 0; - char *rdesc; - int n, len, insize = 0; - - - /* ignore all Wacom devices */ - if (dev->descriptor.idVendor == USB_VENDOR_ID_WACOM) - return NULL; - - for (n = 0; hid_blacklist[n].idVendor; n++) - if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) && - (hid_blacklist[n].idProduct == le16_to_cpu(dev->descriptor.idProduct))) - quirks = hid_blacklist[n].quirks; - - if (quirks & HID_QUIRK_IGNORE) - return NULL; - - if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && - (!interface->desc.bNumEndpoints || - usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { - dbg("class descriptor not present\n"); - return NULL; - } - - for (n = 0; n < hdesc->bNumDescriptors; n++) - if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) - rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); - - if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { - dbg("weird size of report descriptor (%u)", rsize); - return NULL; - } - - if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) { - dbg("couldn't allocate rdesc memory"); - return NULL; - } - - hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0); - - if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { - dbg("reading report descriptor failed"); - kfree(rdesc); - return NULL; - } - - if ((quirks & HID_QUIRK_CYMOTION)) - hid_fixup_cymotion_descriptor(rdesc, rsize); - -#ifdef DEBUG_DATA - printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); - for (n = 0; n < rsize; n++) - printk(" %02x", (unsigned char) rdesc[n]); - printk("\n"); -#endif - - if (!(hid = hid_parse_report(rdesc, n))) { - dbg("parsing report descriptor failed"); - kfree(rdesc); - return NULL; - } - - kfree(rdesc); - hid->quirks = quirks; - - hid->bufsize = HID_MIN_BUFFER_SIZE; - hid_find_max_report(hid, HID_INPUT_REPORT, &hid->bufsize); - hid_find_max_report(hid, HID_OUTPUT_REPORT, &hid->bufsize); - hid_find_max_report(hid, HID_FEATURE_REPORT, &hid->bufsize); - - if (hid->bufsize > HID_MAX_BUFFER_SIZE) - hid->bufsize = HID_MAX_BUFFER_SIZE; - - hid_find_max_report(hid, HID_INPUT_REPORT, &insize); - - if (insize > HID_MAX_BUFFER_SIZE) - insize = HID_MAX_BUFFER_SIZE; - - if (hid_alloc_buffers(dev, hid)) { - hid_free_buffers(dev, hid); - goto fail; - } - - for (n = 0; n < interface->desc.bNumEndpoints; n++) { - - struct usb_endpoint_descriptor *endpoint; - int pipe; - int interval; - - endpoint = &interface->endpoint[n].desc; - if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */ - continue; - - interval = endpoint->bInterval; - - /* Change the polling interval of mice. */ - if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) - interval = hid_mousepoll_interval; - - if (endpoint->bEndpointAddress & USB_DIR_IN) { - if (hid->urbin) - continue; - if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) - goto fail; - pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); - usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, insize, - hid_irq_in, hid, interval); - hid->urbin->transfer_dma = hid->inbuf_dma; - hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - } else { - if (hid->urbout) - continue; - if (!(hid->urbout = usb_alloc_urb(0, GFP_KERNEL))) - goto fail; - pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress); - usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0, - hid_irq_out, hid, interval); - hid->urbout->transfer_dma = hid->outbuf_dma; - hid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - } - } - - if (!hid->urbin) { - err("couldn't find an input interrupt endpoint"); - goto fail; - } - - init_waitqueue_head(&hid->wait); - - spin_lock_init(&hid->outlock); - spin_lock_init(&hid->ctrllock); - - hid->version = le16_to_cpu(hdesc->bcdHID); - hid->country = hdesc->bCountryCode; - hid->dev = dev; - hid->intf = intf; - hid->ifnum = interface->desc.bInterfaceNumber; - - hid->name[0] = 0; - - if (dev->manufacturer) - strlcpy(hid->name, dev->manufacturer, sizeof(hid->name)); - - if (dev->product) { - if (dev->manufacturer) - strlcat(hid->name, " ", sizeof(hid->name)); - strlcat(hid->name, dev->product, sizeof(hid->name)); - } - - if (!strlen(hid->name)) - snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x", - le16_to_cpu(dev->descriptor.idVendor), - le16_to_cpu(dev->descriptor.idProduct)); - - usb_make_path(dev, hid->phys, sizeof(hid->phys)); - strlcat(hid->phys, "/input", sizeof(hid->phys)); - len = strlen(hid->phys); - if (len < sizeof(hid->phys) - 1) - snprintf(hid->phys + len, sizeof(hid->phys) - len, - "%d", intf->altsetting[0].desc.bInterfaceNumber); - - if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) - hid->uniq[0] = 0; - - hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); - if (!hid->urbctrl) - goto fail; - - usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr, - hid->ctrlbuf, 1, hid_ctrl, hid); - hid->urbctrl->setup_dma = hid->cr_dma; - hid->urbctrl->transfer_dma = hid->ctrlbuf_dma; - hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); - - return hid; - -fail: - - if (hid->urbin) - usb_free_urb(hid->urbin); - if (hid->urbout) - usb_free_urb(hid->urbout); - if (hid->urbctrl) - usb_free_urb(hid->urbctrl); - hid_free_buffers(dev, hid); - hid_free_device(hid); - - return NULL; -} - -static void hid_disconnect(struct usb_interface *intf) -{ - struct hid_device *hid = usb_get_intfdata (intf); - - if (!hid) - return; - - usb_set_intfdata(intf, NULL); - usb_kill_urb(hid->urbin); - usb_kill_urb(hid->urbout); - usb_kill_urb(hid->urbctrl); - - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_disconnect(hid); - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_disconnect(hid); - - usb_free_urb(hid->urbin); - usb_free_urb(hid->urbctrl); - if (hid->urbout) - usb_free_urb(hid->urbout); - - hid_free_buffers(hid->dev, hid); - hid_free_device(hid); -} - -static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct hid_device *hid; - char path[64]; - int i; - char *c; - - dbg("HID probe called for ifnum %d", - intf->altsetting->desc.bInterfaceNumber); - - if (!(hid = usb_hid_configure(intf))) - return -ENODEV; - - hid_init_reports(hid); - hid_dump_device(hid); - - if (!hidinput_connect(hid)) - hid->claimed |= HID_CLAIMED_INPUT; - if (!hiddev_connect(hid)) - hid->claimed |= HID_CLAIMED_HIDDEV; - - usb_set_intfdata(intf, hid); - - if (!hid->claimed) { - printk ("HID device not claimed by input or hiddev\n"); - hid_disconnect(intf); - return -ENODEV; - } - - printk(KERN_INFO); - - if (hid->claimed & HID_CLAIMED_INPUT) - printk("input"); - if (hid->claimed == (HID_CLAIMED_INPUT | HID_CLAIMED_HIDDEV)) - printk(","); - if (hid->claimed & HID_CLAIMED_HIDDEV) - printk("hiddev%d", hid->minor); - - c = "Device"; - for (i = 0; i < hid->maxcollection; i++) { - if (hid->collection[i].type == HID_COLLECTION_APPLICATION && - (hid->collection[i].usage & HID_USAGE_PAGE) == HID_UP_GENDESK && - (hid->collection[i].usage & 0xffff) < ARRAY_SIZE(hid_types)) { - c = hid_types[hid->collection[i].usage & 0xffff]; - break; - } - } - - usb_make_path(interface_to_usbdev(intf), path, 63); - - printk(": USB HID v%x.%02x %s [%s] on %s\n", - hid->version >> 8, hid->version & 0xff, c, hid->name, path); - - return 0; -} - -static int hid_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct hid_device *hid = usb_get_intfdata (intf); - - usb_kill_urb(hid->urbin); - dev_dbg(&intf->dev, "suspend\n"); - return 0; -} - -static int hid_resume(struct usb_interface *intf) -{ - struct hid_device *hid = usb_get_intfdata (intf); - int status; - - if (hid->open) - status = usb_submit_urb(hid->urbin, GFP_NOIO); - else - status = 0; - dev_dbg(&intf->dev, "resume status %d\n", status); - return status; -} - -static struct usb_device_id hid_usb_ids [] = { - { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, - .bInterfaceClass = USB_INTERFACE_CLASS_HID }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE (usb, hid_usb_ids); - -static struct usb_driver hid_driver = { - .name = "usbhid", - .probe = hid_probe, - .disconnect = hid_disconnect, - .suspend = hid_suspend, - .resume = hid_resume, - .id_table = hid_usb_ids, -}; - -static int __init hid_init(void) -{ - int retval; - retval = hiddev_init(); - if (retval) - goto hiddev_init_fail; - retval = usb_register(&hid_driver); - if (retval) - goto usb_register_fail; - info(DRIVER_VERSION ":" DRIVER_DESC); - - return 0; -usb_register_fail: - hiddev_exit(); -hiddev_init_fail: - return retval; -} - -static void __exit hid_exit(void) -{ - usb_deregister(&hid_driver); - hiddev_exit(); -} - -module_init(hid_init); -module_exit(hid_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); diff --git a/src/2.6.16/wacom.h b/src/2.6.16/wacom.h deleted file mode 100644 index f041025..0000000 --- a/src/2.6.16/wacom.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * drivers/usb/input/wacom.h - * - * USB Wacom Graphire and Wacom Intuos tablet support - * - * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz> - * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk> - * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at> - * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org> - * Copyright (c) 2000 James E. Blair <corvus@gnu.org> - * Copyright (c) 2000 Daniel Egger <egger@suse.de> - * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> - * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> - * Copyright (c) 2002-2009 Ping Cheng <pingc@wacom.com> - * - * ChangeLog: - * v0.1 (vp) - Initial release - * v0.2 (aba) - Support for all buttons / combinations - * v0.3 (vp) - Support for Intuos added - * v0.4 (sm) - Support for more Intuos models, menustrip - * relative mode, proximity. - * v0.5 (vp) - Big cleanup, nifty features removed, - * they belong in userspace - * v1.8 (vp) - Submit URB only when operating, moved to CVS, - * use input_report_key instead of report_btn and - * other cleanups - * v1.11 (vp) - Add URB ->dev setting for new kernels - * v1.11 (jb) - Add support for the 4D Mouse & Lens - * v1.12 (de) - Add support for two more inking pen IDs - * v1.14 (vp) - Use new USB device id probing scheme. - * Fix Wacom Graphire mouse wheel - * v1.18 (vp) - Fix mouse wheel direction - * Make mouse relative - * v1.20 (fl) - Report tool id for Intuos devices - * - Multi tools support - * - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...) - * - Add PL models support - * - Fix Wacom Graphire mouse wheel again - * v1.21 (vp) - Removed protocol descriptions - * - Added MISC_SERIAL for tool serial numbers - * (gb) - Identify version on module load. - * v1.21.1 (fl) - added Graphire2 support - * v1.21.2 (fl) - added Intuos2 support - * - added all the PL ids - * v1.21.3 (fl) - added another eraser id from Neil Okamoto - * - added smooth filter for Graphire from Peri Hankey - * - added PenPartner support from Olaf van Es - * - new tool ids from Ole Martin Bjoerndalen - * v1.29 (pc) - Add support for more tablets - * - Fix pressure reporting - * v1.30 (vp) - Merge 2.4 and 2.5 drivers - * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse - * - Cleanups here and there - * v1.30.1 (pi) - Added Graphire3 support - * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... - * v1.43 (pc) - Added support for Cintiq 21UX - * - Fixed a Graphire bug - * - Merged wacom_intuos3_irq into wacom_intuos_irq - * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc. - * - Report Device IDs - * v1.45 (pc) - Added support for DTF 521, Intuos3 12x12 and 12x19 - * - Minor data report fix - * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c, - * - where wacom_sys.c deals with system specific code, - * - and wacom_wac.c deals with Wacom specific code - */ - -/* - * 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. - */ -#ifndef WACOM_H -#define WACOM_H -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/input.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/usb.h> -#include <linux/usb_input.h> -#include <asm/unaligned.h> -#include <asm/byteorder.h> - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.46-pc0.5" -#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" -#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" -#define DRIVER_LICENSE "GPL" - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); - -#define USB_VENDOR_ID_WACOM 0x056a - -struct wacom { - dma_addr_t data_dma; - struct input_dev *dev; - struct usb_device *usbdev; - struct urb *irq; - struct wacom_wac * wacom_wac; - char phys[32]; -}; - -struct wacom_combo { - struct wacom * wacom; - struct urb * urb; - struct pt_regs *regs; -}; - -extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo); -extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data); -extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data); -extern void wacom_report_key(void *wcombo, unsigned int key_type, int key_data); -extern void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value); -extern void wacom_input_regs(void *wcombo); -extern void wacom_input_sync(void *wcombo); -extern void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern __u16 wacom_le16_to_cpu(unsigned char *data); -extern __u16 wacom_be16_to_cpu(unsigned char *data); -extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id); -extern const struct usb_device_id * get_device_table(void); - -#endif diff --git a/src/2.6.16/wacom_sys.c b/src/2.6.16/wacom_sys.c deleted file mode 100644 index 554c184..0000000 --- a/src/2.6.16/wacom_sys.c +++ /dev/null @@ -1,507 +0,0 @@ -/* - * drivers/usb/input/wacom_sys.c - * - * USB Wacom Graphire and Wacom Intuos tablet support - system specific code - */ - -/* - * 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. - */ - -#include "wacom.h" -#include "wacom_wac.h" - -/* defines to get HID report descriptor */ -#define HID_DEVICET_HID (USB_TYPE_CLASS | 0x01) -#define HID_DEVICET_REPORT (USB_TYPE_CLASS | 0x02) -#define HID_USAGE_UNDEFINED 0x00 -#define HID_USAGE_PAGE 0x05 -#define HID_USAGE_PAGE_DIGITIZER 0x0d -#define HID_USAGE_PAGE_DESKTOP 0x01 -#define HID_USAGE 0x09 -#define HID_USAGE_X 0x30 -#define HID_USAGE_Y 0x31 -#define HID_USAGE_X_TILT 0x3d -#define HID_USAGE_Y_TILT 0x3e -#define HID_USAGE_FINGER 0x22 -#define HID_USAGE_STYLUS 0x20 -#define HID_COLLECTION 0xc0 -#define HID_USAGE_PAGE_VDEFINED 0xff - -enum { - WCM_UNDEFINED = 0, - WCM_DESKTOP, - WCM_DIGITIZER, - MAX_USAGE_PAGE -}; - -struct hid_descriptor -{ - struct usb_descriptor_header header; - __le16 bcdHID; - u8 bCountryCode; - u8 bNumDescriptors; - u8 bDescriptorType; - __le16 wDescriptorLength; -} __attribute__ ((packed)); - -/* defines to get/set USB message */ -#define USB_REQ_GET_REPORT 0x01 -#define USB_REQ_SET_REPORT 0x09 -#define WAC_HID_FEATURE_REPORT 0x03 - -static int usb_get_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 100); -} - -static int usb_set_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_sndctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 1000); -} - -static struct input_dev * get_input_dev(struct wacom_combo *wcombo) -{ - return wcombo->wacom->dev; -} - -static void wacom_sys_irq(struct urb *urb, struct pt_regs *regs) -{ - struct wacom *wacom = urb->context; - struct wacom_combo wcombo; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - wcombo.wacom = wacom; - wcombo.urb = urb; - wcombo.regs = regs; - - if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo)) - input_sync(get_input_dev(&wcombo)); - - exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) -{ - input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); - return; -} - -void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data) -{ - input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data); - return; -} - -void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data) -{ - input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data); - return; -} - -void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value) -{ - input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value); - return; -} - -__u16 wacom_be16_to_cpu(unsigned char *data) -{ - __u16 value; - value = be16_to_cpu(*(__be16 *) data); - return value; -} - -__u16 wacom_le16_to_cpu(unsigned char *data) -{ - __u16 value; - value = le16_to_cpu(*(__le16 *) data); - return value; -} - -void wacom_input_regs(void *wcombo) -{ - input_regs(get_input_dev((struct wacom_combo *)wcombo), ((struct wacom_combo *)wcombo)->regs); - return; -} - -void wacom_input_sync(void *wcombo) -{ - input_sync(get_input_dev((struct wacom_combo *)wcombo)); - return; -} - -static int wacom_open(struct input_dev *dev) -{ - struct wacom *wacom = dev->private; - - wacom->irq->dev = wacom->usbdev; - if (usb_submit_urb(wacom->irq, GFP_KERNEL)) - return -EIO; - - return 0; -} - -static void wacom_close(struct input_dev *dev) -{ - struct wacom *wacom = dev->private; - - usb_kill_urb(wacom->irq); -} - -void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_1) | BIT(BTN_5); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); -} - -void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_MSC); - input_dev->mscbit[0] |= BIT(MSC_SERIAL); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_4); -} - -void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_REL); - input_dev->relbit[0] |= BIT(REL_WHEEL); - input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); -} - -void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); - input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); - input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); -} - -void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_7) | BIT(BTN_8); -} - -void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_8) | BIT(BTN_9); -} - -void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); - input_dev->mscbit[0] |= BIT(MSC_SERIAL); - input_dev->relbit[0] |= BIT(REL_WHEEL); - input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) - | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); - input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); -} - -void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2); -} - -void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER); -} - -static void wacom_paser_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, - struct wacom_wac *wacom_wac, char *report) -{ - struct usb_device *dev = interface_to_usbdev(intf); - char limit = 0, result = 0; - int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; - - /* retrive report descriptors */ - do { - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, - USB_RECIP_INTERFACE | USB_DIR_IN, - HID_DEVICET_REPORT << 8, - intf->altsetting[0].desc.bInterfaceNumber, /* interface */ - report, - hid_desc->wDescriptorLength, - 5000); /* 5 secs */ - } while (limit++ < 5); - - for (i=0; i<hid_desc->wDescriptorLength; i++) { - if (report[i] == HID_USAGE_PAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_PAGE_DIGITIZER: - usage = WCM_DIGITIZER; - i++; - continue; - case HID_USAGE_PAGE_DESKTOP: - usage = WCM_DESKTOP; - i++; - continue; - } - } - - if ((unsigned short)report[i] == HID_USAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_X: - if (usage == WCM_DESKTOP) { - if (finger) { - wacom_wac->features->touch_x_max = - wacom_wac->features->touch_y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+6])); - i += 7; - } else if (pen) { - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - i += 4; - } - } else if (usage == WCM_DIGITIZER) { - /* max pressure isn't reported - wacom_wac->features->pressure_max = (unsigned short) - (report[i+4] << 8 | report[i+3]); - */ - wacom_wac->features->pressure_max = 255; - i += 4; - } - break; - case HID_USAGE_Y: - if (usage == WCM_DESKTOP) { - wacom_wac->features->y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - case HID_USAGE_FINGER: - finger = 1; - i++; - break; - case HID_USAGE_STYLUS: - pen = 1; - i++; - break; - case HID_USAGE_UNDEFINED: - if (usage == WCM_DESKTOP && finger) { /* capacity */ - wacom_wac->features->pressure_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - } - } - - if ((unsigned short)report[i] == HID_COLLECTION) { - /* reset UsagePage ans Finger */ - finger = usage = 0; - } - } -} - -static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_endpoint_descriptor *endpoint; - struct wacom *wacom; - struct wacom_wac *wacom_wac; - struct input_dev *input_dev; - char rep_data[2], limit = 0, mode = 2, *report = NULL; - struct hid_descriptor *hid_desc; - - wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); - wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!wacom || !input_dev || !wacom_wac) - goto fail1; - - wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); - if (!wacom_wac->data) - goto fail1; - - wacom->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!wacom->irq) - goto fail2; - - wacom->usbdev = dev; - wacom->dev = input_dev; - usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); - strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); - - wacom_wac->features = get_wacom_feature(id); - BUG_ON(wacom_wac->features->pktlen > 10); - - input_dev->name = wacom_wac->features->name; - wacom->wacom_wac = wacom_wac; - usb_to_input_id(dev, &input_dev->id); - - input_dev->cdev.dev = &intf->dev; - input_dev->private = wacom; - input_dev->open = wacom_open; - input_dev->close = wacom_close; - - endpoint = &intf->cur_altsetting->endpoint[0].desc; - - /* Initialize touch_x_max and touch_y_max in case it is not defined */ - if (wacom_wac->features->type == TABLETPC) { - wacom_wac->features->touch_x_max = 1023; - wacom_wac->features->touch_y_max = 1023; - } else { - wacom_wac->features->touch_x_max = 0; - wacom_wac->features->touch_y_max = 0; - } - - /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ - if (wacom_wac->features->type == TABLETPC) { - if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { - if (usb_get_extra_descriptor(&interface->endpoint[0], - HID_DEVICET_REPORT, &hid_desc)) { - printk("wacom: can not retrive extra class descriptor\n"); - goto fail2; - } - } - report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); - if (!report) { - goto fail2; - } - wacom_paser_hid(intf, hid_desc, wacom_wac, report); - } - - input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_STYLUS) | BIT(BTN_TOUCH); - input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0); - input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0); - if (wacom_wac->features->type == TABLETPC) { - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_DOUBLETAP); - input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->touch_x_max, 4, 0); - input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->touch_y_max, 4, 0); - } - input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0); - input_dev->absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC); - - wacom_init_input_dev(input_dev, wacom_wac); - - usb_fill_int_urb(wacom->irq, dev, - usb_rcvintpipe(dev, endpoint->bEndpointAddress), - wacom_wac->data, wacom_wac->features->pktlen, - wacom_sys_irq, wacom, endpoint->bInterval); - wacom->irq->transfer_dma = wacom->data_dma; - wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - input_register_device(wacom->dev); - - /* Ask the tablet to report tablet data if it is not a Tablet PC. - * Repeat until it succeeds - */ - if (wacom_wac->features->type != TABLETPC) { - do { - rep_data[0] = 2; - rep_data[1] = mode; - usb_set_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); - usb_get_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); - } while (rep_data[1] != mode && limit++ < 5); - } - - usb_set_intfdata(intf, wacom); - kfree(report); - return 0; - -fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); -fail1: input_free_device(input_dev); - kfree(wacom); - kfree(wacom_wac); - return -ENOMEM; -} - -static void wacom_disconnect(struct usb_interface *intf) -{ - struct wacom *wacom = usb_get_intfdata (intf); - - usb_set_intfdata(intf, NULL); - if (wacom) { - usb_kill_urb(wacom->irq); - input_unregister_device(wacom->dev); - usb_free_urb(wacom->irq); - usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); - kfree(wacom->wacom_wac); - kfree(wacom); - } -} - -static struct usb_driver wacom_driver = { - .name = "wacom", - .probe = wacom_probe, - .disconnect = wacom_disconnect, -}; - -static int __init wacom_init(void) -{ - int result; - wacom_driver.id_table = get_device_table(); - result = usb_register(&wacom_driver); - if (result == 0) - info(DRIVER_VERSION ":" DRIVER_DESC); - return result; -} - -static void __exit wacom_exit(void) -{ - usb_deregister(&wacom_driver); -} - -module_init(wacom_init); -module_exit(wacom_exit); diff --git a/src/2.6.16/wacom_wac.c b/src/2.6.16/wacom_wac.c deleted file mode 100644 index 06538a6..0000000 --- a/src/2.6.16/wacom_wac.c +++ /dev/null @@ -1,943 +0,0 @@ -/* - * drivers/usb/input/wacom_wac.c - * - * USB Wacom Graphire and Wacom Intuos tablet support - Wacom specific code - * - */ - -/* - * 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. - */ -#include "wacom.h" -#include "wacom_wac.h" - -static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - - switch (data[0]) { - case 1: - wacom_input_regs(wcombo); - if (data[5] & 0x80) { - wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID; - wacom_report_key(wcombo, wacom->tool[0], 1); - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); - wacom_report_abs(wcombo, ABS_PRESSURE, ((signed char)data[6] + 127)); - wacom_report_key(wcombo, BTN_TOUCH, ((signed char)data[6] + 127)); - wacom_report_key(wcombo, BTN_STYLUS, (data[5] & 0x40)); - } else { - wacom_report_key(wcombo, wacom->tool[0], 0); - wacom_report_abs(wcombo, ABS_MISC, 0); /* report tool id */ - wacom_report_abs(wcombo, ABS_PRESSURE, -1); - } - break; - case 2: - wacom_input_regs(wcombo); - wacom_report_key(wcombo, BTN_TOOL_PEN, 1); - wacom_report_abs(wcombo, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */ - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); - wacom_report_abs(wcombo, ABS_PRESSURE, ((signed char)data[6] + 127)); - wacom_report_key(wcombo, BTN_STYLUS, (data[5] & 0x40)); - break; - default: - printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]); - return 0; - } - return 1; -} - -static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - int prox, pressure; - - if (data[0] != 2) { - dbg("wacom_pl_irq: received unknown report #%d", data[0]); - return 0; - } - - prox = data[1] & 0x40; - - wacom_input_regs(wcombo); - - wacom->id[0] = ERASER_DEVICE_ID; - if (prox) { - - pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); - if (wacom->features->pressure_max > 255) - pressure = (pressure << 1) | ((data[4] >> 6) & 1); - pressure += (wacom->features->pressure_max + 1) / 2; - - /* - * if going from out of proximity into proximity select between the eraser - * and the pen based on the state of the stylus2 button, choose eraser if - * pressed else choose pen. if not a proximity change from out to in, send - * an out of proximity for previous tool then a in for new tool. - */ - if (!wacom->tool[0]) { - /* Eraser bit set for DTF */ - if (data[1] & 0x10) - wacom->tool[1] = BTN_TOOL_RUBBER; - else - /* Going into proximity select tool */ - wacom->tool[1] = (data[4] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - } else { - /* was entered with stylus2 pressed */ - if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) { - /* report out proximity for previous tool */ - wacom_report_key(wcombo, wacom->tool[1], 0); - wacom_input_sync(wcombo); - wacom->tool[1] = BTN_TOOL_PEN; - return 0; - } - } - if (wacom->tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom->tool[1] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - } - wacom_report_key(wcombo, wacom->tool[1], prox); /* report in proximity for tool */ - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ - wacom_report_abs(wcombo, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); - wacom_report_abs(wcombo, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); - wacom_report_abs(wcombo, ABS_PRESSURE, pressure); - wacom_report_key(wcombo, BTN_TOUCH, pressure); - wacom_report_key(wcombo, BTN_STYLUS, data[4] & 0x10); - /* Only allow the stylus2 button to be reported for the pen tool. */ - wacom_report_key(wcombo, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20)); - } else { - /* report proximity-out of a (valid) tool */ - if (wacom->tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom->tool[1] = BTN_TOOL_PEN; - } - wacom_report_key(wcombo, wacom->tool[1], prox); - } - - wacom->tool[0] = prox; /* Save proximity state */ - return 1; -} - -static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - - if (data[0] != 2) { - printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); - return 0; - } - - wacom_input_regs(wcombo); - if (data[1] & 0x04) { - wacom_report_key(wcombo, BTN_TOOL_RUBBER, data[1] & 0x20); - wacom->id[0] = ERASER_DEVICE_ID; - } else { - wacom_report_key(wcombo, BTN_TOOL_PEN, data[1] & 0x20); - wacom->id[0] = STYLUS_DEVICE_ID; - } - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); - wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); - wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6])); - wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); - wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); - return 1; -} - -static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - int x, y, rw; - - if (data[0] != 2) { - dbg("wacom_graphire_irq: received unknown report #%d", data[0]); - return 0; - } - - wacom_input_regs(wcombo); - - if (data[1] & 0x80) { - /* in prox and not a pad data */ - - switch ((data[1] >> 5) & 3) { - - case 0: /* Pen */ - wacom->tool[0] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - break; - - case 1: /* Rubber */ - wacom->tool[0] = BTN_TOOL_RUBBER; - wacom->id[0] = ERASER_DEVICE_ID; - break; - - case 2: /* Mouse with wheel */ - wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); - if (wacom->features->type == WACOM_G4 || - wacom->features->type == WACOM_MO) { - rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); - wacom_report_rel(wcombo, REL_WHEEL, -rw); - } else - wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]); - /* fall through */ - - case 3: /* Mouse without wheel */ - wacom->tool[0] = BTN_TOOL_MOUSE; - wacom->id[0] = CURSOR_DEVICE_ID; - wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); - wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); - if (wacom->features->type == WACOM_G4 || - wacom->features->type == WACOM_MO) - wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); - else - wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); - break; - } - x = wacom_le16_to_cpu(&data[2]); - y = wacom_le16_to_cpu(&data[4]); - wacom_report_abs(wcombo, ABS_X, x); - wacom_report_abs(wcombo, ABS_Y, y); - if (wacom->tool[0] != BTN_TOOL_MOUSE) { - wacom_report_abs(wcombo, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8)); - wacom_report_key(wcombo, BTN_TOUCH, data[6] | ((data[7] & 0x01) << 8)); - wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); - wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); - } - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ - wacom_report_key(wcombo, wacom->tool[0], 1); - } else if (wacom->id[0]) { - wacom_report_abs(wcombo, ABS_X, 0); - wacom_report_abs(wcombo, ABS_Y, 0); - if (wacom->tool[0] == BTN_TOOL_MOUSE) { - wacom_report_key(wcombo, BTN_LEFT, 0); - wacom_report_key(wcombo, BTN_RIGHT, 0); - wacom_report_abs(wcombo, ABS_DISTANCE, 0); - } else { - wacom_report_abs(wcombo, ABS_PRESSURE, 0); - wacom_report_key(wcombo, BTN_TOUCH, 0); - wacom_report_key(wcombo, BTN_STYLUS, 0); - wacom_report_key(wcombo, BTN_STYLUS2, 0); - } - wacom->id[0] = 0; - wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ - wacom_report_key(wcombo, wacom->tool[0], 0); - } - - /* send pad data */ - switch (wacom->features->type) { - case WACOM_G4: - if (data[7] & 0xf8) { - wacom_input_sync(wcombo); /* sync last event */ - wacom->id[1] = PAD_DEVICE_ID; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); - rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); - wacom_report_rel(wcombo, REL_WHEEL, rw); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); - wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } else if (wacom->id[1]) { - wacom_input_sync(wcombo); /* sync last event */ - wacom->id[1] = 0; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); - wacom_report_abs(wcombo, ABS_MISC, 0); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } - break; - case WACOM_MO: - if ((data[7] & 0xf8) || (data[8] & 0xff)) { - wacom_input_sync(wcombo); /* sync last event */ - wacom->id[1] = PAD_DEVICE_ID; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); - wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); - wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); - wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); - wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } else if (wacom->id[1]) { - wacom_input_sync(wcombo); /* sync last event */ - wacom->id[1] = 0; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); - wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); - wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); - wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); - wacom_report_abs(wcombo, ABS_MISC, 0); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } - break; - } - return 1; -} - -static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - int idx = 0; - - /* tool number */ - if (wacom->features->type == INTUOS) - idx = data[1] & 0x01; - - /* Enter report */ - if ((data[1] & 0xfc) == 0xc0) { - /* serial number of the tool */ - wacom->serial[idx] = ((data[3] & 0x0f) << 28) + - (data[4] << 20) + (data[5] << 12) + - (data[6] << 4) + (data[7] >> 4); - - wacom->id[idx] = (data[2] << 4) | (data[3] >> 4); - switch (wacom->id[idx]) { - case 0x812: /* Inking pen */ - case 0x801: /* Intuos3 Inking pen */ - case 0x20802: /* Intuos4 Inking Pen */ - case 0x012: - wacom->tool[idx] = BTN_TOOL_PENCIL; - break; - case 0x822: /* Pen */ - case 0x842: - case 0x852: - case 0x823: /* Intuos3 Grip Pen */ - case 0x813: /* Intuos3 Classic Pen */ - case 0x885: /* Intuos3 Marker Pen */ - case 0x802: /* Intuos4 Grip Pen Eraser */ - case 0x804: /* Intuos4 Marker Pen */ - case 0x40802: /* Intuos4 Classic Pen */ - case 0x022: - wacom->tool[idx] = BTN_TOOL_PEN; - break; - case 0x832: /* Stroke pen */ - case 0x032: - wacom->tool[idx] = BTN_TOOL_BRUSH; - break; - case 0x007: /* Mouse 4D and 2D */ - case 0x09c: - case 0x094: - case 0x017: /* Intuos3 2D Mouse */ - case 0x806: /* Intuos4 Mouse */ - wacom->tool[idx] = BTN_TOOL_MOUSE; - break; - case 0x096: /* Lens cursor */ - case 0x097: /* Intuos3 Lens cursor */ - case 0x006: /* Intuos4 Lens cursor */ - wacom->tool[idx] = BTN_TOOL_LENS; - break; - case 0x82a: /* Eraser */ - case 0x85a: - case 0x91a: - case 0xd1a: - case 0x0fa: - case 0x82b: /* Intuos3 Grip Pen Eraser */ - case 0x81b: /* Intuos3 Classic Pen Eraser */ - case 0x91b: /* Intuos3 Airbrush Eraser */ - case 0x80c: /* Intuos4 Marker Pen Eraser */ - case 0x80a: /* Intuos4 Grip Pen Eraser */ - case 0x4080a: /* Intuos4 Classic Pen Eraser */ - case 0x90a: /* Intuos4 Airbrush Eraser */ - wacom->tool[idx] = BTN_TOOL_RUBBER; - break; - case 0xd12: - case 0x912: - case 0x112: - case 0x913: /* Intuos3 Airbrush */ - case 0x902: /* Intuos4 Airbrush */ - wacom->tool[idx] = BTN_TOOL_AIRBRUSH; - break; - default: /* Unknown tool */ - wacom->tool[idx] = BTN_TOOL_PEN; - } - return 1; - } - - /* Exit report */ - if ((data[1] & 0xfe) == 0x80) { - /* reset all states otherwise we lose the initial states - * when in-prox next time - */ - wacom_report_abs(wcombo, ABS_X, 0); - wacom_report_abs(wcombo, ABS_Y, 0); - wacom_report_abs(wcombo, ABS_DISTANCE, 0); - if (wacom->tool[idx] >= BTN_TOOL_MOUSE) { - wacom_report_key(wcombo, BTN_LEFT, 0); - wacom_report_key(wcombo, BTN_MIDDLE, 0); - wacom_report_key(wcombo, BTN_RIGHT, 0); - wacom_report_key(wcombo, BTN_SIDE, 0); - wacom_report_key(wcombo, BTN_EXTRA, 0); - wacom_report_abs(wcombo, ABS_THROTTLE, 0); - wacom_report_abs(wcombo, ABS_RZ, 0); - } else { - wacom_report_abs(wcombo, ABS_PRESSURE, 0); - wacom_report_key(wcombo, BTN_TOUCH, 0); - wacom_report_key(wcombo, BTN_STYLUS, 0); - wacom_report_key(wcombo, BTN_STYLUS2, 0); - wacom_report_abs(wcombo, ABS_WHEEL, 0); - if (wacom->features->type >= INTUOS3S) - wacom_report_abs(wcombo, ABS_Z, 0); - } - wacom_report_abs(wcombo, ABS_TILT_X, 0); - wacom_report_abs(wcombo, ABS_TILT_Y, 0); - wacom_report_key(wcombo, wacom->tool[idx], 0); - wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); - return 2; - } - return 0; -} - -static void wacom_intuos_general(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - unsigned int t; - - /* general pen packet */ - if ((data[1] & 0xb8) == 0xa0) { - t = (data[6] << 2) | ((data[7] >> 6) & 3); - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) - t = (t << 1) | (data[1] & 1); - wacom_report_abs(wcombo, ABS_PRESSURE, t); - wacom_report_key(wcombo, BTN_TOUCH, t); - wacom_report_abs(wcombo, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f); - wacom_report_key(wcombo, BTN_STYLUS, data[1] & 2); - wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 4); - } - - /* airbrush second packet */ - if ((data[1] & 0xbc) == 0xb4) { - wacom_report_abs(wcombo, ABS_WHEEL, - (data[6] << 2) | ((data[7] >> 6) & 3)); - wacom_report_abs(wcombo, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f); - } - return; -} - -static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - unsigned int t; - int idx = 0, result; - - if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) { - dbg("wacom_intuos_irq: received unknown report #%d", data[0]); - return 0; - } - - wacom_input_regs(wcombo); - - /* tool number */ - if (wacom->features->type == INTUOS) - idx = data[1] & 0x01; - - /* pad packets. Works as a second tool */ - if (data[0] == 12) { - /* initiate the pad as a device */ - if (wacom->tool[1] != BTN_TOOL_FINGER) - wacom->tool[1] = BTN_TOOL_FINGER; - - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { - wacom_report_key(wcombo, BTN_0, (data[2] & 0x01)); - wacom_report_key(wcombo, BTN_1, (data[3] & 0x01)); - wacom_report_key(wcombo, BTN_2, (data[3] & 0x02)); - wacom_report_key(wcombo, BTN_3, (data[3] & 0x04)); - wacom_report_key(wcombo, BTN_4, (data[3] & 0x08)); - wacom_report_key(wcombo, BTN_5, (data[3] & 0x10)); - wacom_report_key(wcombo, BTN_6, (data[3] & 0x20)); - if (data[1] & 0x80) { - wacom_report_abs(wcombo, ABS_WHEEL, (data[1] & 0x7f)); - } else { - /* Out of proximity, clear wheel value. */ - wacom_report_abs(wcombo, ABS_WHEEL, 0); - } - if (wacom->features->type != INTUOS4S) { - wacom_report_key(wcombo, BTN_7, (data[3] & 0x40)); - wacom_report_key(wcombo, BTN_8, (data[3] & 0x80)); - } - if (data[1] | (data[2] & 0x01) | data[3]) { - wacom_report_key(wcombo, wacom->tool[1], 1); - wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); - } else { - wacom_report_key(wcombo, wacom->tool[1], 0); - wacom_report_abs(wcombo, ABS_MISC, 0); - } - } else { - wacom_report_key(wcombo, BTN_0, (data[5] & 0x01)); - wacom_report_key(wcombo, BTN_1, (data[5] & 0x02)); - wacom_report_key(wcombo, BTN_2, (data[5] & 0x04)); - wacom_report_key(wcombo, BTN_3, (data[5] & 0x08)); - wacom_report_key(wcombo, BTN_4, (data[6] & 0x01)); - wacom_report_key(wcombo, BTN_5, (data[6] & 0x02)); - wacom_report_key(wcombo, BTN_6, (data[6] & 0x04)); - wacom_report_key(wcombo, BTN_7, (data[6] & 0x08)); - wacom_report_key(wcombo, BTN_8, (data[5] & 0x10)); - wacom_report_key(wcombo, BTN_9, (data[6] & 0x10)); - wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); - wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); - - if ((data[5] & 0x1f) | (data[6] & 0x1f) | (data[1] & 0x1f) | - data[2] | (data[3] & 0x1f) | data[4]) { - wacom_report_key(wcombo, wacom->tool[1], 1); - wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); - } else { - wacom_report_key(wcombo, wacom->tool[1], 0); - wacom_report_abs(wcombo, ABS_MISC, 0); - } - } - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xffffffff); - return 1; - } - - /* process in/out prox events */ - result = wacom_intuos_inout(wacom, wcombo); - if (result) - return result-1; - - /* don't proceed if we don't know the ID */ - if (!wacom->id[idx]) - return 0; - - /* Only large Intuos support Lense Cursor */ - if ((wacom->tool[idx] == BTN_TOOL_LENS) - && ((wacom->features->type == INTUOS3) - || (wacom->features->type == INTUOS3S) - || (wacom->features->type == INTUOS4) - || (wacom->features->type == INTUOS4S))) - return 0; - - /* Cintiq doesn't send data when RDY bit isn't set */ - if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40)) - return 0; - - if (wacom->features->type >= INTUOS3S) { - wacom_report_abs(wcombo, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); - wacom_report_abs(wcombo, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); - wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); - } else { - wacom_report_abs(wcombo, ABS_X, wacom_be16_to_cpu(&data[2])); - wacom_report_abs(wcombo, ABS_Y, wacom_be16_to_cpu(&data[4])); - wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); - } - - /* process general packets */ - wacom_intuos_general(wacom, wcombo); - - /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ - if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) { - - if (data[1] & 0x02) { - /* Rotation packet */ - if (wacom->features->type >= INTUOS3S) { - /* I3 marker pen rotation */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : - ((t-1) / 2 + 450)) : (450 - t / 2) ; - wacom_report_abs(wcombo, ABS_Z, t); - } else { - /* 4D mouse rotation packet */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - wacom_report_abs(wcombo, ABS_RZ, (data[7] & 0x20) ? - ((t - 1) / 2) : -t / 2); - } - - } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3S) { - /* 4D mouse packet */ - wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); - wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); - wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x04); - - wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x20); - wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x10); - t = (data[6] << 2) | ((data[7] >> 6) & 3); - wacom_report_abs(wcombo, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); - - } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { - /* I4 mouse */ - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { - wacom_report_key(wcombo, BTN_LEFT, data[6] & 0x01); - wacom_report_key(wcombo, BTN_MIDDLE, data[6] & 0x02); - wacom_report_key(wcombo, BTN_RIGHT, data[6] & 0x04); - wacom_report_rel(wcombo, REL_WHEEL, ((data[7] & 0x80) >> 7) - - ((data[7] & 0x40) >> 6)); - wacom_report_key(wcombo, BTN_SIDE, data[6] & 0x08); - wacom_report_key(wcombo, BTN_EXTRA, data[6] & 0x10); - - wacom_report_abs(wcombo, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f); - } else { - /* 2D mouse packet */ - wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x04); - wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x08); - wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x10); - wacom_report_rel(wcombo, REL_WHEEL, (data[8] & 0x01) - - ((data[8] & 0x02) >> 1)); - - /* I3 2D mouse side buttons */ - if (wacom->features->type >= INTUOS3S && wacom->features->type <= INTUOS3L) { - wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x40); - wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x20); - } - } - } else if ((wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L || - wacom->features->type == INTUOS4L) && (wacom->tool[idx] == BTN_TOOL_LENS)) { - /* Lens cursor packets */ - wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); - wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); - wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x04); - wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x10); - wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x08); - } - } - wacom_report_abs(wcombo, ABS_MISC, wacom->id[idx]); - wacom_report_key(wcombo, wacom->tool[idx], 1); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); - return 1; -} - -int wacom_tpc_irq (struct wacom_wac *wacom, void *wcombo) -{ - static int stylusInProx, touchInProx = 1, touchOut; - char *data = wacom->data; - int prox = 0, pressure; - struct urb *urb = ((struct wacom_combo *)wcombo)->urb; - - dbg("wacom_tpc_irq: received report #%d", data[0]); - - if (urb->actual_length == 5 || data[0] == 6) { /* Touch data */ - if (urb->actual_length == 5) { /* with touch */ - prox = data[0] & 0x03; - } else { /* with capacity */ - prox = data[1] & 0x03; - } - - if (!stylusInProx) { /* stylus not in prox */ - if (prox) { - if (touchInProx) { - wacom->tool[1] = BTN_TOOL_DOUBLETAP; - wacom->id[0] = TOUCH_DEVICE_ID; - if (urb->actual_length != 5) { - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); - wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); - wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6])); - } else { - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); - wacom_report_key(wcombo, BTN_TOUCH, 1); - } - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); - wacom_report_key(wcombo, wacom->tool[1], prox & 0x01); - touchOut = 1; - return 1; - } - } else { - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); - wacom_report_key(wcombo, wacom->tool[1], prox & 0x01); - wacom_report_key(wcombo, BTN_TOUCH, 0); - touchOut = 0; - touchInProx = 1; - return 1; - } - } else if (touchOut || !prox) { /* force touch out-prox */ - wacom_report_abs(wcombo, ABS_MISC, TOUCH_DEVICE_ID); - wacom_report_key(wcombo, wacom->tool[1], 0); - wacom_report_key(wcombo, BTN_TOUCH, 0); - touchOut = 0; - touchInProx = 1; - return 1; - } - } else if (data[0] == 2) { /* Penabled */ - prox = data[1] & 0x20; - touchInProx = 0; - wacom->id[0] = ERASER_DEVICE_ID; - - /* - * if going from out of proximity into proximity select between the eraser - * and the pen based on the state of the stylus2 button, choose eraser if - * pressed else choose pen. if not a proximity change from out to in, send - * an out of proximity for previous tool then a in for new tool. - */ - if (prox) { /* in prox */ - if (!wacom->tool[0]) { - /* Going into proximity select tool */ - wacom->tool[1] = (data[1] & 0x08) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - if (wacom->tool[1] == BTN_TOOL_PEN) - wacom->id[0] = STYLUS_DEVICE_ID; - } else if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[1] & 0x08)) { - /* - * was entered with stylus2 pressed - * report out proximity for previous tool - */ - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); - wacom_report_key(wcombo, wacom->tool[1], 0); - wacom_input_sync(wcombo); - - /* set new tool */ - wacom->tool[1] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - return 0; - } - if (wacom->tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom->tool[1] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - } - wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); - wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); - pressure = ((data[7] & 0x01) << 8) | data[6]; - if (pressure < 0) - pressure = wacom->features->pressure_max + pressure + 1; - wacom_report_abs(wcombo, ABS_PRESSURE, pressure); - wacom_report_key(wcombo, BTN_TOUCH, pressure); - } else { - wacom_report_abs(wcombo, ABS_PRESSURE, 0); - wacom_report_key(wcombo, BTN_TOUCH, 0); - wacom_report_key(wcombo, BTN_STYLUS, 0); - wacom_report_key(wcombo, BTN_STYLUS2, 0); - } - wacom_report_key(wcombo, wacom->tool[1], prox); - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); - stylusInProx = prox; - wacom->tool[0] = prox; - return 1; - } - return 0; -} - -int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) -{ - switch (wacom_wac->features->type) { - case PENPARTNER: - return (wacom_penpartner_irq(wacom_wac, wcombo)); - break; - case PL: - return (wacom_pl_irq(wacom_wac, wcombo)); - break; - case WACOM_MO: - case WACOM_G4: - case GRAPHIRE: - return (wacom_graphire_irq(wacom_wac, wcombo)); - break; - case PTU: - return (wacom_ptu_irq(wacom_wac, wcombo)); - break; - case INTUOS: - case INTUOS3S: - case INTUOS3: - case INTUOS3L: - case CINTIQ: - case WACOM_BEE: - case INTUOS4S: - case INTUOS4: - case INTUOS4L: - return (wacom_intuos_irq(wacom_wac, wcombo)); - break; - case TABLETPC: - return (wacom_tpc_irq(wacom_wac, wcombo)); - break; - default: - return 0; - } - return 0; -} - -void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - switch (wacom_wac->features->type) { - case WACOM_MO: - input_dev_mo(input_dev, wacom_wac); - case WACOM_G4: - input_dev_g4(input_dev, wacom_wac); - /* fall through */ - case GRAPHIRE: - input_dev_g(input_dev, wacom_wac); - break; - case WACOM_BEE: - input_dev_bee(input_dev, wacom_wac); - case INTUOS3: - case INTUOS3L: - case CINTIQ: - input_dev_i3(input_dev, wacom_wac); - /* fall through */ - case INTUOS3S: - input_dev_i3s(input_dev, wacom_wac); - case INTUOS: - input_dev_i(input_dev, wacom_wac); - break; - case INTUOS4: - case INTUOS4L: - input_dev_i4(input_dev, wacom_wac); - /* fall through */ - case INTUOS4S: - input_dev_i4s(input_dev, wacom_wac); - input_dev_i(input_dev, wacom_wac); - break; - case PL: - case PTU: - case TABLETPC: - input_dev_pl(input_dev, wacom_wac); - /* fall through */ - case PENPARTNER: - input_dev_pt(input_dev, wacom_wac); - break; - } - return; -} - -static struct wacom_features wacom_features[] = { - { "Wacom Penpartner", 7, 5040, 3780, 255, 0, PENPARTNER }, - { "Wacom Graphire", 8, 10206, 7422, 511, 63, GRAPHIRE }, - { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 63, GRAPHIRE }, - { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 63, GRAPHIRE }, - { "Wacom Graphire3", 8, 10208, 7424, 511, 63, GRAPHIRE }, - { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE }, - { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, WACOM_G4 }, - { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 }, - { "Wacom BambooFun 4x5", 9, 14760, 9225, 511, 63, WACOM_MO }, - { "Wacom BambooFun 6x8", 9, 21648, 13530, 511, 63, WACOM_MO }, - { "Wacom Bamboo1 Medium",8, 16704, 12064, 511, 63, GRAPHIRE }, - { "Wacom Volito", 8, 5104, 3712, 511, 63, GRAPHIRE }, - { "Wacom PenStation2", 8, 3250, 2320, 255, 63, GRAPHIRE }, - { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE }, - { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE }, - { "Wacom PenPartner2", 8, 3250, 2320, 511, 63, GRAPHIRE }, - { "Wacom Bamboo", 9, 14760, 9225, 511, 63, WACOM_MO }, - { "Wacom Bamboo1", 8, 5104, 3712, 511, 63, GRAPHIRE }, - { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, - { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, - { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS }, - { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 31, INTUOS }, - { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 31, INTUOS }, - { "Wacom PL400", 8, 5408, 4056, 255, 0, PL }, - { "Wacom PL500", 8, 6144, 4608, 255, 0, PL }, - { "Wacom PL600", 8, 6126, 4604, 255, 0, PL }, - { "Wacom PL600SX", 8, 6260, 5016, 255, 0, PL }, - { "Wacom PL550", 8, 6144, 4608, 511, 0, PL }, - { "Wacom PL800", 8, 7220, 5780, 511, 0, PL }, - { "Wacom PL700", 8, 6758, 5406, 511, 0, PL }, - { "Wacom PL510", 8, 6282, 4762, 511, 0, PL }, - { "Wacom DTU710", 8, 34080, 27660, 511, 0, PL }, - { "Wacom DTF521", 8, 6282, 4762, 511, 0, PL }, - { "Wacom DTF720", 8, 6858, 5506, 511, 0, PL }, - { "Wacom DTF720a", 8, 6858, 5506, 511, 0, PL }, - { "Wacom DTU1931", 8, 37832, 30305, 511, 0, PL }, - { "Wacom Cintiq Partner",8, 20480, 15360, 511, 0, PTU }, - { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, - { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, - { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 31, INTUOS }, - { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 31, INTUOS }, - { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 31, INTUOS }, - { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 63, INTUOS3S }, - { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 63, INTUOS3 }, - { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 63, INTUOS3 }, - { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L }, - { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L }, - { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 }, - { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S }, - { "Wacom Intuos4 4x6", 10, 31496, 19685, 2047, 63, INTUOS4S }, - { "Wacom Intuos4 6x9", 10, 44704, 27940, 2047, 63, INTUOS4 }, - { "Wacom Intuos4 8x13", 10, 65024, 40640, 2047, 63, INTUOS4L }, - { "Wacom Intuos4 12x19", 10, 97536, 60960, 2047, 63, INTUOS4L }, - { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, - { "Wacom Cintiq 20WSX", 10, 86680, 54180, 1023, 63, WACOM_BEE }, - { "Wacom Cintiq 12WX", 10, 53020, 33440, 1023, 63, WACOM_BEE }, - { "Wacom ISDv4 90", 8, 26202, 16325, 255, 0, TABLETPC }, - { "Wacom ISDv4 93", 8, 26202, 16325, 255, 0, TABLETPC }, - { "Wacom ISDv4 9A", 8, 26202, 16325, 255, 0, TABLETPC }, - { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, - { } -}; - -static struct usb_device_id wacom_ids[] = { - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x00) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x11) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x17) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x18) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x19) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x69) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x30) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x32) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC4) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC2) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC7) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB8) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB9) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBA) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBB) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x90) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x93) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9A) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, - { } -}; - -const struct usb_device_id * get_device_table(void) { - const struct usb_device_id * id_table = wacom_ids; - return id_table; -} - -struct wacom_features * get_wacom_feature(const struct usb_device_id * id) { - int index = id - wacom_ids; - struct wacom_features *wf = &wacom_features[index]; - return wf; -} - -MODULE_DEVICE_TABLE(usb, wacom_ids); diff --git a/src/2.6.16/wacom_wac.h b/src/2.6.16/wacom_wac.h deleted file mode 100644 index 1386c46..0000000 --- a/src/2.6.16/wacom_wac.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * drivers/usb/input/wacom_wac.h - * - * 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. - */ -#ifndef WACOM_WAC_H -#define WACOM_WAC_H - -#define STYLUS_DEVICE_ID 0x02 -#define TOUCH_DEVICE_ID 0x03 -#define CURSOR_DEVICE_ID 0x06 -#define ERASER_DEVICE_ID 0x0A -#define PAD_DEVICE_ID 0x0F - -enum { - PENPARTNER = 0, - GRAPHIRE, - WACOM_G4, - PTU, - PL, - INTUOS, - INTUOS3S, - INTUOS3, - INTUOS3L, - CINTIQ, - WACOM_BEE, - INTUOS4S, - INTUOS4, - INTUOS4L, - WACOM_MO, - TABLETPC, - MAX_TYPE -}; - -struct wacom_features { - char *name; - int pktlen; - int x_max; - int y_max; - int pressure_max; - int distance_max; - int type; - int touch_x_max; - int touch_y_max; -}; - -struct wacom_wac { - unsigned char *data; - int tool[2]; - int id[2]; - __u32 serial[2]; - struct wacom_features *features; -}; - -#endif diff --git a/src/2.6.18/Makefile.in b/src/2.6.18/Makefile.in deleted file mode 100755 index 391f026..0000000 --- a/src/2.6.18/Makefile.in +++ /dev/null @@ -1,45 +0,0 @@ -############################ 2.6 kernel compile ############################### -ifneq ($(KERNELRELEASE),) -# We were called by kbuild -# Do NOT indent stuff in this part! It has to be like this to make the -# $(error ... ) stuff work - -ifeq ($(WCM_OPTION_WACOM),yes) -ifneq ($(CONFIG_USB_WACOM),y) -wacom-objs := wacom_wac.o wacom_sys.o -obj-m += wacom.o -else -$(error You requested to build wacom with configure, but wacom is configured as built-in in your kernel config) -endif # CONFIG_USB_WACOM -endif # WCM_OPTION_WACOM - -else # We were called from command line -PWD := $(shell pwd) - -WCM_KERNEL_DIR := @WCM_KERNEL_DIR@ -WCM_OPTION_WACOM := @WCM_OPTION_WACOM@ - -export WCM_OPTION_WACOM - -all: -# Copy Wacom specific code which is common to all kernel releases -ifeq ($(WCM_OPTION_WACOM),yes) - cp -f ../2.6.16/wacom_wac.c . - cp -f ../2.6.16/wacom_wac.h . - cp -f ../2.6.16/wacom_sys.c . -endif - @echo ' Building linuxwacom drivers for 2.6 kernel.' - @echo '***Note: Drivers not enabled as modules in your kernel config but requested through configure are NOT built' - $(MAKE) -C $(WCM_KERNEL_DIR) M=$(PWD) - -endif # End kbuild check - -######################### Version independent targets ########################## - -clean: - rm -rf *.o *.ko *.mod.* .[a-z]* core *.i - -EMPTY_AUTOMAKE_TARGETS = distdir install install-data install-exec uninstall install-info -EMPTY_AUTOMAKE_TARGETS += installdirs check dvi pdf ps info html tags ctags mostlyclean distclean maintainer-clean -.PHONY: $(EMPTY_AUTOMAKE_TARGETS) - $(EMPTY_AUTOMAKE_TARGETS): diff --git a/src/2.6.18/wacom.h b/src/2.6.18/wacom.h deleted file mode 100644 index fe2081e..0000000 --- a/src/2.6.18/wacom.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * drivers/usb/input/wacom.h - * - * USB Wacom Graphire and Wacom Intuos tablet support - * - * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz> - * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk> - * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at> - * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org> - * Copyright (c) 2000 James E. Blair <corvus@gnu.org> - * Copyright (c) 2000 Daniel Egger <egger@suse.de> - * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> - * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> - * Copyright (c) 2002-2009 Ping Cheng <pingc@wacom.com> - * - * ChangeLog: - * v0.1 (vp) - Initial release - * v0.2 (aba) - Support for all buttons / combinations - * v0.3 (vp) - Support for Intuos added - * v0.4 (sm) - Support for more Intuos models, menustrip - * relative mode, proximity. - * v0.5 (vp) - Big cleanup, nifty features removed, - * they belong in userspace - * v1.8 (vp) - Submit URB only when operating, moved to CVS, - * use input_report_key instead of report_btn and - * other cleanups - * v1.11 (vp) - Add URB ->dev setting for new kernels - * v1.11 (jb) - Add support for the 4D Mouse & Lens - * v1.12 (de) - Add support for two more inking pen IDs - * v1.14 (vp) - Use new USB device id probing scheme. - * Fix Wacom Graphire mouse wheel - * v1.18 (vp) - Fix mouse wheel direction - * Make mouse relative - * v1.20 (fl) - Report tool id for Intuos devices - * - Multi tools support - * - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...) - * - Add PL models support - * - Fix Wacom Graphire mouse wheel again - * v1.21 (vp) - Removed protocol descriptions - * - Added MISC_SERIAL for tool serial numbers - * (gb) - Identify version on module load. - * v1.21.1 (fl) - added Graphire2 support - * v1.21.2 (fl) - added Intuos2 support - * - added all the PL ids - * v1.21.3 (fl) - added another eraser id from Neil Okamoto - * - added smooth filter for Graphire from Peri Hankey - * - added PenPartner support from Olaf van Es - * - new tool ids from Ole Martin Bjoerndalen - * v1.29 (pc) - Add support for more tablets - * - Fix pressure reporting - * v1.30 (vp) - Merge 2.4 and 2.5 drivers - * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse - * - Cleanups here and there - * v1.30.1 (pi) - Added Graphire3 support - * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... - * v1.43 (pc) - Added support for Cintiq 21UX - * - Fixed a Graphire bug - * - Merged wacom_intuos3_irq into wacom_intuos_irq - * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc. - * - Report Device IDs - * v1.45 (pc) - Added support for DTF 521, Intuos3 12x12 and 12x19 - * - Minor data report fix - * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c, - * - where wacom_sys.c deals with system specific code, - * - and wacom_wac.c deals with Wacom specific code - * - Support Intuos3 4x6 - */ - -/* - * 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. - */ -#ifndef WACOM_H -#define WACOM_H -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/usb/input.h> -#include <asm/unaligned.h> - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.46-pc0.5" -#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" -#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" -#define DRIVER_LICENSE "GPL" - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); - -#define USB_VENDOR_ID_WACOM 0x056a - -struct wacom { - dma_addr_t data_dma; - struct input_dev *dev; - struct usb_device *usbdev; - struct urb *irq; - struct wacom_wac * wacom_wac; - char phys[32]; -}; - -struct wacom_combo { - struct wacom * wacom; - struct urb * urb; - struct pt_regs *regs; -}; - -extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo); -extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data); -extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data); -extern void wacom_report_key(void *wcombo, unsigned int key_type, int key_data); -extern void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value); -extern void wacom_input_regs(void *wcombo); -extern void wacom_input_sync(void *wcombo); -extern void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern __u16 wacom_le16_to_cpu(unsigned char *data); -extern __u16 wacom_be16_to_cpu(unsigned char *data); -extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id); -extern const struct usb_device_id * get_device_table(void); - -#endif diff --git a/src/2.6.19/Makefile.in b/src/2.6.19/Makefile.in deleted file mode 100755 index 4b034e1..0000000 --- a/src/2.6.19/Makefile.in +++ /dev/null @@ -1,43 +0,0 @@ -############################ 2.6 kernel compile ############################### -ifneq ($(KERNELRELEASE),) -# We were called by kbuild -# Do NOT indent stuff in this part! It has to be like this to make the -# $(error ... ) stuff work - -ifeq ($(WCM_OPTION_WACOM),yes) -ifneq ($(CONFIG_USB_WACOM),y) -wacom-objs := wacom_wac.o wacom_sys.o -obj-m += wacom.o -else -$(error You requested to build wacom with configure, but wacom is configured as built-in in your kernel config) -endif # CONFIG_USB_WACOM -endif # WCM_OPTION_WACOM - -else # We were called from command line -PWD := $(shell pwd) - -WCM_KERNEL_DIR := @WCM_KERNEL_DIR@ -WCM_OPTION_WACOM := @WCM_OPTION_WACOM@ - -export WCM_OPTION_WACOM - -all: -# Copy Wacom specific code which is common to all kernel releases -ifeq ($(WCM_OPTION_WACOM),yes) - cp -f ../2.6.16/wacom_wac.h . -endif - @echo ' Building linuxwacom drivers for 2.6 kernel.' - @echo '***Note: Drivers not enabled as modules in your kernel config but requested through configure are NOT built' - $(MAKE) -C $(WCM_KERNEL_DIR) M=$(PWD) - -endif # End kbuild check - -######################### Version independent targets ########################## - -clean: - rm -rf *.o *.ko *.mod.* .[a-z]* core *.i - -EMPTY_AUTOMAKE_TARGETS = distdir install install-data install-exec uninstall install-info -EMPTY_AUTOMAKE_TARGETS += installdirs check dvi pdf ps info html tags ctags mostlyclean distclean maintainer-clean -.PHONY: $(EMPTY_AUTOMAKE_TARGETS) - $(EMPTY_AUTOMAKE_TARGETS): diff --git a/src/2.6.19/wacom.h b/src/2.6.19/wacom.h deleted file mode 100755 index 03a24fc..0000000 --- a/src/2.6.19/wacom.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * drivers/usb/input/wacom.h - * - * USB Wacom Graphire and Wacom Intuos tablet support - * - * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz> - * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk> - * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at> - * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org> - * Copyright (c) 2000 James E. Blair <corvus@gnu.org> - * Copyright (c) 2000 Daniel Egger <egger@suse.de> - * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> - * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> - * Copyright (c) 2002-2009 Ping Cheng <pingc@wacom.com> - * - * ChangeLog: - * v0.1 (vp) - Initial release - * v0.2 (aba) - Support for all buttons / combinations - * v0.3 (vp) - Support for Intuos added - * v0.4 (sm) - Support for more Intuos models, menustrip - * relative mode, proximity. - * v0.5 (vp) - Big cleanup, nifty features removed, - * they belong in userspace - * v1.8 (vp) - Submit URB only when operating, moved to CVS, - * use input_report_key instead of report_btn and - * other cleanups - * v1.11 (vp) - Add URB ->dev setting for new kernels - * v1.11 (jb) - Add support for the 4D Mouse & Lens - * v1.12 (de) - Add support for two more inking pen IDs - * v1.14 (vp) - Use new USB device id probing scheme. - * Fix Wacom Graphire mouse wheel - * v1.18 (vp) - Fix mouse wheel direction - * Make mouse relative - * v1.20 (fl) - Report tool id for Intuos devices - * - Multi tools support - * - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...) - * - Add PL models support - * - Fix Wacom Graphire mouse wheel again - * v1.21 (vp) - Removed protocol descriptions - * - Added MISC_SERIAL for tool serial numbers - * (gb) - Identify version on module load. - * v1.21.1 (fl) - added Graphire2 support - * v1.21.2 (fl) - added Intuos2 support - * - added all the PL ids - * v1.21.3 (fl) - added another eraser id from Neil Okamoto - * - added smooth filter for Graphire from Peri Hankey - * - added PenPartner support from Olaf van Es - * - new tool ids from Ole Martin Bjoerndalen - * v1.29 (pc) - Add support for more tablets - * - Fix pressure reporting - * v1.30 (vp) - Merge 2.4 and 2.5 drivers - * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse - * - Cleanups here and there - * v1.30.1 (pi) - Added Graphire3 support - * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... - * v1.43 (pc) - Added support for Cintiq 21UX - * - Fixed a Graphire bug - * - Merged wacom_intuos3_irq into wacom_intuos_irq - * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc. - * - Report Device IDs - * v1.45 (pc) - Added support for DTF 521, Intuos3 12x12 and 12x19 - * - Minor data report fix - * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c, - * - where wacom_sys.c deals with system specific code, - * - and wacom_wac.c deals with Wacom specific code - * - Support Intuos3 4x6 - */ - -/* - * 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. - */ -#ifndef WACOM_H -#define WACOM_H -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/usb/input.h> -#include <asm/unaligned.h> - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.46-pc0.5" -#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" -#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" -#define DRIVER_LICENSE "GPL" - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); - -#define USB_VENDOR_ID_WACOM 0x056a - -struct wacom { - dma_addr_t data_dma; - struct input_dev *dev; - struct usb_device *usbdev; - struct urb *irq; - struct wacom_wac * wacom_wac; - char phys[32]; -}; - -struct wacom_combo { - struct wacom * wacom; - struct urb * urb; -}; - -extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo); -extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data); -extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data); -extern void wacom_report_key(void *wcombo, unsigned int key_type, int key_data); -extern void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value); -extern void wacom_input_sync(void *wcombo); -extern void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern __u16 wacom_le16_to_cpu(unsigned char *data); -extern __u16 wacom_be16_to_cpu(unsigned char *data); -extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id); -extern const struct usb_device_id * get_device_table(void); - -#endif diff --git a/src/2.6.19/wacom_sys.c b/src/2.6.19/wacom_sys.c deleted file mode 100755 index 68e5abc..0000000 --- a/src/2.6.19/wacom_sys.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - * drivers/usb/input/wacom_sys.c - * - * USB Wacom Graphire and Wacom Intuos tablet support - system specific code - */ - -/* - * 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. - */ - -#include "wacom.h" -#include "wacom_wac.h" - -/* defines to get HID report descriptor */ -#define HID_DEVICET_HID (USB_TYPE_CLASS | 0x01) -#define HID_DEVICET_REPORT (USB_TYPE_CLASS | 0x02) -#define HID_USAGE_UNDEFINED 0x00 -#define HID_USAGE_PAGE 0x05 -#define HID_USAGE_PAGE_DIGITIZER 0x0d -#define HID_USAGE_PAGE_DESKTOP 0x01 -#define HID_USAGE 0x09 -#define HID_USAGE_X 0x30 -#define HID_USAGE_Y 0x31 -#define HID_USAGE_X_TILT 0x3d -#define HID_USAGE_Y_TILT 0x3e -#define HID_USAGE_FINGER 0x22 -#define HID_USAGE_STYLUS 0x20 -#define HID_COLLECTION 0xc0 -#define HID_USAGE_PAGE_VDEFINED 0xff - -enum { - WCM_UNDEFINED = 0, - WCM_DESKTOP, - WCM_DIGITIZER, - MAX_USAGE_PAGE -}; - -struct hid_descriptor -{ - struct usb_descriptor_header header; - __le16 bcdHID; - u8 bCountryCode; - u8 bNumDescriptors; - u8 bDescriptorType; - __le16 wDescriptorLength; -} __attribute__ ((packed)); - -/* defines to get/set USB message */ -#define USB_REQ_GET_REPORT 0x01 -#define USB_REQ_SET_REPORT 0x09 -#define WAC_HID_FEATURE_REPORT 0x03 - -static int usb_get_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 100); -} - -static int usb_set_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_sndctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 1000); -} - -static struct input_dev * get_input_dev(struct wacom_combo *wcombo) -{ - return wcombo->wacom->dev; -} - -static void wacom_sys_irq(struct urb *urb) -{ - struct wacom *wacom = urb->context; - struct wacom_combo wcombo; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - wcombo.wacom = wacom; - wcombo.urb = urb; - - if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo)) - input_sync(get_input_dev(&wcombo)); - - exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) -{ - input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); - return; -} - -void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data) -{ - input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data); - return; -} - -void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data) -{ - input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data); - return; -} - -void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value) -{ - input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value); - return; -} - -__u16 wacom_be16_to_cpu(unsigned char *data) -{ - __u16 value; - value = be16_to_cpu(*(__be16 *) data); - return value; -} - -__u16 wacom_le16_to_cpu(unsigned char *data) -{ - __u16 value; - value = le16_to_cpu(*(__le16 *) data); - return value; -} - -void wacom_input_sync(void *wcombo) -{ - input_sync(get_input_dev((struct wacom_combo *)wcombo)); - return; -} - -static int wacom_open(struct input_dev *dev) -{ - struct wacom *wacom = dev->private; - - wacom->irq->dev = wacom->usbdev; - if (usb_submit_urb(wacom->irq, GFP_KERNEL)) - return -EIO; - - return 0; -} - -static void wacom_close(struct input_dev *dev) -{ - struct wacom *wacom = dev->private; - - usb_kill_urb(wacom->irq); -} - -void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_1) | BIT(BTN_5); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); -} - -void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_MSC); - input_dev->mscbit[0] |= BIT(MSC_SERIAL); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_4); -} - -void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_REL); - input_dev->relbit[0] |= BIT(REL_WHEEL); - input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); -} - -void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); - input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); - input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); -} - -void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_7) | BIT(BTN_8); -} - -void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_8) | BIT(BTN_9); -} - -void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); - input_dev->mscbit[0] |= BIT(MSC_SERIAL); - input_dev->relbit[0] |= BIT(REL_WHEEL); - input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) - | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); - input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); -} - -void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2); -} - -void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER); -} - -static void wacom_paser_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, - struct wacom_wac *wacom_wac, char *report) -{ - struct usb_device *dev = interface_to_usbdev(intf); - char limit = 0, result = 0; - int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; - - /* retrive report descriptors */ - do { - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, - USB_RECIP_INTERFACE | USB_DIR_IN, - HID_DEVICET_REPORT << 8, - intf->altsetting[0].desc.bInterfaceNumber, /* interface */ - report, - hid_desc->wDescriptorLength, - 5000); /* 5 secs */ - } while (limit++ < 5); - - for (i=0; i<hid_desc->wDescriptorLength; i++) { - if (report[i] == HID_USAGE_PAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_PAGE_DIGITIZER: - usage = WCM_DIGITIZER; - i++; - continue; - case HID_USAGE_PAGE_DESKTOP: - usage = WCM_DESKTOP; - i++; - continue; - } - } - - if ((unsigned short)report[i] == HID_USAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_X: - if (usage == WCM_DESKTOP) { - if (finger) { - wacom_wac->features->touch_x_max = - wacom_wac->features->touch_y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+6])); - i += 7; - } else if (pen) { - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - i += 4; - } - } else if (usage == WCM_DIGITIZER) { - /* max pressure isn't reported - wacom_wac->features->pressure_max = (unsigned short) - (report[i+4] << 8 | report[i+3]); - */ - wacom_wac->features->pressure_max = 255; - i += 4; - } - break; - case HID_USAGE_Y: - if (usage == WCM_DESKTOP) { - wacom_wac->features->y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - case HID_USAGE_FINGER: - finger = 1; - i++; - break; - case HID_USAGE_STYLUS: - pen = 1; - i++; - break; - case HID_USAGE_UNDEFINED: - if (usage == WCM_DESKTOP && finger) { /* capacity */ - wacom_wac->features->pressure_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - } - } - - if ((unsigned short)report[i] == HID_COLLECTION) { - /* reset UsagePage ans Finger */ - finger = usage = 0; - } - } -} - -static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_endpoint_descriptor *endpoint; - struct wacom *wacom; - struct wacom_wac *wacom_wac; - struct input_dev *input_dev; - char limit = 0, rep_data[2], mode = 2, *report = NULL; - struct hid_descriptor *hid_desc; - - wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); - wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!wacom || !input_dev || !wacom_wac) - goto fail1; - - wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); - if (!wacom_wac->data) - goto fail1; - - wacom->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!wacom->irq) - goto fail2; - - wacom->usbdev = dev; - wacom->dev = input_dev; - usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); - strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); - - wacom_wac->features = get_wacom_feature(id); - BUG_ON(wacom_wac->features->pktlen > 10); - - input_dev->name = wacom_wac->features->name; - wacom->wacom_wac = wacom_wac; - usb_to_input_id(dev, &input_dev->id); - - input_dev->cdev.dev = &intf->dev; - input_dev->private = wacom; - input_dev->open = wacom_open; - input_dev->close = wacom_close; - - endpoint = &intf->cur_altsetting->endpoint[0].desc; - - /* Initialize touch_x_max and touch_y_max in case it is not defined */ - if (wacom_wac->features->type == TABLETPC) { - wacom_wac->features->touch_x_max = 1023; - wacom_wac->features->touch_y_max = 1023; - } else { - wacom_wac->features->touch_x_max = 0; - wacom_wac->features->touch_y_max = 0; - } - - /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ - if (wacom_wac->features->type == TABLETPC) { - if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { - if (usb_get_extra_descriptor(&interface->endpoint[0], - HID_DEVICET_REPORT, &hid_desc)) { - printk("wacom: can not retrive extra class descriptor\n"); - goto fail2; - } - } - report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); - if (!report) { - goto fail2; - } - wacom_paser_hid(intf, hid_desc, wacom_wac, report); - } - - input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_STYLUS) | BIT(BTN_TOUCH); - input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0); - input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0); - input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0); - if (wacom_wac->features->type == TABLETPC) { - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_DOUBLETAP); - input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->touch_x_max, 4, 0); - input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->touch_y_max, 4, 0); - } - input_dev->absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC); - - wacom_init_input_dev(input_dev, wacom_wac); - - usb_fill_int_urb(wacom->irq, dev, - usb_rcvintpipe(dev, endpoint->bEndpointAddress), - wacom_wac->data, wacom_wac->features->pktlen, - wacom_sys_irq, wacom, endpoint->bInterval); - wacom->irq->transfer_dma = wacom->data_dma; - wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - input_register_device(wacom->dev); - - /* Ask the tablet to report tablet data if it is not a Tablet PC. - * Repeat until it succeeds - */ - if (wacom_wac->features->type != TABLETPC) { - do { - rep_data[0] = 2; - rep_data[1] = mode; - usb_set_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); - usb_get_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); - } while (rep_data[1] != mode && limit++ < 5); - } - - usb_set_intfdata(intf, wacom); - kfree(report); - return 0; - -fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); -fail1: input_free_device(input_dev); - kfree(wacom); - kfree(wacom_wac); - return -ENOMEM; -} - -static void wacom_disconnect(struct usb_interface *intf) -{ - struct wacom *wacom = usb_get_intfdata (intf); - - usb_set_intfdata(intf, NULL); - if (wacom) { - usb_kill_urb(wacom->irq); - input_unregister_device(wacom->dev); - usb_free_urb(wacom->irq); - usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); - kfree(wacom->wacom_wac); - kfree(wacom); - } -} - -static struct usb_driver wacom_driver = { - .name = "wacom", - .probe = wacom_probe, - .disconnect = wacom_disconnect, -}; - -static int __init wacom_init(void) -{ - int result; - wacom_driver.id_table = get_device_table(); - result = usb_register(&wacom_driver); - if (result == 0) - info(DRIVER_VERSION ":" DRIVER_DESC); - return result; -} - -static void __exit wacom_exit(void) -{ - usb_deregister(&wacom_driver); -} - -module_init(wacom_init); -module_exit(wacom_exit); diff --git a/src/2.6.19/wacom_wac.c b/src/2.6.19/wacom_wac.c deleted file mode 100755 index 8bf5b49..0000000 --- a/src/2.6.19/wacom_wac.c +++ /dev/null @@ -1,937 +0,0 @@ -/* - * drivers/usb/input/wacom_wac.c - * - * USB Wacom Graphire and Wacom Intuos tablet support - Wacom specific code - * - */ - -/* - * 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. - */ -#include "wacom.h" -#include "wacom_wac.h" - -static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - - switch (data[0]) { - case 1: - if (data[5] & 0x80) { - wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID; - wacom_report_key(wcombo, wacom->tool[0], 1); - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); - wacom_report_abs(wcombo, ABS_PRESSURE, ((signed char)data[6] + 127)); - wacom_report_key(wcombo, BTN_TOUCH, ((signed char)data[6] + 127)); - wacom_report_key(wcombo, BTN_STYLUS, (data[5] & 0x40)); - } else { - wacom_report_key(wcombo, wacom->tool[0], 0); - wacom_report_abs(wcombo, ABS_MISC, 0); /* report tool id */ - wacom_report_abs(wcombo, ABS_PRESSURE, -1); - } - break; - case 2: - wacom_report_key(wcombo, BTN_TOOL_PEN, 1); - wacom_report_abs(wcombo, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */ - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); - wacom_report_abs(wcombo, ABS_PRESSURE, (signed char)data[6] + 127); - wacom_report_key(wcombo, BTN_STYLUS, (data[5] & 0x40)); - break; - default: - printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]); - return 0; - } - return 1; -} - -static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - int prox, pressure; - - if (data[0] != 2) { - dbg("wacom_pl_irq: received unknown report #%d", data[0]); - return 0; - } - - prox = data[1] & 0x40; - - wacom->id[0] = ERASER_DEVICE_ID; - if (prox) { - - pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); - if (wacom->features->pressure_max > 255) - pressure = (pressure << 1) | ((data[4] >> 6) & 1); - pressure += (wacom->features->pressure_max + 1) / 2; - - /* - * if going from out of proximity into proximity select between the eraser - * and the pen based on the state of the stylus2 button, choose eraser if - * pressed else choose pen. if not a proximity change from out to in, send - * an out of proximity for previous tool then a in for new tool. - */ - if (!wacom->tool[0]) { - /* Eraser bit set for DTF */ - if (data[1] & 0x10) - wacom->tool[1] = BTN_TOOL_RUBBER; - else - /* Going into proximity select tool */ - wacom->tool[1] = (data[4] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - } else { - /* was entered with stylus2 pressed */ - if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) { - /* report out proximity for previous tool */ - wacom_report_key(wcombo, wacom->tool[1], 0); - wacom_input_sync(wcombo); - wacom->tool[1] = BTN_TOOL_PEN; - return 0; - } - } - if (wacom->tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom->tool[1] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - } - wacom_report_key(wcombo, wacom->tool[1], prox); /* report in proximity for tool */ - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ - wacom_report_abs(wcombo, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); - wacom_report_abs(wcombo, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); - wacom_report_abs(wcombo, ABS_PRESSURE, pressure); - wacom_report_key(wcombo, BTN_TOUCH, pressure); - wacom_report_key(wcombo, BTN_STYLUS, data[4] & 0x10); - /* Only allow the stylus2 button to be reported for the pen tool. */ - wacom_report_key(wcombo, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20)); - } else { - /* report proximity-out of a (valid) tool */ - if (wacom->tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom->tool[1] = BTN_TOOL_PEN; - } - wacom_report_key(wcombo, wacom->tool[1], prox); - } - - wacom->tool[0] = prox; /* Save proximity state */ - return 1; -} - -static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - - if (data[0] != 2) { - printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); - return 0; - } - - if (data[1] & 0x04) { - wacom_report_key(wcombo, BTN_TOOL_RUBBER, data[1] & 0x20); - wacom->id[0] = ERASER_DEVICE_ID; - } else { - wacom_report_key(wcombo, BTN_TOOL_PEN, data[1] & 0x20); - wacom->id[0] = STYLUS_DEVICE_ID; - } - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); - wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); - wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6])); - wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); - wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); - return 1; -} - -static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - int x, y, rw; - - if (data[0] != 2) { - dbg("wacom_graphire_irq: received unknown report #%d", data[0]); - return 0; - } - - if (data[1] & 0x80) { - /* in prox and not a pad data */ - - switch ((data[1] >> 5) & 3) { - - case 0: /* Pen */ - wacom->tool[0] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - break; - - case 1: /* Rubber */ - wacom->tool[0] = BTN_TOOL_RUBBER; - wacom->id[0] = ERASER_DEVICE_ID; - break; - - case 2: /* Mouse with wheel */ - wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); - if (wacom->features->type == WACOM_G4 || - wacom->features->type == WACOM_MO) { - rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); - wacom_report_rel(wcombo, REL_WHEEL, -rw); - } else - wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]); - /* fall through */ - - case 3: /* Mouse without wheel */ - wacom->tool[0] = BTN_TOOL_MOUSE; - wacom->id[0] = CURSOR_DEVICE_ID; - wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); - wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); - if (wacom->features->type == WACOM_G4 || - wacom->features->type == WACOM_MO) - wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); - else - wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); - break; - } - x = wacom_le16_to_cpu(&data[2]); - y = wacom_le16_to_cpu(&data[4]); - wacom_report_abs(wcombo, ABS_X, x); - wacom_report_abs(wcombo, ABS_Y, y); - if (wacom->tool[0] != BTN_TOOL_MOUSE) { - wacom_report_abs(wcombo, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8)); - wacom_report_key(wcombo, BTN_TOUCH, data[6] | ((data[7] & 0x01) << 8)); - wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); - wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); - } - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ - wacom_report_key(wcombo, wacom->tool[0], 1); - } else if (wacom->id[0]) { - wacom_report_abs(wcombo, ABS_X, 0); - wacom_report_abs(wcombo, ABS_Y, 0); - if (wacom->tool[0] == BTN_TOOL_MOUSE) { - wacom_report_key(wcombo, BTN_LEFT, 0); - wacom_report_key(wcombo, BTN_RIGHT, 0); - wacom_report_abs(wcombo, ABS_DISTANCE, 0); - } else { - wacom_report_abs(wcombo, ABS_PRESSURE, 0); - wacom_report_key(wcombo, BTN_TOUCH, 0); - wacom_report_key(wcombo, BTN_STYLUS, 0); - wacom_report_key(wcombo, BTN_STYLUS2, 0); - } - wacom->id[0] = 0; - wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ - wacom_report_key(wcombo, wacom->tool[0], 0); - } - - /* send pad data */ - switch (wacom->features->type) { - case WACOM_G4: - if (data[7] & 0xf8) { - wacom_input_sync(wcombo); /* sync last event */ - wacom->id[1] = PAD_DEVICE_ID; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); - rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); - wacom_report_rel(wcombo, REL_WHEEL, rw); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); - wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } else if (wacom->id[1]) { - wacom_input_sync(wcombo); /* sync last event */ - wacom->id[1] = 0; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); - wacom_report_abs(wcombo, ABS_MISC, 0); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } - break; - case WACOM_MO: - if ((data[7] & 0xf8) || (data[8] & 0xff)) { - wacom_input_sync(wcombo); /* sync last event */ - wacom->id[1] = PAD_DEVICE_ID; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); - wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); - wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); - wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); - wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } else if (wacom->id[1]) { - wacom_input_sync(wcombo); /* sync last event */ - wacom->id[1] = 0; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); - wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); - wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); - wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); - wacom_report_abs(wcombo, ABS_MISC, 0); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } - break; - } - return 1; -} - -static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - int idx = 0; - - /* tool number */ - if (wacom->features->type == INTUOS) - idx = data[1] & 0x01; - - /* Enter report */ - if ((data[1] & 0xfc) == 0xc0) { - /* serial number of the tool */ - wacom->serial[idx] = ((data[3] & 0x0f) << 28) + - (data[4] << 20) + (data[5] << 12) + - (data[6] << 4) + (data[7] >> 4); - - wacom->id[idx] = (data[2] << 4) | (data[3] >> 4); - switch (wacom->id[idx]) { - case 0x812: /* Inking pen */ - case 0x801: /* Intuos3 Inking pen */ - case 0x20802: /* Intuos4 Inking Pen */ - case 0x012: - wacom->tool[idx] = BTN_TOOL_PENCIL; - break; - case 0x822: /* Pen */ - case 0x842: - case 0x852: - case 0x823: /* Intuos3 Grip Pen */ - case 0x813: /* Intuos3 Classic Pen */ - case 0x885: /* Intuos3 Marker Pen */ - case 0x802: /* Intuos4 Grip Pen Eraser */ - case 0x804: /* Intuos4 Marker Pen */ - case 0x40802: /* Intuos4 Classic Pen */ - case 0x022: - wacom->tool[idx] = BTN_TOOL_PEN; - break; - case 0x832: /* Stroke pen */ - case 0x032: - wacom->tool[idx] = BTN_TOOL_BRUSH; - break; - case 0x007: /* Mouse 4D and 2D */ - case 0x09c: - case 0x094: - case 0x017: /* Intuos3 2D Mouse */ - case 0x806: /* Intuos4 Mouse */ - wacom->tool[idx] = BTN_TOOL_MOUSE; - break; - case 0x096: /* Lens cursor */ - case 0x097: /* Intuos3 Lens cursor */ - case 0x006: /* Intuos4 Lens cursor */ - wacom->tool[idx] = BTN_TOOL_LENS; - break; - case 0x82a: /* Eraser */ - case 0x85a: - case 0x91a: - case 0xd1a: - case 0x0fa: - case 0x82b: /* Intuos3 Grip Pen Eraser */ - case 0x81b: /* Intuos3 Classic Pen Eraser */ - case 0x91b: /* Intuos3 Airbrush Eraser */ - case 0x80c: /* Intuos4 Marker Pen Eraser */ - case 0x80a: /* Intuos4 Grip Pen Eraser */ - case 0x4080a: /* Intuos4 Classic Pen Eraser */ - case 0x90a: /* Intuos4 Airbrush Eraser */ - wacom->tool[idx] = BTN_TOOL_RUBBER; - break; - case 0xd12: - case 0x912: - case 0x112: - case 0x913: /* Intuos3 Airbrush */ - case 0x902: /* Intuos4 Airbrush */ - wacom->tool[idx] = BTN_TOOL_AIRBRUSH; - break; - default: /* Unknown tool */ - wacom->tool[idx] = BTN_TOOL_PEN; - } - return 1; - } - - /* Exit report */ - if ((data[1] & 0xfe) == 0x80) { - wacom_report_abs(wcombo, ABS_X, 0); - wacom_report_abs(wcombo, ABS_Y, 0); - wacom_report_abs(wcombo, ABS_DISTANCE, 0); - if (wacom->tool[idx] >= BTN_TOOL_MOUSE) { - wacom_report_key(wcombo, BTN_LEFT, 0); - wacom_report_key(wcombo, BTN_MIDDLE, 0); - wacom_report_key(wcombo, BTN_RIGHT, 0); - wacom_report_key(wcombo, BTN_SIDE, 0); - wacom_report_key(wcombo, BTN_EXTRA, 0); - wacom_report_abs(wcombo, ABS_THROTTLE, 0); - wacom_report_abs(wcombo, ABS_RZ, 0); - } else { - wacom_report_abs(wcombo, ABS_PRESSURE, 0); - wacom_report_key(wcombo, BTN_TOUCH, 0); - wacom_report_key(wcombo, BTN_STYLUS, 0); - wacom_report_key(wcombo, BTN_STYLUS2, 0); - wacom_report_abs(wcombo, ABS_WHEEL, 0); - if (wacom->features->type >= INTUOS3S) - wacom_report_abs(wcombo, ABS_Z, 0); - } - wacom_report_abs(wcombo, ABS_TILT_X, 0); - wacom_report_abs(wcombo, ABS_TILT_Y, 0); - wacom_report_key(wcombo, wacom->tool[idx], 0); - wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); - wacom->id[idx] = 0; - return 2; - } - return 0; -} - -static void wacom_intuos_general(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - unsigned int t; - - /* general pen packet */ - if ((data[1] & 0xb8) == 0xa0) { - t = (data[6] << 2) | ((data[7] >> 6) & 3); - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) - t = (t << 1) | (data[1] & 1); - wacom_report_abs(wcombo, ABS_PRESSURE, t); - wacom_report_key(wcombo, BTN_TOUCH, t); - wacom_report_abs(wcombo, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f); - wacom_report_key(wcombo, BTN_STYLUS, data[1] & 2); - wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 4); - } - - /* airbrush second packet */ - if ((data[1] & 0xbc) == 0xb4) { - wacom_report_abs(wcombo, ABS_WHEEL, - (data[6] << 2) | ((data[7] >> 6) & 3)); - wacom_report_abs(wcombo, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f); - } - return; -} - -static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - unsigned int t; - int idx = 0, result; - - if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) { - dbg("wacom_intuos_irq: received unknown report #%d", data[0]); - return 0; - } - - /* tool number */ - if (wacom->features->type == INTUOS) - idx = data[1] & 0x01; - - /* pad packets. Works as a second tool */ - if (data[0] == 12) { - /* initiate the pad as a device */ - if (wacom->tool[1] != BTN_TOOL_FINGER) - wacom->tool[1] = BTN_TOOL_FINGER; - - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { - wacom_report_key(wcombo, BTN_0, (data[2] & 0x01)); - wacom_report_key(wcombo, BTN_1, (data[3] & 0x01)); - wacom_report_key(wcombo, BTN_2, (data[3] & 0x02)); - wacom_report_key(wcombo, BTN_3, (data[3] & 0x04)); - wacom_report_key(wcombo, BTN_4, (data[3] & 0x08)); - wacom_report_key(wcombo, BTN_5, (data[3] & 0x10)); - wacom_report_key(wcombo, BTN_6, (data[3] & 0x20)); - if (data[1] & 0x80) { - wacom_report_abs(wcombo, ABS_WHEEL, (data[1] & 0x7f)); - } else { - /* Out of proximity, clear wheel value. */ - wacom_report_abs(wcombo, ABS_WHEEL, 0); - } - if (wacom->features->type != INTUOS4S) { - wacom_report_key(wcombo, BTN_7, (data[3] & 0x40)); - wacom_report_key(wcombo, BTN_8, (data[3] & 0x80)); - } - if (data[1] | (data[2] & 0x01) | data[3]) { - wacom_report_key(wcombo, wacom->tool[1], 1); - wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); - } else { - wacom_report_key(wcombo, wacom->tool[1], 0); - wacom_report_abs(wcombo, ABS_MISC, 0); - } - } else { - wacom_report_key(wcombo, BTN_0, (data[5] & 0x01)); - wacom_report_key(wcombo, BTN_1, (data[5] & 0x02)); - wacom_report_key(wcombo, BTN_2, (data[5] & 0x04)); - wacom_report_key(wcombo, BTN_3, (data[5] & 0x08)); - wacom_report_key(wcombo, BTN_4, (data[6] & 0x01)); - wacom_report_key(wcombo, BTN_5, (data[6] & 0x02)); - wacom_report_key(wcombo, BTN_6, (data[6] & 0x04)); - wacom_report_key(wcombo, BTN_7, (data[6] & 0x08)); - wacom_report_key(wcombo, BTN_8, (data[5] & 0x10)); - wacom_report_key(wcombo, BTN_9, (data[6] & 0x10)); - wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); - wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); - - if ((data[5] & 0x1f) | (data[6] & 0x1f) | (data[1] & 0x1f) | - data[2] | (data[3] & 0x1f) | data[4]) { - wacom_report_key(wcombo, wacom->tool[1], 1); - wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); - } else { - wacom_report_key(wcombo, wacom->tool[1], 0); - wacom_report_abs(wcombo, ABS_MISC, 0); - } - } - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xffffffff); - return 1; - } - /* process in/out prox events */ - result = wacom_intuos_inout(wacom, wcombo); - if (result) - return result-1; - - /* don't proceed if we don't know the ID */ - if (!wacom->id[idx]) - return 0; - - /* Only large Intuos support Lense Cursor */ - if ((wacom->tool[idx] == BTN_TOOL_LENS) - && ((wacom->features->type == INTUOS3) - || (wacom->features->type == INTUOS3S) - || (wacom->features->type == INTUOS4) - || (wacom->features->type == INTUOS4S))) - return 0; - - /* Cintiq doesn't send data when RDY bit isn't set */ - if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40)) - return 0; - - if (wacom->features->type >= INTUOS3S) { - wacom_report_abs(wcombo, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); - wacom_report_abs(wcombo, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); - wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); - } else { - wacom_report_abs(wcombo, ABS_X, wacom_be16_to_cpu(&data[2])); - wacom_report_abs(wcombo, ABS_Y, wacom_be16_to_cpu(&data[4])); - wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); - } - - /* process general packets */ - wacom_intuos_general(wacom, wcombo); - - /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ - if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) { - - if (data[1] & 0x02) { - /* Rotation packet */ - if (wacom->features->type >= INTUOS3S) { - /* I3 marker pen rotation */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : - ((t-1) / 2 + 450)) : (450 - t / 2) ; - wacom_report_abs(wcombo, ABS_Z, t); - } else { - /* 4D mouse rotation packet */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - wacom_report_abs(wcombo, ABS_RZ, (data[7] & 0x20) ? - ((t - 1) / 2) : -t / 2); - } - - } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3S) { - /* 4D mouse packet */ - wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); - wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); - wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x04); - - wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x20); - wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x10); - t = (data[6] << 2) | ((data[7] >> 6) & 3); - wacom_report_abs(wcombo, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); - - } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { - /* I4 mouse */ - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { - wacom_report_key(wcombo, BTN_LEFT, data[6] & 0x01); - wacom_report_key(wcombo, BTN_MIDDLE, data[6] & 0x02); - wacom_report_key(wcombo, BTN_RIGHT, data[6] & 0x04); - wacom_report_rel(wcombo, REL_WHEEL, ((data[7] & 0x80) >> 7) - - ((data[7] & 0x40) >> 6)); - wacom_report_key(wcombo, BTN_SIDE, data[6] & 0x08); - wacom_report_key(wcombo, BTN_EXTRA, data[6] & 0x10); - - wacom_report_abs(wcombo, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f); - } else { - /* 2D mouse packet */ - wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x04); - wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x08); - wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x10); - wacom_report_rel(wcombo, REL_WHEEL, (data[8] & 0x01) - - ((data[8] & 0x02) >> 1)); - - /* I3 2D mouse side buttons */ - if (wacom->features->type >= INTUOS3S && wacom->features->type <= INTUOS3L) { - wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x40); - wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x20); - } - } - } else if ((wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L || - wacom->features->type == INTUOS4L) && (wacom->tool[idx] == BTN_TOOL_LENS)) { - /* Lens cursor packets */ - wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); - wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); - wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x04); - wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x10); - wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x08); - } - } - - wacom_report_abs(wcombo, ABS_MISC, wacom->id[idx]); /* report tool id */ - wacom_report_key(wcombo, wacom->tool[idx], 1); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); - return 1; -} - -int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) -{ - char *data = wacom->data; - int prox = 0, pressure; - static int stylusInProx, touchInProx = 1, touchOut; - struct urb *urb = ((struct wacom_combo *)wcombo)->urb; - - dbg("wacom_tpc_irq: received report #%d", data[0]); - - if (urb->actual_length == 5 || data[0] == 6) { /* Touch data */ - if (urb->actual_length == 5) { /* with touch */ - prox = data[0] & 0x03; - } else { /* with capacity */ - prox = data[1] & 0x03; - } - - if (!stylusInProx) { /* stylus not in prox */ - if (prox) { - if (touchInProx) { - wacom->tool[1] = BTN_TOOL_DOUBLETAP; - wacom->id[0] = TOUCH_DEVICE_ID; - if (urb->actual_length != 5) { - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); - wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); - wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6])); - } else { - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); - wacom_report_key(wcombo, BTN_TOUCH, 1); - } - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); - wacom_report_key(wcombo, wacom->tool[1], prox & 0x01); - touchOut = 1; - return 1; - } - } else { - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); - wacom_report_key(wcombo, wacom->tool[1], prox & 0x01); - wacom_report_key(wcombo, BTN_TOUCH, 0); - touchOut = 0; - touchInProx = 1; - return 1; - } - } else if (touchOut || !prox) { /* force touch out-prox */ - wacom_report_abs(wcombo, ABS_MISC, TOUCH_DEVICE_ID); - wacom_report_key(wcombo, wacom->tool[1], 0); - wacom_report_key(wcombo, BTN_TOUCH, 0); - touchOut = 0; - touchInProx = 1; - return 1; - } - } else if (data[0] == 2) { /* Penabled */ - prox = data[1] & 0x20; - - touchInProx = 0; - - wacom->id[0] = ERASER_DEVICE_ID; - - /* - * if going from out of proximity into proximity select between the eraser - * and the pen based on the state of the stylus2 button, choose eraser if - * pressed else choose pen. if not a proximity change from out to in, send - * an out of proximity for previous tool then a in for new tool. - */ - if (prox) { /* in prox */ - if (!wacom->tool[0]) { - /* Going into proximity select tool */ - wacom->tool[1] = (data[1] & 0x08) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - if (wacom->tool[1] == BTN_TOOL_PEN) - wacom->id[0] = STYLUS_DEVICE_ID; - } else if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[1] & 0x08)) { - /* - * was entered with stylus2 pressed - * report out proximity for previous tool - */ - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); - wacom_report_key(wcombo, wacom->tool[1], 0); - wacom_input_sync(wcombo); - - /* set new tool */ - wacom->tool[1] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - return 0; - } - if (wacom->tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom->tool[1] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - } - wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); - wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); - pressure = ((data[7] & 0x01) << 8) | data[6]; - if (pressure < 0) - pressure = wacom->features->pressure_max + pressure + 1; - wacom_report_abs(wcombo, ABS_PRESSURE, pressure); - wacom_report_key(wcombo, BTN_TOUCH, pressure); - } else { - wacom_report_abs(wcombo, ABS_PRESSURE, 0); - wacom_report_key(wcombo, BTN_TOUCH, 0); - wacom_report_key(wcombo, BTN_STYLUS, 0); - wacom_report_key(wcombo, BTN_STYLUS2, 0); - } - wacom_report_key(wcombo, wacom->tool[1], prox); - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); - stylusInProx = prox; - wacom->tool[0] = prox; - return 1; - } - return 0; -} - -int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) -{ - switch (wacom_wac->features->type) { - case PENPARTNER: - return (wacom_penpartner_irq(wacom_wac, wcombo)); - break; - case PL: - return (wacom_pl_irq(wacom_wac, wcombo)); - break; - case WACOM_G4: - case GRAPHIRE: - case WACOM_MO: - return (wacom_graphire_irq(wacom_wac, wcombo)); - break; - case PTU: - return (wacom_ptu_irq(wacom_wac, wcombo)); - break; - case INTUOS: - case INTUOS3S: - case INTUOS3: - case INTUOS3L: - case CINTIQ: - case WACOM_BEE: - case INTUOS4S: - case INTUOS4: - case INTUOS4L: - return (wacom_intuos_irq(wacom_wac, wcombo)); - break; - case TABLETPC: - return (wacom_tpc_irq(wacom_wac, wcombo)); - break; - default: - return 0; - } - return 0; -} - -void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - switch (wacom_wac->features->type) { - case WACOM_MO: - input_dev_mo(input_dev, wacom_wac); - case WACOM_G4: - input_dev_g4(input_dev, wacom_wac); - /* fall through */ - case GRAPHIRE: - input_dev_g(input_dev, wacom_wac); - break; - case WACOM_BEE: - input_dev_bee(input_dev, wacom_wac); - case INTUOS3: - case INTUOS3L: - case CINTIQ: - input_dev_i3(input_dev, wacom_wac); - /* fall through */ - case INTUOS3S: - input_dev_i3s(input_dev, wacom_wac); - /* fall through */ - case INTUOS: - input_dev_i(input_dev, wacom_wac); - break; - case INTUOS4: - case INTUOS4L: - input_dev_i4(input_dev, wacom_wac); - /* fall through */ - case INTUOS4S: - input_dev_i4s(input_dev, wacom_wac); - input_dev_i(input_dev, wacom_wac); - break; - case PL: - case PTU: - case TABLETPC: - input_dev_pl(input_dev, wacom_wac); - /* fall through */ - case PENPARTNER: - input_dev_pt(input_dev, wacom_wac); - break; - } - return; -} - -static struct wacom_features wacom_features[] = { - { "Wacom Penpartner", 7, 5040, 3780, 255, 0, PENPARTNER }, - { "Wacom Graphire", 8, 10206, 7422, 511, 63, GRAPHIRE }, - { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 63, GRAPHIRE }, - { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 63, GRAPHIRE }, - { "Wacom Graphire3", 8, 10208, 7424, 511, 63, GRAPHIRE }, - { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE }, - { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, WACOM_G4 }, - { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 }, - { "Wacom BambooFun 4x5", 9, 14760, 9225, 511, 63, WACOM_MO }, - { "Wacom BambooFun 6x8", 9, 21648, 13530, 511, 63, WACOM_MO }, - { "Wacom Bamboo1 Medium", 8, 16704, 12064, 511, 63, GRAPHIRE }, - { "Wacom Volito", 8, 5104, 3712, 511, 63, GRAPHIRE }, - { "Wacom PenStation2", 8, 3250, 2320, 255, 63, GRAPHIRE }, - { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE }, - { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE }, - { "Wacom PenPartner2", 8, 3250, 2320, 511, 63, GRAPHIRE }, - { "Wacom Bamboo", 9, 14760, 9225, 511, 63, WACOM_MO }, - { "Wacom Bamboo1", 8, 5104, 3712, 511, 63, GRAPHIRE }, - { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, - { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, - { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS }, - { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 31, INTUOS }, - { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 31, INTUOS }, - { "Wacom PL400", 8, 5408, 4056, 255, 0, PL }, - { "Wacom PL500", 8, 6144, 4608, 255, 0, PL }, - { "Wacom PL600", 8, 6126, 4604, 255, 0, PL }, - { "Wacom PL600SX", 8, 6260, 5016, 255, 0, PL }, - { "Wacom PL550", 8, 6144, 4608, 511, 0, PL }, - { "Wacom PL800", 8, 7220, 5780, 511, 0, PL }, - { "Wacom PL700", 8, 6758, 5406, 511, 0, PL }, - { "Wacom PL510", 8, 6282, 4762, 511, 0, PL }, - { "Wacom DTU710", 8, 34080, 27660, 511, 0, PL }, - { "Wacom DTF521", 8, 6282, 4762, 511, 0, PL }, - { "Wacom DTF720", 8, 6858, 5506, 511, 0, PL }, - { "Wacom DTF720a", 8, 6858, 5506, 511, 0, PL }, - { "Wacom DTU1931", 8, 37832, 30305, 511, 0, PL }, - { "Wacom Cintiq Partner", 8, 20480, 15360, 511, 0, PTU }, - { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, - { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, - { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 31, INTUOS }, - { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 31, INTUOS }, - { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 31, INTUOS }, - { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 63, INTUOS3S }, - { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 63, INTUOS3 }, - { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 63, INTUOS3 }, - { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L }, - { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L }, - { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 }, - { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S }, - { "Wacom Intuos4 4x6", 10, 31496, 19685, 2047, 63, INTUOS4S }, - { "Wacom Intuos4 6x9", 10, 44704, 27940, 2047, 63, INTUOS4 }, - { "Wacom Intuos4 8x13", 10, 65024, 40640, 2047, 63, INTUOS4L }, - { "Wacom Intuos4 12x19", 10, 97536, 60960, 2047, 63, INTUOS4L }, - { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, - { "Wacom Cintiq 20WSX", 10, 86680, 54180, 1023, 63, WACOM_BEE }, - { "Wacom Cintiq 12WX", 10, 53020, 33440, 1023, 63, WACOM_BEE }, - { "Wacom Graphire Bluetooth", 8, 10208, 7424, 511, 63, WACOM_G4 }, - { "Wacom ISDv4 90", 8, 26202, 16325, 255, 0, TABLETPC }, - { "Wacom ISDv4 93", 8, 26202, 16325, 255, 0, TABLETPC }, - { "Wacom ISDv4 9A", 8, 26202, 16325, 255, 0, TABLETPC }, - { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, - { } -}; - -static struct usb_device_id wacom_ids[] = { - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x00) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x11) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x17) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x18) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x19) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x69) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x30) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x32) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC4) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC2) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC7) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB8) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB9) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBA) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBB) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x81) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x90) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x93) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9A) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, - { } -}; - -const struct usb_device_id * get_device_table(void) { - const struct usb_device_id * id_table = wacom_ids; - return id_table; -} - -struct wacom_features * get_wacom_feature(const struct usb_device_id * id) { - int index = id - wacom_ids; - struct wacom_features *wf = &wacom_features[index]; - return wf; -} - -MODULE_DEVICE_TABLE(usb, wacom_ids); diff --git a/src/2.6.22/Makefile.in b/src/2.6.22/Makefile.in deleted file mode 100755 index 0278d1a..0000000 --- a/src/2.6.22/Makefile.in +++ /dev/null @@ -1,44 +0,0 @@ -############################ 2.6 kernel compile ############################### -ifneq ($(KERNELRELEASE),) -# We were called by kbuild -# Do NOT indent stuff in this part! It has to be like this to make the -# $(error ... ) stuff work - -ifeq ($(WCM_OPTION_WACOM),yes) -ifneq ($(CONFIG_USB_WACOM),y) -wacom-objs := wacom_wac.o wacom_sys.o -obj-m += wacom.o -else -$(error You requested to build wacom with configure, but wacom is configured as built-in in your kernel config) -endif # CONFIG_USB_WACOM -endif # WCM_OPTION_WACOM - -else # We were called from command line -PWD := $(shell pwd) - -WCM_KERNEL_DIR := @WCM_KERNEL_DIR@ -WCM_OPTION_WACOM := @WCM_OPTION_WACOM@ - -export WCM_OPTION_WACOM - -all: -# Copy Wacom specific code which is common to all kernel releases -ifeq ($(WCM_OPTION_WACOM),yes) - cp -f ../2.6.19/wacom_wac.c . - cp -f ../2.6.19/wacom.h . -endif - @echo ' Building linuxwacom drivers for 2.6 kernel.' - @echo '***Note: Drivers not enabled as modules in your kernel config but requested through configure are NOT built' - $(MAKE) -C $(WCM_KERNEL_DIR) M=$(PWD) - -endif # End kbuild check - -######################### Version independent targets ########################## - -clean: - rm -rf *.o *.ko *.mod.* .[a-z]* core *.i - -EMPTY_AUTOMAKE_TARGETS = distdir install install-data install-exec uninstall install-info -EMPTY_AUTOMAKE_TARGETS += installdirs check dvi pdf ps info html tags ctags mostlyclean distclean maintainer-clean -.PHONY: $(EMPTY_AUTOMAKE_TARGETS) - $(EMPTY_AUTOMAKE_TARGETS): diff --git a/src/2.6.22/wacom_sys.c b/src/2.6.22/wacom_sys.c deleted file mode 100755 index cf7212d..0000000 --- a/src/2.6.22/wacom_sys.c +++ /dev/null @@ -1,505 +0,0 @@ -/* - * drivers/input/tablet/wacom_sys.c - * - * USB Wacom Graphire and Wacom Intuos tablet support - system specific code - */ - -/* - * 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. - */ - -#include "wacom.h" -#include "wacom_wac.h" - -/* defines to get HID report descriptor */ -#define HID_DEVICET_HID (USB_TYPE_CLASS | 0x01) -#define HID_DEVICET_REPORT (USB_TYPE_CLASS | 0x02) -#define HID_USAGE_UNDEFINED 0x00 -#define HID_USAGE_PAGE 0x05 -#define HID_USAGE_PAGE_DIGITIZER 0x0d -#define HID_USAGE_PAGE_DESKTOP 0x01 -#define HID_USAGE 0x09 -#define HID_USAGE_X 0x30 -#define HID_USAGE_Y 0x31 -#define HID_USAGE_X_TILT 0x3d -#define HID_USAGE_Y_TILT 0x3e -#define HID_USAGE_FINGER 0x22 -#define HID_USAGE_STYLUS 0x20 -#define HID_COLLECTION 0xc0 -#define HID_USAGE_PAGE_VDEFINED 0xff - -enum { - WCM_UNDEFINED = 0, - WCM_DESKTOP, - WCM_DIGITIZER, - MAX_USAGE_PAGE -}; - -struct hid_descriptor -{ - struct usb_descriptor_header header; - __le16 bcdHID; - u8 bCountryCode; - u8 bNumDescriptors; - u8 bDescriptorType; - __le16 wDescriptorLength; -} __attribute__ ((packed)); - -/* defines to get/set USB message */ -#define USB_REQ_GET_REPORT 0x01 -#define USB_REQ_SET_REPORT 0x09 -#define WAC_HID_FEATURE_REPORT 0x03 - -static int usb_get_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 100); -} - -static int usb_set_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_sndctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 1000); -} - -static struct input_dev * get_input_dev(struct wacom_combo *wcombo) -{ - return wcombo->wacom->dev; -} - -static void wacom_sys_irq(struct urb *urb) -{ - struct wacom *wacom = urb->context; - struct wacom_combo wcombo; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - wcombo.wacom = wacom; - wcombo.urb = urb; - - if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo)) - input_sync(get_input_dev(&wcombo)); - - exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) -{ - input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); - return; -} - -void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data) -{ - input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data); - return; -} - -void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data) -{ - input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data); - return; -} - -void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value) -{ - input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value); - return; -} - -__u16 wacom_be16_to_cpu(unsigned char *data) -{ - __u16 value; - value = be16_to_cpu(*(__be16 *) data); - return value; -} - -__u16 wacom_le16_to_cpu(unsigned char *data) -{ - __u16 value; - value = le16_to_cpu(*(__le16 *) data); - return value; -} - -void wacom_input_sync(void *wcombo) -{ - input_sync(get_input_dev((struct wacom_combo *)wcombo)); - return; -} - -static int wacom_open(struct input_dev *dev) -{ - struct wacom *wacom = input_get_drvdata(dev); - - wacom->irq->dev = wacom->usbdev; - if (usb_submit_urb(wacom->irq, GFP_KERNEL)) - return -EIO; - - return 0; -} - -static void wacom_close(struct input_dev *dev) -{ - struct wacom *wacom = input_get_drvdata(dev); - - usb_kill_urb(wacom->irq); -} - -void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_1) | BIT(BTN_5); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); -} - -void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_MSC); - input_dev->mscbit[0] |= BIT(MSC_SERIAL); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_4); -} - -void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_REL); - input_dev->relbit[0] |= BIT(REL_WHEEL); - input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); -} - -void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); - input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); - input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); -} - -void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_7) | BIT(BTN_8); -} - -void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_MISC)] |= BIT(BTN_8) | BIT(BTN_9); -} - -void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); - input_dev->mscbit[0] |= BIT(MSC_SERIAL); - input_dev->relbit[0] |= BIT(REL_WHEEL); - input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) - | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); - input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); -} - -void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2); -} - -void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER); -} - - -static void wacom_paser_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, - struct wacom_wac *wacom_wac, char *report) -{ - struct usb_device *dev = interface_to_usbdev(intf); - char limit = 0, result = 0; - int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; - - /* retrive report descriptors */ - do { - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, - USB_RECIP_INTERFACE | USB_DIR_IN, - HID_DEVICET_REPORT << 8, - intf->altsetting[0].desc.bInterfaceNumber, /* interface */ - report, - hid_desc->wDescriptorLength, - 5000); /* 5 secs */ - } while (limit++ < 5); - - for (i=0; i<hid_desc->wDescriptorLength; i++) { - if (report[i] == HID_USAGE_PAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_PAGE_DIGITIZER: - usage = WCM_DIGITIZER; - i++; - continue; - case HID_USAGE_PAGE_DESKTOP: - usage = WCM_DESKTOP; - i++; - continue; - } - } - - if ((unsigned short)report[i] == HID_USAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_X: - if (usage == WCM_DESKTOP) { - if (finger) { - wacom_wac->features->touch_x_max = - wacom_wac->features->touch_y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+6])); - i += 7; - } else if (pen) { - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - i += 4; - } - } else if (usage == WCM_DIGITIZER) { - /* max pressure isn't reported - wacom_wac->features->pressure_max = (unsigned short) - (report[i+4] << 8 | report[i+3]); - */ - wacom_wac->features->pressure_max = 255; - i += 4; - } - break; - case HID_USAGE_Y: - if (usage == WCM_DESKTOP) { - wacom_wac->features->y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - case HID_USAGE_FINGER: - finger = 1; - i++; - break; - case HID_USAGE_STYLUS: - pen = 1; - i++; - break; - case HID_USAGE_UNDEFINED: - if (usage == WCM_DESKTOP && finger) { /* capacity */ - wacom_wac->features->pressure_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - } - } - - if ((unsigned short)report[i] == HID_COLLECTION) { - /* reset UsagePage ans Finger */ - finger = usage = 0; - } - } -} - -static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - int error = -ENOMEM; - struct usb_device *dev = interface_to_usbdev(intf); - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_endpoint_descriptor *endpoint; - struct wacom *wacom; - struct wacom_wac *wacom_wac; - struct input_dev *input_dev; - char rep_data[2], limit = 0, mode = 2, *report = NULL; - struct hid_descriptor *hid_desc; - - wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); - wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!wacom || !input_dev || !wacom_wac) - goto fail1; - - wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); - if (!wacom_wac->data) - goto fail1; - - wacom->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!wacom->irq) - goto fail2; - - wacom->usbdev = dev; - wacom->dev = input_dev; - usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); - strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); - - wacom_wac->features = get_wacom_feature(id); - BUG_ON(wacom_wac->features->pktlen > 10); - - input_dev->name = wacom_wac->features->name; - wacom->wacom_wac = wacom_wac; - usb_to_input_id(dev, &input_dev->id); - - input_dev->dev.parent = &intf->dev; - input_set_drvdata(input_dev, wacom); - input_dev->open = wacom_open; - input_dev->close = wacom_close; - - endpoint = &intf->cur_altsetting->endpoint[0].desc; - - /* Initialize touch_x_max and touch_y_max in case it is not defined */ - if (wacom_wac->features->type == TABLETPC) { - wacom_wac->features->touch_x_max = 1023; - wacom_wac->features->touch_y_max = 1023; - } else { - wacom_wac->features->touch_x_max = 0; - wacom_wac->features->touch_y_max = 0; - } - - /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ - if (wacom_wac->features->type == TABLETPC) { - if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { - if (usb_get_extra_descriptor(&interface->endpoint[0], - HID_DEVICET_REPORT, &hid_desc)) { - printk("wacom: can not retrive extra class descriptor\n"); - goto fail2; - } - } - report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); - if (!report) { - goto fail2; - } - wacom_paser_hid(intf, hid_desc, wacom_wac, report); - } - - input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_STYLUS) | BIT(BTN_TOUCH); - input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0); - input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0); - if (wacom_wac->features->type == TABLETPC) { - input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_DOUBLETAP); - input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->touch_x_max, 4, 0); - input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->touch_y_max, 4, 0); - } - input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0); - input_dev->absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC); - - wacom_init_input_dev(input_dev, wacom_wac); - - usb_fill_int_urb(wacom->irq, dev, - usb_rcvintpipe(dev, endpoint->bEndpointAddress), - wacom_wac->data, wacom_wac->features->pktlen, - wacom_sys_irq, wacom, endpoint->bInterval); - wacom->irq->transfer_dma = wacom->data_dma; - wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - error = input_register_device(wacom->dev); - if (error) - goto fail3; - - /* Ask the tablet to report tablet data if it is not a Tablet PC. - * Repeat until it succeeds - */ - if (wacom_wac->features->type != TABLETPC) { - do { - rep_data[0] = 2; - rep_data[1] = mode; - usb_set_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); - usb_get_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); - } while (rep_data[1] != mode && limit++ < 5); - } - - usb_set_intfdata(intf, wacom); - kfree(report); - return 0; - - fail3: usb_free_urb(wacom->irq); - fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); - fail1: input_free_device(input_dev); - kfree(wacom); - kfree(wacom_wac); - return error; -} - -static void wacom_disconnect(struct usb_interface *intf) -{ - struct wacom *wacom = usb_get_intfdata (intf); - - usb_set_intfdata(intf, NULL); - if (wacom) { - usb_kill_urb(wacom->irq); - input_unregister_device(wacom->dev); - usb_free_urb(wacom->irq); - usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); - kfree(wacom->wacom_wac); - kfree(wacom); - } -} - -static struct usb_driver wacom_driver = { - .name = "wacom", - .probe = wacom_probe, - .disconnect = wacom_disconnect, -}; - -static int __init wacom_init(void) -{ - int result; - wacom_driver.id_table = get_device_table(); - result = usb_register(&wacom_driver); - if (result == 0) - info(DRIVER_VERSION ":" DRIVER_DESC); - return result; -} - -static void __exit wacom_exit(void) -{ - usb_deregister(&wacom_driver); -} - -module_init(wacom_init); -module_exit(wacom_exit); diff --git a/src/2.6.22/wacom_wac.h b/src/2.6.22/wacom_wac.h deleted file mode 100755 index a0c8818..0000000 --- a/src/2.6.22/wacom_wac.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * drivers/input/tablet/wacom_wac.h - * - * 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. - */ -#ifndef WACOM_WAC_H -#define WACOM_WAC_H - -#define STYLUS_DEVICE_ID 0x02 -#define TOUCH_DEVICE_ID 0x03 -#define CURSOR_DEVICE_ID 0x06 -#define ERASER_DEVICE_ID 0x0A -#define PAD_DEVICE_ID 0x0F - -enum { - PENPARTNER = 0, - GRAPHIRE, - WACOM_G4, - PTU, - PL, - INTUOS, - INTUOS3S, - INTUOS3, - INTUOS3L, - CINTIQ, - WACOM_BEE, - INTUOS4S, - INTUOS4, - INTUOS4L, - WACOM_MO, - TABLETPC, - MAX_TYPE -}; - -struct wacom_features { - char *name; - int pktlen; - int x_max; - int y_max; - int pressure_max; - int distance_max; - int type; - int touch_x_max; - int touch_y_max; -}; - -struct wacom_wac { - unsigned char *data; - int tool[2]; - int id[2]; - __u32 serial[2]; - struct wacom_features *features; -}; - -#endif diff --git a/src/2.6.24/Makefile.in b/src/2.6.24/Makefile.in deleted file mode 100755 index 7dbd0c3..0000000 --- a/src/2.6.24/Makefile.in +++ /dev/null @@ -1,45 +0,0 @@ -############################ 2.6 kernel compile ############################### -ifneq ($(KERNELRELEASE),) -# We were called by kbuild -# Do NOT indent stuff in this part! It has to be like this to make the -# $(error ... ) stuff work - -ifeq ($(WCM_OPTION_WACOM),yes) -ifneq ($(CONFIG_USB_WACOM),y) -wacom-objs := wacom_wac.o wacom_sys.o -obj-m += wacom.o -else -$(error You requested to build wacom with configure, but wacom is configured as built-in in your kernel config) -endif # CONFIG_USB_WACOM -endif # WCM_OPTION_WACOM - -else # We were called from command line -PWD := $(shell pwd) - -WCM_KERNEL_DIR := @WCM_KERNEL_DIR@ -WCM_OPTION_WACOM := @WCM_OPTION_WACOM@ - -export WCM_OPTION_WACOM - -all: -# Copy Wacom specific code which is common to all kernel releases -ifeq ($(WCM_OPTION_WACOM),yes) - cp -f ../2.6.19/wacom_wac.c . - cp -f ../2.6.19/wacom.h . - cp -f ../2.6.22/wacom_wac.h . -endif - @echo ' Building linuxwacom drivers for 2.6 kernel.' - @echo '***Note: Drivers not enabled as modules in your kernel config but requested through configure are NOT built' - $(MAKE) -C $(WCM_KERNEL_DIR) M=$(PWD) - -endif # End kbuild check - -######################### Version independent targets ########################## - -clean: - rm -rf *.o *.ko *.mod.* .[a-z]* core *.i - -EMPTY_AUTOMAKE_TARGETS = distdir install install-data install-exec uninstall install-info -EMPTY_AUTOMAKE_TARGETS += installdirs check dvi pdf ps info html tags ctags mostlyclean distclean maintainer-clean -.PHONY: $(EMPTY_AUTOMAKE_TARGETS) - $(EMPTY_AUTOMAKE_TARGETS): diff --git a/src/2.6.24/wacom_sys.c b/src/2.6.24/wacom_sys.c deleted file mode 100755 index 76bca5e..0000000 --- a/src/2.6.24/wacom_sys.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - * drivers/input/tablet/wacom_sys.c - * - * USB Wacom Graphire and Wacom Intuos tablet support - system specific code - */ - -/* - * 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. - */ - -#include "wacom.h" -#include "wacom_wac.h" - -/* defines to get HID report descriptor */ -#define HID_DEVICET_HID (USB_TYPE_CLASS | 0x01) -#define HID_DEVICET_REPORT (USB_TYPE_CLASS | 0x02) -#define HID_USAGE_UNDEFINED 0x00 -#define HID_USAGE_PAGE 0x05 -#define HID_USAGE_PAGE_DIGITIZER 0x0d -#define HID_USAGE_PAGE_DESKTOP 0x01 -#define HID_USAGE 0x09 -#define HID_USAGE_X 0x30 -#define HID_USAGE_Y 0x31 -#define HID_USAGE_X_TILT 0x3d -#define HID_USAGE_Y_TILT 0x3e -#define HID_USAGE_FINGER 0x22 -#define HID_USAGE_STYLUS 0x20 -#define HID_COLLECTION 0xc0 -#define HID_USAGE_PAGE_VDEFINED 0xff - -enum { - WCM_UNDEFINED = 0, - WCM_DESKTOP, - WCM_DIGITIZER, - MAX_USAGE_PAGE -}; - -struct hid_descriptor -{ - struct usb_descriptor_header header; - __le16 bcdHID; - u8 bCountryCode; - u8 bNumDescriptors; - u8 bDescriptorType; - __le16 wDescriptorLength; -} __attribute__ ((packed)); - -/* defines to get/set USB message */ -#define USB_REQ_GET_REPORT 0x01 -#define USB_REQ_SET_REPORT 0x09 -#define WAC_HID_FEATURE_REPORT 0x03 - -static int usb_get_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_GET_REPORT, - USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 100); -} - -static int usb_set_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_sndctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_SET_REPORT, - USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 1000); -} - -static struct input_dev * get_input_dev(struct wacom_combo *wcombo) -{ - return wcombo->wacom->dev; -} - -static void wacom_sys_irq(struct urb *urb) -{ - struct wacom *wacom = urb->context; - struct wacom_combo wcombo; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - wcombo.wacom = wacom; - wcombo.urb = urb; - - if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo)) - input_sync(get_input_dev(&wcombo)); - - exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) -{ - input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); - return; -} - -void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data) -{ - input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data); - return; -} - -void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data) -{ - input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data); - return; -} - -void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value) -{ - input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value); - return; -} - -__u16 wacom_be16_to_cpu(unsigned char *data) -{ - __u16 value; - value = be16_to_cpu(*(__be16 *) data); - return value; -} - -__u16 wacom_le16_to_cpu(unsigned char *data) -{ - __u16 value; - value = le16_to_cpu(*(__le16 *) data); - return value; -} - -void wacom_input_sync(void *wcombo) -{ - input_sync(get_input_dev((struct wacom_combo *)wcombo)); - return; -} - -static int wacom_open(struct input_dev *dev) -{ - struct wacom *wacom = input_get_drvdata(dev); - - wacom->irq->dev = wacom->usbdev; - if (usb_submit_urb(wacom->irq, GFP_KERNEL)) - return -EIO; - - return 0; -} - -static void wacom_close(struct input_dev *dev) -{ - struct wacom *wacom = input_get_drvdata(dev); - - usb_kill_urb(wacom->irq); -} - -void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_1) | - BIT_MASK(BTN_5); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); -} - -void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT_MASK(EV_MSC); - input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | - BIT_MASK(BTN_4); -} - -void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT_MASK(EV_REL); - input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); - input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | - BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); -} - -void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | - BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); - input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_4) | - BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7); - input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); -} - -void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_4) | BIT_MASK(BTN_5) | BIT_MASK(BTN_6); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_7) | BIT_MASK(BTN_8); -} - -void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9); -} - -void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL); - input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); - input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); - input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) | - BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | - BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) | - BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) | - BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); - input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); -} - -void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2); -} - -void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER); -} - -static void wacom_paser_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, - struct wacom_wac *wacom_wac, char *report) -{ - struct usb_device *dev = interface_to_usbdev(intf); - char limit = 0, result = 0; - int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; - - /* retrive report descriptors */ - do { - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, - USB_RECIP_INTERFACE | USB_DIR_IN, - HID_DEVICET_REPORT << 8, - intf->altsetting[0].desc.bInterfaceNumber, /* interface */ - report, - hid_desc->wDescriptorLength, - 5000); /* 5 secs */ - } while (limit++ < 5); - - for (i=0; i<hid_desc->wDescriptorLength; i++) { - if ((unsigned short)report[i] == HID_USAGE_PAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_PAGE_DIGITIZER: - usage = WCM_DIGITIZER; - i++; - continue; - case HID_USAGE_PAGE_DESKTOP: - usage = WCM_DESKTOP; - i++; - continue; - } - } - - if ((unsigned short)report[i] == HID_USAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_X: - if (usage == WCM_DESKTOP) { - if (finger) { - wacom_wac->features->touch_x_max = - wacom_wac->features->touch_y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+6])); - i += 7; - } else if (pen) { - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - i += 4; - } - } else if (usage == WCM_DIGITIZER) { - /* max pressure isn't reported - wacom_wac->features->pressure_max = (unsigned short) - (report[i+4] << 8 | report[i+3]); - */ - wacom_wac->features->pressure_max = 255; - i += 4; - } - break; - case HID_USAGE_Y: - if (usage == WCM_DESKTOP) { - wacom_wac->features->y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - case HID_USAGE_FINGER: - finger = 1; - i++; - break; - case HID_USAGE_STYLUS: - pen = 1; - i++; - break; - case HID_USAGE_UNDEFINED: - if (usage == WCM_DESKTOP && finger) { /* capacity */ - wacom_wac->features->pressure_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - } - } - - if ((unsigned short)report[i] == HID_COLLECTION) { - /* reset UsagePage ans Finger */ - finger = usage = 0; - } - } -} - -static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_endpoint_descriptor *endpoint; - struct wacom *wacom; - struct wacom_wac *wacom_wac; - struct input_dev *input_dev; - int error = -ENOMEM; - char rep_data[2], limit = 0, mode = 2, *report = NULL; - struct hid_descriptor *hid_desc; - - wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); - wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!wacom || !input_dev || !wacom_wac) - goto fail1; - - wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); - if (!wacom_wac->data) - goto fail1; - - wacom->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!wacom->irq) - goto fail2; - - wacom->usbdev = dev; - wacom->dev = input_dev; - usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); - strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); - - wacom_wac->features = get_wacom_feature(id); - BUG_ON(wacom_wac->features->pktlen > 10); - - input_dev->name = wacom_wac->features->name; - wacom->wacom_wac = wacom_wac; - usb_to_input_id(dev, &input_dev->id); - - input_dev->dev.parent = &intf->dev; - - input_set_drvdata(input_dev, wacom); - - input_dev->open = wacom_open; - input_dev->close = wacom_close; - - endpoint = &intf->cur_altsetting->endpoint[0].desc; - - /* Initialize touch_x_max and touch_y_max in case it is not defined */ - if (wacom_wac->features->type == TABLETPC) { - wacom_wac->features->touch_x_max = 1023; - wacom_wac->features->touch_y_max = 1023; - } else { - wacom_wac->features->touch_x_max = 0; - wacom_wac->features->touch_y_max = 0; - } - - /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ - if (wacom_wac->features->type == TABLETPC) { - if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { - if (usb_get_extra_descriptor(&interface->endpoint[0], - HID_DEVICET_REPORT, &hid_desc)) { - printk("wacom: can not retrive extra class descriptor\n"); - goto fail2; - } - } - report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); - if (!report) { - goto fail2; - } - wacom_paser_hid(intf, hid_desc, wacom_wac, report); - } - - input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) | - BIT_MASK(BTN_TOUCH); - input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0); - input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0); - input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0); - if (wacom_wac->features->type == TABLETPC) { - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); - input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->touch_x_max, 4, 0); - input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->touch_y_max, 4, 0); - } - input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); - - wacom_init_input_dev(input_dev, wacom_wac); - - usb_fill_int_urb(wacom->irq, dev, - usb_rcvintpipe(dev, endpoint->bEndpointAddress), - wacom_wac->data, wacom_wac->features->pktlen, - wacom_sys_irq, wacom, endpoint->bInterval); - wacom->irq->transfer_dma = wacom->data_dma; - wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - error = input_register_device(wacom->dev); - if (error) - goto fail3; - - /* Ask the tablet to report tablet data if it is not a Tablet PC. - * Repeat until it succeeds - */ - if (wacom_wac->features->type != TABLETPC) { - do { - rep_data[0] = 2; - rep_data[1] = mode; - error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); - if(error >= 0) - error = usb_get_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); - } while (((error <= 0) || (rep_data[1] != mode)) && limit++ < 5); - } - - usb_set_intfdata(intf, wacom); - kfree(report); - return 0; - - fail3: usb_free_urb(wacom->irq); - fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); - fail1: input_free_device(input_dev); - kfree(wacom); - kfree(wacom_wac); - return error; -} - -static void wacom_disconnect(struct usb_interface *intf) -{ - struct wacom *wacom = usb_get_intfdata (intf); - - usb_set_intfdata(intf, NULL); - if (wacom) { - usb_kill_urb(wacom->irq); - input_unregister_device(wacom->dev); - usb_free_urb(wacom->irq); - usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); - kfree(wacom->wacom_wac); - kfree(wacom); - } -} - -static struct usb_driver wacom_driver = { - .name = "wacom", - .probe = wacom_probe, - .disconnect = wacom_disconnect, -}; - -static int __init wacom_init(void) -{ - int result; - wacom_driver.id_table = get_device_table(); - result = usb_register(&wacom_driver); - if (result == 0) - info(DRIVER_VERSION ":" DRIVER_DESC); - return result; -} - -static void __exit wacom_exit(void) -{ - usb_deregister(&wacom_driver); -} - -module_init(wacom_init); -module_exit(wacom_exit); diff --git a/src/2.6.26/Makefile.in b/src/2.6.26/Makefile.in deleted file mode 100755 index eeb3b81..0000000 --- a/src/2.6.26/Makefile.in +++ /dev/null @@ -1,44 +0,0 @@ -############################ 2.6 kernel compile ############################### -ifneq ($(KERNELRELEASE),) -# We were called by kbuild -# Do NOT indent stuff in this part! It has to be like this to make the -# $(error ... ) stuff work - -ifeq ($(WCM_OPTION_WACOM),yes) -ifneq ($(CONFIG_USB_WACOM),y) -wacom-objs := wacom_wac.o wacom_sys.o -obj-m += wacom.o -else -$(error You requested to build wacom with configure, but wacom is configured as built-in in your kernel config) -endif # CONFIG_USB_WACOM -endif # WCM_OPTION_WACOM - -else # We were called from command line -PWD := $(shell pwd) - -WCM_KERNEL_DIR := @WCM_KERNEL_DIR@ -WCM_OPTION_WACOM := @WCM_OPTION_WACOM@ - -export WCM_OPTION_WACOM - -all: -# Copy Wacom specific code which is common to all kernel releases -ifeq ($(WCM_OPTION_WACOM),yes) - cp -f ../2.6.19/wacom_wac.c . - cp -f ../2.6.22/wacom_wac.h . -endif - @echo ' Building linuxwacom drivers for 2.6 kernel.' - @echo '***Note: Drivers not enabled as modules in your kernel config but requested through configure are NOT built' - $(MAKE) -C $(WCM_KERNEL_DIR) M=$(PWD) - -endif # End kbuild check - -######################### Version independent targets ########################## - -clean: - rm -rf *.o *.ko *.mod.* .[a-z]* core *.i - -EMPTY_AUTOMAKE_TARGETS = distdir install install-data install-exec uninstall install-info -EMPTY_AUTOMAKE_TARGETS += installdirs check dvi pdf ps info html tags ctags mostlyclean distclean maintainer-clean -.PHONY: $(EMPTY_AUTOMAKE_TARGETS) - $(EMPTY_AUTOMAKE_TARGETS): diff --git a/src/2.6.26/wacom.h b/src/2.6.26/wacom.h deleted file mode 100755 index 390f7d2..0000000 --- a/src/2.6.26/wacom.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * drivers/input/tablet/wacom.h - * - * USB Wacom Graphire and Wacom Intuos tablet support - * - * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz> - * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk> - * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at> - * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org> - * Copyright (c) 2000 James E. Blair <corvus@gnu.org> - * Copyright (c) 2000 Daniel Egger <egger@suse.de> - * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> - * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> - * Copyright (c) 2002-2009 Ping Cheng <pingc@wacom.com> - * - * ChangeLog: - * v0.1 (vp) - Initial release - * v0.2 (aba) - Support for all buttons / combinations - * v0.3 (vp) - Support for Intuos added - * v0.4 (sm) - Support for more Intuos models, menustrip - * relative mode, proximity. - * v0.5 (vp) - Big cleanup, nifty features removed, - * they belong in userspace - * v1.8 (vp) - Submit URB only when operating, moved to CVS, - * use input_report_key instead of report_btn and - * other cleanups - * v1.11 (vp) - Add URB ->dev setting for new kernels - * v1.11 (jb) - Add support for the 4D Mouse & Lens - * v1.12 (de) - Add support for two more inking pen IDs - * v1.14 (vp) - Use new USB device id probing scheme. - * Fix Wacom Graphire mouse wheel - * v1.18 (vp) - Fix mouse wheel direction - * Make mouse relative - * v1.20 (fl) - Report tool id for Intuos devices - * - Multi tools support - * - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...) - * - Add PL models support - * - Fix Wacom Graphire mouse wheel again - * v1.21 (vp) - Removed protocol descriptions - * - Added MISC_SERIAL for tool serial numbers - * (gb) - Identify version on module load. - * v1.21.1 (fl) - added Graphire2 support - * v1.21.2 (fl) - added Intuos2 support - * - added all the PL ids - * v1.21.3 (fl) - added another eraser id from Neil Okamoto - * - added smooth filter for Graphire from Peri Hankey - * - added PenPartner support from Olaf van Es - * - new tool ids from Ole Martin Bjoerndalen - * v1.29 (pc) - Add support for more tablets - * - Fix pressure reporting - * v1.30 (vp) - Merge 2.4 and 2.5 drivers - * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse - * - Cleanups here and there - * v1.30.1 (pi) - Added Graphire3 support - * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... - * v1.43 (pc) - Added support for Cintiq 21UX - * - Fixed a Graphire bug - * - Merged wacom_intuos3_irq into wacom_intuos_irq - * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc. - * - Report Device IDs - * v1.45 (pc) - Added support for DTF 521, Intuos3 12x12 and 12x19 - * - Minor data report fix - * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c, - * - where wacom_sys.c deals with system specific code, - * - and wacom_wac.c deals with Wacom specific code - * - Support Intuos3 4x6 - * v1.47 (pc) - Added support for Bamboo - * v1.48 (pc) - Added support for Bamboo1, BambooFun, and Cintiq 12WX - * v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A) - */ - -/* - * 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. - */ -#ifndef WACOM_H -#define WACOM_H -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/usb/input.h> -#include <asm/unaligned.h> - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.49-pc-1" -#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" -#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" -#define DRIVER_LICENSE "GPL" - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); - -#define USB_VENDOR_ID_WACOM 0x056a - -struct wacom { - dma_addr_t data_dma; - struct input_dev *dev; - struct usb_device *usbdev; - struct usb_interface *intf; - struct urb *irq; - struct wacom_wac * wacom_wac; - struct mutex lock; - int open:1; - char phys[32]; -}; - -struct wacom_combo { - struct wacom * wacom; - struct urb * urb; -}; - -extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo); -extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data); -extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data); -extern void wacom_report_key(void *wcombo, unsigned int key_type, int key_data); -extern void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value); -extern void wacom_input_sync(void *wcombo); -extern void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern __u16 wacom_le16_to_cpu(unsigned char *data); -extern __u16 wacom_be16_to_cpu(unsigned char *data); -extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id); -extern const struct usb_device_id * get_device_table(void); - -#endif diff --git a/src/2.6.26/wacom_sys.c b/src/2.6.26/wacom_sys.c deleted file mode 100755 index 1b5165b..0000000 --- a/src/2.6.26/wacom_sys.c +++ /dev/null @@ -1,574 +0,0 @@ -/* - * drivers/input/tablet/wacom_sys.c - * - * USB Wacom Graphire and Wacom Intuos tablet support - system specific code - */ - -/* - * 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. - */ - -#include "wacom.h" -#include "wacom_wac.h" - -/* defines to get HID report descriptor */ -#define HID_DEVICET_HID (USB_TYPE_CLASS | 0x01) -#define HID_DEVICET_REPORT (USB_TYPE_CLASS | 0x02) -#define HID_USAGE_UNDEFINED 0x00 -#define HID_USAGE_PAGE 0x05 -#define HID_USAGE_PAGE_DIGITIZER 0x0d -#define HID_USAGE_PAGE_DESKTOP 0x01 -#define HID_USAGE 0x09 -#define HID_USAGE_X 0x30 -#define HID_USAGE_Y 0x31 -#define HID_USAGE_X_TILT 0x3d -#define HID_USAGE_Y_TILT 0x3e -#define HID_USAGE_FINGER 0x22 -#define HID_USAGE_STYLUS 0x20 -#define HID_COLLECTION 0xc0 -#define HID_USAGE_PAGE_VDEFINED 0xff - -enum { - WCM_UNDEFINED = 0, - WCM_DESKTOP, - WCM_DIGITIZER, - MAX_USAGE_PAGE -}; - -struct hid_descriptor -{ - struct usb_descriptor_header header; - __le16 bcdHID; - u8 bCountryCode; - u8 bNumDescriptors; - u8 bDescriptorType; - __le16 wDescriptorLength; -} __attribute__ ((packed)); - -/* defines to get/set USB message */ -#define USB_REQ_GET_REPORT 0x01 -#define USB_REQ_SET_REPORT 0x09 -#define WAC_HID_FEATURE_REPORT 0x03 - -static int usb_get_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 100); -} - -static int usb_set_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_sndctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 1000); -} - -static struct input_dev * get_input_dev(struct wacom_combo *wcombo) -{ - return wcombo->wacom->dev; -} - -static void wacom_sys_irq(struct urb *urb) -{ - struct wacom *wacom = urb->context; - struct wacom_combo wcombo; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - wcombo.wacom = wacom; - wcombo.urb = urb; - - if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo)) - input_sync(get_input_dev(&wcombo)); - - exit: - usb_mark_last_busy(wacom->usbdev); - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) -{ - input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); - return; -} - -void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data) -{ - input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data); - return; -} - -void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data) -{ - input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data); - return; -} - -void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value) -{ - input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value); - return; -} - -__u16 wacom_be16_to_cpu(unsigned char *data) -{ - __u16 value; - value = be16_to_cpu(*(__be16 *) data); - return value; -} - -__u16 wacom_le16_to_cpu(unsigned char *data) -{ - __u16 value; - value = le16_to_cpu(*(__le16 *) data); - return value; -} - -void wacom_input_sync(void *wcombo) -{ - input_sync(get_input_dev((struct wacom_combo *)wcombo)); - return; -} - -static int wacom_open(struct input_dev *dev) -{ - struct wacom *wacom = input_get_drvdata(dev); - - mutex_lock(&wacom->lock); - - wacom->irq->dev = wacom->usbdev; - - if (usb_autopm_get_interface(wacom->intf) < 0) { - mutex_unlock(&wacom->lock); - return -EIO; - } - - if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { - usb_autopm_put_interface(wacom->intf); - mutex_unlock(&wacom->lock); - return -EIO; - } - - wacom->open = 1; - wacom->intf->needs_remote_wakeup = 1; - - mutex_unlock(&wacom->lock); - return 0; -} - -static void wacom_close(struct input_dev *dev) -{ - struct wacom *wacom = input_get_drvdata(dev); - - mutex_lock(&wacom->lock); - usb_kill_urb(wacom->irq); - wacom->open = 0; - wacom->intf->needs_remote_wakeup = 0; - mutex_unlock(&wacom->lock); -} - -void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_1) | - BIT_MASK(BTN_5); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); -} - -void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT_MASK(EV_MSC); - input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | - BIT_MASK(BTN_4); -} - -void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT_MASK(EV_REL); - input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); - input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | - BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); -} - -void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | - BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); - input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_4) | - BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7); - input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); -} - -void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_4) | BIT_MASK(BTN_5) | BIT_MASK(BTN_6); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_7) | BIT_MASK(BTN_8); -} - -void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9); -} - -void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL); - input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); - input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); - input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) | - BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | - BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) | - BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) | - BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); - input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); -} - -void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2); -} - -void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER); -} - -static void wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, - struct wacom_wac *wacom_wac, char *report) -{ - struct usb_device *dev = interface_to_usbdev(intf); - char limit = 0, result = 0; - int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; - - /* retrive report descriptors */ - do { - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, - USB_RECIP_INTERFACE | USB_DIR_IN, - HID_DEVICET_REPORT << 8, - intf->altsetting[0].desc.bInterfaceNumber, /* interface */ - report, - hid_desc->wDescriptorLength, - 5000); /* 5 secs */ - } while (limit++ < 5); - - for (i=0; i<hid_desc->wDescriptorLength; i++) { - if ((unsigned short)report[i] == HID_USAGE_PAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_PAGE_DIGITIZER: - usage = WCM_DIGITIZER; - i++; - continue; - case HID_USAGE_PAGE_DESKTOP: - usage = WCM_DESKTOP; - i++; - continue; - } - } - - if ((unsigned short)report[i] == HID_USAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_X: - if (usage == WCM_DESKTOP) { - if (finger) { - wacom_wac->features->touch_x_max = - wacom_wac->features->touch_y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+6])); - i += 7; - } else if (pen) { - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - i += 4; - } - } else if (usage == WCM_DIGITIZER) { - /* max pressure isn't reported - wacom_wac->features->pressure_max = (unsigned short) - (report[i+4] << 8 | report[i+3]); - */ - wacom_wac->features->pressure_max = 255; - i += 4; - } - break; - case HID_USAGE_Y: - if (usage == WCM_DESKTOP) { - wacom_wac->features->y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - case HID_USAGE_FINGER: - finger = 1; - i++; - break; - case HID_USAGE_STYLUS: - pen = 1; - i++; - break; - case HID_USAGE_UNDEFINED: - if (usage == WCM_DESKTOP && finger) { /* capacity */ - wacom_wac->features->pressure_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - } - } - - if ((unsigned short)report[i] == HID_COLLECTION) { - /* reset UsagePage ans Finger */ - finger = usage = 0; - } - } -} - -static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_endpoint_descriptor *endpoint; - struct wacom *wacom; - struct wacom_wac *wacom_wac; - struct input_dev *input_dev; - int error = -ENOMEM; - char rep_data[2], limit = 0, *report = NULL; - struct hid_descriptor *hid_desc; - - wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); - wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!wacom || !input_dev || !wacom_wac) - goto fail1; - - wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); - if (!wacom_wac->data) - goto fail1; - - wacom->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!wacom->irq) - goto fail2; - - wacom->usbdev = dev; - wacom->dev = input_dev; - wacom->intf = intf; - mutex_init(&wacom->lock); - usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); - strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); - - wacom_wac->features = get_wacom_feature(id); - BUG_ON(wacom_wac->features->pktlen > 10); - - input_dev->name = wacom_wac->features->name; - wacom->wacom_wac = wacom_wac; - usb_to_input_id(dev, &input_dev->id); - - input_dev->dev.parent = &intf->dev; - - input_set_drvdata(input_dev, wacom); - - input_dev->open = wacom_open; - input_dev->close = wacom_close; - - endpoint = &intf->cur_altsetting->endpoint[0].desc; - - /* Initialize touch_x_max and touch_y_max in case it is not defined */ - if (wacom_wac->features->type == TABLETPC) { - wacom_wac->features->touch_x_max = 1023; - wacom_wac->features->touch_y_max = 1023; - } else { - wacom_wac->features->touch_x_max = 0; - wacom_wac->features->touch_y_max = 0; - } - - /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ - if (wacom_wac->features->type == TABLETPC) { - if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { - if (usb_get_extra_descriptor(&interface->endpoint[0], - HID_DEVICET_REPORT, &hid_desc)) { - printk("wacom: can not retrive extra class descriptor\n"); - goto fail2; - } - } - report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); - if (!report) { - goto fail2; - } - wacom_parse_hid(intf, hid_desc, wacom_wac, report); - } - - input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) | - BIT_MASK(BTN_TOUCH); - input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0); - input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0); - input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0); - if (wacom_wac->features->type == TABLETPC) { - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); - input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->touch_x_max, 4, 0); - input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->touch_y_max, 4, 0); - } - input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); - - wacom_init_input_dev(input_dev, wacom_wac); - - usb_fill_int_urb(wacom->irq, dev, - usb_rcvintpipe(dev, endpoint->bEndpointAddress), - wacom_wac->data, wacom_wac->features->pktlen, - wacom_sys_irq, wacom, endpoint->bInterval); - wacom->irq->transfer_dma = wacom->data_dma; - wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - error = input_register_device(wacom->dev); - if (error) - goto fail3; - - /* Ask the tablet to report tablet data if it is not a Tablet PC. - * Repeat until it succeeds - */ - if (wacom_wac->features->type != TABLETPC) { - do { - rep_data[0] = 2; - rep_data[1] = 2; - error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); - if(error >= 0) - error = usb_get_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); - } while (((error <= 0) || (rep_data[1] != 2)) && limit++ < 5); - } - - usb_set_intfdata(intf, wacom); - kfree(report); - return 0; - - fail3: usb_free_urb(wacom->irq); - fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); - fail1: input_free_device(input_dev); - kfree(wacom); - kfree(wacom_wac); - return error; -} - -static void wacom_disconnect(struct usb_interface *intf) -{ - struct wacom *wacom = usb_get_intfdata(intf); - - usb_set_intfdata(intf, NULL); - - usb_kill_urb(wacom->irq); - input_unregister_device(wacom->dev); - usb_free_urb(wacom->irq); - usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); - kfree(wacom->wacom_wac); - kfree(wacom); -} - -static int wacom_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct wacom *wacom = usb_get_intfdata(intf); - - mutex_lock(&wacom->lock); - usb_kill_urb(wacom->irq); - mutex_unlock(&wacom->lock); - - return 0; -} - -static int wacom_resume(struct usb_interface *intf) -{ - struct wacom *wacom = usb_get_intfdata(intf); - int rv; - - mutex_lock(&wacom->lock); - if (wacom->open) - rv = usb_submit_urb(wacom->irq, GFP_NOIO); - else - rv = 0; - mutex_unlock(&wacom->lock); - - return rv; -} - -static int wacom_reset_resume(struct usb_interface *intf) -{ - return wacom_resume(intf); -} - -static struct usb_driver wacom_driver = { - .name = "wacom", - .probe = wacom_probe, - .disconnect = wacom_disconnect, - .suspend = wacom_suspend, - .resume = wacom_resume, - .reset_resume = wacom_reset_resume, - .supports_autosuspend = 1, -}; - -static int __init wacom_init(void) -{ - int result; - wacom_driver.id_table = get_device_table(); - result = usb_register(&wacom_driver); - if (result == 0) - info(DRIVER_VERSION ":" DRIVER_DESC); - return result; -} - -static void __exit wacom_exit(void) -{ - usb_deregister(&wacom_driver); -} - -module_init(wacom_init); -module_exit(wacom_exit); diff --git a/src/2.6.27/Makefile.in b/src/2.6.27/Makefile.in deleted file mode 100755 index eeb3b81..0000000 --- a/src/2.6.27/Makefile.in +++ /dev/null @@ -1,44 +0,0 @@ -############################ 2.6 kernel compile ############################### -ifneq ($(KERNELRELEASE),) -# We were called by kbuild -# Do NOT indent stuff in this part! It has to be like this to make the -# $(error ... ) stuff work - -ifeq ($(WCM_OPTION_WACOM),yes) -ifneq ($(CONFIG_USB_WACOM),y) -wacom-objs := wacom_wac.o wacom_sys.o -obj-m += wacom.o -else -$(error You requested to build wacom with configure, but wacom is configured as built-in in your kernel config) -endif # CONFIG_USB_WACOM -endif # WCM_OPTION_WACOM - -else # We were called from command line -PWD := $(shell pwd) - -WCM_KERNEL_DIR := @WCM_KERNEL_DIR@ -WCM_OPTION_WACOM := @WCM_OPTION_WACOM@ - -export WCM_OPTION_WACOM - -all: -# Copy Wacom specific code which is common to all kernel releases -ifeq ($(WCM_OPTION_WACOM),yes) - cp -f ../2.6.19/wacom_wac.c . - cp -f ../2.6.22/wacom_wac.h . -endif - @echo ' Building linuxwacom drivers for 2.6 kernel.' - @echo '***Note: Drivers not enabled as modules in your kernel config but requested through configure are NOT built' - $(MAKE) -C $(WCM_KERNEL_DIR) M=$(PWD) - -endif # End kbuild check - -######################### Version independent targets ########################## - -clean: - rm -rf *.o *.ko *.mod.* .[a-z]* core *.i - -EMPTY_AUTOMAKE_TARGETS = distdir install install-data install-exec uninstall install-info -EMPTY_AUTOMAKE_TARGETS += installdirs check dvi pdf ps info html tags ctags mostlyclean distclean maintainer-clean -.PHONY: $(EMPTY_AUTOMAKE_TARGETS) - $(EMPTY_AUTOMAKE_TARGETS): diff --git a/src/2.6.27/wacom.h b/src/2.6.27/wacom.h deleted file mode 100755 index 046b6c1..0000000 --- a/src/2.6.27/wacom.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * drivers/input/tablet/wacom.h - * - * USB Wacom Graphire and Wacom Intuos tablet support - * - * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz> - * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk> - * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at> - * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org> - * Copyright (c) 2000 James E. Blair <corvus@gnu.org> - * Copyright (c) 2000 Daniel Egger <egger@suse.de> - * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> - * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> - * Copyright (c) 2002-2009 Ping Cheng <pingc@wacom.com> - * - * ChangeLog: - * v0.1 (vp) - Initial release - * v0.2 (aba) - Support for all buttons / combinations - * v0.3 (vp) - Support for Intuos added - * v0.4 (sm) - Support for more Intuos models, menustrip - * relative mode, proximity. - * v0.5 (vp) - Big cleanup, nifty features removed, - * they belong in userspace - * v1.8 (vp) - Submit URB only when operating, moved to CVS, - * use input_report_key instead of report_btn and - * other cleanups - * v1.11 (vp) - Add URB ->dev setting for new kernels - * v1.11 (jb) - Add support for the 4D Mouse & Lens - * v1.12 (de) - Add support for two more inking pen IDs - * v1.14 (vp) - Use new USB device id probing scheme. - * Fix Wacom Graphire mouse wheel - * v1.18 (vp) - Fix mouse wheel direction - * Make mouse relative - * v1.20 (fl) - Report tool id for Intuos devices - * - Multi tools support - * - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...) - * - Add PL models support - * - Fix Wacom Graphire mouse wheel again - * v1.21 (vp) - Removed protocol descriptions - * - Added MISC_SERIAL for tool serial numbers - * (gb) - Identify version on module load. - * v1.21.1 (fl) - added Graphire2 support - * v1.21.2 (fl) - added Intuos2 support - * - added all the PL ids - * v1.21.3 (fl) - added another eraser id from Neil Okamoto - * - added smooth filter for Graphire from Peri Hankey - * - added PenPartner support from Olaf van Es - * - new tool ids from Ole Martin Bjoerndalen - * v1.29 (pc) - Add support for more tablets - * - Fix pressure reporting - * v1.30 (vp) - Merge 2.4 and 2.5 drivers - * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse - * - Cleanups here and there - * v1.30.1 (pi) - Added Graphire3 support - * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... - * v1.43 (pc) - Added support for Cintiq 21UX - * - Fixed a Graphire bug - * - Merged wacom_intuos3_irq into wacom_intuos_irq - * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc. - * - Report Device IDs - * v1.45 (pc) - Added support for DTF 521, Intuos3 12x12 and 12x19 - * - Minor data report fix - * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c, - * - where wacom_sys.c deals with system specific code, - * - and wacom_wac.c deals with Wacom specific code - * - Support Intuos3 4x6 - * v1.47 (pc) - Added support for Bamboo - * v1.48 (pc) - Added support for Bamboo1, BambooFun, and Cintiq 12WX - * v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A) - */ - -/* - * 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. - */ -#ifndef WACOM_H -#define WACOM_H -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/usb/input.h> -#include <asm/unaligned.h> - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.49-pc-1" -#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" -#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" -#define DRIVER_LICENSE "GPL" - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); - -#define USB_VENDOR_ID_WACOM 0x056a - -struct wacom { - dma_addr_t data_dma; - struct input_dev *dev; - struct usb_device *usbdev; - struct usb_interface *intf; - struct urb *irq; - struct wacom_wac * wacom_wac; - struct mutex lock; - unsigned int open:1; - char phys[32]; -}; - -struct wacom_combo { - struct wacom * wacom; - struct urb * urb; -}; - -extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo); -extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data); -extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data); -extern void wacom_report_key(void *wcombo, unsigned int key_type, int key_data); -extern void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value); -extern void wacom_input_sync(void *wcombo); -extern void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern __u16 wacom_le16_to_cpu(unsigned char *data); -extern __u16 wacom_be16_to_cpu(unsigned char *data); -extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id); -extern const struct usb_device_id * get_device_table(void); - -#endif diff --git a/src/2.6.27/wacom_sys.c b/src/2.6.27/wacom_sys.c deleted file mode 100755 index 50c17fe..0000000 --- a/src/2.6.27/wacom_sys.c +++ /dev/null @@ -1,574 +0,0 @@ -/* - * drivers/input/tablet/wacom_sys.c - * - * USB Wacom Graphire and Wacom Intuos tablet support - system specific code - */ - -/* - * 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. - */ - -#include "wacom.h" -#include "wacom_wac.h" - -/* defines to get HID report descriptor */ -#define HID_DEVICET_HID (USB_TYPE_CLASS | 0x01) -#define HID_DEVICET_REPORT (USB_TYPE_CLASS | 0x02) -#define HID_USAGE_UNDEFINED 0x00 -#define HID_USAGE_PAGE 0x05 -#define HID_USAGE_PAGE_DIGITIZER 0x0d -#define HID_USAGE_PAGE_DESKTOP 0x01 -#define HID_USAGE 0x09 -#define HID_USAGE_X 0x30 -#define HID_USAGE_Y 0x31 -#define HID_USAGE_X_TILT 0x3d -#define HID_USAGE_Y_TILT 0x3e -#define HID_USAGE_FINGER 0x22 -#define HID_USAGE_STYLUS 0x20 -#define HID_COLLECTION 0xc0 -#define HID_USAGE_PAGE_VDEFINED 0xff - -enum { - WCM_UNDEFINED = 0, - WCM_DESKTOP, - WCM_DIGITIZER, - MAX_USAGE_PAGE -}; - -struct hid_descriptor -{ - struct usb_descriptor_header header; - __le16 bcdHID; - u8 bCountryCode; - u8 bNumDescriptors; - u8 bDescriptorType; - __le16 wDescriptorLength; -} __attribute__ ((packed)); - -/* defines to get/set USB message */ -#define USB_REQ_GET_REPORT 0x01 -#define USB_REQ_SET_REPORT 0x09 -#define WAC_HID_FEATURE_REPORT 0x03 - -static int usb_get_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 100); -} - -static int usb_set_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_sndctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 1000); -} - -static struct input_dev * get_input_dev(struct wacom_combo *wcombo) -{ - return wcombo->wacom->dev; -} - -static void wacom_sys_irq(struct urb *urb) -{ - struct wacom *wacom = urb->context; - struct wacom_combo wcombo; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __func__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __func__, urb->status); - goto exit; - } - - wcombo.wacom = wacom; - wcombo.urb = urb; - - if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo)) - input_sync(get_input_dev(&wcombo)); - - exit: - usb_mark_last_busy(wacom->usbdev); - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __func__, retval); -} - -void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) -{ - input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); - return; -} - -void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data) -{ - input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data); - return; -} - -void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data) -{ - input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data); - return; -} - -void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value) -{ - input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value); - return; -} - -__u16 wacom_be16_to_cpu(unsigned char *data) -{ - __u16 value; - value = be16_to_cpu(*(__be16 *) data); - return value; -} - -__u16 wacom_le16_to_cpu(unsigned char *data) -{ - __u16 value; - value = le16_to_cpu(*(__le16 *) data); - return value; -} - -void wacom_input_sync(void *wcombo) -{ - input_sync(get_input_dev((struct wacom_combo *)wcombo)); - return; -} - -static int wacom_open(struct input_dev *dev) -{ - struct wacom *wacom = input_get_drvdata(dev); - - mutex_lock(&wacom->lock); - - wacom->irq->dev = wacom->usbdev; - - if (usb_autopm_get_interface(wacom->intf) < 0) { - mutex_unlock(&wacom->lock); - return -EIO; - } - - if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { - usb_autopm_put_interface(wacom->intf); - mutex_unlock(&wacom->lock); - return -EIO; - } - - wacom->open = 1; - wacom->intf->needs_remote_wakeup = 1; - - mutex_unlock(&wacom->lock); - return 0; -} - -static void wacom_close(struct input_dev *dev) -{ - struct wacom *wacom = input_get_drvdata(dev); - - mutex_lock(&wacom->lock); - usb_kill_urb(wacom->irq); - wacom->open = 0; - wacom->intf->needs_remote_wakeup = 0; - mutex_unlock(&wacom->lock); -} - -void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_1) | - BIT_MASK(BTN_5); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); -} - -void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT_MASK(EV_MSC); - input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | - BIT_MASK(BTN_4); -} - -void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT_MASK(EV_REL); - input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); - input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | - BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); -} - -void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | - BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); - input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_4) | - BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7); - input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); -} - -void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_4) | BIT_MASK(BTN_5) | BIT_MASK(BTN_6); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_7) | BIT_MASK(BTN_8); -} - -void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9); -} - -void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL); - input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); - input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); - input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) | - BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | - BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) | - BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) | - BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); - input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); -} - -void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2); -} - -void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER); -} - -static void wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, - struct wacom_wac *wacom_wac, char *report) -{ - struct usb_device *dev = interface_to_usbdev(intf); - char limit = 0, result = 0; - int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; - - /* retrive report descriptors */ - do { - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, - USB_RECIP_INTERFACE | USB_DIR_IN, - HID_DEVICET_REPORT << 8, - intf->altsetting[0].desc.bInterfaceNumber, /* interface */ - report, - hid_desc->wDescriptorLength, - 5000); /* 5 secs */ - } while (limit++ < 5); - - for (i=0; i<hid_desc->wDescriptorLength; i++) { - if ((unsigned short)report[i] == HID_USAGE_PAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_PAGE_DIGITIZER: - usage = WCM_DIGITIZER; - i++; - continue; - case HID_USAGE_PAGE_DESKTOP: - usage = WCM_DESKTOP; - i++; - continue; - } - } - - if ((unsigned short)report[i] == HID_USAGE) { - switch ((unsigned short)report[i+1]) { - case HID_USAGE_X: - if (usage == WCM_DESKTOP) { - if (finger) { - wacom_wac->features->touch_x_max = - wacom_wac->features->touch_y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+6])); - i += 7; - } else if (pen) { - wacom_wac->features->x_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - i += 4; - } - } else if (usage == WCM_DIGITIZER) { - /* max pressure isn't reported - wacom_wac->features->pressure_max = (unsigned short) - (report[i+4] << 8 | report[i+3]); - */ - wacom_wac->features->pressure_max = 255; - i += 4; - } - break; - case HID_USAGE_Y: - if (usage == WCM_DESKTOP) { - wacom_wac->features->y_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - case HID_USAGE_FINGER: - finger = 1; - i++; - break; - case HID_USAGE_STYLUS: - pen = 1; - i++; - break; - case HID_USAGE_UNDEFINED: - if (usage == WCM_DESKTOP && finger) { /* capacity */ - wacom_wac->features->pressure_max = (unsigned short) - (wacom_le16_to_cpu(&report[i+3])); - } - i += 4; - break; - } - } - - if ((unsigned short)report[i] == HID_COLLECTION) { - /* reset UsagePage ans Finger */ - finger = usage = 0; - } - } -} - -static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_endpoint_descriptor *endpoint; - struct wacom *wacom; - struct wacom_wac *wacom_wac; - struct input_dev *input_dev; - int error = -ENOMEM; - char rep_data[2], limit = 0, *report = NULL; - struct hid_descriptor *hid_desc; - - wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); - wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!wacom || !input_dev || !wacom_wac) - goto fail1; - - wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); - if (!wacom_wac->data) - goto fail1; - - wacom->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!wacom->irq) - goto fail2; - - wacom->usbdev = dev; - wacom->dev = input_dev; - wacom->intf = intf; - mutex_init(&wacom->lock); - usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); - strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); - - wacom_wac->features = get_wacom_feature(id); - BUG_ON(wacom_wac->features->pktlen > 10); - - input_dev->name = wacom_wac->features->name; - wacom->wacom_wac = wacom_wac; - usb_to_input_id(dev, &input_dev->id); - - input_dev->dev.parent = &intf->dev; - - input_set_drvdata(input_dev, wacom); - - input_dev->open = wacom_open; - input_dev->close = wacom_close; - - endpoint = &intf->cur_altsetting->endpoint[0].desc; - - /* Initialize touch_x_max and touch_y_max in case it is not defined */ - if (wacom_wac->features->type == TABLETPC) { - wacom_wac->features->touch_x_max = 1023; - wacom_wac->features->touch_y_max = 1023; - } else { - wacom_wac->features->touch_x_max = 0; - wacom_wac->features->touch_y_max = 0; - } - - /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ - if (wacom_wac->features->type == TABLETPC) { - if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { - if (usb_get_extra_descriptor(&interface->endpoint[0], - HID_DEVICET_REPORT, &hid_desc)) { - printk("wacom: can not retrive extra class descriptor\n"); - goto fail2; - } - } - report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); - if (!report) { - goto fail2; - } - wacom_parse_hid(intf, hid_desc, wacom_wac, report); - } - - input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) | - BIT_MASK(BTN_TOUCH); - input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0); - input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0); - input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0); - if (wacom_wac->features->type == TABLETPC) { - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); - input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->touch_x_max, 4, 0); - input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->touch_y_max, 4, 0); - } - input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); - - wacom_init_input_dev(input_dev, wacom_wac); - - usb_fill_int_urb(wacom->irq, dev, - usb_rcvintpipe(dev, endpoint->bEndpointAddress), - wacom_wac->data, wacom_wac->features->pktlen, - wacom_sys_irq, wacom, endpoint->bInterval); - wacom->irq->transfer_dma = wacom->data_dma; - wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - error = input_register_device(wacom->dev); - if (error) - goto fail3; - - /* Ask the tablet to report tablet data. if it is not a Tablet PC. - * Repeat until it succeeds - */ - if (wacom_wac->features->type != TABLETPC) { - do { - rep_data[0] = 2; - rep_data[1] = 2; - error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); - if(error >= 0) - error = usb_get_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); - } while (((error <= 0) || (rep_data[1] != 2)) && limit++ < 5); - } - - usb_set_intfdata(intf, wacom); - kfree(report); - return 0; - - fail3: usb_free_urb(wacom->irq); - fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); - fail1: input_free_device(input_dev); - kfree(wacom); - kfree(wacom_wac); - return error; -} - -static void wacom_disconnect(struct usb_interface *intf) -{ - struct wacom *wacom = usb_get_intfdata(intf); - - usb_set_intfdata(intf, NULL); - - usb_kill_urb(wacom->irq); - input_unregister_device(wacom->dev); - usb_free_urb(wacom->irq); - usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); - kfree(wacom->wacom_wac); - kfree(wacom); -} - -static int wacom_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct wacom *wacom = usb_get_intfdata(intf); - - mutex_lock(&wacom->lock); - usb_kill_urb(wacom->irq); - mutex_unlock(&wacom->lock); - - return 0; -} - -static int wacom_resume(struct usb_interface *intf) -{ - struct wacom *wacom = usb_get_intfdata(intf); - int rv; - - mutex_lock(&wacom->lock); - if (wacom->open) - rv = usb_submit_urb(wacom->irq, GFP_NOIO); - else - rv = 0; - mutex_unlock(&wacom->lock); - - return rv; -} - -static int wacom_reset_resume(struct usb_interface *intf) -{ - return wacom_resume(intf); -} - -static struct usb_driver wacom_driver = { - .name = "wacom", - .probe = wacom_probe, - .disconnect = wacom_disconnect, - .suspend = wacom_suspend, - .resume = wacom_resume, - .reset_resume = wacom_reset_resume, - .supports_autosuspend = 1, -}; - -static int __init wacom_init(void) -{ - int result; - wacom_driver.id_table = get_device_table(); - result = usb_register(&wacom_driver); - if (result == 0) - info(DRIVER_VERSION ":" DRIVER_DESC); - return result; -} - -static void __exit wacom_exit(void) -{ - usb_deregister(&wacom_driver); -} - -module_init(wacom_init); -module_exit(wacom_exit); diff --git a/src/2.6.28/Makefile.in b/src/2.6.28/Makefile.in deleted file mode 100755 index b00a819..0000000 --- a/src/2.6.28/Makefile.in +++ /dev/null @@ -1,44 +0,0 @@ -############################ 2.6 kernel compile ############################### -ifneq ($(KERNELRELEASE),) -# We were called by kbuild -# Do NOT indent stuff in this part! It has to be like this to make the -# $(error ... ) stuff work - -ifeq ($(WCM_OPTION_WACOM),yes) -ifneq ($(CONFIG_USB_WACOM),y) -wacom-objs := wacom_wac.o wacom_sys.o -obj-m += wacom.o -else -$(error You requested to build wacom with configure, but wacom is configured as built-in in your kernel config) -endif # CONFIG_USB_WACOM -endif # WCM_OPTION_WACOM - -else # We were called from command line -PWD := $(shell pwd) - -WCM_KERNEL_DIR := @WCM_KERNEL_DIR@ -WCM_OPTION_WACOM := @WCM_OPTION_WACOM@ - -export WCM_OPTION_WACOM - -all: -# Copy Wacom specific code which is common to all kernel releases -ifeq ($(WCM_OPTION_WACOM),yes) - cp -f ../2.6.27/wacom.h . -endif - @echo ' Building linuxwacom drivers for 2.6 kernel.' - @echo '***Note: Drivers not enabled as modules in your kernel config but requested through configure are NOT built' - $(MAKE) -C $(WCM_KERNEL_DIR) M=$(PWD) - -endif # End kbuild check - -######################### Version independent targets ########################## - -clean: - rm -rf *.o *.ko *.mod.* .[a-z]* core *.i - -EMPTY_AUTOMAKE_TARGETS = distdir install install-data install-exec uninstall install-info -EMPTY_AUTOMAKE_TARGETS += installdirs check dvi pdf ps info html tags ctags mostlyclean distclean maintainer-clean -.PHONY: $(EMPTY_AUTOMAKE_TARGETS) - $(EMPTY_AUTOMAKE_TARGETS): - diff --git a/src/2.6.28/wacom_sys.c b/src/2.6.28/wacom_sys.c deleted file mode 100644 index c60c576..0000000 --- a/src/2.6.28/wacom_sys.c +++ /dev/null @@ -1,591 +0,0 @@ -/* - * drivers/input/tablet/wacom_sys.c - * - * USB Wacom Graphire and Wacom Intuos tablet support - system specific code - */ - -/* - * 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. - */ - -#include "wacom.h" -#include "wacom_wac.h" - -/* defines to get HID report descriptor */ -#define HID_DEVICET_HID (USB_TYPE_CLASS | 0x01) -#define HID_DEVICET_REPORT (USB_TYPE_CLASS | 0x02) -#define HID_USAGE_UNDEFINED 0x00 -#define HID_USAGE_PAGE 0x05 -#define HID_USAGE_PAGE_DIGITIZER 0x0d -#define HID_USAGE_PAGE_DESKTOP 0x01 -#define HID_USAGE 0x09 -#define HID_USAGE_X 0x30 -#define HID_USAGE_Y 0x31 -#define HID_USAGE_X_TILT 0x3d -#define HID_USAGE_Y_TILT 0x3e -#define HID_USAGE_FINGER 0x22 -#define HID_USAGE_STYLUS 0x20 -#define HID_COLLECTION 0xc0 - -enum { - WCM_UNDEFINED = 0, - WCM_DESKTOP, - WCM_DIGITIZER, -}; - -struct hid_descriptor { - struct usb_descriptor_header header; - __le16 bcdHID; - u8 bCountryCode; - u8 bNumDescriptors; - u8 bDescriptorType; - __le16 wDescriptorLength; -} __attribute__ ((packed)); - -/* defines to get/set USB message */ -#define USB_REQ_GET_REPORT 0x01 -#define USB_REQ_SET_REPORT 0x09 -#define WAC_HID_FEATURE_REPORT 0x03 - -static int usb_get_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 100); -} - -static int usb_set_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_sndctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 1000); -} - -static struct input_dev * get_input_dev(struct wacom_combo *wcombo) -{ - return wcombo->wacom->dev; -} - -static void wacom_sys_irq(struct urb *urb) -{ - struct wacom *wacom = urb->context; - struct wacom_combo wcombo; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __func__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __func__, urb->status); - goto exit; - } - - wcombo.wacom = wacom; - wcombo.urb = urb; - - if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo)) - input_sync(get_input_dev(&wcombo)); - - exit: - usb_mark_last_busy(wacom->usbdev); - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __func__, retval); -} - -void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) -{ - input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); -} - -void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data) -{ - input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data); -} - -void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data) -{ - input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data); -} - -void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value) -{ - input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value); -} - -__u16 wacom_be16_to_cpu(unsigned char *data) -{ - __u16 value; - value = be16_to_cpu(*(__be16 *) data); - return value; -} - -__u16 wacom_le16_to_cpu(unsigned char *data) -{ - __u16 value; - value = le16_to_cpu(*(__le16 *) data); - return value; -} - -void wacom_input_sync(void *wcombo) -{ - input_sync(get_input_dev((struct wacom_combo *)wcombo)); -} - -static int wacom_open(struct input_dev *dev) -{ - struct wacom *wacom = input_get_drvdata(dev); - - mutex_lock(&wacom->lock); - - wacom->irq->dev = wacom->usbdev; - - if (usb_autopm_get_interface(wacom->intf) < 0) { - mutex_unlock(&wacom->lock); - return -EIO; - } - - if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { - usb_autopm_put_interface(wacom->intf); - mutex_unlock(&wacom->lock); - return -EIO; - } - - wacom->open = 1; - wacom->intf->needs_remote_wakeup = 1; - - mutex_unlock(&wacom->lock); - return 0; -} - -static void wacom_close(struct input_dev *dev) -{ - struct wacom *wacom = input_get_drvdata(dev); - - mutex_lock(&wacom->lock); - usb_kill_urb(wacom->irq); - wacom->open = 0; - wacom->intf->needs_remote_wakeup = 0; - mutex_unlock(&wacom->lock); -} - -void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_1) | - BIT_MASK(BTN_5); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); -} - -void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT_MASK(EV_MSC); - input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | - BIT_MASK(BTN_4); -} - -void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT_MASK(EV_REL); - input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); - input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | - BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); -} - -void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | - BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); - input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_4) | - BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7); - input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); -} - -void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_4) | BIT_MASK(BTN_5) | BIT_MASK(BTN_6); - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); -} - -void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_7) | BIT_MASK(BTN_8); -} - -void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9); -} - -void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL); - input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); - input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); - input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) | - BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | - BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) | - BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) | - BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); - input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); -} - -void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2); -} - -void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER); -} - -static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, - struct wacom_wac *wacom_wac) -{ - struct usb_device *dev = interface_to_usbdev(intf); - struct wacom_features *features = wacom_wac->features; - char limit = 0, result = 0; - int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; - unsigned char *report; - - report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); - if (!report) - return -ENOMEM; - - /* retrive report descriptors */ - do { - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, - USB_RECIP_INTERFACE | USB_DIR_IN, - HID_DEVICET_REPORT << 8, - intf->altsetting[0].desc.bInterfaceNumber, /* interface */ - report, - hid_desc->wDescriptorLength, - 5000); /* 5 secs */ - } while (result < 0 && limit++ < 5); - - /* No need to parse the Descriptor. It isn't an error though */ - if (result < 0) - goto out; - - for (i = 0; i < hid_desc->wDescriptorLength; i++) { - - switch (report[i]) { - case HID_USAGE_PAGE: - switch (report[i + 1]) { - case HID_USAGE_PAGE_DIGITIZER: - usage = WCM_DIGITIZER; - i++; - break; - - case HID_USAGE_PAGE_DESKTOP: - usage = WCM_DESKTOP; - i++; - break; - } - break; - - case HID_USAGE: - switch (report[i + 1]) { - case HID_USAGE_X: - if (usage == WCM_DESKTOP) { - if (finger) { - features->touch_x_max = - features->touch_y_max = - wacom_le16_to_cpu(&report[i + 3]); - features->x_max = - wacom_le16_to_cpu(&report[i + 6]); - i += 7; - } else if (pen) { - features->x_max = - wacom_le16_to_cpu(&report[i + 3]); - i += 4; - } - } else if (usage == WCM_DIGITIZER) { - /* max pressure isn't reported - features->pressure_max = (unsigned short) - (report[i+4] << 8 | report[i + 3]); - */ - features->pressure_max = 255; - i += 4; - } - break; - - case HID_USAGE_Y: - if (usage == WCM_DESKTOP) - features->y_max = - wacom_le16_to_cpu(&report[i + 3]); - i += 4; - break; - - case HID_USAGE_FINGER: - finger = 1; - i++; - break; - - case HID_USAGE_STYLUS: - pen = 1; - i++; - break; - - case HID_USAGE_UNDEFINED: - if (usage == WCM_DESKTOP && finger) /* capacity */ - features->pressure_max = - wacom_le16_to_cpu(&report[i + 3]); - i += 4; - break; - } - break; - - case HID_COLLECTION: - /* reset UsagePage ans Finger */ - finger = usage = 0; - break; - } - } - - out: - result = 0; - kfree(report); - return result; -} - -static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_endpoint_descriptor *endpoint; - struct wacom *wacom; - struct wacom_wac *wacom_wac; - struct wacom_features *features; - struct input_dev *input_dev; - int error = -ENOMEM; - char rep_data[2], limit = 0; - struct hid_descriptor *hid_desc; - - wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); - wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!wacom || !input_dev || !wacom_wac) - goto fail1; - - wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); - if (!wacom_wac->data) - goto fail1; - - wacom->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!wacom->irq) - goto fail2; - - wacom->usbdev = dev; - wacom->dev = input_dev; - wacom->intf = intf; - mutex_init(&wacom->lock); - usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); - strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); - - wacom_wac->features = features = get_wacom_feature(id); - BUG_ON(features->pktlen > 10); - - input_dev->name = wacom_wac->features->name; - wacom->wacom_wac = wacom_wac; - usb_to_input_id(dev, &input_dev->id); - - input_dev->dev.parent = &intf->dev; - - input_set_drvdata(input_dev, wacom); - - input_dev->open = wacom_open; - input_dev->close = wacom_close; - - endpoint = &intf->cur_altsetting->endpoint[0].desc; - - /* Initialize touch_x_max and touch_y_max in case it is not defined */ - if (wacom_wac->features->type == TABLETPC) { - features->touch_x_max = 1023; - features->touch_y_max = 1023; - } else { - features->touch_x_max = 0; - features->touch_y_max = 0; - } - - /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ - if (wacom_wac->features->type == TABLETPC) { - if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { - if (usb_get_extra_descriptor(&interface->endpoint[0], - HID_DEVICET_REPORT, &hid_desc)) { - printk("wacom: can not retrive extra class descriptor\n"); - goto fail2; - } - } - error = wacom_parse_hid(intf, hid_desc, wacom_wac); - if (error) - goto fail2; - } - - input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | - BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS); - input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0); - input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0); - input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0); - if (features->type == TABLETPC) { - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); - input_set_abs_params(input_dev, ABS_RX, 0, features->touch_x_max, 4, 0); - input_set_abs_params(input_dev, ABS_RY, 0, features->touch_y_max, 4, 0); - } - input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); - - wacom_init_input_dev(input_dev, wacom_wac); - - usb_fill_int_urb(wacom->irq, dev, - usb_rcvintpipe(dev, endpoint->bEndpointAddress), - wacom_wac->data, wacom_wac->features->pktlen, - wacom_sys_irq, wacom, endpoint->bInterval); - wacom->irq->transfer_dma = wacom->data_dma; - wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - error = input_register_device(wacom->dev); - if (error) - goto fail3; - - /* - * Ask the tablet to report tablet data if it is not a Tablet PC. - * Repeat until it succeeds - */ - if ((wacom_wac->features->type != TABLETPC) && (wacom_wac->features->type != WACOM_GB)) { - do { - rep_data[0] = 2; - rep_data[1] = 2; - error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, - 2, rep_data, 2); - if (error >= 0) - error = usb_get_report(intf, - WAC_HID_FEATURE_REPORT, 2, - rep_data, 2); - } while ((error < 0 || rep_data[1] != 2) && limit++ < 5); - } - - usb_set_intfdata(intf, wacom); - return 0; - - fail3: usb_free_urb(wacom->irq); - fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); - fail1: input_free_device(input_dev); - kfree(wacom); - kfree(wacom_wac); - return error; -} - -static void wacom_disconnect(struct usb_interface *intf) -{ - struct wacom *wacom = usb_get_intfdata(intf); - - usb_set_intfdata(intf, NULL); - - usb_kill_urb(wacom->irq); - input_unregister_device(wacom->dev); - usb_free_urb(wacom->irq); - usb_buffer_free(interface_to_usbdev(intf), 10, - wacom->wacom_wac->data, wacom->data_dma); - kfree(wacom->wacom_wac); - kfree(wacom); -} - -static int wacom_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct wacom *wacom = usb_get_intfdata(intf); - - mutex_lock(&wacom->lock); - usb_kill_urb(wacom->irq); - mutex_unlock(&wacom->lock); - - return 0; -} - -static int wacom_resume(struct usb_interface *intf) -{ - struct wacom *wacom = usb_get_intfdata(intf); - int rv; - - mutex_lock(&wacom->lock); - if (wacom->open) - rv = usb_submit_urb(wacom->irq, GFP_NOIO); - else - rv = 0; - mutex_unlock(&wacom->lock); - - return rv; -} - -static int wacom_reset_resume(struct usb_interface *intf) -{ - return wacom_resume(intf); -} - -static struct usb_driver wacom_driver = { - .name = "wacom", - .probe = wacom_probe, - .disconnect = wacom_disconnect, - .suspend = wacom_suspend, - .resume = wacom_resume, - .reset_resume = wacom_reset_resume, - .supports_autosuspend = 1, -}; - -static int __init wacom_init(void) -{ - int result; - wacom_driver.id_table = get_device_table(); - result = usb_register(&wacom_driver); - if (result == 0) - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); - return result; -} - -static void __exit wacom_exit(void) -{ - usb_deregister(&wacom_driver); -} - -module_init(wacom_init); -module_exit(wacom_exit); diff --git a/src/2.6.28/wacom_wac.c b/src/2.6.28/wacom_wac.c deleted file mode 100755 index 53b0e56..0000000 --- a/src/2.6.28/wacom_wac.c +++ /dev/null @@ -1,971 +0,0 @@ -/* - * drivers/input/tablet/wacom_wac.c - * - * USB Wacom Graphire and Wacom Intuos tablet support - Wacom specific code - * - */ - -/* - * 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. - */ -#include "wacom.h" -#include "wacom_wac.h" - -static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - - switch (data[0]) { - case 1: - if (data[5] & 0x80) { - wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID; - wacom_report_key(wcombo, wacom->tool[0], 1); - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); - wacom_report_abs(wcombo, ABS_PRESSURE, (signed char)data[6] + 127); - wacom_report_key(wcombo, BTN_TOUCH, ((signed char)data[6] > -127)); - wacom_report_key(wcombo, BTN_STYLUS, (data[5] & 0x40)); - } else { - wacom_report_key(wcombo, wacom->tool[0], 0); - wacom_report_abs(wcombo, ABS_MISC, 0); /* report tool id */ - wacom_report_abs(wcombo, ABS_PRESSURE, -1); - wacom_report_key(wcombo, BTN_TOUCH, 0); - } - break; - case 2: - wacom_report_key(wcombo, BTN_TOOL_PEN, 1); - wacom_report_abs(wcombo, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */ - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); - wacom_report_abs(wcombo, ABS_PRESSURE, (signed char)data[6] + 127); - wacom_report_key(wcombo, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20)); - wacom_report_key(wcombo, BTN_STYLUS, (data[5] & 0x40)); - break; - default: - printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]); - return 0; - } - return 1; -} - -static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - int prox, pressure; - - if (data[0] != 2) { - dbg("wacom_pl_irq: received unknown report #%d", data[0]); - return 0; - } - - prox = data[1] & 0x40; - - wacom->id[0] = ERASER_DEVICE_ID; - if (prox) { - - pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); - if (wacom->features->pressure_max > 255) - pressure = (pressure << 1) | ((data[4] >> 6) & 1); - pressure += (wacom->features->pressure_max + 1) / 2; - - /* - * if going from out of proximity into proximity select between the eraser - * and the pen based on the state of the stylus2 button, choose eraser if - * pressed else choose pen. if not a proximity change from out to in, send - * an out of proximity for previous tool then a in for new tool. - */ - if (!wacom->tool[0]) { - /* Eraser bit set for DTF */ - if (data[1] & 0x10) - wacom->tool[1] = BTN_TOOL_RUBBER; - else - /* Going into proximity select tool */ - wacom->tool[1] = (data[4] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - } else { - /* was entered with stylus2 pressed */ - if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) { - /* report out proximity for previous tool */ - wacom_report_key(wcombo, wacom->tool[1], 0); - wacom_input_sync(wcombo); - wacom->tool[1] = BTN_TOOL_PEN; - return 0; - } - } - if (wacom->tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom->tool[1] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - } - wacom_report_key(wcombo, wacom->tool[1], prox); /* report in proximity for tool */ - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ - wacom_report_abs(wcombo, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); - wacom_report_abs(wcombo, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); - wacom_report_abs(wcombo, ABS_PRESSURE, pressure); - - wacom_report_key(wcombo, BTN_TOUCH, data[4] & 0x08); - wacom_report_key(wcombo, BTN_STYLUS, data[4] & 0x10); - /* Only allow the stylus2 button to be reported for the pen tool. */ - wacom_report_key(wcombo, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20)); - } else { - /* report proximity-out of a (valid) tool */ - if (wacom->tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom->tool[1] = BTN_TOOL_PEN; - } - wacom_report_key(wcombo, wacom->tool[1], prox); - } - - wacom->tool[0] = prox; /* Save proximity state */ - return 1; -} - -static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - - if (data[0] != 2) { - printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); - return 0; - } - - if (data[1] & 0x04) { - wacom_report_key(wcombo, BTN_TOOL_RUBBER, data[1] & 0x20); - wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x08); - wacom->id[0] = ERASER_DEVICE_ID; - } else { - wacom_report_key(wcombo, BTN_TOOL_PEN, data[1] & 0x20); - wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); - wacom->id[0] = STYLUS_DEVICE_ID; - } - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); - wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); - wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); - wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); - return 1; -} - -static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - int x, y, rw; - - if ((data[0] != 2) && (data[0] != 0x03)) { /* 0x03 for GB data */ - dbg("wacom_graphire_irq: received unknown report #%d", data[0]); - return 0; - } - - if (data[1] & 0x80) { - /* in prox and not a pad data */ - - switch ((data[1] >> 5) & 3) { - - case 0: /* Pen */ - wacom->tool[0] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - break; - - case 1: /* Rubber */ - wacom->tool[0] = BTN_TOOL_RUBBER; - wacom->id[0] = ERASER_DEVICE_ID; - break; - - case 2: /* Mouse with wheel */ - wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); - if (wacom->features->type == WACOM_G4 || - wacom->features->type == WACOM_MO || - wacom->features->type == WACOM_GB ) { - rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); - wacom_report_rel(wcombo, REL_WHEEL, -rw); - } else - wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]); - /* fall through */ - - case 3: /* Mouse without wheel */ - wacom->tool[0] = BTN_TOOL_MOUSE; - wacom->id[0] = CURSOR_DEVICE_ID; - wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); - wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); - if (wacom->features->type == WACOM_G4 || - wacom->features->type == WACOM_MO || - wacom->features->type == WACOM_GB ) - wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); - else - wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); - break; - } - x = wacom_le16_to_cpu(&data[2]); - y = wacom_le16_to_cpu(&data[4]); - wacom_report_abs(wcombo, ABS_X, x); - wacom_report_abs(wcombo, ABS_Y, y); - if (wacom->tool[0] != BTN_TOOL_MOUSE) { - wacom_report_abs(wcombo, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8)); - wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); - wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); - wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); - } - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ - wacom_report_key(wcombo, wacom->tool[0], 1); - } else if (wacom->id[0]) { - wacom_report_abs(wcombo, ABS_X, 0); - wacom_report_abs(wcombo, ABS_Y, 0); - if (wacom->tool[0] == BTN_TOOL_MOUSE) { - wacom_report_key(wcombo, BTN_LEFT, 0); - wacom_report_key(wcombo, BTN_RIGHT, 0); - wacom_report_abs(wcombo, ABS_DISTANCE, 0); - } else { - wacom_report_abs(wcombo, ABS_PRESSURE, 0); - wacom_report_key(wcombo, BTN_TOUCH, 0); - wacom_report_key(wcombo, BTN_STYLUS, 0); - wacom_report_key(wcombo, BTN_STYLUS2, 0); - } - wacom->id[0] = 0; - wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ - wacom_report_key(wcombo, wacom->tool[0], 0); - } - - /* send pad data */ - switch (wacom->features->type) { - case WACOM_G4: - if (data[7] & 0xf8) { - wacom_input_sync(wcombo); /* sync last event */ - wacom->id[1] = PAD_DEVICE_ID; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); - rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); - wacom_report_rel(wcombo, REL_WHEEL, rw); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); - wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } else if (wacom->id[1]) { - wacom_input_sync(wcombo); /* sync last event */ - wacom->id[1] = 0; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); - wacom_report_abs(wcombo, ABS_MISC, 0); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } - break; - case WACOM_MO: - if ((data[7] & 0xf8) || (data[8] & 0xff)) { - wacom_input_sync(wcombo); /* sync last event */ - wacom->id[1] = PAD_DEVICE_ID; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); - wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); - wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); - wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); - wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } else if (wacom->id[1]) { - wacom_input_sync(wcombo); /* sync last event */ - wacom->id[1] = 0; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); - wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); - wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); - wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); - wacom_report_abs(wcombo, ABS_MISC, 0); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } - break; - case WACOM_GB: - if (data [7] & 0x03) { - wacom_input_sync(wcombo); /* sync last event */ - wacom->id[1] = PAD_DEVICE_ID; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x02)); - wacom_report_key(wcombo, BTN_1, (data[7] & 0x01)); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); - wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } else if (wacom->id[1]) { - wacom_input_sync(wcombo); /* sync last event */ - wacom->id[1] = 0; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x02)); - wacom_report_key(wcombo, BTN_1, (data[7] & 0x01)); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); - wacom_report_abs(wcombo, ABS_MISC, 0); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } - } - return 1; -} - -static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - int idx = 0; - - /* tool number */ - if (wacom->features->type == INTUOS) - idx = data[1] & 0x01; - - /* Enter report */ - if ((data[1] & 0xfc) == 0xc0) { - /* serial number of the tool */ - wacom->serial[idx] = ((data[3] & 0x0f) << 28) + - (data[4] << 20) + (data[5] << 12) + - (data[6] << 4) + (data[7] >> 4); - - wacom->id[idx] = (data[2] << 4) | (data[3] >> 4); - switch (wacom->id[idx]) { - case 0x812: /* Inking pen */ - case 0x801: /* Intuos3 Inking pen */ - case 0x20802: /* Intuos4 Classic Pen */ - case 0x012: - wacom->tool[idx] = BTN_TOOL_PENCIL; - break; - case 0x822: /* Pen */ - case 0x842: - case 0x852: - case 0x823: /* Intuos3 Grip Pen */ - case 0x813: /* Intuos3 Classic Pen */ - case 0x885: /* Intuos3 Marker Pen */ - case 0x802: /* Intuos4 Grip Pen Eraser */ - case 0x804: /* Intuos4 Marker Pen */ - case 0x40802: /* Intuos4 Classic Pen */ - case 0x022: - wacom->tool[idx] = BTN_TOOL_PEN; - break; - case 0x832: /* Stroke pen */ - case 0x032: - wacom->tool[idx] = BTN_TOOL_BRUSH; - break; - case 0x007: /* Mouse 4D and 2D */ - case 0x09c: - case 0x094: - case 0x017: /* Intuos3 2D Mouse */ - case 0x806: /* Intuos4 Mouse */ - wacom->tool[idx] = BTN_TOOL_MOUSE; - break; - case 0x096: /* Lens cursor */ - case 0x097: /* Intuos3 Lens cursor */ - case 0x006: /* Intuos4 Lens cursor */ - wacom->tool[idx] = BTN_TOOL_LENS; - break; - case 0x82a: /* Eraser */ - case 0x85a: - case 0x91a: - case 0xd1a: - case 0x0fa: - case 0x82b: /* Intuos3 Grip Pen Eraser */ - case 0x81b: /* Intuos3 Classic Pen Eraser */ - case 0x91b: /* Intuos3 Airbrush Eraser */ - case 0x80c: /* Intuos4 Marker Pen Eraser */ - case 0x80a: /* Intuos4 Grip Pen Eraser */ - case 0x4080a: /* Intuos4 Classic Pen Eraser */ - case 0x90a: /* Intuos4 Airbrush Eraser */ - wacom->tool[idx] = BTN_TOOL_RUBBER; - break; - case 0xd12: - case 0x912: - case 0x112: - case 0x913: /* Intuos3 Airbrush */ - case 0x902: /* Intuos4 Airbrush */ - wacom->tool[idx] = BTN_TOOL_AIRBRUSH; - break; - default: /* Unknown tool */ - wacom->tool[idx] = BTN_TOOL_PEN; - } - return 1; - } - - /* Exit report */ - if ((data[1] & 0xfe) == 0x80) { - /* reset all states otherwise we lose the initial states - * when in-prox next time - */ - wacom_report_abs(wcombo, ABS_X, 0); - wacom_report_abs(wcombo, ABS_Y, 0); - wacom_report_abs(wcombo, ABS_DISTANCE, 0); - wacom_report_abs(wcombo, ABS_TILT_X, 0); - wacom_report_abs(wcombo, ABS_TILT_Y, 0); - if (wacom->tool[idx] >= BTN_TOOL_MOUSE) { - wacom_report_key(wcombo, BTN_LEFT, 0); - wacom_report_key(wcombo, BTN_MIDDLE, 0); - wacom_report_key(wcombo, BTN_RIGHT, 0); - wacom_report_key(wcombo, BTN_SIDE, 0); - wacom_report_key(wcombo, BTN_EXTRA, 0); - wacom_report_abs(wcombo, ABS_THROTTLE, 0); - wacom_report_abs(wcombo, ABS_RZ, 0); - } else { - wacom_report_abs(wcombo, ABS_PRESSURE, 0); - wacom_report_key(wcombo, BTN_STYLUS, 0); - wacom_report_key(wcombo, BTN_STYLUS2, 0); - wacom_report_key(wcombo, BTN_TOUCH, 0); - wacom_report_abs(wcombo, ABS_WHEEL, 0); - if (wacom->features->type >= INTUOS3S) - wacom_report_abs(wcombo, ABS_Z, 0); - } - wacom_report_key(wcombo, wacom->tool[idx], 0); - wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); - wacom->id[idx] = 0; - return 2; - } - return 0; -} - -static void wacom_intuos_general(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - unsigned int t; - - /* general pen packet */ - if ((data[1] & 0xb8) == 0xa0) { - t = (data[6] << 2) | ((data[7] >> 6) & 3); - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) - t = (t << 1) | (data[1] & 1); - wacom_report_abs(wcombo, ABS_PRESSURE, t); - wacom_report_abs(wcombo, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f); - wacom_report_key(wcombo, BTN_STYLUS, data[1] & 2); - wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 4); - wacom_report_key(wcombo, BTN_TOUCH, t > 10); - } - - /* airbrush second packet */ - if ((data[1] & 0xbc) == 0xb4) { - wacom_report_abs(wcombo, ABS_WHEEL, - (data[6] << 2) | ((data[7] >> 6) & 3)); - wacom_report_abs(wcombo, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f); - } - return; -} - -static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) -{ - unsigned char *data = wacom->data; - unsigned int t; - int idx = 0, result; - - if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) { - dbg("wacom_intuos_irq: received unknown report #%d", data[0]); - return 0; - } - - /* tool number */ - if (wacom->features->type == INTUOS) - idx = data[1] & 0x01; - - /* pad packets. Works as a second tool and is always in prox */ - if (data[0] == 12) { - /* initiate the pad as a device */ - if (wacom->tool[1] != BTN_TOOL_FINGER) - wacom->tool[1] = BTN_TOOL_FINGER; - - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { - wacom_report_key(wcombo, BTN_0, (data[2] & 0x01)); - wacom_report_key(wcombo, BTN_1, (data[3] & 0x01)); - wacom_report_key(wcombo, BTN_2, (data[3] & 0x02)); - wacom_report_key(wcombo, BTN_3, (data[3] & 0x04)); - wacom_report_key(wcombo, BTN_4, (data[3] & 0x08)); - wacom_report_key(wcombo, BTN_5, (data[3] & 0x10)); - wacom_report_key(wcombo, BTN_6, (data[3] & 0x20)); - if (data[1] & 0x80) { - wacom_report_abs(wcombo, ABS_WHEEL, (data[1] & 0x7f)); - } else { - /* Out of proximity, clear wheel value. */ - wacom_report_abs(wcombo, ABS_WHEEL, 0); - } - if (wacom->features->type != INTUOS4S) { - wacom_report_key(wcombo, BTN_7, (data[3] & 0x40)); - wacom_report_key(wcombo, BTN_8, (data[3] & 0x80)); - } - if (data[1] | (data[2] & 0x01) | data[3]) { - wacom_report_key(wcombo, wacom->tool[1], 1); - wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); - } else { - wacom_report_key(wcombo, wacom->tool[1], 0); - wacom_report_abs(wcombo, ABS_MISC, 0); - } - } else { - wacom_report_key(wcombo, BTN_0, (data[5] & 0x01)); - wacom_report_key(wcombo, BTN_1, (data[5] & 0x02)); - wacom_report_key(wcombo, BTN_2, (data[5] & 0x04)); - wacom_report_key(wcombo, BTN_3, (data[5] & 0x08)); - wacom_report_key(wcombo, BTN_4, (data[6] & 0x01)); - wacom_report_key(wcombo, BTN_5, (data[6] & 0x02)); - wacom_report_key(wcombo, BTN_6, (data[6] & 0x04)); - wacom_report_key(wcombo, BTN_7, (data[6] & 0x08)); - wacom_report_key(wcombo, BTN_8, (data[5] & 0x10)); - wacom_report_key(wcombo, BTN_9, (data[6] & 0x10)); - wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); - wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); - - if ((data[5] & 0x1f) | (data[6] & 0x1f) | (data[1] & 0x1f) | - data[2] | (data[3] & 0x1f) | data[4]) { - wacom_report_key(wcombo, wacom->tool[1], 1); - wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); - } else { - wacom_report_key(wcombo, wacom->tool[1], 0); - wacom_report_abs(wcombo, ABS_MISC, 0); - } - } - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xffffffff); - return 1; - } - - /* process in/out prox events */ - result = wacom_intuos_inout(wacom, wcombo); - if (result) - return result-1; - - /* don't proceed if we don't know the ID */ - if (!wacom->id[idx]) - return 0; - - /* Only large Intuos support Lense Cursor */ - if ((wacom->tool[idx] == BTN_TOOL_LENS) - && ((wacom->features->type == INTUOS3) - || (wacom->features->type == INTUOS3S) - || (wacom->features->type == INTUOS4) - || (wacom->features->type == INTUOS4S))) - return 0; - - /* Cintiq doesn't send data when RDY bit isn't set */ - if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40)) - return 0; - - if (wacom->features->type >= INTUOS3S) { - wacom_report_abs(wcombo, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); - wacom_report_abs(wcombo, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); - wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); - } else { - wacom_report_abs(wcombo, ABS_X, wacom_be16_to_cpu(&data[2])); - wacom_report_abs(wcombo, ABS_Y, wacom_be16_to_cpu(&data[4])); - wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); - } - - /* process general packets */ - wacom_intuos_general(wacom, wcombo); - - /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ - if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) { - - if (data[1] & 0x02) { - /* Rotation packet */ - if (wacom->features->type >= INTUOS3S) { - /* I3 marker pen rotation */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : - ((t-1) / 2 + 450)) : (450 - t / 2) ; - wacom_report_abs(wcombo, ABS_Z, t); - } else { - /* 4D mouse rotation packet */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - wacom_report_abs(wcombo, ABS_RZ, (data[7] & 0x20) ? - ((t - 1) / 2) : -t / 2); - } - - } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3S) { - /* 4D mouse packet */ - wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); - wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); - wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x04); - - wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x20); - wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x10); - t = (data[6] << 2) | ((data[7] >> 6) & 3); - wacom_report_abs(wcombo, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); - - } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { - /* I4 mouse */ - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { - wacom_report_key(wcombo, BTN_LEFT, data[6] & 0x01); - wacom_report_key(wcombo, BTN_MIDDLE, data[6] & 0x02); - wacom_report_key(wcombo, BTN_RIGHT, data[6] & 0x04); - wacom_report_rel(wcombo, REL_WHEEL, ((data[7] & 0x80) >> 7) - - ((data[7] & 0x40) >> 6)); - wacom_report_key(wcombo, BTN_SIDE, data[6] & 0x08); - wacom_report_key(wcombo, BTN_EXTRA, data[6] & 0x10); - - wacom_report_abs(wcombo, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f); - } else { - /* 2D mouse packet */ - wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x04); - wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x08); - wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x10); - wacom_report_rel(wcombo, REL_WHEEL, (data[8] & 0x01) - - ((data[8] & 0x02) >> 1)); - - /* I3 2D mouse side buttons */ - if (wacom->features->type >= INTUOS3S && wacom->features->type <= INTUOS3L) { - wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x40); - wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x20); - } - } - } else if ((wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L || - wacom->features->type == INTUOS4L) && (wacom->tool[idx] == BTN_TOOL_LENS)) { - /* Lens cursor packets */ - wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); - wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); - wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x04); - wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x10); - wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x08); - } - } - - wacom_report_abs(wcombo, ABS_MISC, wacom->id[idx]); /* report tool id */ - wacom_report_key(wcombo, wacom->tool[idx], 1); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); - return 1; -} - -static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) -{ - char *data = wacom->data; - int prox = 0, pressure; - static int stylusInProx, touchInProx = 1, touchOut; - struct urb *urb = ((struct wacom_combo *)wcombo)->urb; - - dbg("wacom_tpc_irq: received report #%d", data[0]); - - if (urb->actual_length == 5 || data[0] == 6) { /* Touch data */ - if (urb->actual_length == 5) { /* with touch */ - prox = data[0] & 0x03; - } else { /* with capacity */ - prox = data[1] & 0x03; - } - - if (!stylusInProx) { /* stylus not in prox */ - if (prox) { - if (touchInProx) { - wacom->tool[1] = BTN_TOOL_DOUBLETAP; - wacom->id[0] = TOUCH_DEVICE_ID; - if (urb->actual_length != 5) { - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); - wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); - wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6])); - } else { - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); - wacom_report_key(wcombo, BTN_TOUCH, 1); - } - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); - wacom_report_key(wcombo, wacom->tool[1], prox & 0x01); - touchOut = 1; - return 1; - } - } else { - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); - wacom_report_key(wcombo, wacom->tool[1], prox & 0x01); - wacom_report_key(wcombo, BTN_TOUCH, 0); - touchOut = 0; - touchInProx = 1; - return 1; - } - } else if (touchOut || !prox) { /* force touch out-prox */ - wacom_report_abs(wcombo, ABS_MISC, TOUCH_DEVICE_ID); - wacom_report_key(wcombo, wacom->tool[1], 0); - wacom_report_key(wcombo, BTN_TOUCH, 0); - touchOut = 0; - touchInProx = 1; - return 1; - } - } else if (data[0] == 2) { /* Penabled */ - prox = data[1] & 0x20; - - touchInProx = 0; - - wacom->id[0] = ERASER_DEVICE_ID; - - /* - * if going from out of proximity into proximity select between the eraser - * and the pen based on the state of the stylus2 button, choose eraser if - * pressed else choose pen. if not a proximity change from out to in, send - * an out of proximity for previous tool then a in for new tool. - */ - if (prox) { /* in prox */ - if (!wacom->tool[0]) { - /* Going into proximity select tool */ - wacom->tool[1] = (data[1] & 0x08) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - if (wacom->tool[1] == BTN_TOOL_PEN) - wacom->id[0] = STYLUS_DEVICE_ID; - } else if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[1] & 0x08)) { - /* - * was entered with stylus2 pressed - * report out proximity for previous tool - */ - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); - wacom_report_key(wcombo, wacom->tool[1], 0); - wacom_input_sync(wcombo); - - /* set new tool */ - wacom->tool[1] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - return 0; - } - if (wacom->tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom->tool[1] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - } - wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); - wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); - pressure = ((data[7] & 0x01) << 8) | data[6]; - if (pressure < 0) - pressure = wacom->features->pressure_max + pressure + 1; - wacom_report_abs(wcombo, ABS_PRESSURE, pressure); - wacom_report_key(wcombo, BTN_TOUCH, pressure); - } else { - wacom_report_abs(wcombo, ABS_PRESSURE, 0); - wacom_report_key(wcombo, BTN_STYLUS, 0); - wacom_report_key(wcombo, BTN_STYLUS2, 0); - wacom_report_key(wcombo, BTN_TOUCH, 0); - } - wacom_report_key(wcombo, wacom->tool[1], prox); - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); - stylusInProx = prox; - wacom->tool[0] = prox; - return 1; - } - return 0; -} - -int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) -{ - switch (wacom_wac->features->type) { - case PENPARTNER: - return wacom_penpartner_irq(wacom_wac, wcombo); - - case PL: - return wacom_pl_irq(wacom_wac, wcombo); - - case WACOM_G4: - case GRAPHIRE: - case WACOM_MO: - case WACOM_GB: - return wacom_graphire_irq(wacom_wac, wcombo); - - case PTU: - return wacom_ptu_irq(wacom_wac, wcombo); - - case INTUOS: - case INTUOS3S: - case INTUOS3: - case INTUOS3L: - case INTUOS4S: - case INTUOS4: - case INTUOS4L: - case CINTIQ: - case WACOM_BEE: - return wacom_intuos_irq(wacom_wac, wcombo); - - case TABLETPC: - return wacom_tpc_irq(wacom_wac, wcombo); - - default: - return 0; - } - return 0; -} - -void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - switch (wacom_wac->features->type) { - case WACOM_MO: - input_dev_mo(input_dev, wacom_wac); - case WACOM_G4: - case WACOM_GB: - input_dev_g4(input_dev, wacom_wac); - /* fall through */ - case GRAPHIRE: - input_dev_g(input_dev, wacom_wac); - break; - case WACOM_BEE: - input_dev_bee(input_dev, wacom_wac); - case INTUOS3: - case INTUOS3L: - case CINTIQ: - input_dev_i3(input_dev, wacom_wac); - /* fall through */ - case INTUOS3S: - input_dev_i3s(input_dev, wacom_wac); - /* fall through */ - case INTUOS: - input_dev_i(input_dev, wacom_wac); - break; - case INTUOS4: - case INTUOS4L: - input_dev_i4(input_dev, wacom_wac); - /* fall through */ - case INTUOS4S: - input_dev_i4s(input_dev, wacom_wac); - input_dev_i(input_dev, wacom_wac); - break; - case PL: - case PTU: - case TABLETPC: - input_dev_pl(input_dev, wacom_wac); - /* fall through */ - case PENPARTNER: - input_dev_pt(input_dev, wacom_wac); - break; - } - return; -} - -static struct wacom_features wacom_features[] = { - { "Wacom Penpartner", 7, 5040, 3780, 255, 0, PENPARTNER }, - { "Wacom Graphire", 8, 10206, 7422, 511, 63, GRAPHIRE }, - { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 63, GRAPHIRE }, - { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 63, GRAPHIRE }, - { "Wacom Graphire3", 8, 10208, 7424, 511, 63, GRAPHIRE }, - { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE }, - { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, WACOM_G4 }, - { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 }, - { "Wacom BambooFun 4x5", 9, 14760, 9225, 511, 63, WACOM_MO }, - { "Wacom BambooFun 6x8", 9, 21648, 13530, 511, 63, WACOM_MO }, - { "Wacom Bamboo1 Medium", 8, 16704, 12064, 511, 63, GRAPHIRE }, - { "Wacom Volito", 8, 5104, 3712, 511, 63, GRAPHIRE }, - { "Wacom PenStation2", 8, 3250, 2320, 255, 63, GRAPHIRE }, - { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE }, - { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE }, - { "Wacom PenPartner2", 8, 3250, 2320, 511, 63, GRAPHIRE }, - { "Wacom Bamboo", 9, 14760, 9225, 511, 63, WACOM_MO }, - { "Wacom Bamboo1", 8, 5104, 3712, 511, 63, GRAPHIRE }, - { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, - { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, - { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS }, - { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 31, INTUOS }, - { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 31, INTUOS }, - { "Wacom PL400", 8, 5408, 4056, 255, 0, PL }, - { "Wacom PL500", 8, 6144, 4608, 255, 0, PL }, - { "Wacom PL600", 8, 6126, 4604, 255, 0, PL }, - { "Wacom PL600SX", 8, 6260, 5016, 255, 0, PL }, - { "Wacom PL550", 8, 6144, 4608, 511, 0, PL }, - { "Wacom PL800", 8, 7220, 5780, 511, 0, PL }, - { "Wacom PL700", 8, 6758, 5406, 511, 0, PL }, - { "Wacom PL510", 8, 6282, 4762, 511, 0, PL }, - { "Wacom DTU710", 8, 34080, 27660, 511, 0, PL }, - { "Wacom DTF521", 8, 6282, 4762, 511, 0, PL }, - { "Wacom DTF720", 8, 6858, 5506, 511, 0, PL }, - { "Wacom DTF720a", 8, 6858, 5506, 511, 0, PL }, - { "Wacom Cintiq Partner", 8, 20480, 15360, 511, 0, PTU }, - { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, - { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, - { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 31, INTUOS }, - { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 31, INTUOS }, - { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 31, INTUOS }, - { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 63, INTUOS3S }, - { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 63, INTUOS3 }, - { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 63, INTUOS3 }, - { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L }, - { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L }, - { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 }, - { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S }, - { "Wacom Intuos4 4x6", 10, 31496, 19685, 2047, 63, INTUOS4S }, - { "Wacom Intuos4 6x9", 10, 44704, 27940, 2047, 63, INTUOS4 }, - { "Wacom Intuos4 8x13", 10, 65024, 40640, 2047, 63, INTUOS4L }, - { "Wacom Intuos4 12x19", 10, 97536, 60960, 2047, 63, INTUOS4L }, - { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, - { "Wacom Cintiq 20WSX", 10, 86680, 54180, 1023, 63, WACOM_BEE }, - { "Wacom Cintiq 12WX", 10, 53020, 33440, 1023, 63, WACOM_BEE }, - { "Wacom DTU1931", 8, 37832, 30305, 511, 0, PL }, - { "Wacom Graphire Bluetooth", 8, 10208, 7424, 511, 63, WACOM_GB }, - { "Wacom ISDv4 90", 8, 26202, 16325, 255, 0, TABLETPC }, - { "Wacom ISDv4 93", 8, 26202, 16325, 255, 0, TABLETPC }, - { "Wacom ISDv4 9A", 8, 26202, 16325, 255, 0, TABLETPC }, - { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, - { } -}; - -static struct usb_device_id wacom_ids[] = { - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x00) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x11) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x17) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x18) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x19) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x69) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x30) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x32) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC4) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC2) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB8) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB9) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBA) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBB) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC7) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x81) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x90) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x93) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9A) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, - { } -}; - -const struct usb_device_id *get_device_table(void) -{ - const struct usb_device_id *id_table = wacom_ids; - - return id_table; -} - -struct wacom_features * get_wacom_feature(const struct usb_device_id *id) -{ - int index = id - wacom_ids; - struct wacom_features *wf = &wacom_features[index]; - - return wf; -} - -MODULE_DEVICE_TABLE(usb, wacom_ids); diff --git a/src/2.6.28/wacom_wac.h b/src/2.6.28/wacom_wac.h deleted file mode 100755 index db987e5..0000000 --- a/src/2.6.28/wacom_wac.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * drivers/input/tablet/wacom_wac.h - * - * 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. - */ -#ifndef WACOM_WAC_H -#define WACOM_WAC_H - -#define STYLUS_DEVICE_ID 0x02 -#define TOUCH_DEVICE_ID 0x03 -#define CURSOR_DEVICE_ID 0x06 -#define ERASER_DEVICE_ID 0x0A -#define PAD_DEVICE_ID 0x0F - -enum { - PENPARTNER = 0, - GRAPHIRE, - WACOM_G4, - PTU, - PL, - INTUOS, - INTUOS3S, - INTUOS3, - INTUOS3L, - INTUOS4S, - INTUOS4, - INTUOS4L, - CINTIQ, - WACOM_BEE, - WACOM_MO, - TABLETPC, - WACOM_GB, - MAX_TYPE -}; - -struct wacom_features { - char *name; - int pktlen; - int x_max; - int y_max; - int pressure_max; - int distance_max; - int type; - int touch_x_max; - int touch_y_max; -}; - -struct wacom_wac { - unsigned char *data; - int tool[2]; - int id[2]; - __u32 serial[2]; - struct wacom_features *features; -}; - -#endif diff --git a/src/2.6.31/Makefile.in b/src/2.6.31/Makefile.in deleted file mode 100755 index 4014d8a..0000000 --- a/src/2.6.31/Makefile.in +++ /dev/null @@ -1,55 +0,0 @@ -############################ 2.6 kernel compile ############################### -ifneq ($(KERNELRELEASE),) -# We were called by kbuild -# Do NOT indent stuff in this part! It has to be like this to make the -# $(error ... ) stuff work - -ifeq ($(WCM_OPTION_WACOM),yes) -ifneq ($(CONFIG_USB_WACOM),y) -wacom-objs := wacom_wac.o wacom_sys.o -obj-m += wacom.o -else -$(error You requested to build wacom with configure, but wacom is configured as built-in in your kernel config) -endif # CONFIG_USB_WACOM - -ifneq ($(CONFIG_HID_WACOM),y) -obj-m += hid-wacom.o -else -$(error You requested to build hid-wacom with configure, but hid-wacom is configured as built-in in your kernel config) -endif # CONFIG_HID_WACOM - -endif # WCM_OPTION_WACOM - -else # We were called from command line -PWD := $(shell pwd) - -WCM_KERNEL_DIR := @WCM_KERNEL_DIR@ -WCM_OPTION_WACOM := @WCM_OPTION_WACOM@ - -export WCM_OPTION_WACOM - -all: -# Copy Wacom specific code which is common to all kernel releases -ifeq ($(WCM_OPTION_WACOM),yes) - cp -f ../2.6.27/wacom.h . - cp -f ../2.6.28/wacom_wac.h . - cp -f ../2.6.28/wacom_sys.c . - cp -f ../2.6.28/wacom_wac.c . - cp $(WCM_KERNEL_DIR)/drivers/hid/hid-ids.h . -endif - @echo ' Building linuxwacom drivers for 2.6 kernel.' - @echo '***Note: Drivers not enabled as modules in your kernel config but requested through configure are NOT built' - $(MAKE) -C $(WCM_KERNEL_DIR) M=$(PWD) - -endif # End kbuild check - -######################### Version independent targets ########################## - -clean: - rm -rf *.o *.ko *.mod.* .[a-z]* core *.i - -EMPTY_AUTOMAKE_TARGETS = distdir install install-data install-exec uninstall install-info -EMPTY_AUTOMAKE_TARGETS += installdirs check dvi pdf ps info html tags ctags mostlyclean distclean maintainer-clean -.PHONY: $(EMPTY_AUTOMAKE_TARGETS) - $(EMPTY_AUTOMAKE_TARGETS): - diff --git a/src/2.6.31/hid-wacom.c b/src/2.6.31/hid-wacom.c deleted file mode 100755 index 1f9237f..0000000 --- a/src/2.6.31/hid-wacom.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Bluetooth Wacom Tablet support - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> - * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com> - * Copyright (c) 2006 Andrew Zabolotny <zap@homelink.ru> - * Copyright (c) 2009 Bastien Nocera <hadess@hadess.net> - */ - -/* - * 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. - */ - -#include <linux/device.h> -#include <linux/hid.h> -#include <linux/module.h> - -#include "hid-ids.h" - -struct wacom_data { - __u16 tool; - unsigned char butstate; -}; - -static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, - u8 *raw_data, int size) -{ - struct wacom_data *wdata = hid_get_drvdata(hdev); - struct hid_input *hidinput; - struct input_dev *input; - unsigned char *data = (unsigned char *) raw_data; - int tool, x, y, rw; - - if (!(hdev->claimed & HID_CLAIMED_INPUT)) - return 0; - - tool = 0; - hidinput = list_entry(hdev->inputs.next, struct hid_input, list); - input = hidinput->input; - - /* Check if this is a tablet report */ - if (data[0] != 0x03) - return 0; - - /* Get X & Y positions */ - x = le16_to_cpu(*(__le16 *) &data[2]); - y = le16_to_cpu(*(__le16 *) &data[4]); - - /* Get current tool identifier */ - if (data[1] & 0x90) { /* If pen is in the in/active area */ - switch ((data[1] >> 5) & 3) { - case 0: /* Pen */ - tool = BTN_TOOL_PEN; - break; - - case 1: /* Rubber */ - tool = BTN_TOOL_RUBBER; - break; - - case 2: /* Mouse with wheel */ - case 3: /* Mouse without wheel */ - tool = BTN_TOOL_MOUSE; - break; - } - - /* Reset tool if out of active tablet area */ - if (!(data[1] & 0x10)) - tool = 0; - } - - /* If tool changed, notify input subsystem */ - if (wdata->tool != tool) { - if (wdata->tool) { - /* Completely reset old tool state */ - if (wdata->tool == BTN_TOOL_MOUSE) { - input_report_key(input, BTN_LEFT, 0); - input_report_key(input, BTN_RIGHT, 0); - input_report_key(input, BTN_MIDDLE, 0); - input_report_abs(input, ABS_DISTANCE, - input->absmax[ABS_DISTANCE]); - } else { - input_report_key(input, BTN_TOUCH, 0); - input_report_key(input, BTN_STYLUS, 0); - input_report_key(input, BTN_STYLUS2, 0); - input_report_abs(input, ABS_PRESSURE, 0); - } - input_report_key(input, wdata->tool, 0); - input_sync(input); - } - wdata->tool = tool; - if (tool) - input_report_key(input, tool, 1); - } - - if (tool) { - input_report_abs(input, ABS_X, x); - input_report_abs(input, ABS_Y, y); - - switch ((data[1] >> 5) & 3) { - case 2: /* Mouse with wheel */ - input_report_key(input, BTN_MIDDLE, data[1] & 0x04); - rw = (data[6] & 0x01) ? -1 : - (data[6] & 0x02) ? 1 : 0; - input_report_rel(input, REL_WHEEL, rw); - /* fall through */ - - case 3: /* Mouse without wheel */ - input_report_key(input, BTN_LEFT, data[1] & 0x01); - input_report_key(input, BTN_RIGHT, data[1] & 0x02); - /* Compute distance between mouse and tablet */ - rw = 44 - (data[6] >> 2); - if (rw < 0) - rw = 0; - else if (rw > 31) - rw = 31; - input_report_abs(input, ABS_DISTANCE, rw); - break; - - default: - input_report_abs(input, ABS_PRESSURE, - data[6] | (((__u16) (data[1] & 0x08)) << 5)); - input_report_key(input, BTN_TOUCH, data[1] & 0x01); - input_report_key(input, BTN_STYLUS, data[1] & 0x02); - input_report_key(input, BTN_STYLUS2, (tool == BTN_TOOL_PEN) && data[1] & 0x04); - break; - } - - input_sync(input); - } - - /* Report the state of the two buttons at the top of the tablet - * as two extra fingerpad keys (buttons 4 & 5). */ - rw = data[7] & 0x03; - if (rw != wdata->butstate) { - wdata->butstate = rw; - input_report_key(input, BTN_0, rw & 0x02); - input_report_key(input, BTN_1, rw & 0x01); - input_event(input, EV_MSC, MSC_SERIAL, 0xf0); - input_sync(input); - } - - return 1; -} - -static int wacom_probe(struct hid_device *hdev, - const struct hid_device_id *id) -{ - struct hid_input *hidinput; - struct input_dev *input; - struct wacom_data *wdata; - int ret; - - wdata = kzalloc(sizeof(*wdata), GFP_KERNEL); - if (wdata == NULL) { - dev_err(&hdev->dev, "can't alloc wacom descriptor\n"); - return -ENOMEM; - } - - hid_set_drvdata(hdev, wdata); - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err_free; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err_free; - } - - hidinput = list_entry(hdev->inputs.next, struct hid_input, list); - input = hidinput->input; - - /* Basics */ - input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL); - input->absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | - BIT(ABS_PRESSURE) | BIT(ABS_DISTANCE); - input->relbit[0] |= BIT(REL_WHEEL); - set_bit(BTN_TOOL_PEN, input->keybit); - set_bit(BTN_TOUCH, input->keybit); - set_bit(BTN_STYLUS, input->keybit); - set_bit(BTN_STYLUS2, input->keybit); - set_bit(BTN_LEFT, input->keybit); - set_bit(BTN_RIGHT, input->keybit); - set_bit(BTN_MIDDLE, input->keybit); - - /* Pad */ - input->evbit[0] |= BIT(EV_MSC); - input->mscbit[0] |= BIT(MSC_SERIAL); - - /* Distance, rubber and mouse */ - input->absbit[0] |= BIT(ABS_DISTANCE); - set_bit(BTN_TOOL_RUBBER, input->keybit); - set_bit(BTN_TOOL_MOUSE, input->keybit); - - input->absmax[ABS_PRESSURE] = 511; - input->absmax[ABS_DISTANCE] = 32; - - input->absmax[ABS_X] = 16704; - input->absmax[ABS_Y] = 12064; - input->absfuzz[ABS_X] = 4; - input->absfuzz[ABS_Y] = 4; - - return 0; -err_free: - kfree(wdata); - return ret; -} - -static void wacom_remove(struct hid_device *hdev) -{ - hid_hw_stop(hdev); - kfree(hid_get_drvdata(hdev)); -} - -static const struct hid_device_id wacom_devices[] = { - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, - - { } -}; -MODULE_DEVICE_TABLE(hid, wacom_devices); - -static struct hid_driver wacom_driver = { - .name = "wacom", - .id_table = wacom_devices, - .probe = wacom_probe, - .remove = wacom_remove, - .raw_event = wacom_raw_event, -}; - -static int wacom_init(void) -{ - int ret; - - ret = hid_register_driver(&wacom_driver); - if (ret) - printk(KERN_ERR "can't register wacom driver\n"); - printk(KERN_ERR "wacom driver registered\n"); - return ret; -} - -static void wacom_exit(void) -{ - hid_unregister_driver(&wacom_driver); -} - -module_init(wacom_init); -module_exit(wacom_exit); -MODULE_LICENSE("GPL"); - diff --git a/src/2.6.9/Makefile.in b/src/2.6.9/Makefile.in deleted file mode 100644 index 2657b92..0000000 --- a/src/2.6.9/Makefile.in +++ /dev/null @@ -1,101 +0,0 @@ -############################ 2.6 kernel compile ############################### -ifneq ($(KERNELRELEASE),) -# We were called by kbuild -# Do NOT indent stuff in this part! It has to be like this to make the -# $(error ... ) stuff work - -# only compile those modules which are enabled by global configure -ifeq ($(WCM_OPTION_HID),yes) - -# check if kernel was configured to have hid as an module -ifeq ($(CONFIG_USB_HID),m) - -# check if HID module should be usbhid.ko or hid.ko -NEWHID := $(shell test $(SUBLEVEL) -ge 6 && echo usb) - -$(NEWHID)hid-objs := hid-core.o - -# behave exactly as kernel config wants us to behave -ifeq ($(CONFIG_USB_HIDDEV),y) -$(NEWHID)hid-objs += hiddev.o -endif -ifeq ($(CONFIG_USB_HIDINPUT),y) -$(NEWHID)hid-objs += hid-input.o -endif -ifeq ($(CONFIG_HID_PID),y) -$(NEWHID)hid-objs += pid.o -endif -ifeq ($(CONFIG_LOGITECH_FF),y) -$(NEWHID)hid-objs += hid-lgff.o -endif -ifeq ($(CONFIG_THRUSTMASTER_FF),y) -$(NEWHID)hid-objs += hid-tmff.o -endif -ifeq ($(CONFIG_HID_FF),y) -$(NEWHID)hid-objs += hid-ff.o -endif - -obj-$(CONFIG_USB_HID) += $(NEWHID)hid.o - -else -ifeq ($(CONFIG_USB_HID),y) -$(error You requested to build hid with configure, but hid is configured as built-in in your kernel config) -endif - -$(error You requested to build hid with configure, but hid is not configured in your kernel config) -endif # CONFIG_USB_HID -endif # WCM_OPTION_HID not - -ifeq ($(WCM_OPTION_WACOM),yes) -ifneq ($(CONFIG_USB_WACOM),y) -obj-m += wacom.o -else -$(error You requested to build wacom with configure, but wacom is configured as built-in in your kernel config) -endif # CONFIG_USB_WACOM -endif # WCM_OPTION_WACOM - -else # We were called from command line -PWD := $(shell pwd) - -WCM_KERNEL_DIR := @WCM_KERNEL_DIR@ -WCM_OPTION_WACOM := @WCM_OPTION_WACOM@ -WCM_OPTION_HID := @WCM_OPTION_HID@ - -export WCM_OPTION_WACOM WCM_OPTION_HID - -COPY_FROM_KERNEL_TREE := hiddev.c hid.h hid-ff.c hid-input.c fixp-arith.h -COPY_FROM_KERNEL_TREE += hid-lgff.c hid-tmff.c pid.c pid.h - -all: -# Copy hid-stuff from kernel-dir to local dir -ifeq ($(WCM_OPTION_HID),yes) - @for i in $(COPY_FROM_KERNEL_TREE); do \ - if test ! -f "$$i" && test -f $(WCM_KERNEL_DIR)/drivers/usb/input/$$i ; then \ - cp $(WCM_KERNEL_DIR)/drivers/usb/input/$$i .; \ - fi; \ - done -endif - - @echo ' Building linuxwacom drivers for 2.6 kernel.' - @echo '***Note: Drivers not enabled as modules in your kernel config but requested through configure are NOT built' - $(MAKE) -C $(WCM_KERNEL_DIR) M=$(PWD) - -endif # End kbuild check - -######################### Version independent targets ########################## - -clean: - rm -rf *.o *.ko *.mod.* .[a-z]* core *.i - -# also remove copied stuff -distclean: clean - @for i in $(COPY_FROM_KERNEL_TREE); do \ - if test -f "$$i"; then \ - rm -f $$i ; \ - fi; \ - done - -EMPTY_AUTOMAKE_TARGETS = distdir install install-data install-exec uninstall install-info -EMPTY_AUTOMAKE_TARGETS += installdirs check dvi pdf ps info html tags ctags mostlyclean distclean maintainer-clean -.PHONY: $(EMPTY_AUTOMAKE_TARGETS) - $(EMPTY_AUTOMAKE_TARGETS): diff --git a/src/2.6.9/hid-core.c b/src/2.6.9/hid-core.c deleted file mode 100644 index 89e6789..0000000 --- a/src/2.6.9/hid-core.c +++ /dev/null @@ -1,1845 +0,0 @@ -/* - * USB HID support for Linux - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@suse.cz> - */ - -/* - * 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. - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/list.h> -#include <linux/mm.h> -#include <linux/smp_lock.h> -#include <linux/spinlock.h> -#include <asm/unaligned.h> -#include <asm/byteorder.h> -#include <linux/input.h> - -#undef DEBUG -#undef DEBUG_DATA - -#include <linux/usb.h> - -#include "hid.h" -#include <linux/hiddev.h> - -/* - * Version Information - */ - -#define DRIVER_VERSION "v2.0 - 2.6.9-pc-0.5" -#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik" -#define DRIVER_DESC "USB HID core driver" -#define DRIVER_LICENSE "GPL" - -static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick", - "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"}; - -/* - * Register a new report for a device. - */ - -static struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id) -{ - struct hid_report_enum *report_enum = device->report_enum + type; - struct hid_report *report; - - if (report_enum->report_id_hash[id]) - return report_enum->report_id_hash[id]; - - if (!(report = kmalloc(sizeof(struct hid_report), GFP_KERNEL))) - return NULL; - memset(report, 0, sizeof(struct hid_report)); - - if (id != 0) - report_enum->numbered = 1; - - report->id = id; - report->type = type; - report->size = 0; - report->device = device; - report_enum->report_id_hash[id] = report; - - list_add_tail(&report->list, &report_enum->report_list); - - return report; -} - -/* - * Register a new field for this report. - */ - -static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) -{ - struct hid_field *field; - - if (report->maxfield == HID_MAX_FIELDS) { - dbg("too many fields in report"); - return NULL; - } - - if (!(field = kmalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) - + values * sizeof(unsigned), GFP_KERNEL))) return NULL; - - memset(field, 0, sizeof(struct hid_field) + usages * sizeof(struct hid_usage) - + values * sizeof(unsigned)); - - report->field[report->maxfield++] = field; - field->usage = (struct hid_usage *)(field + 1); - field->value = (unsigned *)(field->usage + usages); - field->report = report; - - return field; -} - -/* - * Open a collection. The type/usage is pushed on the stack. - */ - -static int open_collection(struct hid_parser *parser, unsigned type) -{ - struct hid_collection *collection; - unsigned usage; - - usage = parser->local.usage[0]; - - if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { - dbg("collection stack overflow"); - return -1; - } - - if (parser->device->maxcollection == parser->device->collection_size) { - collection = kmalloc(sizeof(struct hid_collection) * - parser->device->collection_size * 2, - GFP_KERNEL); - if (collection == NULL) { - dbg("failed to reallocate collection array"); - return -1; - } - memcpy(collection, parser->device->collection, - sizeof(struct hid_collection) * - parser->device->collection_size); - memset(collection + parser->device->collection_size, 0, - sizeof(struct hid_collection) * - parser->device->collection_size); - kfree(parser->device->collection); - parser->device->collection = collection; - parser->device->collection_size *= 2; - } - - parser->collection_stack[parser->collection_stack_ptr++] = - parser->device->maxcollection; - - collection = parser->device->collection + - parser->device->maxcollection++; - collection->type = type; - collection->usage = usage; - collection->level = parser->collection_stack_ptr - 1; - - if (type == HID_COLLECTION_APPLICATION) - parser->device->maxapplication++; - - return 0; -} - -/* - * Close a collection. - */ - -static int close_collection(struct hid_parser *parser) -{ - if (!parser->collection_stack_ptr) { - dbg("collection stack underflow"); - return -1; - } - parser->collection_stack_ptr--; - return 0; -} - -/* - * Climb up the stack, search for the specified collection type - * and return the usage. - */ - -static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) -{ - int n; - for (n = parser->collection_stack_ptr - 1; n >= 0; n--) - if (parser->device->collection[parser->collection_stack[n]].type == type) - return parser->device->collection[parser->collection_stack[n]].usage; - return 0; /* we know nothing about this usage type */ -} - -/* - * Add a usage to the temporary parser table. - */ - -static int hid_add_usage(struct hid_parser *parser, unsigned usage) -{ - if (parser->local.usage_index >= HID_MAX_USAGES) { - dbg("usage index exceeded"); - return -1; - } - parser->local.usage[parser->local.usage_index] = usage; - parser->local.collection_index[parser->local.usage_index] = - parser->collection_stack_ptr ? - parser->collection_stack[parser->collection_stack_ptr - 1] : 0; - parser->local.usage_index++; - return 0; -} - -/* - * Register a new field for this report. - */ - -static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags) -{ - struct hid_report *report; - struct hid_field *field; - int usages; - unsigned offset; - int i; - - if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { - dbg("hid_register_report failed"); - return -1; - } - - if (parser->global.logical_maximum < parser->global.logical_minimum) { - dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum); - return -1; - } - - if (!(usages = max_t(int, parser->local.usage_index, parser->global.report_count))) - return 0; /* Ignore padding fields */ - - offset = report->size; - report->size += parser->global.report_size * parser->global.report_count; - - if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL) - return 0; - - field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); - field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL); - field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); - - for (i = 0; i < usages; i++) { - int j = i; - /* Duplicate the last usage we parsed if we have excess values */ - if (i >= parser->local.usage_index) - j = parser->local.usage_index - 1; - field->usage[i].hid = parser->local.usage[j]; - field->usage[i].collection_index = - parser->local.collection_index[j]; - } - - field->maxusage = usages; - field->flags = flags; - field->report_offset = offset; - field->report_type = report_type; - field->report_size = parser->global.report_size; - field->report_count = parser->global.report_count; - field->logical_minimum = parser->global.logical_minimum; - field->logical_maximum = parser->global.logical_maximum; - field->physical_minimum = parser->global.physical_minimum; - field->physical_maximum = parser->global.physical_maximum; - field->unit_exponent = parser->global.unit_exponent; - field->unit = parser->global.unit; - - return 0; -} - -/* - * Read data value from item. - */ - -static __inline__ __u32 item_udata(struct hid_item *item) -{ - switch (item->size) { - case 1: return item->data.u8; - case 2: return item->data.u16; - case 4: return item->data.u32; - } - return 0; -} - -static __inline__ __s32 item_sdata(struct hid_item *item) -{ - switch (item->size) { - case 1: return item->data.s8; - case 2: return item->data.s16; - case 4: return item->data.s32; - } - return 0; -} - -/* - * Process a global item. - */ - -static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) -{ - switch (item->tag) { - - case HID_GLOBAL_ITEM_TAG_PUSH: - - if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { - dbg("global enviroment stack overflow"); - return -1; - } - - memcpy(parser->global_stack + parser->global_stack_ptr++, - &parser->global, sizeof(struct hid_global)); - return 0; - - case HID_GLOBAL_ITEM_TAG_POP: - - if (!parser->global_stack_ptr) { - dbg("global enviroment stack underflow"); - return -1; - } - - memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr, - sizeof(struct hid_global)); - return 0; - - case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: - parser->global.usage_page = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: - parser->global.logical_minimum = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: - if (parser->global.logical_minimum < 0) - parser->global.logical_maximum = item_sdata(item); - else - parser->global.logical_maximum = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: - parser->global.physical_minimum = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: - if (parser->global.physical_minimum < 0) - parser->global.physical_maximum = item_sdata(item); - else - parser->global.physical_maximum = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: - parser->global.unit_exponent = item_sdata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_UNIT: - parser->global.unit = item_udata(item); - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: - if ((parser->global.report_size = item_udata(item)) > 32) { - dbg("invalid report_size %d", parser->global.report_size); - return -1; - } - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: - if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) { - dbg("invalid report_count %d", parser->global.report_count); - return -1; - } - return 0; - - case HID_GLOBAL_ITEM_TAG_REPORT_ID: - if ((parser->global.report_id = item_udata(item)) == 0) { - dbg("report_id 0 is invalid"); - return -1; - } - return 0; - - default: - dbg("unknown global tag 0x%x", item->tag); - return -1; - } -} - -/* - * Process a local item. - */ - -static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) -{ - __u32 data; - unsigned n; - - if (item->size == 0) { - dbg("item data expected for local item"); - return -1; - } - - data = item_udata(item); - - switch (item->tag) { - - case HID_LOCAL_ITEM_TAG_DELIMITER: - - if (data) { - /* - * We treat items before the first delimiter - * as global to all usage sets (branch 0). - * In the moment we process only these global - * items and the first delimiter set. - */ - if (parser->local.delimiter_depth != 0) { - dbg("nested delimiters"); - return -1; - } - parser->local.delimiter_depth++; - parser->local.delimiter_branch++; - } else { - if (parser->local.delimiter_depth < 1) { - dbg("bogus close delimiter"); - return -1; - } - parser->local.delimiter_depth--; - } - return 1; - - case HID_LOCAL_ITEM_TAG_USAGE: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - return hid_add_usage(parser, data); - - case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - parser->local.usage_minimum = data; - return 0; - - case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: - - if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); - return 0; - } - - if (item->size <= 2) - data = (parser->global.usage_page << 16) + data; - - for (n = parser->local.usage_minimum; n <= data; n++) - if (hid_add_usage(parser, n)) { - dbg("hid_add_usage failed\n"); - return -1; - } - return 0; - - default: - - dbg("unknown local item tag 0x%x", item->tag); - return 0; - } - return 0; -} - -/* - * Process a main item. - */ - -static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) -{ - __u32 data; - int ret; - - data = item_udata(item); - - switch (item->tag) { - case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: - ret = open_collection(parser, data & 0xff); - break; - case HID_MAIN_ITEM_TAG_END_COLLECTION: - ret = close_collection(parser); - break; - case HID_MAIN_ITEM_TAG_INPUT: - ret = hid_add_field(parser, HID_INPUT_REPORT, data); - break; - case HID_MAIN_ITEM_TAG_OUTPUT: - ret = hid_add_field(parser, HID_OUTPUT_REPORT, data); - break; - case HID_MAIN_ITEM_TAG_FEATURE: - ret = hid_add_field(parser, HID_FEATURE_REPORT, data); - break; - default: - dbg("unknown main item tag 0x%x", item->tag); - ret = 0; - } - - memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */ - - return ret; -} - -/* - * Process a reserved item. - */ - -static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) -{ - dbg("reserved item type, tag 0x%x", item->tag); - return 0; -} - -/* - * Free a report and all registered fields. The field->usage and - * field->value table's are allocated behind the field, so we need - * only to free(field) itself. - */ - -static void hid_free_report(struct hid_report *report) -{ - unsigned n; - - for (n = 0; n < report->maxfield; n++) - kfree(report->field[n]); - kfree(report); -} - -/* - * Free a device structure, all reports, and all fields. - */ - -static void hid_free_device(struct hid_device *device) -{ - unsigned i,j; - - hid_ff_exit(device); - - for (i = 0; i < HID_REPORT_TYPES; i++) { - struct hid_report_enum *report_enum = device->report_enum + i; - - for (j = 0; j < 256; j++) { - struct hid_report *report = report_enum->report_id_hash[j]; - if (report) - hid_free_report(report); - } - } - - if (device->rdesc) - kfree(device->rdesc); - kfree(device); -} - -/* - * Fetch a report description item from the data stream. We support long - * items, though they are not used yet. - */ - -static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) -{ - u8 b; - - if ((end - start) <= 0) - return NULL; - - b = *start++; - - item->type = (b >> 2) & 3; - item->tag = (b >> 4) & 15; - - if (item->tag == HID_ITEM_TAG_LONG) { - - item->format = HID_ITEM_FORMAT_LONG; - - if ((end - start) < 2) - return NULL; - - item->size = *start++; - item->tag = *start++; - - if ((end - start) < item->size) - return NULL; - - item->data.longdata = start; - start += item->size; - return start; - } - - item->format = HID_ITEM_FORMAT_SHORT; - item->size = b & 3; - - switch (item->size) { - - case 0: - return start; - - case 1: - if ((end - start) < 1) - return NULL; - item->data.u8 = *start++; - return start; - - case 2: - if ((end - start) < 2) - return NULL; - item->data.u16 = le16_to_cpu(get_unaligned((__le16*)start)); - start = (__u8 *)((__le16 *)start + 1); - return start; - - case 3: - item->size++; - if ((end - start) < 4) - return NULL; - item->data.u32 = le32_to_cpu(get_unaligned((__le32*)start)); - start = (__u8 *)((__le32 *)start + 1); - return start; - } - - return NULL; -} - -/* - * Parse a report description into a hid_device structure. Reports are - * enumerated, fields are attached to these reports. - */ - -static struct hid_device *hid_parse_report(__u8 *start, unsigned size) -{ - struct hid_device *device; - struct hid_parser *parser; - struct hid_item item; - __u8 *end; - unsigned i; - static int (*dispatch_type[])(struct hid_parser *parser, - struct hid_item *item) = { - hid_parser_main, - hid_parser_global, - hid_parser_local, - hid_parser_reserved - }; - - if (!(device = kmalloc(sizeof(struct hid_device), GFP_KERNEL))) - return NULL; - memset(device, 0, sizeof(struct hid_device)); - - if (!(device->collection =kmalloc(sizeof(struct hid_collection) * - HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) { - kfree(device); - return NULL; - } - memset(device->collection, 0, sizeof(struct hid_collection) * - HID_DEFAULT_NUM_COLLECTIONS); - device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; - - for (i = 0; i < HID_REPORT_TYPES; i++) - INIT_LIST_HEAD(&device->report_enum[i].report_list); - - if (!(device->rdesc = (__u8 *)kmalloc(size, GFP_KERNEL))) { - kfree(device->collection); - kfree(device); - return NULL; - } - memcpy(device->rdesc, start, size); - device->rsize = size; - - if (!(parser = kmalloc(sizeof(struct hid_parser), GFP_KERNEL))) { - kfree(device->rdesc); - kfree(device->collection); - kfree(device); - return NULL; - } - memset(parser, 0, sizeof(struct hid_parser)); - parser->device = device; - - end = start + size; - while ((start = fetch_item(start, end, &item)) != 0) { - - if (item.format != HID_ITEM_FORMAT_SHORT) { - dbg("unexpected long global item"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - - if (dispatch_type[item.type](parser, &item)) { - dbg("item %u %u %u %u parsing failed\n", - item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - - if (start == end) { - if (parser->collection_stack_ptr) { - dbg("unbalanced collection at end of report description"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - if (parser->local.delimiter_depth) { - dbg("unbalanced delimiter at end of report description"); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; - } - kfree(parser); - return device; - } - } - - dbg("item fetching failed at offset %d\n", (int)(end - start)); - kfree(device->collection); - hid_free_device(device); - kfree(parser); - return NULL; -} - -/* - * Convert a signed n-bit integer to signed 32-bit integer. Common - * cases are done through the compiler, the screwed things has to be - * done by hand. - */ - -static __inline__ __s32 snto32(__u32 value, unsigned n) -{ - switch (n) { - case 8: return ((__s8)value); - case 16: return ((__s16)value); - case 32: return ((__s32)value); - } - return value & (1 << (n - 1)) ? value | (-1 << n) : value; -} - -/* - * Convert a signed 32-bit integer to a signed n-bit integer. - */ - -static __inline__ __u32 s32ton(__s32 value, unsigned n) -{ - __s32 a = value >> (n - 1); - if (a && a != -1) - return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; - return value & ((1 << n) - 1); -} - -/* - * Extract/implement a data field from/to a report. - */ - -static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) -{ - report += (offset >> 5) << 2; offset &= 31; - return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1 << n) - 1); -} - -static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) -{ - report += (offset >> 5) << 2; offset &= 31; - put_unaligned((get_unaligned((__le64*)report) - & cpu_to_le64(~((((__u64) 1 << n) - 1) << offset))) - | cpu_to_le64((__u64)value << offset), (__le64*)report); -} - -/* - * Search an array for a value. - */ - -static __inline__ int search(__s32 *array, __s32 value, unsigned n) -{ - while (n--) { - if (*array++ == value) - return 0; - } - return -1; -} - -static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) -{ - hid_dump_input(usage, value); - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_hid_event(hid, field, usage, value, regs); - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_hid_event(hid, field, usage, value, regs); -} - -/* - * Analyse a received field, and fetch the data from it. The field - * content is stored for next report processing (we do differential - * reporting to the layer). - */ - -static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, struct pt_regs *regs) -{ - unsigned n; - unsigned count = field->report_count; - unsigned offset = field->report_offset; - unsigned size = field->report_size; - __s32 min = field->logical_minimum; - __s32 max = field->logical_maximum; - __s32 *value; - - value = kmalloc(sizeof(__s32)*count, GFP_ATOMIC); - if (!value) - return; - - for (n = 0; n < count; n++) { - - value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : - extract(data, offset + n * size, size); - - if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */ - && value[n] >= min && value[n] <= max - && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) - goto exit; - } - - for (n = 0; n < count; n++) { - - if (HID_MAIN_ITEM_VARIABLE & field->flags) { - - if (field->flags & HID_MAIN_ITEM_RELATIVE) { - if (!value[n]) - continue; - } else { - if (value[n] == field->value[n]) - continue; - } - hid_process_event(hid, field, &field->usage[n], value[n], regs); - continue; - } - - if (field->value[n] >= min && field->value[n] <= max - && field->usage[field->value[n] - min].hid - && search(value, field->value[n], count)) - hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, regs); - - if (value[n] >= min && value[n] <= max - && field->usage[value[n] - min].hid - && search(field->value, value[n], count)) - hid_process_event(hid, field, &field->usage[value[n] - min], 1, regs); - } - - memcpy(field->value, value, count * sizeof(__s32)); -exit: - kfree(value); -} - -static int hid_input_report(int type, struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - struct hid_report_enum *report_enum = hid->report_enum + type; - u8 *data = urb->transfer_buffer; - int len = urb->actual_length; - struct hid_report *report; - int n, size; - - if (!len) { - dbg("empty report"); - return -1; - } - -#ifdef DEBUG_DATA - printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", len, report_enum->numbered ? "" : "un"); -#endif - - n = 0; /* Normally report number is 0 */ - if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */ - n = *data++; - len--; - } - -#ifdef DEBUG_DATA - { - int i; - printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, len); - for (i = 0; i < len; i++) - printk(" %02x", data[i]); - printk("\n"); - } -#endif - - if (!(report = report_enum->report_id_hash[n])) { - dbg("undefined report_id %d received", n); - return -1; - } - - size = ((report->size - 1) >> 3) + 1; - - if (len < size) { - dbg("report %d is too short, (%d < %d)", report->id, len, size); - return -1; - } - - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_report_event(hid, report); - - for (n = 0; n < report->maxfield; n++) - hid_input_field(hid, report->field[n], data, regs); - - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_report_event(hid, report); - - return 0; -} - -/* - * Input interrupt completion handler. - */ - -static void hid_irq_in(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - int status; - - switch (urb->status) { - case 0: /* success */ - hid_input_report(HID_INPUT_REPORT, urb, regs); - break; - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -ESHUTDOWN: - return; - case -ETIMEDOUT: /* NAK */ - break; - default: /* error */ - warn("input irq status %d received", urb->status); - } - - status = usb_submit_urb(urb, SLAB_ATOMIC); - if (status) - err("can't resubmit intr, %s-%s/input%d, status %d", - hid->dev->bus->bus_name, hid->dev->devpath, - hid->ifnum, status); -} - -/* - * Output the field into the report. - */ - -static void hid_output_field(struct hid_field *field, __u8 *data) -{ - unsigned count = field->report_count; - unsigned offset = field->report_offset; - unsigned size = field->report_size; - unsigned n; - - for (n = 0; n < count; n++) { - if (field->logical_minimum < 0) /* signed values */ - implement(data, offset + n * size, size, s32ton(field->value[n], size)); - else /* unsigned values */ - implement(data, offset + n * size, size, field->value[n]); - } -} - -/* - * Create a report. - */ - -static void hid_output_report(struct hid_report *report, __u8 *data) -{ - unsigned n; - - if (report->id > 0) - *data++ = report->id; - - for (n = 0; n < report->maxfield; n++) - hid_output_field(report->field[n], data); -} - -/* - * Set a field value. The report this field belongs to has to be - * created and transferred to the device, to set this value in the - * device. - */ - -int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) -{ - unsigned size = field->report_size; - - hid_dump_input(field->usage + offset, value); - - if (offset >= field->report_count) { - dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count); - hid_dump_field(field, 8); - return -1; - } - if (field->logical_minimum < 0) { - if (value != snto32(s32ton(value, size), size)) { - dbg("value %d is out of range", value); - return -1; - } - } - field->value[offset] = value; - return 0; -} - -int hid_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field) -{ - struct hid_report_enum *report_enum = hid->report_enum + HID_OUTPUT_REPORT; - struct list_head *list = report_enum->report_list.next; - int i, j; - - while (list != &report_enum->report_list) { - struct hid_report *report = (struct hid_report *) list; - list = list->next; - for (i = 0; i < report->maxfield; i++) { - *field = report->field[i]; - for (j = 0; j < (*field)->maxusage; j++) - if ((*field)->usage[j].type == type && (*field)->usage[j].code == code) - return j; - } - } - return -1; -} - -/* - * Find a report with a specified HID usage. - */ - -int hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, struct hid_report **report, int type) -{ - struct hid_report_enum *report_enum = hid->report_enum + type; - struct list_head *list = report_enum->report_list.next; - int i, j; - - while (list != &report_enum->report_list) { - *report = (struct hid_report *) list; - list = list->next; - for (i = 0; i < (*report)->maxfield; i++) { - struct hid_field *field = (*report)->field[i]; - for (j = 0; j < field->maxusage; j++) - if (field->logical == wanted_usage) - return j; - } - } - return -1; -} - -#if 0 -static int hid_find_field_in_report(struct hid_report *report, __u32 wanted_usage, struct hid_field **field) -{ - int i, j; - - for (i = 0; i < report->maxfield; i++) { - *field = report->field[i]; - for (j = 0; j < (*field)->maxusage; j++) - if ((*field)->usage[j].hid == wanted_usage) - return j; - } - - return -1; -} -#endif - -static int hid_submit_out(struct hid_device *hid) -{ - struct hid_report *report; - - report = hid->out[hid->outtail]; - - hid_output_report(report, hid->outbuf); - hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); - hid->urbout->dev = hid->dev; - - dbg("submitting out urb"); - - if (usb_submit_urb(hid->urbout, GFP_ATOMIC)) { - err("usb_submit_urb(out) failed"); - return -1; - } - - return 0; -} - -static int hid_submit_ctrl(struct hid_device *hid) -{ - struct hid_report *report; - unsigned char dir; - int len; - - report = hid->ctrl[hid->ctrltail].report; - dir = hid->ctrl[hid->ctrltail].dir; - - len = ((report->size - 1) >> 3) + 1 + (report->id > 0); - if (dir == USB_DIR_OUT) { - hid_output_report(report, hid->ctrlbuf); - hid->urbctrl->pipe = usb_sndctrlpipe(hid->dev, 0); - hid->urbctrl->transfer_buffer_length = len; - } else { - int maxpacket, padlen; - - hid->urbctrl->pipe = usb_rcvctrlpipe(hid->dev, 0); - maxpacket = usb_maxpacket(hid->dev, hid->urbctrl->pipe, 0); - if (maxpacket > 0) { - padlen = (len + maxpacket - 1) / maxpacket; - padlen *= maxpacket; - if (padlen > HID_BUFFER_SIZE) - padlen = HID_BUFFER_SIZE; - } else - padlen = 0; - hid->urbctrl->transfer_buffer_length = padlen; - } - hid->urbctrl->dev = hid->dev; - - hid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; - hid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; - hid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id); - hid->cr->wIndex = cpu_to_le16(hid->ifnum); - hid->cr->wLength = cpu_to_le16(len); - - dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u", - hid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", - hid->cr->wValue, hid->cr->wIndex, hid->cr->wLength); - - if (usb_submit_urb(hid->urbctrl, GFP_ATOMIC)) { - err("usb_submit_urb(ctrl) failed"); - return -1; - } - - return 0; -} - -/* - * Output interrupt completion handler. - */ - -static void hid_irq_out(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - unsigned long flags; - - switch (urb->status) { - case 0: /* success */ - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -ESHUTDOWN: - break; - default: /* error */ - warn("output irq status %d received", urb->status); - } - - spin_lock_irqsave(&hid->outlock, flags); - - hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); - - if (hid->outhead != hid->outtail) { - if (hid_submit_out(hid)) { - clear_bit(HID_OUT_RUNNING, &hid->iofl);; - wake_up(&hid->wait); - } - spin_unlock_irqrestore(&hid->outlock, flags); - return; - } - - clear_bit(HID_OUT_RUNNING, &hid->iofl); - spin_unlock_irqrestore(&hid->outlock, flags); - wake_up(&hid->wait); -} - -/* - * Control pipe completion handler. - */ - -static void hid_ctrl(struct urb *urb, struct pt_regs *regs) -{ - struct hid_device *hid = urb->context; - unsigned long flags; - - spin_lock_irqsave(&hid->ctrllock, flags); - - switch (urb->status) { - case 0: /* success */ - if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) - hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, regs); - case -ECONNRESET: /* unlink */ - case -ENOENT: - case -ESHUTDOWN: - case -EPIPE: /* report not available */ - break; - default: /* error */ - warn("ctrl urb status %d received", urb->status); - } - - hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); - - if (hid->ctrlhead != hid->ctrltail) { - if (hid_submit_ctrl(hid)) { - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - wake_up(&hid->wait); - } - spin_unlock_irqrestore(&hid->ctrllock, flags); - return; - } - - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - spin_unlock_irqrestore(&hid->ctrllock, flags); - wake_up(&hid->wait); -} - -void hid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) -{ - int head; - unsigned long flags; - - if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) - return; - - if (hid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { - - spin_lock_irqsave(&hid->outlock, flags); - - if ((head = (hid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == hid->outtail) { - spin_unlock_irqrestore(&hid->outlock, flags); - warn("output queue full"); - return; - } - - hid->out[hid->outhead] = report; - hid->outhead = head; - - if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl)) - if (hid_submit_out(hid)) - clear_bit(HID_OUT_RUNNING, &hid->iofl); - - spin_unlock_irqrestore(&hid->outlock, flags); - return; - } - - spin_lock_irqsave(&hid->ctrllock, flags); - - if ((head = (hid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == hid->ctrltail) { - spin_unlock_irqrestore(&hid->ctrllock, flags); - warn("control queue full"); - return; - } - - hid->ctrl[hid->ctrlhead].report = report; - hid->ctrl[hid->ctrlhead].dir = dir; - hid->ctrlhead = head; - - if (!test_and_set_bit(HID_CTRL_RUNNING, &hid->iofl)) - if (hid_submit_ctrl(hid)) - clear_bit(HID_CTRL_RUNNING, &hid->iofl); - - spin_unlock_irqrestore(&hid->ctrllock, flags); -} - -int hid_wait_io(struct hid_device *hid) -{ - DECLARE_WAITQUEUE(wait, current); - int timeout = 10*HZ; - - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&hid->wait, &wait); - - while (timeout && (test_bit(HID_CTRL_RUNNING, &hid->iofl) || - test_bit(HID_OUT_RUNNING, &hid->iofl))) - timeout = schedule_timeout(timeout); - - set_current_state(TASK_RUNNING); - remove_wait_queue(&hid->wait, &wait); - - if (!timeout) { - dbg("timeout waiting for ctrl or out queue to clear"); - return -1; - } - - return 0; -} - -static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, - unsigned char type, void *buf, int size) -{ - return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, - (type << 8), ifnum, buf, size, HZ * USB_CTRL_GET_TIMEOUT); -} - -int hid_open(struct hid_device *hid) -{ - if (hid->open++) - return 0; - - hid->urbin->dev = hid->dev; - - if (usb_submit_urb(hid->urbin, GFP_KERNEL)) - return -EIO; - - return 0; -} - -void hid_close(struct hid_device *hid) -{ - if (!--hid->open) - usb_kill_urb(hid->urbin); -} - -/* - * Initialize all reports - */ - -void hid_init_reports(struct hid_device *hid) -{ - struct hid_report_enum *report_enum; - struct hid_report *report; - struct list_head *list; - int err, ret; - - /* - * The Set_Idle request is supposed to affect only the - * "Interrupt In" pipe. Unfortunately, buggy devices such as - * the BTC keyboard (ID 046e:5303) the request also affects - * Get_Report requests on the control pipe. In the worst - * case, if the device was put on idle for an indefinite - * amount of time (as we do below) and there are no input - * events to report, the Get_Report requests will just hang - * until we get a USB timeout. To avoid this, we temporarily - * establish a minimal idle time of 1ms. This shouldn't hurt - * bugfree devices and will cause a worst-case extra delay of - * 1ms for buggy ones. - */ - usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0), - HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (1 << 8), - hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); - - report_enum = hid->report_enum + HID_INPUT_REPORT; - list = report_enum->report_list.next; - while (list != &report_enum->report_list) { - report = (struct hid_report *) list; - hid_submit_report(hid, report, USB_DIR_IN); - list = list->next; - } - - report_enum = hid->report_enum + HID_FEATURE_REPORT; - list = report_enum->report_list.next; - while (list != &report_enum->report_list) { - report = (struct hid_report *) list; - hid_submit_report(hid, report, USB_DIR_IN); - list = list->next; - } - - err = 0; - ret = hid_wait_io(hid); - while (ret) { - err |= ret; - if (test_bit(HID_CTRL_RUNNING, &hid->iofl)) - usb_unlink_urb(hid->urbctrl); - if (test_bit(HID_OUT_RUNNING, &hid->iofl)) - usb_unlink_urb(hid->urbout); - ret = hid_wait_io(hid); - } - - if (err) - warn("timeout initializing reports\n"); - - report_enum = hid->report_enum + HID_INPUT_REPORT; - list = report_enum->report_list.next; - while (list != &report_enum->report_list) { - report = (struct hid_report *) list; - usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0), - HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, report->id, - hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); - list = list->next; - } -} - -#define USB_VENDOR_ID_WACOM 0x056a - -#define USB_VENDOR_ID_KBGEAR 0x084e -#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 - -#define USB_VENDOR_ID_AIPTEK 0x08ca -#define USB_DEVICE_ID_AIPTEK_01 0x0001 -#define USB_DEVICE_ID_AIPTEK_10 0x0010 -#define USB_DEVICE_ID_AIPTEK_20 0x0020 -#define USB_DEVICE_ID_AIPTEK_21 0x0021 -#define USB_DEVICE_ID_AIPTEK_22 0x0022 -#define USB_DEVICE_ID_AIPTEK_23 0x0023 -#define USB_DEVICE_ID_AIPTEK_24 0x0024 - -#define USB_VENDOR_ID_GRIFFIN 0x077d -#define USB_DEVICE_ID_POWERMATE 0x0410 -#define USB_DEVICE_ID_SOUNDKNOB 0x04AA - -#define USB_VENDOR_ID_ATEN 0x0557 -#define USB_DEVICE_ID_ATEN_UC100KM 0x2004 -#define USB_DEVICE_ID_ATEN_CS124U 0x2202 -#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204 -#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 -#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 - -#define USB_VENDOR_ID_TOPMAX 0x0663 -#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 - -#define USB_VENDOR_ID_HAPP 0x078b -#define USB_DEVICE_ID_UGCI_DRIVING 0x0010 -#define USB_DEVICE_ID_UGCI_FLYING 0x0020 -#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 - -#define USB_VENDOR_ID_MGE 0x0463 -#define USB_DEVICE_ID_MGE_UPS 0xffff -#define USB_DEVICE_ID_MGE_UPS1 0x0001 - -#define USB_VENDOR_ID_ONTRAK 0x0a07 -#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 - -#define USB_VENDOR_ID_TANGTOP 0x0d3d -#define USB_DEVICE_ID_TANGTOP_USBPS2 0x0001 - -#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f -#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 - -#define USB_VENDOR_ID_A4TECH 0x09DA -#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 - -#define USB_VENDOR_ID_CYPRESS 0x04b4 -#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 - -#define USB_VENDOR_ID_BERKSHIRE 0x0c98 -#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 - -#define USB_VENDOR_ID_ALPS 0x0433 -#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 - -#define USB_VENDOR_ID_SAITEK 0x06a3 -#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 - -#define USB_VENDOR_ID_NEC 0x073e -#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 - -#define USB_VENDOR_ID_CHIC 0x05fe -#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014 - -#define USB_VENDOR_ID_GLAB 0x06c2 -#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 -#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 -#define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045 -#define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040 -#define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053 - -#define USB_VENDOR_ID_WISEGROUP 0x0925 -#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 -#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 - -#define USB_VENDOR_ID_CODEMERCS 0x07c0 -#define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500 -#define USB_DEVICE_ID_CODEMERCS_IOW24 0x1501 - - -static struct hid_blacklist { - __u16 idVendor; - __u16 idProduct; - unsigned quirks; -} hid_blacklist[] = { - - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, - - { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_BACK }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_EXTRA }, - - { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, - - { 0, 0 } -}; - -static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) -{ - if (!(hid->inbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->inbuf_dma))) - return -1; - if (!(hid->outbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->outbuf_dma))) - return -1; - if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma))) - return -1; - if (!(hid->ctrlbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->ctrlbuf_dma))) - return -1; - - return 0; -} - -static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) -{ - if (hid->inbuf) - usb_buffer_free(dev, HID_BUFFER_SIZE, hid->inbuf, hid->inbuf_dma); - if (hid->outbuf) - usb_buffer_free(dev, HID_BUFFER_SIZE, hid->outbuf, hid->outbuf_dma); - if (hid->cr) - usb_buffer_free(dev, sizeof(*(hid->cr)), hid->cr, hid->cr_dma); - if (hid->ctrlbuf) - usb_buffer_free(dev, HID_BUFFER_SIZE, hid->ctrlbuf, hid->ctrlbuf_dma); -} - -static struct hid_device *usb_hid_configure(struct usb_interface *intf) -{ - struct usb_host_interface *interface = intf->cur_altsetting; - struct usb_device *dev = interface_to_usbdev (intf); - struct hid_descriptor *hdesc; - struct hid_device *hid; - unsigned quirks = 0, rsize = 0; - char *buf, *rdesc; - int n; - - /* ignore all Wacom devices */ - if (dev->descriptor.idVendor == USB_VENDOR_ID_WACOM) - return NULL; - - for (n = 0; hid_blacklist[n].idVendor; n++) - if ((hid_blacklist[n].idVendor == dev->descriptor.idVendor) && - (hid_blacklist[n].idProduct == dev->descriptor.idProduct)) - quirks = hid_blacklist[n].quirks; - - if (quirks & HID_QUIRK_IGNORE) - return NULL; - - if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->desc.bNumEndpoints) || - usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { - dbg("class descriptor not present\n"); - return NULL; - } - - for (n = 0; n < hdesc->bNumDescriptors; n++) - if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) - rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); - - if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { - dbg("weird size of report descriptor (%u)", rsize); - return NULL; - } - - if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) { - dbg("couldn't allocate rdesc memory"); - return NULL; - } - - if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { - dbg("reading report descriptor failed"); - kfree(rdesc); - return NULL; - } - -#ifdef DEBUG_DATA - printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); - for (n = 0; n < rsize; n++) - printk(" %02x", (unsigned char) rdesc[n]); - printk("\n"); -#endif - - if (!(hid = hid_parse_report(rdesc, rsize))) { - dbg("parsing report descriptor failed"); - kfree(rdesc); - return NULL; - } - - kfree(rdesc); - hid->quirks = quirks; - - if (hid_alloc_buffers(dev, hid)) { - hid_free_buffers(dev, hid); - goto fail; - } - - for (n = 0; n < interface->desc.bNumEndpoints; n++) { - - struct usb_endpoint_descriptor *endpoint; - int pipe; - int interval; - - endpoint = &interface->endpoint[n].desc; - if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */ - continue; - - /* handle potential highspeed HID correctly */ - interval = endpoint->bInterval; - if (dev->speed == USB_SPEED_HIGH) - interval = 1 << (interval - 1); - - if (endpoint->bEndpointAddress & USB_DIR_IN) { - int len; - - if (hid->urbin) - continue; - if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) - goto fail; - pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); - len = usb_maxpacket(dev, pipe, 0); - if (len > HID_BUFFER_SIZE) - len = HID_BUFFER_SIZE; - usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, len, - hid_irq_in, hid, interval); - hid->urbin->transfer_dma = hid->inbuf_dma; - hid->urbin->transfer_flags |=(URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK); - } else { - if (hid->urbout) - continue; - if (!(hid->urbout = usb_alloc_urb(0, GFP_KERNEL))) - goto fail; - pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress); - usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0, - hid_irq_out, hid, interval); - hid->urbout->transfer_dma = hid->outbuf_dma; - hid->urbout->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK); - } - } - - if (!hid->urbin) { - err("couldn't find an input interrupt endpoint"); - goto fail; - } - - init_waitqueue_head(&hid->wait); - - hid->outlock = SPIN_LOCK_UNLOCKED; - hid->ctrllock = SPIN_LOCK_UNLOCKED; - - hid->version = le16_to_cpu(hdesc->bcdHID); - hid->country = hdesc->bCountryCode; - hid->dev = dev; - hid->intf = intf; - hid->ifnum = interface->desc.bInterfaceNumber; - - hid->name[0] = 0; - - if (!(buf = kmalloc(64, GFP_KERNEL))) - goto fail; - - if (usb_string(dev, dev->descriptor.iManufacturer, buf, 64) > 0) { - strcat(hid->name, buf); - if (usb_string(dev, dev->descriptor.iProduct, buf, 64) > 0) - snprintf(hid->name, 64, "%s %s", hid->name, buf); - } else if (usb_string(dev, dev->descriptor.iProduct, buf, 128) > 0) { - snprintf(hid->name, 128, "%s", buf); - } else - snprintf(hid->name, 128, "%04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct); - - usb_make_path(dev, buf, 64); - snprintf(hid->phys, 64, "%s/input%d", buf, - intf->altsetting[0].desc.bInterfaceNumber); - - if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) - hid->uniq[0] = 0; - - kfree(buf); - - hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); - if (!hid->urbctrl) - goto fail; - usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr, - hid->ctrlbuf, 1, hid_ctrl, hid); - hid->urbctrl->setup_dma = hid->cr_dma; - hid->urbctrl->transfer_dma = hid->ctrlbuf_dma; - hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | URB_ASYNC_UNLINK); - - return hid; - -fail: - - if (hid->urbin) - usb_free_urb(hid->urbin); - if (hid->urbout) - usb_free_urb(hid->urbout); - if (hid->urbctrl) - usb_free_urb(hid->urbctrl); - hid_free_buffers(dev, hid); - hid_free_device(hid); - - return NULL; -} - -static void hid_disconnect(struct usb_interface *intf) -{ - struct hid_device *hid = usb_get_intfdata (intf); - - if (!hid) - return; - - usb_set_intfdata(intf, NULL); - usb_kill_urb(hid->urbin); - usb_kill_urb(hid->urbout); - usb_kill_urb(hid->urbctrl); - - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_disconnect(hid); - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_disconnect(hid); - - usb_free_urb(hid->urbin); - usb_free_urb(hid->urbctrl); - if (hid->urbout) - usb_free_urb(hid->urbout); - - hid_free_buffers(hid->dev, hid); - hid_free_device(hid); -} - -static int hid_probe (struct usb_interface *intf, const struct usb_device_id *id) -{ - struct hid_device *hid; - char path[64]; - int i; - char *c; - - dbg("HID probe called for ifnum %d", - intf->altsetting->desc.bInterfaceNumber); - - if (!(hid = usb_hid_configure(intf))) - return -EIO; - - hid_init_reports(hid); - hid_dump_device(hid); - - if (!hidinput_connect(hid)) - hid->claimed |= HID_CLAIMED_INPUT; - if (!hiddev_connect(hid)) - hid->claimed |= HID_CLAIMED_HIDDEV; - - usb_set_intfdata(intf, hid); - - if (!hid->claimed) { - printk ("HID device not claimed by input or hiddev\n"); - hid_disconnect(intf); - return -EIO; - } - - printk(KERN_INFO); - - if (hid->claimed & HID_CLAIMED_INPUT) - printk("input"); - if (hid->claimed == (HID_CLAIMED_INPUT | HID_CLAIMED_HIDDEV)) - printk(","); - if (hid->claimed & HID_CLAIMED_HIDDEV) - printk("hiddev%d", hid->minor); - - c = "Device"; - for (i = 0; i < hid->maxcollection; i++) { - if (hid->collection[i].type == HID_COLLECTION_APPLICATION && - (hid->collection[i].usage & HID_USAGE_PAGE) == HID_UP_GENDESK && - (hid->collection[i].usage & 0xffff) < ARRAY_SIZE(hid_types)) { - c = hid_types[hid->collection[i].usage & 0xffff]; - break; - } - } - - usb_make_path(interface_to_usbdev(intf), path, 63); - - printk(": USB HID v%x.%02x %s [%s] on %s\n", - hid->version >> 8, hid->version & 0xff, c, hid->name, path); - - return 0; -} - -static struct usb_device_id hid_usb_ids [] = { - { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, - .bInterfaceClass = USB_INTERFACE_CLASS_HID }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE (usb, hid_usb_ids); - -static struct usb_driver hid_driver = { - .owner = THIS_MODULE, - .name = "usbhid", - .probe = hid_probe, - .disconnect = hid_disconnect, - .id_table = hid_usb_ids, -}; - -static int __init hid_init(void) -{ - int retval; - retval = hiddev_init(); - if (retval) - goto hiddev_init_fail; - retval = usb_register(&hid_driver); - if (retval) - goto usb_register_fail; - info(DRIVER_VERSION ":" DRIVER_DESC); - - return 0; -usb_register_fail: - hiddev_exit(); -hiddev_init_fail: - return retval; -} - -static void __exit hid_exit(void) -{ - usb_deregister(&hid_driver); - hiddev_exit(); -} - -module_init(hid_init); -module_exit(hid_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); diff --git a/src/2.6.9/wacom.c b/src/2.6.9/wacom.c deleted file mode 100644 index be0c01e..0000000 --- a/src/2.6.9/wacom.c +++ /dev/null @@ -1,1264 +0,0 @@ -/* - * USB Wacom Graphire and Wacom Intuos tablet support - * - * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz> - * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk> - * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at> - * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org> - * Copyright (c) 2000 James E. Blair <corvus@gnu.org> - * Copyright (c) 2000 Daniel Egger <egger@suse.de> - * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> - * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> - * Copyright (c) 2002-2009 Ping Cheng <pingc@wacom.com> - * - * ChangeLog: - * v0.1 (vp) - Initial release - * v0.2 (aba) - Support for all buttons / combinations - * v0.3 (vp) - Support for Intuos added - * v0.4 (sm) - Support for more Intuos models, menustrip - * relative mode, proximity. - * v0.5 (vp) - Big cleanup, nifty features removed, - * they belong in userspace - * v1.8 (vp) - Submit URB only when operating, moved to CVS, - * use input_report_key instead of report_btn and - * other cleanups - * v1.11 (vp) - Add URB ->dev setting for new kernels - * v1.11 (jb) - Add support for the 4D Mouse & Lens - * v1.12 (de) - Add support for two more inking pen IDs - * v1.14 (vp) - Use new USB device id probing scheme. - * Fix Wacom Graphire mouse wheel - * v1.18 (vp) - Fix mouse wheel direction - * Make mouse relative - * v1.20 (fl) - Report tool id for Intuos devices - * - Multi tools support - * - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...) - * - Add PL models support - * - Fix Wacom Graphire mouse wheel again - * v1.21 (vp) - Removed protocol descriptions - * - Added MISC_SERIAL for tool serial numbers - * (gb) - Identify version on module load. - * v1.21.1 (fl) - added Graphire2 support - * v1.21.2 (fl) - added Intuos2 support - * - added all the PL ids - * v1.21.3 (fl) - added another eraser id from Neil Okamoto - * - added smooth filter for Graphire from Peri Hankey - * - added PenPartner support from Olaf van Es - * - new tool ids from Ole Martin Bjoerndalen - * v1.29 (pc) - Add support for more tablets - * - Fix pressure reporting - * v1.30 (vp) - Merge 2.4 and 2.5 drivers - * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse - * - Cleanups here and there - * v1.30.1 (pi) - Added Graphire3 support - * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... - * - * WARNING: THIS IS NOT PART OF THE OFFICIAL KERNEL TREE - * THIS IS FOR TESTING PURPOSES - * - * v1.40-2.6.9-pc-0.1 - incorporate with 2.6.9 - * v1.40-2.6.9-pc-0.2 - linuxwacom-0.6.6 - * v1.40-2.6.9-pc-0.3 - fixed a Graphire bug - * v1.40-2.6.9-pc-0.4 - added Cintiq 21UX - * v1.40-2.6.9-pc-0.5 - fixed an I3 bug - * v1.40-2.6.9-pc-0.6 - fixed a Cintiq 21UX bug - * v1.40-2.6.9-pc-0.7 - Added G4, DTF720 and DTU710 - * v1.40-2.6.9-pc-0.8 - added DTF 521, I3 12x12, and I3 12x19 - * v1.40-2.6.9-pc-0.9 - Support tablet buttons/keys - * v1.40-2.6.9-pc-0.10 - Support Intuos outbound tracking - * v1.40-2.6.9-pc-0.11 - Added Bamboo - * v1.40-2.6.9-pc-0.12 - added Bamboo1, Bamboo Fun, and Hummingbird - * v1.40-2.6.9-pc-0.13 - Added Cintiq 20WSX - * v1.40-2.6.9-pc-0.14 - Added Intuos4 - * v1.40-2.6.9-pc-0.15 - Fixed an expresskey bug - */ - -/* - * 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. - */ - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/input.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/usb.h> -#include <asm/unaligned.h> -#include <asm/byteorder.h> - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.40 - 2.6.9-pc-0.16" -#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" -#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" -#define DRIVER_LICENSE "GPL" - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); - -#define USB_VENDOR_ID_WACOM 0x056a -#define STYLUS_DEVICE_ID 0x02 -#define CURSOR_DEVICE_ID 0x06 -#define ERASER_DEVICE_ID 0x0A -#define PAD_DEVICE_ID 0x0F - -enum { - PENPARTNER = 0, - GRAPHIRE, - G4, - PL, - INTUOS, - INTUOS3S, - INTUOS3, - INTUOS3L, - CINTIQ, - INTUOS4S, - INTUOS4, - INTUOS4L, - MO, - BEE, - MAX_TYPE -}; - -struct wacom_features { - char *name; - int pktlen; - int x_max; - int y_max; - int pressure_max; - int distance_max; - int type; - usb_complete_t irq; -}; - -struct wacom { - unsigned char *data; - dma_addr_t data_dma; - struct input_dev dev; - struct usb_device *usbdev; - struct urb *irq; - struct wacom_features *features; - int tool[2]; - int id[2]; - int open; - __u32 serial[2]; - char phys[32]; -}; - -#define USB_REQ_GET_REPORT 0x01 -#define USB_REQ_SET_REPORT 0x09 -static int usb_set_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_sndctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, HZ); -} - -static int usb_get_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) -{ - return usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, HZ); -} - -static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) -{ - struct wacom *wacom = urb->context; - unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; - int prox, pressure; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - if (data[0] != 2) { - dbg("wacom_pl_irq: received unknown report #%d", data[0]); - goto exit; - } - - prox = data[1] & 0x40; - - input_regs(dev, regs); - - wacom->id[0] = ERASER_DEVICE_ID; - if (prox) { - - pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); - if (wacom->features->pressure_max > 255) - pressure = (pressure << 1) | ((data[4] >> 6) & 1); - pressure += (wacom->features->pressure_max + 1) / 2; - - /* - * if going from out of proximity into proximity select between the eraser - * and the pen based on the state of the stylus2 button, choose eraser if - * pressed else choose pen. if not a proximity change from out to in, send - * an out of proximity for previous tool then a in for new tool. - */ - if (!wacom->tool[0]) { - /* Eraser bit set for DTF */ - if (data[1] & 0x10) - wacom->tool[1] = BTN_TOOL_RUBBER; - else - /* Going into proximity select tool */ - wacom->tool[1] = (data[4] & 0x20)? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - } - else { - /* was entered with stylus2 pressed */ - if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) { - /* report out proximity for previous tool */ - input_report_key(dev, wacom->tool[1], 0); - input_sync(dev); - wacom->tool[1] = BTN_TOOL_PEN; - goto exit; - } - } - if (wacom->tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom->tool[1] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - } - input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */ - input_report_abs(dev, ABS_MISC, wacom->id[0]); /* report tool id */ - input_report_abs(dev, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); - input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); - input_report_abs(dev, ABS_PRESSURE, pressure); - - input_report_key(dev, BTN_TOUCH, data[4] & 0x08); - input_report_key(dev, BTN_STYLUS, data[4] & 0x10); - /* Only allow the stylus2 button to be reported for the pen tool. */ - input_report_key(dev, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20)); - } - else { - /* report proximity-out of a (valid) tool */ - if (wacom->tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom->tool[1] = BTN_TOOL_PEN; - } - input_report_key(dev, wacom->tool[1], prox); - input_report_abs(dev, ABS_MISC, 0); /* reset tool id */ - } - - wacom->tool[0] = prox; /* Save proximity state */ - input_sync(dev); - -exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs) -{ - struct wacom *wacom = urb->context; - unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - if (data[0] != 2) - { - printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); - goto exit; - } - - input_regs(dev, regs); - if (data[1] & 0x04) - { - input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20); - input_report_key(dev, BTN_TOUCH, data[1] & 0x08); - wacom->id[0] = ERASER_DEVICE_ID; - } - else - { - input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20); - input_report_key(dev, BTN_TOUCH, data[1] & 0x01); - wacom->id[0] = STYLUS_DEVICE_ID; - } - input_report_abs(dev, ABS_MISC, wacom->id[0]); /* report tool id */ - input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[2])); - input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[4])); - input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6])); - input_report_key(dev, BTN_STYLUS, data[1] & 0x02); - input_report_key(dev, BTN_STYLUS2, data[1] & 0x10); - - input_sync(dev); - -exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs) -{ - struct wacom *wacom = urb->context; - unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - switch (data[0]) { - case 1: - input_regs(dev, regs); - if (data[5] & 0x80) { - wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID; - input_report_key(dev, wacom->tool[0], 1); - input_report_abs(dev, ABS_MISC, wacom->id[0]); /* report tool id */ - input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[1])); - input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[3])); - input_report_abs(dev, ABS_PRESSURE, (signed char)data[6] + 127); - input_report_key(dev, BTN_TOUCH, ((signed char)data[6] > -127)); - input_report_key(dev, BTN_STYLUS, (data[5] & 0x40)); - } else { - input_report_key(dev, wacom->tool[0], 0); - input_report_abs(dev, ABS_MISC, 0); /* report tool id */ - input_report_abs(dev, ABS_PRESSURE, -1); - input_report_key(dev, BTN_TOUCH, 0); - } - input_sync(dev); - break; - case 2: - input_regs(dev, regs); - input_report_key(dev, BTN_TOOL_PEN, 1); - input_report_abs(dev, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */ - input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[1])); - input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[3])); - input_report_abs(dev, ABS_PRESSURE, (signed char)data[6] + 127); - input_report_key(dev, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20)); - input_report_key(dev, BTN_STYLUS, (data[5] & 0x40)); - input_sync(dev); - break; - default: - printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]); - goto exit; - } - -exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) -{ - struct wacom *wacom = urb->context; - unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; - int x, y, rw; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - /* 2 Volito1 and 2 users say this is wrong - if (data[0] == 99) return; */ - - if (data[0] != 2) { - dbg("wacom_graphire_irq: received unknown report #%d", data[0]); - goto exit; - } - - input_regs(dev, regs); - - if (data[1] & 0x80) { - /* in prox and not a pad data */ - - switch ((data[1] >> 5) & 3) { - - case 0: /* Pen */ - wacom->tool[0] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - break; - - case 1: /* Rubber */ - wacom->tool[0] = BTN_TOOL_RUBBER; - wacom->id[0] = ERASER_DEVICE_ID; - break; - - case 2: /* Mouse with wheel */ - input_report_key(dev, BTN_MIDDLE, data[1] & 0x04); - if ( wacom->features->type == G4 || - wacom->features->type == MO ) { - rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); - input_report_rel(dev, REL_WHEEL, -rw); - } else - input_report_rel(dev, REL_WHEEL, -(signed char) data[6]); - /* fall through */ - - case 3: /* Mouse without wheel */ - wacom->tool[0] = BTN_TOOL_MOUSE; - wacom->id[0] = CURSOR_DEVICE_ID; - input_report_key(dev, BTN_LEFT, data[1] & 0x01); - input_report_key(dev, BTN_RIGHT, data[1] & 0x02); - if ( wacom->features->type == G4 || - wacom->features->type == MO ) - input_report_abs(dev, ABS_DISTANCE, data[6]); - else - input_report_abs(dev, ABS_DISTANCE, data[7]); - break; - } - x = le16_to_cpu(*(__le16 *) &data[2]); - y = le16_to_cpu(*(__le16 *) &data[4]); - input_report_abs(dev, ABS_X, x); - input_report_abs(dev, ABS_Y, y); - - if (wacom->tool[0] != BTN_TOOL_MOUSE) { - input_report_abs(dev, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8)); - input_report_key(dev, BTN_TOUCH, data[1] & 0x01); - input_report_key(dev, BTN_STYLUS, data[1] & 0x02); - input_report_key(dev, BTN_STYLUS2, data[1] & 0x04); - } - input_report_abs(dev, ABS_MISC, wacom->id[0]); /* report tool id */ - input_report_key(dev, wacom->tool[0], 1); - } else if (wacom->id[0]) { - input_report_abs(dev, ABS_X, 0); - input_report_abs(dev, ABS_Y, 0); - if (wacom->tool[0] == BTN_TOOL_MOUSE) { - input_report_key(dev, BTN_LEFT, 0); - input_report_key(dev, BTN_RIGHT, 0); - input_report_abs(dev, ABS_DISTANCE, 0); - } else { - input_report_abs(dev, ABS_PRESSURE, 0); - input_report_key(dev, BTN_TOUCH, 0); - input_report_key(dev, BTN_STYLUS, 0); - input_report_key(dev, BTN_STYLUS2, 0); - } - wacom->id[0] = 0; - input_report_abs(dev, ABS_MISC, 0); /* reset tool id */ - input_report_key(dev, wacom->tool[0], 0); - } - input_sync(dev); - - /* send pad data */ - switch (wacom->features->type) { - case G4: - if (data[7] & 0xf8) { - wacom->id[1] = PAD_DEVICE_ID; - input_report_key(dev, BTN_0, (data[7] & 0x40)); - input_report_key(dev, BTN_4, (data[7] & 0x80)); - rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); - input_report_rel(dev, REL_WHEEL, rw); - input_report_key(dev, BTN_TOOL_FINGER, 0xf0); - input_report_abs(dev, ABS_MISC, wacom->id[1]); - input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); - } else if ( wacom->id[1] ) { - wacom->id[1] = 0; - input_report_key(dev, BTN_TOOL_FINGER, 0); - input_report_abs(dev, ABS_MISC, 0); - input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); - } - input_sync(dev); - break; - case MO: - if ((data[7] & 0xf8) || (data[8] & 0xff)) { - wacom->id[1] = PAD_DEVICE_ID; - input_report_key(dev, BTN_0, (data[7] & 0x08)); - input_report_key(dev, BTN_1, (data[7] & 0x20)); - input_report_key(dev, BTN_4, (data[7] & 0x10)); - input_report_key(dev, BTN_5, (data[7] & 0x40)); - input_report_abs(dev, ABS_WHEEL, (data[8] & 0x7f)); - input_report_key(dev, BTN_TOOL_FINGER, 0xf0); - input_report_abs(dev, ABS_MISC, wacom->id[1]); - input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); - } else if (wacom->id[1]) { - wacom->id[1] = 0; - input_report_key(dev, BTN_0, (data[7] & 0x08)); - input_report_key(dev, BTN_1, (data[7] & 0x20)); - input_report_key(dev, BTN_4, (data[7] & 0x10)); - input_report_key(dev, BTN_5, (data[7] & 0x40)); - input_report_abs(dev, ABS_WHEEL, (data[8] & 0x7f)); - input_report_key(dev, BTN_TOOL_FINGER, 0); - input_report_abs(dev, ABS_MISC, 0); - input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); - } - input_sync(dev); - break; - } - -exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -static int wacom_intuos_inout(struct urb *urb) -{ - struct wacom *wacom = urb->context; - unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; - int idx = 0; - - /* tool number */ - if (wacom->features->type == INTUOS) - idx = data[1] & 0x01; - - /* Enter report */ - if ((data[1] & 0xfc) == 0xc0) - { - /* serial number of the tool */ - wacom->serial[idx] = ((data[3] & 0x0f) << 28) + - (data[4] << 20) + (data[5] << 12) + - (data[6] << 4) + (data[7] >> 4); - - wacom->id[idx] = (data[2] << 4) | (data[3] >> 4); - switch (wacom->id[idx]) { - case 0x812: /* Inking pen */ - case 0x801: /* Intuos3 Inking pen */ - case 0x20802: /* Intuos4 Inking Pen */ - case 0x012: - wacom->tool[idx] = BTN_TOOL_PENCIL; - break; - case 0x822: /* Pen */ - case 0x842: - case 0x852: - case 0x823: /* Intuos3 Grip Pen */ - case 0x813: /* Intuos3 Classic Pen */ - case 0x885: /* Intuos3 Marker Pen */ - case 0x802: /* Intuos4 Grip Pen Eraser */ - case 0x804: /* Intuos4 Marker Pen */ - case 0x40802: /* Intuos4 Classic Pen */ - case 0x022: - wacom->tool[idx] = BTN_TOOL_PEN; - break; - case 0x832: /* Stroke pen */ - case 0x032: - wacom->tool[idx] = BTN_TOOL_BRUSH; - break; - case 0x007: /* Mouse 4D and 2D */ - case 0x09c: - case 0x094: - case 0x017: /* Intuos3 2D Mouse */ - case 0x806: /* Intuos4 Mouse */ - wacom->tool[idx] = BTN_TOOL_MOUSE; - break; - case 0x096: /* Lens cursor */ - case 0x097: /* Intuos3 Lens cursor */ - case 0x006: /* Intuos4 Lens cursor */ - wacom->tool[idx] = BTN_TOOL_LENS; - break; - case 0x82a: /* Eraser */ - case 0x85a: - case 0x91a: - case 0xd1a: - case 0x0fa: - case 0x82b: /* Intuos3 Grip Pen Eraser */ - case 0x81b: /* Intuos3 Classic Pen Eraser */ - case 0x91b: /* Intuos3 Airbrush Eraser */ - case 0x80c: /* Intuos4 Marker Pen Eraser */ - case 0x80a: /* Intuos4 Grip Pen Eraser */ - case 0x4080a: /* Intuos4 Classic Pen Eraser */ - case 0x90a: /* Intuos4 Airbrush Eraser */ - wacom->tool[idx] = BTN_TOOL_RUBBER; - break; - case 0xd12: /* Airbrush */ - case 0x912: - case 0x112: - case 0x913: /* Intuos3 Airbrush */ - case 0x902: /* Intuos4 Airbrush */ - wacom->tool[idx] = BTN_TOOL_AIRBRUSH; - break; - default: /* Unknown tool */ - wacom->tool[idx] = BTN_TOOL_PEN; - } - return 1; - } - - /* Exit report */ - if ((data[1] & 0xfe) == 0x80) { - input_report_abs(dev, ABS_X, 0); - input_report_abs(dev, ABS_Y, 0); - input_report_abs(dev, ABS_DISTANCE, 0); - if (wacom->tool[idx] >= BTN_TOOL_MOUSE) { - input_report_key(dev, BTN_LEFT, 0); - input_report_key(dev, BTN_MIDDLE, 0); - input_report_key(dev, BTN_RIGHT, 0); - input_report_key(dev, BTN_SIDE, 0); - input_report_key(dev, BTN_EXTRA, 0); - input_report_abs(dev, ABS_THROTTLE, 0); - input_report_abs(dev, ABS_RZ, 0); - } else { - input_report_abs(dev, ABS_PRESSURE, 0); - input_report_key(dev, BTN_STYLUS, 0); - input_report_key(dev, BTN_STYLUS2, 0); - input_report_key(dev, BTN_TOUCH, 0); - input_report_abs(dev, ABS_WHEEL, 0); - if(wacom->features->type >= INTUOS3S) - input_report_abs(dev, ABS_Z, 0); - } - input_report_abs(dev, ABS_TILT_X, 0); - input_report_abs(dev, ABS_TILT_Y, 0); - input_report_key(dev, wacom->tool[idx], 0); - input_report_abs(dev, ABS_MISC, 0); /* reset tool id */ - input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); - input_sync(dev); - return 1; - } - return 0; -} - -static void wacom_intuos_general(struct urb *urb) -{ - struct wacom *wacom = urb->context; - unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; - unsigned int t; - - /* general pen packet */ - if ((data[1] & 0xb8) == 0xa0) - { - t = (data[6] << 2) | ((data[7] >> 6) & 3); - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) - t = (t << 1) | (data[1] & 1); - input_report_abs(dev, ABS_PRESSURE, t); - input_report_abs(dev, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); - input_report_key(dev, BTN_STYLUS, data[1] & 2); - input_report_key(dev, BTN_STYLUS2, data[1] & 4); - input_report_key(dev, BTN_TOUCH, t > 10); - } - - /* airbrush second packet */ - if ((data[1] & 0xbc) == 0xb4) - { - input_report_abs(dev, ABS_WHEEL, - (data[6] << 2) | ((data[7] >> 6) & 3)); - input_report_abs(dev, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); - } - return; -} - -static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) -{ - struct wacom *wacom = urb->context; - unsigned char *data = wacom->data; - struct input_dev *dev = &wacom->dev; - unsigned int t; - int idx = 0; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); - goto exit; - } - - if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) { - dbg("wacom_intuos_irq: received unknown report #%d", data[0]); - goto exit; - } - - input_regs(dev, regs); - - /* tool number */ - if (wacom->features->type == INTUOS) - idx = data[1] & 0x01; - - /* pad packets. Works as a second tool */ - if (data[0] == 12) - { - /* initiate the pad as a device */ - if (wacom->tool[1] != BTN_TOOL_FINGER) - wacom->tool[1] = BTN_TOOL_FINGER; - - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { - input_report_key(dev, BTN_0, (data[2] & 0x01)); - input_report_key(dev, BTN_1, (data[3] & 0x01)); - input_report_key(dev, BTN_2, (data[3] & 0x02)); - input_report_key(dev, BTN_3, (data[3] & 0x04)); - input_report_key(dev, BTN_4, (data[3] & 0x08)); - input_report_key(dev, BTN_5, (data[3] & 0x10)); - input_report_key(dev, BTN_6, (data[3] & 0x20)); - if (data[1] & 0x80) { - input_report_abs(dev, ABS_WHEEL, (data[1] & 0x7f)); - } else { - /* Out of proximity, clear wheel value. */ - input_report_abs(dev, ABS_WHEEL, 0); - } - if (wacom->features->type != INTUOS4S) { - input_report_key(dev, BTN_7, (data[3] & 0x40)); - input_report_key(dev, BTN_8, (data[3] & 0x80)); - } - if (data[1] | (data[2] & 0x01) | data[3]) { - input_report_key(dev, wacom->tool[1], 1); - input_report_abs(dev, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_key(dev, wacom->tool[1], 0); - input_report_abs(dev, ABS_MISC, 0); - } - } else { - input_report_key(dev, BTN_0, (data[5] & 0x01)); - input_report_key(dev, BTN_1, (data[5] & 0x02)); - input_report_key(dev, BTN_2, (data[5] & 0x04)); - input_report_key(dev, BTN_3, (data[5] & 0x08)); - input_report_key(dev, BTN_4, (data[6] & 0x01)); - input_report_key(dev, BTN_5, (data[6] & 0x02)); - input_report_key(dev, BTN_6, (data[6] & 0x04)); - input_report_key(dev, BTN_7, (data[6] & 0x08)); - input_report_key(dev, BTN_8, (data[5] & 0x10)); - input_report_key(dev, BTN_9, (data[6] & 0x10)); - input_report_abs(dev, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); - input_report_abs(dev, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); - - if((data[5] & 0x1f) | (data[6] & 0x1f) | (data[1] & 0x1f) | - data[2] | (data[3] & 0x1f) | data[4]) { - input_report_key(dev, wacom->tool[1], 1); - input_report_abs(dev, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_key(dev, wacom->tool[1], 0); - input_report_abs(dev, ABS_MISC, 0); - } - } - input_event(dev, EV_MSC, MSC_SERIAL, 0xffffffff); - input_sync(dev); - goto exit; - } - - /* process in/out prox events */ - if (wacom_intuos_inout(urb)) goto exit; - - /* don't proceed if we don't know the ID */ - if (!wacom->id[idx]) goto exit; - - /* Only large Intuos support Lense Cursor */ - if((wacom->tool[idx] == BTN_TOOL_LENS) - && ((wacom->features->type == INTUOS3) - || (wacom->features->type == INTUOS3S) - || (wacom->features->type == INTUOS4) - || (wacom->features->type == INTUOS4S))) - goto exit; - - /* Cintiq doesn't send data when RDY bit isn't set */ - if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40)) goto exit; - - if(wacom->features->type >= INTUOS3S) - { - input_report_abs(dev, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); - input_report_abs(dev, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); - input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); - } - else - { - input_report_abs(dev, ABS_X, be16_to_cpu(*(__be16 *) &data[2])); - input_report_abs(dev, ABS_Y, be16_to_cpu(*(__be16 *) &data[4])); - input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); - } - - /* process general packets */ - wacom_intuos_general(urb); - - /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ - if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) { - /* Rotation packet */ - if (data[1] & 0x02) - { - if(wacom->features->type >= INTUOS3S) - { - /* I3 marker pen rotation */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : - ((t-1) / 2 + 450)) : (450 - t / 2) ; - input_report_abs(dev, ABS_Z, t); - } - else - { - /* 4D mouse rotation packet */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ? - ((t - 1) / 2) : -t / 2); - } - } - /* 4D mouse packets */ - else if ( !(data[1] & 0x10) && wacom->features->type < INTUOS3S) - { - input_report_key(dev, BTN_LEFT, data[8] & 0x01); - input_report_key(dev, BTN_MIDDLE, data[8] & 0x02); - input_report_key(dev, BTN_RIGHT, data[8] & 0x04); - - input_report_key(dev, BTN_SIDE, data[8] & 0x20); - input_report_key(dev, BTN_EXTRA, data[8] & 0x10); - t = (data[6] << 2) | ((data[7] >> 6) & 3); - input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); - } - else if (wacom->tool[idx] == BTN_TOOL_MOUSE) - { - /* I4 mouse */ - if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { - input_report_key(dev, BTN_LEFT, data[6] & 0x01); - input_report_key(dev, BTN_MIDDLE, data[6] & 0x02); - input_report_key(dev, BTN_RIGHT, data[6] & 0x04); - input_report_rel(dev, REL_WHEEL, ((data[7] & 0x80) >> 7) - - ((data[7] & 0x40) >> 6)); - input_report_key(dev, BTN_SIDE, data[6] & 0x08); - input_report_key(dev, BTN_EXTRA, data[6] & 0x10); - - input_report_abs(dev, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); - } else { - /* 2D mouse packets */ - input_report_key(dev, BTN_LEFT, data[8] & 0x04); - input_report_key(dev, BTN_MIDDLE, data[8] & 0x08); - input_report_key(dev, BTN_RIGHT, data[8] & 0x10); - input_report_rel(dev, REL_WHEEL, (data[8] & 0x01) - - ((data[8] & 0x02) >> 1)); - - /* I3 2D mouse side buttons */ - if (wacom->features->type <= INTUOS3S && wacom->features->type >= INTUOS3L) - { - input_report_key(dev, BTN_SIDE, data[8] & 0x40); - input_report_key(dev, BTN_EXTRA, data[8] & 0x20); - } - } - } - /* Lens cursor packets */ - else if ((wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L || - wacom->features->type == INTUOS4L) && (wacom->tool[idx] == BTN_TOOL_LENS)) - { - input_report_key(dev, BTN_LEFT, data[8] & 0x01); - input_report_key(dev, BTN_MIDDLE, data[8] & 0x02); - input_report_key(dev, BTN_RIGHT, data[8] & 0x04); - input_report_key(dev, BTN_SIDE, data[8] & 0x10); - input_report_key(dev, BTN_EXTRA, data[8] & 0x08); - } - } - - input_report_abs(dev, ABS_MISC, wacom->id[idx]); /* report tool id */ - input_report_key(dev, wacom->tool[idx], 1); - input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); - input_sync(dev); - -exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); -} - -static struct wacom_features wacom_features[] = { - { "Wacom Penpartner", 7, 5040, 3780, 255, 0, PENPARTNER, wacom_penpartner_irq }, - { "Wacom Graphire", 8, 10206, 7422, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Graphire3 4x5", 8, 10208, 7424, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, G4, wacom_graphire_irq }, - { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, G4, wacom_graphire_irq }, - { "Wacom BambooFun 4x5", 9, 14760, 9225, 511, 63, MO, wacom_graphire_irq }, - { "Wacom BambooFun 6x8", 9, 21648, 13530, 511, 63, MO, wacom_graphire_irq }, - { "Wacom Volito", 8, 5104, 3712, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom PenStation2", 8, 3250, 2320, 255, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom PenPartner2", 8, 3250, 2320, 255, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Bamboo", 9, 14760, 9225, 511, 63, MO, wacom_graphire_irq }, - { "Wacom Bamboo1", 8, 5104, 3712, 511, 63, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom PL400", 8, 5408, 4056, 255, 0, PL, wacom_pl_irq }, - { "Wacom PL500", 8, 6144, 4608, 255, 0, PL, wacom_pl_irq }, - { "Wacom PL600", 8, 6126, 4604, 255, 0, PL, wacom_pl_irq }, - { "Wacom PL600SX", 8, 6260, 5016, 255, 0, PL, wacom_pl_irq }, - { "Wacom PL550", 8, 6144, 4608, 511, 0, PL, wacom_pl_irq }, - { "Wacom PL800", 8, 7220, 5780, 511, 0, PL, wacom_pl_irq }, - { "Wacom PL700", 8, 6758, 5406, 511, 0, PL, wacom_pl_irq }, - { "Wacom PL510", 8, 6282, 4762, 511, 0, PL, wacom_pl_irq }, - { "Wacom DTU710", 8, 34080, 27660, 511, 0, PL, wacom_pl_irq }, - { "Wacom DTF521", 8, 6282, 4762, 511, 0, PL, wacom_pl_irq }, - { "Wacom DTF720", 8, 6858, 5506, 511, 0, PL, wacom_pl_irq }, - { "Wacom DTF720a", 8, 6858, 5506, 511, 0, PL, wacom_pl_irq }, - { "Wacom Cintiq Partner",8, 20480, 15360, 511, 0, PL, wacom_ptu_irq }, - { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 31, INTUOS, wacom_intuos_irq }, - { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 63, INTUOS3S, wacom_intuos_irq }, - { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 63, INTUOS3, wacom_intuos_irq }, - { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 63, INTUOS3, wacom_intuos_irq }, - { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L, wacom_intuos_irq }, - { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L, wacom_intuos_irq }, - { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3, wacom_intuos_irq }, - { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S, wacom_intuos_irq }, - { "Wacom Intuos4 4x6", 10, 31496, 19685, 2047, 63, INTUOS4S, wacom_intuos_irq }, - { "Wacom Intuos4 6x9", 10, 44704, 27940, 2047, 63, INTUOS4, wacom_intuos_irq }, - { "Wacom Intuos4 8x13", 10, 65024, 40640, 2047, 63, INTUOS4L, wacom_intuos_irq }, - { "Wacom Intuos4 12x19", 10, 97536, 60960, 2047, 63, INTUOS4L, wacom_intuos_irq }, - { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ, wacom_intuos_irq }, - { "Wacom Cintiq 20WSX", 10, 86680, 54180, 1023, 63, BEE, wacom_intuos_irq }, - { "Wacom Cintiq 12WX", 10, 53020, 33440, 1023, 63, BEE, wacom_intuos_irq }, - { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS, wacom_intuos_irq }, - { } -}; - -static struct usb_device_id wacom_ids[] = { - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x00) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x11) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x17) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x18) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x69) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x30) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x32) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC4) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC2) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB8) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB9) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBA) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBB) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, - { } -}; - -MODULE_DEVICE_TABLE(usb, wacom_ids); - -static int wacom_open(struct input_dev *dev) -{ - struct wacom *wacom = dev->private; - - if (wacom->open++) - return 0; - - wacom->irq->dev = wacom->usbdev; - if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { - wacom->open--; - return -EIO; - } - - return 0; -} - -static void wacom_close(struct input_dev *dev) -{ - struct wacom *wacom = dev->private; - - if (!--wacom->open) - usb_unlink_urb(wacom->irq); -} - -static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); - struct usb_endpoint_descriptor *endpoint; - char rep_data[2], limit = 0; - struct wacom *wacom; - char path[64]; - - if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) - return -ENOMEM; - memset(wacom, 0, sizeof(struct wacom)); - - wacom->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); - if (!wacom->data) { - kfree(wacom); - return -ENOMEM; - } - - wacom->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!wacom->irq) { - usb_buffer_free(dev, 10, wacom->data, wacom->data_dma); - kfree(wacom); - return -ENOMEM; - } - - wacom->features = wacom_features + (id - wacom_ids); - - wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); - wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); - wacom->dev.absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC); - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS); - - switch (wacom->features->type) { - case MO: - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_1) | BIT(BTN_5); - wacom->dev.absbit[0] |= BIT(ABS_WHEEL); - wacom->dev.absmax[ABS_WHEEL] = 71; - case G4: - wacom->dev.evbit[0] |= BIT(EV_MSC); - wacom->dev.mscbit[0] |= BIT(MSC_SERIAL); - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_4); - /* fall through */ - - case GRAPHIRE: - wacom->dev.evbit[0] |= BIT(EV_REL); - wacom->dev.relbit[0] |= BIT(REL_WHEEL); - wacom->dev.absbit[0] |= BIT(ABS_DISTANCE); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); - break; - - case INTUOS3: - case INTUOS3L: - case CINTIQ: - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); - wacom->dev.absbit[0] |= BIT(ABS_RY); - wacom->dev.absmax[ABS_RY] = 4096; - /* fall through */ - - case INTUOS3S: - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); - wacom->dev.absbit[0] |= BIT(ABS_RX); - wacom->dev.absmax[ABS_RX] = 4096; - /* fall through */ - - case INTUOS: - wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); - wacom->dev.mscbit[0] |= BIT(MSC_SERIAL); - wacom->dev.relbit[0] |= BIT(REL_WHEEL); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) - | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); - wacom->dev.absbit[0] |= BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE); - break; - - case INTUOS4: - case INTUOS4L: - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_7) | BIT(BTN_8); - /* fall through */ - - case INTUOS4S: - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6); - wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); - wacom->dev.mscbit[0] |= BIT(MSC_SERIAL); - wacom->dev.relbit[0] |= BIT(REL_WHEEL); - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) - | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); - wacom->dev.absbit[0] |= BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE); - break; - - case PL: - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER); - break; - - case PENPARTNER: - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER); - break; - } - - wacom->dev.absmax[ABS_X] = wacom->features->x_max; - wacom->dev.absmax[ABS_Y] = wacom->features->y_max; - wacom->dev.absmax[ABS_PRESSURE] = wacom->features->pressure_max; - wacom->dev.absmax[ABS_DISTANCE] = wacom->features->distance_max; - wacom->dev.absmax[ABS_TILT_X] = 127; - wacom->dev.absmax[ABS_TILT_Y] = 127; - wacom->dev.absmax[ABS_WHEEL] = 1023; - - wacom->dev.absmin[ABS_RZ] = -900; - wacom->dev.absmax[ABS_RZ] = 899; - wacom->dev.absmin[ABS_Z] = -900; - wacom->dev.absmax[ABS_Z] = 899; - wacom->dev.absmin[ABS_THROTTLE] = -1023; - wacom->dev.absmax[ABS_THROTTLE] = 1023; - - wacom->dev.absfuzz[ABS_X] = 4; - wacom->dev.absfuzz[ABS_Y] = 4; - - wacom->dev.private = wacom; - wacom->dev.open = wacom_open; - wacom->dev.close = wacom_close; - - usb_make_path(dev, path, 64); - sprintf(wacom->phys, "%s/input0", path); - - wacom->dev.name = wacom->features->name; - wacom->dev.phys = wacom->phys; - wacom->dev.id.bustype = BUS_USB; - wacom->dev.id.vendor = dev->descriptor.idVendor; - wacom->dev.id.product = dev->descriptor.idProduct; - wacom->dev.id.version = dev->descriptor.bcdDevice; - wacom->dev.dev = &intf->dev; - wacom->usbdev = dev; - - endpoint = &intf->cur_altsetting->endpoint[0].desc; - - if (wacom->features->pktlen > 10) - BUG(); - - usb_fill_int_urb(wacom->irq, dev, - usb_rcvintpipe(dev, endpoint->bEndpointAddress), - wacom->data, wacom->features->pktlen, - wacom->features->irq, wacom, endpoint->bInterval); - wacom->irq->transfer_dma = wacom->data_dma; - wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - input_register_device(&wacom->dev); - - /* ask the tablet to report tablet data. repeats until it succeeds*/ - do { - rep_data[0] = 2; - rep_data[1] = 2; - usb_set_report(intf, 3, 2, rep_data, 2); - usb_get_report(intf, 3, 2, rep_data, 2); - } while (rep_data[1] != 2 && limit++ < 5); - - printk(KERN_INFO "input: %s on %s\n", wacom->features->name, path); - - usb_set_intfdata(intf, wacom); - - return 0; -} - -static void wacom_disconnect(struct usb_interface *intf) -{ - struct wacom *wacom = usb_get_intfdata (intf); - - usb_set_intfdata(intf, NULL); - if (wacom) { - usb_unlink_urb(wacom->irq); - input_unregister_device(&wacom->dev); - usb_free_urb(wacom->irq); - usb_buffer_free(interface_to_usbdev(intf), 10, wacom->data, wacom->data_dma); - kfree(wacom); - } -} - -static struct usb_driver wacom_driver = { - .owner = THIS_MODULE, - .name = "wacom", - .probe = wacom_probe, - .disconnect = wacom_disconnect, - .id_table = wacom_ids, -}; - -static int __init wacom_init(void) -{ - int result = usb_register(&wacom_driver); - if (result == 0) - info(DRIVER_VERSION ":" DRIVER_DESC); - return result; -} - -static void __exit wacom_exit(void) -{ - usb_deregister(&wacom_driver); -} - -module_init(wacom_init); -module_exit(wacom_exit); diff --git a/src/Makefile.am b/src/Makefile.am index f7753ae..7344747 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = . wacomxi util xdrv @WCM_KERNEL_VER@ +SUBDIRS = . xdrv wmanpagedir = @mandir@/man4 wmanpage_HEADERS = wacom.4x.gz diff --git a/src/include/kernel-config.h.in b/src/include/kernel-config.h.in deleted file mode 100644 index ffe22c7..0000000 --- a/src/include/kernel-config.h.in +++ /dev/null @@ -1,9 +0,0 @@ -/* kernel-config.h.in */ - -#ifndef _KERNEL_CONFIG_H_ -#define _KERNEL_CONFIG_H_ - -/* Do not need the dr.wValue patch */ -#undef WCM_PATCH_DRVALUE - -#endif /* _KERNEL_CONFIG_H_ */ diff --git a/src/include/util-config.h.in b/src/include/util-config.h.in deleted file mode 100644 index ceeae0e..0000000 --- a/src/include/util-config.h.in +++ /dev/null @@ -1,27 +0,0 @@ -/* util-config.h.in */ - -#ifndef _UTIL_CONFIG_H_ -#define _UTIL_CONFIG_H_ - -/* Compiling for X.org */ -#undef WCM_XORG - -/* Compiling for XFree86 */ -#undef WCM_XFREE86 - -/* ncurses header files available */ -#undef WCM_ENABLE_NCURSES - -/* Enable the Linux Input subsystem */ -#undef WCM_ENABLE_LINUXINPUT - -/* Some X.org versions require that the events are scaled to screen size */ -#undef WCM_XORG_TABLET_SCALING - -/* IsXExtensionPointer is only defined in later X.org releases */ -#undef WCM_ISXEXTENSIONPOINTER - -/* xf86config lib is only included in some Xorg systems */ -#undef WCM_XF86CONFIG - -#endif /* _UTIL_CONFIG_H_ */ diff --git a/src/include/xdrv-config.h.in b/src/include/xdrv-config.h.in index afe7748..436addb 100644 --- a/src/include/xdrv-config.h.in +++ b/src/include/xdrv-config.h.in @@ -1,42 +1,113 @@ -/* xdrv-config.h.in */ +/* src/include/xdrv-config.h.in. Generated from configure.in by autoheader. */ -#ifndef _XDRV_CONFIG_H_ -#define _XDRV_CONFIG_H_ +/* Define to 1 if you have the <dlfcn.h> header file. */ +#undef HAVE_DLFCN_H -/* Misc defines moved from the command line */ +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* cmdline substitute */ #undef IN_MODULE -#undef XFree86LOADER -#undef XINPUT -#undef XKB -/* Compiling for X.org */ -#undef WCM_XORG +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR -/* Compiling for XFree86 */ -#undef WCM_XFREE86 +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION /* Enable the Linux Input subsystem */ #undef WCM_ENABLE_LINUXINPUT +/* ncurses header files available */ +#undef WCM_ENABLE_NCURSES + +/* Later X.org version uses dixScreenOrigins for screen positions and sizes */ +#undef WCM_HAVE_DIXSCREENORIGINS + +/* IsXExtensionPointer is only defined in later X.org releases */ +#undef WCM_ISXEXTENSIONPOINTER + +/* The X-driver can send key events for a button */ +#undef WCM_KEY_SENDING_SUPPORT + /* The xserver have no wraps around libc-functions */ #undef WCM_NO_LIBCWRAPPER +/* libxf86config isn't included */ +#undef WCM_XF86CONFIG + +/* Compiling for XFree86 */ +#undef WCM_XFREE86 + +/* Slightly diffent abi in XINPUT >= 1.0 */ +#undef WCM_XINPUTABI_MAJOR + +/* Compiling for X.org */ +#undef WCM_XORG + /* Some X.org versions require that the events are scaled to screen size */ #undef WCM_XORG_TABLET_SCALING -/* Xserver versions 1.4 and later call Uninit before closing a device. */ +/* Xserver versions 1.4 and later call Uninit before closing a device */ #undef WCM_XORG_XSERVER_1_4 -/* Xserver versions 1.6 and later changed a few interfaces. */ +/* Using version 1.6 or later of X.org */ #undef WCM_XORG_XSERVER_1_6 -/* The X-driver can send key events for a button */ -#undef WCM_KEY_SENDING_SUPPORT +/* cmdline substitute */ +#undef XFree86LOADER -/* Later X.org version uses dixScreenOrigins for screen positions and sizes */ -#undef WCM_HAVE_DIXSCREENORIGINS +/* cmdline substitute */ +#undef XINPUT -/* Slightly diffent abi in XINPUT >= 1.0 */ -#undef WCM_XINPUTABI_MAJOR +/* cmdline substitute */ +#undef XKB -#endif /* _XDRV_CONFIG_H_ */ +/* Define to 1 if the X Window System is missing or not being used. */ +#undef X_DISPLAY_MISSING diff --git a/src/util/10-linuxwacom.fdi b/src/util/10-linuxwacom.fdi deleted file mode 100644 index ecb88cd..0000000 --- a/src/util/10-linuxwacom.fdi +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!-- this is probably a bit imprecise --> -<deviceinfo version="0.2"> - <device> - <match key="info.category" contains="input"> - <match key="info.product" contains_outof="Wacom"> - <merge key="input.x11_driver" type="string">wacom</merge> - <merge key="input.x11_options.Type" type="string">stylus</merge> - <append key="info.callouts.add" type="strlist">hal-setup-wacom</append> - <append key="wacom.types" type="strlist">eraser</append> - <append key="wacom.types" type="strlist">cursor</append> - <append key="wacom.types" type="strlist">pad</append> - </match> - </match> - <match key="info.capabilities" contains="serial"> - <match key="@info.parent:pnp.id" contains_outof="WACf001;WACf002;WACf003;WACf004;WACf005;WACf006;WACf007;WACf008;WACf009;WACf00a;WACf00b;WACf00c;FUJ02e5"> - <append key="info.capabilities" type="strlist">input</append> - <merge key="input.x11_driver" type="string">wacom</merge> - <merge key="input.x11_options.Type" type="string">stylus</merge> - <merge key="input.x11_options.ForceDevice" type="string">ISDV4</merge> - <merge key="input.device" type="copy_property">serial.device</merge> - <append key="info.callouts.add" type="strlist">hal-setup-wacom</append> - <append key="wacom.types" type="strlist">eraser</append> - <match key="@info.parent:pnp.id" contains_outof="WACf008;WACf009"> - <!-- Serial tablets with touch capabilities --> - <append key="wacom.types" type="strlist">touch</append> - </match> - </match> - </match> - </device> - <!-- Match the Wacom Bluetooth A5 pen tablet --> - <device> - <match key="info.capabilities" contains="input.mouse"> - <match key="info.product" contains="WACOM"> - <match key="info.product" contains="Tablet"> - <merge key="input.x11_driver" type="string">wacom</merge> - <merge key="input.x11_options.Type" type="string">stylus</merge> - <append key="info.callouts.add" type="strlist">hal-setup-wacom</append> - <append key="wacom.types" type="strlist">eraser</append> - <append key="wacom.types" type="strlist">cursor</append> - </match> - </match> - </match> - </device> -</deviceinfo> - - diff --git a/src/util/60-wacom.rules b/src/util/60-wacom.rules deleted file mode 100644 index 40dfe91..0000000 --- a/src/util/60-wacom.rules +++ /dev/null @@ -1,100 +0,0 @@ -# udev rules for wacom tablets. -# These rules were compiled for the Debian GNU/Linux distribution, -# but others may, and indeed are encouraged to, use them also. -# -# Should you do so, PLEASE CO-ORDINATE ANY CHANGES OR ADDITIONS -# of new devices with Ron so that we can try -# to present users with a standard set of device nodes -# which they can rely on across the board. - -KERNEL!="event[0-9]*", GOTO="wacom_end" - -# Port specific link for users of multiple tablets of the same type. -# The ID_PATH variable is set by the "path_id" script in an earlier rule file. -ATTRS{idVendor}=="056a", ENV{ID_PATH}=="?*", SYMLINK="input/by-path/$env{ID_PATH}-wacom" - -# Multiple interface support for stylus and touch devices. -DRIVERS=="wacom", ATTRS{bInterfaceNumber}=="00", ENV{WACOM_TYPE}="stylus" -DRIVERS=="wacom", ATTRS{bInterfaceNumber}=="01", ENV{WACOM_TYPE}="touch" - -# Type-named links for multiple tablets. If you want to use multiple -# tablets of the _same_ type, you will probably need to use the links -# from /dev/input/by-path to identify which is plugged into what usb -# port. For different tablet types though, just pick your links from -# the list below. -# -# We override SYMLINK for tabletpc devices because the by-path link -# is not required with such devices, there will only ever be one. -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0000", SYMLINK+="input/tablet-penpartner" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0003", SYMLINK+="input/tablet-cintiq_partner" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0010", SYMLINK+="input/tablet-graphire" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0011", SYMLINK+="input/tablet-graphire2-4x5" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0012", SYMLINK+="input/tablet-graphire2-5x7" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0013", SYMLINK+="input/tablet-graphire3" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0014", SYMLINK+="input/tablet-graphire3-6x8" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0015", SYMLINK+="input/tablet-graphire4-4x5" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0016", SYMLINK+="input/tablet-graphire4-6x8" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0017", SYMLINK+="input/tablet-bamboofun-4x5" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0018", SYMLINK+="input/tablet-bamboofun-6x8" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0019", SYMLINK+="input/tablet-bamboo1-medium" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0020", SYMLINK+="input/tablet-intuos-4x5" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0021", SYMLINK+="input/tablet-intuos-6x8" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0022", SYMLINK+="input/tablet-intuos-9x12" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0023", SYMLINK+="input/tablet-intuos-12x12" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0024", SYMLINK+="input/tablet-intuos-12x18" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0030", SYMLINK+="input/tablet-pl400" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0031", SYMLINK+="input/tablet-pl500" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0032", SYMLINK+="input/tablet-pl600" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0033", SYMLINK+="input/tablet-pl600sx" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0034", SYMLINK+="input/tablet-pl550" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0035", SYMLINK+="input/tablet-pl800" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0037", SYMLINK+="input/tablet-pl700" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0038", SYMLINK+="input/tablet-pl510" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0039", SYMLINK+="input/tablet-dtu710" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="003f", SYMLINK+="input/tablet-cintiq21ux" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0041", SYMLINK+="input/tablet-intuos2-4x5" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0042", SYMLINK+="input/tablet-intuos2-6x8" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0043", SYMLINK+="input/tablet-intuos2-9x12" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0044", SYMLINK+="input/tablet-intuos2-12x12" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0045", SYMLINK+="input/tablet-intuos2-12x18" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0047", SYMLINK+="input/tablet-intuos2-6x8a" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0060", SYMLINK+="input/tablet-volito" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0061", SYMLINK+="input/tablet-penstation2" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0062", SYMLINK+="input/tablet-volito2-4x5" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0063", SYMLINK+="input/tablet-volito2-2x3" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0064", SYMLINK+="input/tablet-penpartner2" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0065", SYMLINK+="input/tablet-bamboo" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0069", SYMLINK+="input/tablet-bamboo1" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0081", SYMLINK+="input/tablet-graphire_bt-6x8" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0090", SYMLINK="input/tablet-tpc90" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="0093", SYMLINK="input/tablet-tpc93-$env{WACOM_TYPE}" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="009a", SYMLINK="input/tablet-tpc9a-$env{WACOM_TYPE}" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b0", SYMLINK+="input/tablet-intuos3-4x5" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b1", SYMLINK+="input/tablet-intuos3-6x8" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b2", SYMLINK+="input/tablet-intuos3-9x12" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b3", SYMLINK+="input/tablet-intuos3-12x12" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b4", SYMLINK+="input/tablet-intuos3-12x19" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b5", SYMLINK+="input/tablet-intuos3-6x11" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b7", SYMLINK+="input/tablet-intuos3-4x6" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b8", SYMLINK+="input/tablet-intuos4-4x6" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00b9", SYMLINK+="input/tablet-intuos4-6x9" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00ba", SYMLINK+="input/tablet-intuos4-8x13" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00bb", SYMLINK+="input/tablet-intuos4-12x19" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00c0", SYMLINK+="input/tablet-dtf521" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00c4", SYMLINK+="input/tablet-dtf720" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00c5", SYMLINK+="input/tablet-cintiq20wsx" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00c6", SYMLINK+="input/tablet-cintiq12wx" -ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00c7", ENV{WACOM_TYPE}!="touch", SYMLINK+="input/tablet-dtu1931" - -# Convenience links for the common case of a single tablet. We could do just this: -#ATTRS{idVendor}=="056a", SYMLINK+="input/wacom-$env{WACOM_TYPE}" -# but for legacy reasons, we keep the input/wacom link as the generic stylus device. -ATTRS{idVendor}=="056a", ENV{WACOM_TYPE}!="touch", SYMLINK+="input/wacom" -ATTRS{idVendor}=="056a", ENV{WACOM_TYPE}=="touch", SYMLINK+="input/wacom-touch" - -# Check and repossess the device if a module other than the wacom one -# is already bound to it. -ATTRS{idVendor}=="056a", ACTION=="add", RUN+="check_driver wacom $devpath $env{ID_BUS}" - -LABEL="wacom_end" - diff --git a/src/util/Makefile.am b/src/util/Makefile.am deleted file mode 100755 index 34e013b..0000000 --- a/src/util/Makefile.am +++ /dev/null @@ -1,54 +0,0 @@ -bin_PROGRAMS = @WCM_PROGS@ -lib_LTLIBRARIES = libwacomcfg.la - -wacomcfgdir = $(includedir)/wacomcfg -wacomcfg_HEADERS = wacomcfg.h - -if WCM_ENV_XORGSDK -WACOMCFG_INCLUDES = -I$(WCM_XORGSDK_DIR) $(X_CFLAGS) $(HAL_CFLAGS) -endif - -if WCM_ENV_XFREE86 -WACOMCFG_INCLUDES = -I$(WCM_XFREE86_DIR) -endif - -AM_CFLAGS = -Wall -pedantic $(WACOMCFG_INCLUDES) - -# These identify which programs, libraries, and headers could -# potentially be built or installed depending on the results of -# the configuration. -EXTRA_PROGRAMS = wacdump xidump xsetwacom -if WCM_HAVE_HAL -libexec_PROGRAMS = hal-setup-wacom -fdidir = $(prefix)/share/hal/fdi/policy/20thirdparty -fdi_SCRIPTS = 10-linuxwacom.fdi -endif - -# Source dependencies -wacdump_SOURCES = wacdump.c wacscrn.c wacscrn.h \ - wactablet.c wactablet.h \ - wacserial.c wacserial.h \ - wacusb.c wacusb.h -if WCM_ENV_NCURSES -wacdump_LDADD = -lncurses -endif - -xidump_SOURCES = xidump.c wacscrn.c wacscrn.h -xidump_LDFLAGS = @WCM_XIDUMP_LIBS@ -if WCM_ENV_NCURSES -xidump_LDADD = -lncurses -endif - -libwacomcfg_la_SOURCES = wacomcfg.c wacomcfg.h ../include/Xwacom.h -libwacomcfg_la_LDFLAGS = -no-undefined -version-info @WCM_LIBWACOMCFG_VER@ -libwacomcfg_la_LIBADD = @WCM_LIBWACOMCFG_LIBS@ - -xsetwacom_SOURCES = xsetwacom.c wacomcfg.h wcmAction.c wcmAction.h ../include/Xwacom.h -xsetwacom_LDADD = libwacomcfg.la - -if WCM_HAVE_HAL -hal_setup_wacom_SOURCES = hal-setup-wacom.c -hal_setup_wacom_LDADD = $(HAL_LIBS) -endif - - diff --git a/src/util/hal-setup-wacom.c b/src/util/hal-setup-wacom.c deleted file mode 100644 index dd6183c..0000000 --- a/src/util/hal-setup-wacom.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Licensed under the GNU General Public License Version 2 - * - * Copyright (C) 2009 Red Hat <mjg@redhat.com> - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> - -#include <hal/libhal.h> - -static LibHalContext *ctx = NULL; -static char* udi; - -int -main (int argc, char **argv) -{ - char *device; - char *newudi; - char *forcedev; - char *name; - char *subname; - char **types; - int i; - DBusError error; - - udi = getenv ("UDI"); - if (udi == NULL) { - fprintf (stderr, "hal-setup-wacom: Failed to get UDI\n"); - return 1; - } - - asprintf (&newudi, "%s_subdev", udi); - - dbus_error_init (&error); - if ((ctx = libhal_ctx_init_direct (&error)) == NULL) { - fprintf (stderr, "hal-setup-wacom: Unable to initialise libhal context: %s\n", error.message); - return 1; - } - - dbus_error_init (&error); - if (!libhal_device_addon_is_ready (ctx, udi, &error)) { - return 1; - } - - dbus_error_init (&error); - - /* get the device */ - device = libhal_device_get_property_string (ctx, udi, "input.device", - &error); - if (dbus_error_is_set (&error) == TRUE) { - fprintf (stderr, - "hal-setup-wacom: Failed to get input device: '%s'\n", - error.message); - return 1; - } - - /* Is there a forcedevice? */ - dbus_error_init (&error); - forcedev = libhal_device_get_property_string - (ctx, udi, "input.x11_options.ForceDevice", &error); - - dbus_error_init (&error); - name = libhal_device_get_property_string (ctx, udi, "info.product", - &error); - - dbus_error_init (&error); - types = libhal_device_get_property_strlist (ctx, udi, "wacom.types", - &error); - - if (dbus_error_is_set (&error) == TRUE) { - fprintf (stderr, - "hal-setup-wacom: Failed to get wacom types: '%s'\n", - error.message); - return 1; - } - - /* Set up the extra devices */ - for (i=0; types[i] != NULL; i++) { - char *tmpdev; - - dbus_error_init (&error); - tmpdev = libhal_new_device(ctx, &error); - if (dbus_error_is_set (&error) == TRUE) { - fprintf (stderr, - "hal-setup-wacom: Failed to create input device: '%s'\n", - error.message); - return 1; - } - dbus_error_init (&error); - libhal_device_set_property_string (ctx, tmpdev, "input.device", - device, &error); - dbus_error_init (&error); - libhal_device_set_property_string (ctx, tmpdev, - "input.x11_driver", "wacom", - &error); - dbus_error_init (&error); - libhal_device_set_property_string (ctx, tmpdev, - "input.x11_options.Type", - types[i], &error); - dbus_error_init (&error); - libhal_device_set_property_string (ctx, tmpdev, "info.parent", - udi, &error); - dbus_error_init (&error); - libhal_device_property_strlist_append (ctx, tmpdev, - "info.capabilities", - "input", &error); - if (forcedev) { - dbus_error_init (&error); - libhal_device_set_property_string (ctx, tmpdev, - "input.x11_options.ForceDevice", - forcedev, &error); - } - if (name) { - dbus_error_init (&error); - asprintf (&subname, "%s %s", name, types[i]); - libhal_device_set_property_string (ctx, tmpdev, - "info.product", - subname, &error); - free (subname); - } - dbus_error_init (&error); - libhal_device_commit_to_gdl (ctx, tmpdev, newudi, &error); - - if (dbus_error_is_set (&error) == TRUE) { - fprintf (stderr, - "hal-setup-wacom: Failed to add input device: '%s'\n", - error.message); - return 1; - } - } - - return 0; -} - diff --git a/src/util/wacdump.c b/src/util/wacdump.c deleted file mode 100755 index 54b2811..0000000 --- a/src/util/wacdump.c +++ /dev/null @@ -1,632 +0,0 @@ -/***************************************************************************** -** wacdump.c -** -** Copyright (C) 2002 - 2008 - John E. Joganic and Ping Cheng -** -** 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 Lesser 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -** REVISION HISTORY -** 2002-12-17 0.3.3 - split ncurses from main file to avoid namespace -** collision in linux/input.h -** 2002-12-21 0.3.4 - changed to FILE* to file descriptors -** 2003-01-01 0.3.5 - moved refresh to start display immediately -** 2003-01-25 0.3.6 - moved usb code to wacusb.c -** 2003-01-26 0.3.7 - applied Dean Townsley's Acer C100 patch -** 2003-01-27 0.3.8 - added logging, better error recovery -** 2003-01-31 0.5.0 - new release -** 2003-02-12 0.5.1 - added version option and fixed usage -** 2003-06-19 0.5.2 - added patch for I2 6x8 id 0x47 -** 2005-02-17 0.6.6 - added I3 and support 64-bit system -** 2005-09-01 0.7.0 - Added Cintiq 21UX -** 2005-02-17 0.7.1 - added Graphire 4 -** 2006-02-27 0.7.3 - added DTF 521, I3 12x12 & 12x19 -** 2006-05-05 0.7.4 - Removed older 2.6 kernels -** 2008-12-31 0.8.2 - Support USB Tabket PCs -** -****************************************************************************/ - -#include "../include/util-config.h" - -#include "wactablet.h" -#include "wacscrn.h" - -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <ctype.h> -#include <string.h> -#include <unistd.h> -#include <time.h> - -#define WACDUMP_VER "0.8.2" - -/* from linux/input.h */ -#define BITS_PER_LONG (sizeof(long) * 8) -#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) -#define BIT(x) (1UL<<((x)%BITS_PER_LONG)) -#define LONG(x) ((x)/BITS_PER_LONG) -#define ISBITSET(x,y) ((x)[LONG(y)] & BIT(y)) - -static int InitTablet(WACOMTABLET hTablet); -void FetchTablet(WACOMTABLET hTablet); -static void DisplaySerialValue(unsigned int uField); -static void DisplaySerialButton(unsigned int uCode); - -struct ABS_STATE -{ - int bValid; - int nRow, nCol; - int nValue, nMin, nMax; -}; - -struct KEY_STATE -{ - int bValid; - int nRow, nCol; - int nValue; -}; - -struct ABS_STATE gAbsState[WACOMFIELD_MAX]; -struct KEY_STATE gKeyState[WACOMBUTTON_MAX]; -int gnSerialDataRow = 0; -int gbCursesRunning = 0; -FILE* gLogFile = NULL; - -void Usage(void) -{ - int i, j, nClsSize, nDevSize; - unsigned int uDeviceCls; - WACOMCLASSREC* pCls; - WACOMDEVICEREC* pDev; - - fprintf(stderr,"Usage: wacdump [options] device\n" - "Options:\n" - " -h, --help - usage\n" - " -c, --class device_cls - use specified class (see below)\n" - " -f, --force device_name - use specified device (see below)\n" - " -l, --list - list all supported devices\n" - " -v, --verbose - increase log output; multiple OK\n" - " -V, --version - display version number\n" - " --logfile log_file - output log to file\n" - "\n"); - fprintf(stderr, - "Example devices:\n" -#ifdef WCM_ENABLE_LINUXINPUT - " /dev/input/event0 - usb tablet device\n" -#endif - " /dev/ttyS0 - serial tablet on com1\n" - " /dev/ttyUSB0 - serial tablet on USB adapter\n" - "\n" - "Supported device classes:\n"); - - if (!WacomGetSupportedClassList(&pCls,&nClsSize)) - { - fprintf(stderr," "); - for (i=0; i<nClsSize; ++i) - fprintf(stderr,"%s%s", i ? ", " : "", pCls[i].pszName); - fprintf(stderr,"\n"); - - fprintf(stderr,"Supported device names:\n"); - for (i=0; i<nClsSize; ++i) - { - fprintf(stderr," %s: ",pCls[i].pszName); - uDeviceCls = pCls[i].uDeviceClass; - if (!WacomGetSupportedDeviceList(uDeviceCls,&pDev,&nDevSize)) - { - for (j=0; j<nDevSize; ++j) - fprintf(stderr,"%s%s", j ? ", " : "", pDev[j].pszName); - fprintf(stderr,"\n"); - WacomFreeList(pDev); - } - } - WacomFreeList(pCls); - } -} - -void Version(void) -{ - fprintf(stdout,"%s\n", WACDUMP_VER); -} - -void ListSupportedDevices(void) -{ - int i, nListSize; - WACOMDEVICEREC* pList; - - if (!WacomGetSupportedDeviceList(0,&pList,&nListSize)) - { - for (i=0; i<nListSize; ++i) - { - fprintf(stdout,"%s\t%s\t%s\t\"%s\"\n", - pList[i].pszName, - pList[i].pszVendorName, - pList[i].pszClass, - pList[i].pszDesc); - } - WacomFreeList(pList); - } -} - -static void termscr(void) -{ - wacscrn_term(); -} - -static int InitTablet(WACOMTABLET hTablet) -{ - int i, nCaps, nItem, nRow=0; - int nMajor, nMinor, nRelease; - char chBuf[256]; - WACOMMODEL model; - WACOMSTATE ranges = WACOMSTATE_INIT; - const char* pszName; - const char* pszClass = "UNK_CLS"; - const char* pszVendor = "UNK_VNDR"; - const char* pszDevice = "UNK_DEV"; - const char* pszSub = "UNK_SUB"; - - /* Identify program and version */ - wacscrn_standout(); - for (i=0; i<80; ++i) wacscrn_output(nRow,i," "); - wacscrn_output(nRow,0,"wacdump v" WACDUMP_VER); - wacscrn_normal(); - nRow += 2; - - /* get model */ - model = WacomGetModel(hTablet); - pszVendor = WacomGetVendorName(hTablet); - pszClass = WacomGetClassName(hTablet); - pszDevice = WacomGetDeviceName(hTablet); - pszSub = WacomGetSubTypeName(hTablet); - pszName = WacomGetModelName(hTablet); - WacomGetROMVersion(hTablet,&nMajor,&nMinor,&nRelease); - snprintf(chBuf,sizeof(chBuf),"MODEL=%s",pszName); - wacscrn_output(nRow,0,chBuf); - snprintf(chBuf,sizeof(chBuf),"ROM=%d.%d-%d",nMajor, nMinor, nRelease); - wacscrn_output(nRow,40,chBuf); - ++nRow; - snprintf(chBuf,sizeof(chBuf),"CLS=%s VNDR=%s DEV=%s SUB=%s", - pszClass, pszVendor, pszDevice, pszSub); - wacscrn_output(nRow,0,chBuf); - nRow += 2; - - gnSerialDataRow = nRow++; /* data */ - nRow += 2; - - /* get event types supported, ranges, and immediate values */ - nCaps = WacomGetCapabilities(hTablet); - WacomGetState(hTablet,&ranges); - - nItem = 0; - for (i=0; i<31; ++i) - { - if (nCaps & (1<<i)) - { - gAbsState[i].bValid = 1; - gAbsState[i].nValue = ranges.values[i].nValue; - gAbsState[i].nMin = ranges.values[i].nMin; - gAbsState[i].nMax = ranges.values[i].nMax; - gAbsState[i].nRow = nRow + nItem / 2; - gAbsState[i].nCol = nItem % 2; - DisplaySerialValue(i); - ++nItem; - } - } - nRow += ((nItem + 1) / 2) + 1; - - /* get key event types */ - nItem = 0; - for (i=0; i<WACOMBUTTON_MAX; ++i) - { - gKeyState[i].bValid = 1; - gKeyState[i].nRow = nRow + nItem / 4; - gKeyState[i].nCol = nItem % 4; - DisplaySerialButton(i); - ++nItem; - } - nRow += ((nItem + 3) / 4) + 1; - return 0; -} - -const char* GetSerialField(unsigned int uField) -{ - static const char* xszField[WACOMFIELD_MAX] = - { - "TOOLTYPE", "SERIAL", "IN_PROX", "BUTTON", - "POS_X", "POS_Y", "ROT_Z", "DISTANCE", - "PRESSURE", "TILT_X", "TILT_Y", "ABSWHEEL", - "RELWHEEL", "THROTTLE" - }; - - return (uField >= WACOMFIELD_MAX) ? "FIELD?" : xszField[uField]; -} - -static void DisplaySerialValue(unsigned int uField) -{ - static char xchBuf[256]; - static const char* xszTool[WACOMTOOLTYPE_MAX] = - { - "NONE", "PEN", "PENCIL", "BRUSH", "ERASER", "AIRBRUSH", - "MOUSE", "LENS", "PAD", "TOUCH" - }; - - int bBold = 0; - if ((uField >= WACOMFIELD_MAX) || !gAbsState[uField].bValid) - { - snprintf(xchBuf,sizeof(xchBuf),"Bad FIELD Code: 0x%X",uField); - wacscrn_output(24,0,xchBuf); - return; - } - - snprintf(xchBuf,sizeof(xchBuf),"%8s=",GetSerialField(uField)); - wacscrn_output(gAbsState[uField].nRow,gAbsState[uField].nCol*40,xchBuf); - - if (uField == WACOMFIELD_TOOLTYPE) - { - int nToolType = gAbsState[uField].nValue; - if ((nToolType<WACOMTOOLTYPE_NONE) || (nToolType>WACOMTOOLTYPE_MAX)) - snprintf(xchBuf,sizeof(xchBuf),"UNKNOWN"); - else - snprintf(xchBuf,sizeof(xchBuf),"%-10s", - xszTool[nToolType]); - bBold = (nToolType != WACOMTOOLTYPE_NONE); - } - else if (uField == WACOMFIELD_SERIAL) - { - snprintf(xchBuf,sizeof(xchBuf),"0x%08X",gAbsState[uField].nValue); - } - else if (uField == WACOMFIELD_PROXIMITY) - { - snprintf(xchBuf,sizeof(xchBuf),"%-3s", - gAbsState[uField].nValue ? "in" : "out"); - bBold = gAbsState[uField].nValue; - } - else - { - /* deal with tool in prox before wacdump launched */ - if (gAbsState[uField].nValue && !gAbsState[WACOMFIELD_PROXIMITY].nValue) - { - gAbsState[WACOMFIELD_PROXIMITY].nValue |= BIT(WACOMTOOLTYPE_PEN); - gAbsState[WACOMFIELD_TOOLTYPE].nValue = WACOMTOOLTYPE_PEN; - wacscrn_standout(); - snprintf(xchBuf,sizeof(xchBuf),"%-3s","in"); - wacscrn_output(gAbsState[WACOMFIELD_PROXIMITY]. - nRow,gAbsState[WACOMFIELD_PROXIMITY].nCol*40+9,xchBuf); - wacscrn_normal(); - wacscrn_standout(); - snprintf(xchBuf,sizeof(xchBuf),"%-10s",xszTool[WACOMTOOLTYPE_PEN]); - wacscrn_output(gAbsState[WACOMFIELD_TOOLTYPE]. - nRow,gAbsState[WACOMFIELD_TOOLTYPE].nCol*40+9,xchBuf); - wacscrn_normal(); - } - - snprintf(xchBuf,sizeof(xchBuf),"%+06d (%+06d .. %+06d)", - gAbsState[uField].nValue, - gAbsState[uField].nMin, - gAbsState[uField].nMax); - } - - if (bBold) wacscrn_standout(); - wacscrn_output(gAbsState[uField].nRow,gAbsState[uField].nCol*40+9,xchBuf); - if (bBold) wacscrn_normal(); -} - -const char* GetSerialButton(unsigned int uButton) -{ - static const char* xszButton[WACOMBUTTON_MAX] = - { - "LEFT", "MIDDLE", "RIGHT", "EXTRA", "SIDE", - "TOUCH", "STYLUS", "STYLUS2", "BT0", "BT1", - "BT2", "BT3", "BT4", "BT5", "BT6", "BT7", - "BT8", "BT9", "BT10", "BT11", "BT12", "BT13", - "BT14", "BT15", "BT16", "BT17", "BT18", "BT19", - "BT20", "BT21", "BT22", "BT23" - }; - - return (uButton >= WACOMBUTTON_MAX) ? "FIELD?" : xszButton[uButton]; -} - -static void DisplaySerialButton(unsigned int uButton) -{ - int bDown; - static char xchBuf[256]; - if ((uButton >= WACOMBUTTON_MAX) || !gKeyState[uButton].bValid) - { - snprintf(xchBuf,sizeof(xchBuf),"Bad Button Code: 0x%X",uButton); - wacscrn_output(24,0,xchBuf); - return; - } - - bDown = gKeyState[uButton].nValue ? 1 : 0; - - snprintf(xchBuf,sizeof(xchBuf),"%8s=%s", - GetSerialButton(uButton), bDown ? "DOWN" : " "); - - if (bDown) wacscrn_standout(); - wacscrn_output(gKeyState[uButton].nRow,gKeyState[uButton].nCol*20,xchBuf); - wacscrn_normal(); -} - -void FetchTablet(WACOMTABLET hTablet) -{ - char chOut[128]; - unsigned char uchBuf[64]; - int i, nLength, nRow=gnSerialDataRow, nErrors=0; - WACOMSTATE state = WACOMSTATE_INIT; - - while (1) - { - wacscrn_refresh(); - - nLength = WacomReadRaw(hTablet,uchBuf,sizeof(uchBuf)); - if (nLength < 0) - { - snprintf(chOut,sizeof(chOut),"ReadRaw: %10d (%d)", - nLength,++nErrors); - wacscrn_output(22,0,chOut); - wacscrn_refresh(); - sleep(1); - continue; - } - - for (i=0; i<nLength; ++i) - { - snprintf(chOut,sizeof(chOut),"%02X",uchBuf[i]); - wacscrn_output(nRow,i*3,chOut); - } - for (i=0; i<nLength; ++i) - { - snprintf(chOut,sizeof(chOut),"%c",isprint(uchBuf[i]) ? - uchBuf[i] : '.'); - wacscrn_output(nRow,60 + i,chOut); - } - - if ((i=WacomParseData(hTablet,uchBuf,nLength,&state))) - { - snprintf(chOut,sizeof(chOut), - "ParseData: %10d %-40s (%d)", - i,strerror(errno),++nErrors); - wacscrn_output(23,0,chOut); - wacscrn_refresh(); - continue; - } - - for (i=WACOMFIELD_TOOLTYPE; i<WACOMFIELD_MAX; ++i) - { - if (state.uValid & BIT(i)) - { - if (i == WACOMFIELD_RELWHEEL) - gAbsState[i].nValue += state.values[i].nValue; - else - gAbsState[i].nValue = state.values[i].nValue; - DisplaySerialValue(i); - } - } - - for (i=WACOMBUTTON_LEFT; i<WACOMBUTTON_MAX; ++i) - { - gKeyState[i].nValue = state.values[WACOMFIELD_BUTTONS].nValue & - (1 << i) ? 1 : 0; - DisplaySerialButton(i); - } - } -} - -void LogCallback(struct timeval tv, WACOMLOGLEVEL level, const char* psz) -{ - int i; - struct tm* pTM; - - static const char* xszLog[WACOMLOGLEVEL_MAX] = - { - "", "CRITICAL", "ERROR", "WARN", - "INFO", "DEBUG", "TRACE" - }; - - if ((level < WACOMLOGLEVEL_CRITICAL) || (level >= WACOMLOGLEVEL_MAX)) - level = WACOMLOGLEVEL_NONE; - - /* get the time */ - pTM = localtime((time_t*)&tv.tv_sec); - - if (gbCursesRunning) - { - static char chBuf[1024]; - snprintf(chBuf,sizeof(chBuf),"%02d:%02d:%02d.%03d %s: %s", - pTM->tm_hour,pTM->tm_min,pTM->tm_min, - (int)(tv.tv_usec / 1000),xszLog[level],psz); - for (i=0; i<78; ++i) wacscrn_output(24,i," "); - wacscrn_output(24,0,chBuf); - wacscrn_refresh(); - } - else - { - fprintf(stderr,"%02d:%02d:%02d.%03d %s: %s\n", - pTM->tm_hour,pTM->tm_min,pTM->tm_min, - (int)(tv.tv_usec / 1000), xszLog[level], psz); - } - - if (gLogFile) - { - fprintf(gLogFile,"%02d:%02d:%02d.%03d %s: %s\n", - pTM->tm_hour,pTM->tm_min,pTM->tm_min, - (int)(tv.tv_usec / 1000), xszLog[level], psz); - fflush(gLogFile); - } -} - -int main(int argc, char** argv) -{ - const char* pszFile = NULL; - const char* arg; - WACOMENGINE hEngine = NULL; - WACOMTABLET hTablet = NULL; - int nLevel = (int)WACOMLOGLEVEL_WARN; - const char* pszDeviceCls = NULL; - const char* pszDeviceType = NULL; - const char* pszLogFile = NULL; - WACOMMODEL model = { 0 }; - - /* parse args */ - ++argv; - while (*argv) - { - arg = *(argv++); - - /* handle options */ - if (arg[0] == '-') - { - /* information */ - if ((strcmp(arg,"-h") == 0) || (strcmp(arg,"--help")==0)) - { Usage(); exit(0); } - if ((strcmp(arg,"-V") == 0) || (strcmp(arg,"--version")==0)) - { Version(); exit(0); } - else if ((strcmp(arg,"-l") == 0) || (strcmp(arg,"--list") == 0)) - { ListSupportedDevices(); exit(0); } - - /* force device type */ - else if ((strcmp(arg,"-f") == 0) || (strcmp(arg,"--force") == 0)) - { - arg = *(argv++); - if (arg == NULL) - { fprintf(stderr,"Missing device\n"); exit(1); } - pszDeviceType = arg; - } - - /* serial and usb class overrides */ - else if ((strcmp(arg,"-c") == 0) || (strcmp(arg,"--class") == 0)) - { - arg = *(argv++); - if (arg == NULL) - { fprintf(stderr,"Missing class\n"); exit(1); } - pszDeviceCls = arg; - } - - /* log file */ - else if (strcmp(arg,"--logfile") == 0) - { - arg = *(argv++); - if (arg == NULL) - { fprintf(stderr,"Missing log file\n"); exit(1); } - pszLogFile = arg; - } - else if ((strcmp(arg,"-v") == 0) || (strcmp(arg,"--verbose") == 0)) - { - ++nLevel; - } - - /* unknown options */ - else - { fprintf(stderr,"Unknown option %s\n",arg); exit(1); } - } - - /* device name */ - else - { - if (pszFile) - { fprintf(stderr,"Extra argument %s\n",arg); exit(1); } - - pszFile = arg; - } - } - - /* check for device */ - if (!pszFile) - { - Usage(); - exit(1); - } - - /* check for log file */ - if (pszLogFile) - { - gLogFile = fopen(pszLogFile,"w"); - if (!gLogFile) - { - perror("failed to open log file for writing"); - exit(1); - } - } - - /* set device class, if provided */ - if (pszDeviceCls) - { - model.uClass = WacomGetClassFromName(pszDeviceCls); - if (!model.uClass) - { - fprintf(stderr, "Unrecognized class: %s\n",pszDeviceCls); - exit(1); - } - } - - /* set device type, if provided */ - if (pszDeviceType) - { - model.uDevice = WacomGetDeviceFromName(pszDeviceType,model.uClass); - if (!model.uDevice) - { - fprintf(stderr, "Unrecognized device: %s\n",pszDeviceType); - exit(1); - } - } - - /* open engine */ - hEngine = WacomInitEngine(); - if (!hEngine) - { - perror("failed to open tablet engine"); - exit(1); - } - - WacomSetLogFunc(hEngine,LogCallback); - WacomSetLogLevel(hEngine,(WACOMLOGLEVEL)nLevel); - - WacomLog(hEngine,WACOMLOGLEVEL_INFO,"Opening log"); - - /* open tablet */ - hTablet = WacomOpenTablet(hEngine,pszFile,&model); - if (!hTablet) - { - perror("WacomOpenTablet"); - exit(1); - } - - /* begin curses window mode */ - wacscrn_init(); - atexit(termscr); - - gbCursesRunning = 1; - - /* get device capabilities, build screen */ - if (InitTablet(hTablet)) - { - perror("InitTablet"); - WacomCloseTablet(hTablet); - exit(1); - } - - /* read, parse, and display */ - FetchTablet(hTablet); - - /* close device */ - WacomCloseTablet(hTablet); - WacomTermEngine(hEngine); - - /* close log file, if open */ - if (gLogFile) - fclose(gLogFile); - - return 0; -} diff --git a/src/util/wacomcfg.c b/src/util/wacomcfg.c deleted file mode 100755 index 9a53c85..0000000 --- a/src/util/wacomcfg.c +++ /dev/null @@ -1,512 +0,0 @@ -/***************************************************************************** -** wacomcfg.c -** -** Copyright (C) 2003-2004 - John E. Joganic -** Copyright (C) 2004-2008 - Ping Cheng -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -** REVISION HISTORY -** 2003-05-02 0.0.1 - JEJ - created -** 2004-05-28 0.0.2 - PC - updated WacomConfigListDevices -** 2005-06-10 0.0.3 - PC - updated for x86_64 -** 2005-10-24 0.0.4 - PC - Added Pad -** 2005-11-17 0.0.5 - PC - update mode code -** 2006-07-17 0.0.6 - PC - Exchange info directly with wacom_drv.o -** 2007-01-10 0.0.7 - PC - don't display uninitialized tools -** 2008-03-24 0.0.8 - PC - Added touch for serial TabletPC (ISDv4) -** 2008-07-31 0.0.9 - PC - Added patches from Danny Kukawka -** -****************************************************************************/ - -#include "../include/util-config.h" -#include "wacomcfg.h" -#include "../include/Xwacom.h" /* Hopefully it will be included in XFree86 someday, but - * in the meantime, we are expecting it in the local - * directory. */ - -#include <stdio.h> /* debugging only, we've got no business output text */ -#include <ctype.h> -#include <stdlib.h> -#include <stdarg.h> -#include <errno.h> -#include <string.h> -#include <memory.h> -#include <assert.h> - -WACOMDEVICETYPE mapStringToType (const char*); -#if WCM_XF86CONFIG - #include "xf86Parser.h" - - WACOMDEVICETYPE checkIfWacomDevice (XF86ConfigPtr, const char*); - XF86ConfigPtr readConfig (char *); - void VErrorF(const char*, va_list); - void ErrorF (const char*, ...); -#endif - -/***************************************************************************** -** Internal structures -*****************************************************************************/ - - -/***************************************************************************** -** Library operations -*****************************************************************************/ - -static int CfgError(WACOMCONFIG* pCfg, int err, const char* pszText) -{ - /* report error */ - if (pCfg->pfnError) - (*pCfg->pfnError)(err,pszText); - - /* set and return */ - errno = err; - return -1; -} - -static int CfgGetDevs(WACOMCONFIG* pCfg) -{ - /* request device list */ - pCfg->pDevs = XListInputDevices(pCfg->pDisp, - &pCfg->nDevCnt); - - if (!pCfg->pDevs) - return CfgError(pCfg,EIO,"CfgGetDevs: failed to get devices"); - - return 0; -} - -/***************************************************************************** -** Library initialization, termination -*****************************************************************************/ - -WACOMCONFIG * WacomConfigInit(Display* pDisplay, WACOMERRORFUNC pfnErrorHandler) -{ - WACOMCONFIG* pCfg; - int nMajor, nFEV, nFER; - - /* check for XInput extension */ - if (!XQueryExtension(pDisplay,INAME,&nMajor,&nFEV,&nFER)) - { - if (pfnErrorHandler) - (*pfnErrorHandler)(EINVAL,"XInput not supported."); - return NULL; - } - - /* allocate configuration structure */ - pCfg = (WACOMCONFIG*)malloc(sizeof(WACOMCONFIG)); - if (!pCfg) - { - if (pfnErrorHandler) - (*pfnErrorHandler)(errno,strerror(errno)); - return NULL; - } - - memset(pCfg,0,sizeof(*pCfg)); - pCfg->pDisp = pDisplay; - pCfg->pfnError = pfnErrorHandler; - return pCfg; -} - -void WacomConfigTerm(WACOMCONFIG *hConfig) -{ - if (!hConfig) return; - free(hConfig); -} - -int WacomConfigListDevices(WACOMCONFIG *hConfig, WACOMDEVICEINFO** ppInfo, - unsigned int* puCount) -{ - int i, j, nSize, nPos, nLen, nCount; - unsigned char* pReq; - WACOMDEVICEINFO* pInfo; - XDeviceInfo* info; -#if WCM_XF86CONFIG - XF86ConfigPtr conf; -#endif - char devName[64]; - - if (!hConfig || !ppInfo || !puCount) - { errno=EINVAL; return -1; } - - /* load devices, if not already in memory */ - if (!hConfig->pDevs && CfgGetDevs(hConfig)) - return -1; - -#if WCM_XF86CONFIG - /* read the config in for wacom devices which don't use the commnon identifier */ - #if WCM_XORG - conf = readConfig ("/etc/X11/xorg.conf"); - #else - conf = readConfig ("/etc/X11/XF86Config"); - #endif -#endif - - /* estimate size of memory needed to hold structures */ - nSize = nCount = 0; - for (i=0; i<hConfig->nDevCnt; ++i) - { - info = hConfig->pDevs + i; -#ifndef WCM_ISXEXTENSIONPOINTER - if (info->use != IsXExtensionDevice) continue; -#else - if (info->use != IsXExtensionDevice && info->use != IsXExtensionPointer - && info->use != IsXExtensionKeyboard) continue; -#endif - - if (!info->num_classes) continue; - nSize += sizeof(WACOMDEVICEINFO); - nSize += strlen(info->name) + 1; - ++nCount; - } - - /* allocate memory and zero */ - pReq = (unsigned char*)malloc(nSize); - if (!pReq) return CfgError(hConfig,errno, - "WacomConfigListDevices: failed to allocate memory"); - memset(pReq,0,nSize); - - /* populate data */ - pInfo = (WACOMDEVICEINFO*)pReq; - nPos = nCount * sizeof(WACOMDEVICEINFO); - nCount = 0; - for (i=0; i<hConfig->nDevCnt; ++i) - { - info = hConfig->pDevs + i; - /* ignore non-extension devices */ -#ifndef WCM_ISXEXTENSIONPOINTER - if (info->use != IsXExtensionDevice) continue; -#else - if (info->use != IsXExtensionDevice && info->use != IsXExtensionPointer - && info->use != IsXExtensionKeyboard) continue; -#endif - /* ignore uninitialized tools */ - if (!info->num_classes) continue; - /* copy name */ - nLen = strlen(info->name); - pInfo->pszName = (char*)(pReq + nPos); - memcpy(pReq+nPos,info->name,nLen+1); - nPos += nLen + 1; - /* guess type for now - discard unknowns */ - for (j=0; j<strlen(pInfo->pszName); j++) - devName[j] = tolower(pInfo->pszName[j]); - devName[j] = '\0'; - - pInfo->type = mapStringToType (devName); - -#if WCM_XF86CONFIG - if ( pInfo->type == WACOMDEVICETYPE_UNKNOWN ) - pInfo->type = checkIfWacomDevice (conf, pInfo->pszName); -#endif - - if ( pInfo->type != WACOMDEVICETYPE_UNKNOWN ) - { - ++pInfo; - ++nCount; - } - } - - /* double check our work */ - assert(nPos == nSize); - - *ppInfo = (WACOMDEVICEINFO*)pReq; - *puCount = nCount; - return 0; -} - -#if WCM_XF86CONFIG -WACOMDEVICETYPE checkIfWacomDevice (XF86ConfigPtr conf, const char* pszDeviceName) { - XF86ConfInputPtr ip; - - if (!conf || !pszDeviceName) { return WACOMDEVICETYPE_UNKNOWN; } - - ip = (XF86ConfInputPtr) conf->conf_input_lst; - if (!ip) { return WACOMDEVICETYPE_UNKNOWN; } - - for (;ip;ip=ip->list.next) - { - XF86OptionPtr op = (XF86OptionPtr) ip->inp_option_lst; - char* type = 0; - - if (!op) { return WACOMDEVICETYPE_UNKNOWN; } - - if (strcasecmp(ip->inp_identifier, pszDeviceName) != 0) - continue; - - if (strcasecmp(ip->inp_driver,"wacom") != 0) - continue; - - for (;op;op=op->list.next) - { - if (strcasecmp(op->opt_name,"Type") == 0) - { - type = op->opt_val; - return mapStringToType(type); - } - } - } - - return WACOMDEVICETYPE_UNKNOWN; -} -#endif - -WACOMDEVICETYPE mapStringToType (const char* name) -{ - if (!name) - return WACOMDEVICETYPE_UNKNOWN; - - /* No spaces are allowed in Wacom device identifiers */ - if (strstr(name," ") != NULL) - return WACOMDEVICETYPE_UNKNOWN; - if (strstr(name,"cursor") != NULL) - return WACOMDEVICETYPE_CURSOR; - else if (strstr(name,"stylus") != NULL) - return WACOMDEVICETYPE_STYLUS; - else if (strstr(name,"eraser") != NULL) - return WACOMDEVICETYPE_ERASER; - else if (strstr(name,"touch") != NULL) - return WACOMDEVICETYPE_TOUCH; - else if (strstr(name,"pad") != NULL) - return WACOMDEVICETYPE_PAD; - else - return WACOMDEVICETYPE_UNKNOWN; - -} - -WACOMDEVICE * WacomConfigOpenDevice(WACOMCONFIG * hConfig, - const char* pszDeviceName) -{ - int i; - WACOMDEVICE* pInt; - XDevice* pDev; - XDeviceInfo *pDevInfo = NULL, *info; - - /* sanity check input */ - if (!hConfig || !pszDeviceName) { errno=EINVAL; return NULL; } - - /* load devices, if not already in memory */ - if (!hConfig->pDevs && CfgGetDevs(hConfig)) - return NULL; - - /* find device in question */ - for (i=0; i<hConfig->nDevCnt; ++i) - { - info = hConfig->pDevs + i; - if (!strcmp(info->name, pszDeviceName) && info->num_classes) - pDevInfo = info; - } - - /* no device, bail. */ - if (!pDevInfo) - { - CfgError(hConfig,ENOENT,"WacomConfigOpenDevice: No such device"); - return NULL; - } - - /* Open the device. */ - pDev = XOpenDevice(hConfig->pDisp,pDevInfo->id); - if (!pDev) - { - CfgError(hConfig,EIO,"WacomConfigOpenDevice: " - "Failed to open device"); - return NULL; - } - - /* allocate device structure and return */ - pInt = (WACOMDEVICE*)malloc(sizeof(WACOMDEVICE)); - memset(pInt,0,sizeof(*pInt)); - pInt->pCfg = hConfig; - pInt->pDev = pDev; - - return pInt; -} - -int WacomConfigCloseDevice(WACOMDEVICE *hDevice) -{ - if (!hDevice) { errno=EINVAL; return -1; } - - if (hDevice->pDev) - XFree(hDevice->pDev); - free(hDevice); - return 0; -} - -int WacomConfigSetRawParam(WACOMDEVICE *hDevice, int nParam, int nValue, unsigned * keys) -{ - int nReturn, i; - int nValues[2]; - XDeviceResolutionControl c; - XDeviceControl *dc = (XDeviceControl *)(void *)&c; - - nValues[0] = nParam; - nValues[1] = nValue; - if (!hDevice || !nParam) { errno=EINVAL; return -1; } - - c.control = DEVICE_RESOLUTION; - c.length = sizeof(c); - c.first_valuator = 0; - c.num_valuators = 2; - c.resolutions = nValues; - /* Dispatch request */ - nReturn = XChangeDeviceControl (hDevice->pCfg->pDisp, hDevice->pDev, - DEVICE_RESOLUTION, dc); - - /* Convert error codes: - * hell knows what XChangeDeviceControl should return */ - if (nReturn == BadValue || nReturn == BadRequest) - return CfgError(hDevice->pCfg,EINVAL, - "WacomConfigSetRawParam: failed"); - - if (nParam >= XWACOM_PARAM_BUTTON1 && nParam <= XWACOM_PARAM_STRIPRDN) - { - for (i=1; i<((nValue & AC_NUM_KEYS)>>20); i += 2) - { - nValues[1] = keys[i] | (keys[i+1]<<16); - nReturn = XChangeDeviceControl (hDevice->pCfg->pDisp, hDevice->pDev, - DEVICE_RESOLUTION, dc); - - if (nReturn == BadValue || nReturn == BadRequest) - return CfgError(hDevice->pCfg,EINVAL, - "WacomConfigSetRawParam: keystroke failed"); - } - } - - if (nParam == XWACOM_PARAM_MODE) - { - /* tell Xinput the mode has been changed */ - XSetDeviceMode(hDevice->pCfg->pDisp, hDevice->pDev, nValue); - } - return 0; -} - -int WacomConfigGetRawParam(WACOMDEVICE *hDevice, int nParam, int *nValue, int valu, unsigned * keys) -{ - int nReturn, i; - XDeviceResolutionControl c; - XDeviceResolutionState *ds; - int nValues[1]; - - if (!hDevice || !nParam) { errno=EINVAL; return -1; } - - nValues[0] = nParam; - - c.control = DEVICE_RESOLUTION; - c.length = sizeof(c); - c.first_valuator = 0; - c.num_valuators = valu; - c.resolutions = nValues; - /* Dispatch request */ - nReturn = XChangeDeviceControl(hDevice->pCfg->pDisp, hDevice->pDev, - DEVICE_RESOLUTION, (XDeviceControl *)(void *)&c); - - if (nReturn == BadValue || nReturn == BadRequest) - { -error: return CfgError(hDevice->pCfg, EINVAL, - "WacomConfigGetRawParam: failed"); - } - - ds = (XDeviceResolutionState *)XGetDeviceControl (hDevice->pCfg->pDisp, - hDevice->pDev, DEVICE_RESOLUTION); - - if (!ds) - goto error; - - *nValue = ds->resolutions [ds->num_valuators-1]; - - if (nParam >= XWACOM_PARAM_BUTTON1 && nParam <= XWACOM_PARAM_STRIPRDN) - { - int num = (*nValue & AC_NUM_KEYS)>>20; - if (num) keys[0] = ((*nValue) & AC_CODE); - - for (i=1; i<num; i += 2) - { - nReturn = XChangeDeviceControl(hDevice->pCfg->pDisp, - hDevice->pDev, DEVICE_RESOLUTION, - (XDeviceControl *)(void *)&c); - - if (nReturn == BadValue || nReturn == BadRequest) - { -errork: return CfgError(hDevice->pCfg, EINVAL, - "WacomConfigGetRawParam: keystroke failed"); - } - - ds = (XDeviceResolutionState *)XGetDeviceControl (hDevice->pCfg->pDisp, - hDevice->pDev, DEVICE_RESOLUTION); - if (!ds) - goto errork; - - keys[i] = ds->resolutions [ds->num_valuators-1] & 0xffff; - keys[i+1] = ((ds->resolutions [ds->num_valuators-1] & 0xffff0000)>>16); - } - } - - /* Restore resolution */ - nValues [0] = 0; - XChangeDeviceControl(hDevice->pCfg->pDisp, hDevice->pDev, - DEVICE_RESOLUTION, (XDeviceControl *)(void *)&c); - - XFreeDeviceControl ((XDeviceControl *)ds); - - return 0; -} - -void WacomConfigFree(void* pvData) -{ - /* JEJ - if in the future, more context is needed, make an alloc - * function that places the context before the data. - * In the meantime, free is good enough. */ - - free(pvData); -} - -#if WCM_XF86CONFIG -XF86ConfigPtr readConfig (char *filename) -{ - XF86ConfigPtr conf = 0; - const char *file = 0; - char CONFPATH[]= "%A,%R,/etc/%R,%P/etc/X11/%R,%E,%F,/etc/X11/%F," \ - "%P/etc/X11/%F,%D/%X,/etc/X11/%X,/etc/%X,%P/etc/X11/%X.%H," \ - "%P/etc/X11/%X,%P/lib/X11/%X.%H,%P/lib/X11/%X"; - - if (!(file = (char*)xf86openConfigFile (CONFPATH, filename, 0))) - { - fprintf (stderr, "Unable to open config file\n"); - return 0; - } - - if ((conf = (XF86ConfigPtr)xf86readConfigFile ()) == 0) - { - fprintf (stderr, "Problem when parsing config file\n"); - xf86closeConfigFile (); - return 0; - } - - xf86closeConfigFile (); - return conf; -} - -void VErrorF(const char *f, va_list args) -{ - vfprintf(stderr, f, args); -} - -void ErrorF(const char *f, ...) -{ - va_list args; - va_start(args, f); - vfprintf(stderr, f, args); - va_end(args); -} -#endif diff --git a/src/util/wacomcfg.h b/src/util/wacomcfg.h deleted file mode 100755 index 03528df..0000000 --- a/src/util/wacomcfg.h +++ /dev/null @@ -1,138 +0,0 @@ -/***************************************************************************** -** wacomcfg.h -** -** Copyright (C) 2003 - John E. Joganic -** Copyright (C) 2004-2008 - Ping Cheng -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -****************************************************************************/ - -#ifndef __LINUXWACOM_WACOMCFG_H -#define __LINUXWACOM_WACOMCFG_H - -#include <X11/Xlib.h> -#include <X11/extensions/XInput.h> -#include <X11/extensions/XIproto.h> - -/* JEJ - NOTE WE DO NOT INCLUDE Xwacom.h HERE. THIS ELIMINATES A CONFLICT - * WHEN THIS FILE IS INSTALLED SINCE Xwacom.h WILL IN MANY CASES NOT - * GO WITH IT. SOMEDAY IT MAY BE PART OF XFREE86. */ - -typedef struct _WACOMCONFIG WACOMCONFIG; -typedef struct _WACOMDEVICE WACOMDEVICE; -typedef void (*WACOMERRORFUNC)(int err, const char* pszText); -typedef struct _WACOMDEVICEINFO WACOMDEVICEINFO; - -typedef enum -{ - WACOMDEVICETYPE_UNKNOWN, - WACOMDEVICETYPE_CURSOR, - WACOMDEVICETYPE_STYLUS, - WACOMDEVICETYPE_ERASER, - WACOMDEVICETYPE_PAD, - WACOMDEVICETYPE_TOUCH, - WACOMDEVICETYPE_MAX -} WACOMDEVICETYPE; - -struct _WACOMDEVICEINFO -{ - const char* pszName; - WACOMDEVICETYPE type; -}; - -struct _WACOMCONFIG -{ - Display* pDisp; - WACOMERRORFUNC pfnError; - XDeviceInfo * pDevs; - int nDevCnt; -}; - -struct _WACOMDEVICE -{ - WACOMCONFIG* pCfg; - XDevice* pDev; -}; - - -/***************************************************************************** -** Functions -*****************************************************************************/ - -WACOMCONFIG * WacomConfigInit(Display* pDisplay, WACOMERRORFUNC pfnErrorHandler); -/* Initializes configuration library. - * pDisplay - display to configure - * pfnErrorHandler - handler to which errors are reported; may be NULL - * Returns WACOMCONFIG handle on success, NULL on error. - * errno contains error code. */ - -void WacomConfigTerm(WACOMCONFIG * hConfig); -/* Terminates configuration library, releasing display. */ - -int WacomConfigListDevices(WACOMCONFIG * hConfig, WACOMDEVICEINFO** ppInfo, - unsigned int* puCount); -/* Returns a list of wacom devices. - * ppInfo - pointer to WACOMDEVICEINFO* to receive device data - * puSize - pointer to receive device count - * Returns 0 on success, -1 on failure. errno contains error code. - * Comments: You must free this structure using WacomConfigFree. */ - -WACOMDEVICE * WacomConfigOpenDevice(WACOMCONFIG * hConfig, - const char* pszDeviceName); -/* Open a device by name. - * pszDeviceName - name of XInput device corresponding to wacom device - * Returns handle to device on success, NULL on error. - * errno contains error code. - * Comments: Close using WacomConfigCloseDevice */ - -int WacomConfigCloseDevice(WACOMDEVICE * hDevice); -/* Closes a device. - * Returns 0 on success, -1 on error. errno contains error code. */ - -int WacomConfigSetRawParam(WACOMDEVICE * hDevice, int nParam, int nValue, unsigned * keys); -/* Sets the raw device parameter to specified value. - * nParam - valid paramters can be found Xwacom.h which is not - * automatically included. - * nValue - 32 bit integer value - * keys - an array of keys and modifiers - * Returns 0 on success, -1 on error. errno contains error code. - * EINVAL - invalid parameter or value - * EIO - unknown X failure, use XSetErrorHandler to capture complete - * error code and message - * Comments: Data is sent to wacom_drv module without any error checking. - * Generally, you should use the more specific handler functions in this - * library, but for some parameters, particularly experimental ones, you - * will probably have to set them directly. */ - -int WacomConfigGetRawParam(WACOMDEVICE *hDevice, int nParam, int *nValue, int valu, unsigned * keys); -/* Gets the raw device parameter. - * nParam - valid paramters can be found Xwacom.h which is not - * automatically included. - * nValue - the device parameter is returned in the integer - * pointed by this parameter. - * valu - calling valuator value: 1: Get 3: GetDefault - * keys - an array of keys and modifiers - * Returns 0 on success, -1 on error. errno contains error code. - * EINVAL - invalid parameter or value - * EIO - unknown X failure, use XSetErrorHandler to capture complete - * error code and message - */ - -void WacomConfigFree(void* pvData); -/* Frees memory allocated by library. */ - -#endif /* __LINUXWACOM_WACOMCFG_H */ - diff --git a/src/util/wacscrn.c b/src/util/wacscrn.c deleted file mode 100755 index 79dd11b..0000000 --- a/src/util/wacscrn.c +++ /dev/null @@ -1,45 +0,0 @@ -/***************************************************************************** -** wacscrn.c -** -** Copyright (C) 2002 - John E. Joganic -** -** 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 Lesser 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -****************************************************************************/ - -#include "../include/util-config.h" - -#include <stdio.h> -#include <stdlib.h> - -#if WCM_ENABLE_NCURSES -#include <ncurses.h> - -/****************************************************************************/ - -void wacscrn_init(void) - { initscr(); } -void wacscrn_term(void) - { endwin(); } -void wacscrn_output(int y, int x, const char* pszText) - { mvaddstr(y,x,pszText); } -void wacscrn_standout(void) - { attron(A_STANDOUT); } -void wacscrn_normal(void) - { attrset(A_NORMAL); } -void wacscrn_refresh(void) - { refresh(); } - -#endif /* WCM_ENABLE_NCURSES */ diff --git a/src/util/wacscrn.h b/src/util/wacscrn.h deleted file mode 100755 index ba33f01..0000000 --- a/src/util/wacscrn.h +++ /dev/null @@ -1,32 +0,0 @@ -/***************************************************************************** -** wacscrn.h -** -** Copyright (C) 2002 - John E. Joganic -** -** 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 Lesser 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -****************************************************************************/ - -#ifndef __WACPACK_WACSCRN_H -#define __WACPACK_WACSCRN_H - -void wacscrn_init(void); -void wacscrn_term(void); -void wacscrn_output(int y, int x, const char* pszText); -void wacscrn_standout(void); -void wacscrn_normal(void); -void wacscrn_refresh(void); - -#endif /* __WACPACK_WACSCRN_H */ diff --git a/src/util/wacserial.c b/src/util/wacserial.c deleted file mode 100755 index 0833ca2..0000000 --- a/src/util/wacserial.c +++ /dev/null @@ -1,1711 +0,0 @@ -/***************************************************************************** -** wacserial.c -** -** Copyright (C) 2002, 2003 - John E. Joganic -** Copyright (C) 2002 - 2008 - Ping Cheng -** -** 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 Lesser 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -****************************************************************************/ - -#include "wacserial.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <termios.h> -#include <ctype.h> -#include <unistd.h> -#include <assert.h> - -/***************************************************************************** -** Serial Tablet Object -*****************************************************************************/ - -typedef struct _SERIALTABLET SERIALTABLET; -typedef struct _SERIALSUBTYPE SERIALSUBTYPE; -typedef struct _SERIALDEVICE SERIALDEVICE; -typedef struct _SERIALVENDOR SERIALVENDOR; - -typedef int (*IDENTFUNC)(SERIALTABLET* pSerial); -typedef int (*INITFUNC)(SERIALTABLET* pSerial); -typedef int (*PARSEFUNC)(SERIALTABLET* pSerial, const unsigned char* puchData, - unsigned int uLength, WACOMSTATE* pState); - -struct _SERIALTABLET -{ - WACOMTABLET_PRIV tablet; - WACOMENGINE hEngine; - int fd; - SERIALVENDOR* pVendor; - SERIALDEVICE* pDevice; - SERIALSUBTYPE* pSubType; - unsigned int uPacketLength; - int nVerMajor, nVerMinor, nVerRelease; - IDENTFUNC pfnIdent; - INITFUNC pfnInit; - PARSEFUNC pfnParse; - int nToolID; - WACOMSTATE state; - int nBitErrors; - WACOMMODEL modelRequested; -}; - -/***************************************************************************** -** Internal structures -*****************************************************************************/ - -struct _SERIALSUBTYPE -{ - const char* pszName; - const char* pszDesc; - unsigned int uSubType; - const char* pszIdent; - INITFUNC pfnInit; -}; - -struct _SERIALDEVICE -{ - const char* pszName; - const char* pszDesc; - unsigned int uDevice; - SERIALSUBTYPE* pSubTypes; - int nProtocol; - unsigned int uPacketLength; - unsigned int uCaps; - int nMinBaudRate; - IDENTFUNC pfnIdent; -}; - -struct _SERIALVENDOR -{ - const char* pszName; - const char* pszDesc; - unsigned int uVendor; - SERIALDEVICE* pDevices; -}; - -/***************************************************************************** -** Static operations -*****************************************************************************/ - -static void SerialClose(WACOMTABLET_PRIV* pTablet); -static WACOMMODEL SerialGetModel(WACOMTABLET_PRIV* pTablet); -static const char* SerialGetVendorName(WACOMTABLET_PRIV* pTablet); -static const char* SerialGetClassName(WACOMTABLET_PRIV* pTablet); -static const char* SerialGetDeviceName(WACOMTABLET_PRIV* pTablet); -static const char* SerialGetSubTypeName(WACOMTABLET_PRIV* pTablet); -static const char* SerialGetModelName(WACOMTABLET_PRIV* pTablet); -static int SerialGetROMVer(WACOMTABLET_PRIV* pTablet, int* pnMajor, - int* pnMinor, int* pnRelease); -static int SerialGetCaps(WACOMTABLET_PRIV* pTablet); -static int SerialGetState(WACOMTABLET_PRIV* pTablet, WACOMSTATE* pState); -static int SerialGetFD(WACOMTABLET_PRIV* pTablet); -static int SerialReadRaw(WACOMTABLET_PRIV* pTablet, unsigned char* puchData, - unsigned int uSize); -static int SerialParseData(WACOMTABLET_PRIV* pTablet, - const unsigned char* puchData, unsigned int uLength, - WACOMSTATE* pState); - -static int SerialReset(SERIALTABLET* pSerial, WACOMMODEL* pModel); -static int SerialConfigTTY(SERIALTABLET* pSerial); -static int SerialResetAtBaud(SERIALTABLET* pSerial, struct termios* pTIOS, - int nBaud); -static int SerialSetDevice(SERIALTABLET* pSerial, SERIALVENDOR* pVendor, - SERIALDEVICE* pDevice, SERIALSUBTYPE* pSubType); - -static int SerialIdentDefault(SERIALTABLET* pSerial); -static int SerialIdentTabletPC(SERIALTABLET* pSerial); -static int SerialInitTabletPC(SERIALTABLET* pSerial); -static int SerialIdentWacom(SERIALTABLET* pSerial); -static int SerialInitWacom(SERIALTABLET* pSerial); - -static int SerialParseWacomV(SERIALTABLET* pSerial, - const unsigned char* puchData, unsigned int uLength, - WACOMSTATE* pState); -static int SerialParseWacomIV_1_4(SERIALTABLET* pSerial, - const unsigned char* puchData, unsigned int uLength, - WACOMSTATE* pState); -static int SerialParseWacomIV_1_3(SERIALTABLET* pSerial, - const unsigned char* puchData, unsigned int uLength, - WACOMSTATE* pState); -static int SerialParseWacomIV_1_2(SERIALTABLET* pSerial, - const unsigned char* puchData, unsigned int uLength, - WACOMSTATE* pState); -static int SerialParseTabletPC(SERIALTABLET* pSerial, - const unsigned char* puchData, unsigned int uLength, - WACOMSTATE* pState); - -static void SerialError(SERIALTABLET* pSerial, const char* pszFmt, ...); -static void SerialWarn(SERIALTABLET* pSerial, const char* pszFmt, ...); -static void SerialInfo(SERIALTABLET* pSerial, const char* pszFmt, ...); -static void SerialDump(SERIALTABLET* pSerial, const void* pvData, int nCnt); -/* NOT USED, YET -static void SerialCritical(SERIALTABLET* pSerial, const char* pszFmt, ...); -static void SerialDebug(SERIALTABLET* pSerial, const char* pszFmt, ...); -static void SerialTrace(SERIALTABLET* pSerial, const char* pszFmt, ...); -*/ - -/***************************************************************************** -** Defines -*****************************************************************************/ - -#ifndef BIT -#undef BIT -#define BIT(x) (1<<(x)) -#endif - -#define WACOMVALID(x) BIT(WACOMFIELD_##x) - -#define ARTPAD_CAPS (WACOMVALID(TOOLTYPE)|WACOMVALID(PROXIMITY)| \ - WACOMVALID(BUTTONS)|WACOMVALID(POSITION_X)|WACOMVALID(POSITION_Y)| \ - WACOMVALID(PRESSURE)) - -#define ARTPADII_CAPS (WACOMVALID(TOOLTYPE)|WACOMVALID(PROXIMITY)| \ - WACOMVALID(BUTTONS)|WACOMVALID(POSITION_X)|WACOMVALID(POSITION_Y)| \ - WACOMVALID(PRESSURE)) - -#define DIGITIZER_CAPS (WACOMVALID(TOOLTYPE)|WACOMVALID(PROXIMITY)| \ - WACOMVALID(BUTTONS)|WACOMVALID(POSITION_X)|WACOMVALID(POSITION_Y)| \ - WACOMVALID(PRESSURE)|WACOMVALID(TILT_X)|WACOMVALID(TILT_Y)) - -#define DIGITIZERII_CAPS (WACOMVALID(TOOLTYPE)|WACOMVALID(PROXIMITY)| \ - WACOMVALID(BUTTONS)|WACOMVALID(POSITION_X)|WACOMVALID(POSITION_Y)| \ - WACOMVALID(PRESSURE)|WACOMVALID(TILT_X)|WACOMVALID(TILT_Y)) - -#define PENPARTNER_CAPS (WACOMVALID(TOOLTYPE)|WACOMVALID(PROXIMITY)| \ - WACOMVALID(BUTTONS)|WACOMVALID(POSITION_X)|WACOMVALID(POSITION_Y)| \ - WACOMVALID(PRESSURE)) - -#define GRAPHIRE_CAPS (WACOMVALID(TOOLTYPE)|WACOMVALID(PROXIMITY)| \ - WACOMVALID(BUTTONS)|WACOMVALID(POSITION_X)|WACOMVALID(POSITION_Y)| \ - WACOMVALID(PRESSURE)|WACOMVALID(TILT_X)|WACOMVALID(TILT_Y)) - -#define CINTIQ_CAPS (WACOMVALID(TOOLTYPE)|WACOMVALID(PROXIMITY)| \ - WACOMVALID(BUTTONS)|WACOMVALID(POSITION_X)|WACOMVALID(POSITION_Y)| \ - WACOMVALID(PRESSURE)|WACOMVALID(TILT_X)|WACOMVALID(TILT_Y)) - -#define INTUOS_CAPS (WACOMVALID(TOOLTYPE)|WACOMVALID(SERIAL)| \ - WACOMVALID(PROXIMITY)|WACOMVALID(BUTTONS)|WACOMVALID(POSITION_X)| \ - WACOMVALID(POSITION_Y)|WACOMVALID(ROTATION_Z)|WACOMVALID(DISTANCE)| \ - WACOMVALID(PRESSURE)|WACOMVALID(TILT_X)|WACOMVALID(TILT_Y)| \ - WACOMVALID(ABSWHEEL)|WACOMVALID(RELWHEEL)|WACOMVALID(THROTTLE)) - -#define TABLETPC_CAPS (WACOMVALID(TOOLTYPE)|WACOMVALID(SERIAL)| \ - WACOMVALID(PROXIMITY)|WACOMVALID(BUTTONS)|WACOMVALID(POSITION_X)| \ - WACOMVALID(POSITION_Y)|WACOMVALID(PRESSURE)) - -#define INTUOS2_CAPS INTUOS_CAPS - -#define PROTOCOL_4 4 -#define PROTOCOL_5 5 - -#define WACOM_SUBTYPE(id,d,s) \ - { id, d, s, id, SerialInitWacom } -#define TPC_SUBTYPE(id,d,s) \ - { id, d, s, id, SerialInitTabletPC } - -#define WACOM_DEVICE_P4(n,d,i,s,c) \ - { n, d, i, s, PROTOCOL_4, 7, c, 9600, SerialIdentWacom } -#define WACOM_DEVICE_P5(n,d,i,s,c) \ - { n, d, i, s, PROTOCOL_5, 9, c, 9600, SerialIdentWacom } -#define TPC_DEVICE(n,d,i,s,c) \ - { n, d, i, s, 0, 9, c, 19200, SerialIdentTabletPC } - -/***************************************************************************** -** Globals -*****************************************************************************/ - - static SERIALSUBTYPE xArtPadII[] = - { - WACOM_SUBTYPE("KT-0405-R", "Wacom ArtPadII 4x5", 1), - { NULL } - }; - - static SERIALSUBTYPE xDigitizerII[] = - { - WACOM_SUBTYPE("UD-0608-R", "Wacom DigitizerII 6x8", 1), - WACOM_SUBTYPE("UD-1212-R", "Wacom DigitizerII 12x12", 2), - WACOM_SUBTYPE("UD-1218-R", "Wacom DigitizerII 12x18", 3), - WACOM_SUBTYPE("UD-1825-R", "Wacom DigitizerII 18x25", 4), - { NULL } - }; - - static SERIALSUBTYPE xPenPartner[] = - { - WACOM_SUBTYPE("CT-0405-R", "Wacom PenPartner", 1), - { NULL } - }; - - static SERIALSUBTYPE xGraphire[] = - { - WACOM_SUBTYPE("ET-0405-R", "Wacom Graphire", 1), - { NULL } - }; - - static SERIALSUBTYPE xIntuos[] = - { - WACOM_SUBTYPE("GD-0405-R", "Wacom Intuos 4x5", 1), - WACOM_SUBTYPE("GD-0608-R", "Wacom Intuos 6x8", 2), - WACOM_SUBTYPE("GD-0912-R", "Wacom Intuos 9x12", 3), - WACOM_SUBTYPE("GD-1212-R", "Wacom Intuos 12x12", 4), - WACOM_SUBTYPE("GD-1218-R", "Wacom Intuos 12x18", 5), - { NULL } - }; - - static SERIALSUBTYPE xIntuos2[] = - { - WACOM_SUBTYPE("XD-0405-R", "Wacom Intuos2 4x5", 1), - WACOM_SUBTYPE("XD-0608-R", "Wacom Intuos2 6x8", 2), - WACOM_SUBTYPE("XD-0912-R", "Wacom Intuos2 9x12", 3), - WACOM_SUBTYPE("XD-1212-R", "Wacom Intuos2 12x12", 4), - WACOM_SUBTYPE("XD-1218-R", "Wacom Intuos2 12x18", 5), - { NULL } - }; - - static SERIALSUBTYPE xCintiq[] = - { - WACOM_SUBTYPE("PL-250", "Wacom PL-250", 1), - WACOM_SUBTYPE("PL-270", "Wacom PL-270", 2), - WACOM_SUBTYPE("PL-400", "Wacom PL-400", 3), - WACOM_SUBTYPE("PL-500", "Wacom PL-500", 4), - WACOM_SUBTYPE("PL-550", "Wacom PL-550", 5), - WACOM_SUBTYPE("PL-600", "Wacom PL-600", 6), - WACOM_SUBTYPE("PL-600SX", "Wacom PL-600SX", 7), - WACOM_SUBTYPE("PL-800", "Wacom PL-800", 8), - { NULL } - }; - - static SERIALDEVICE xWacomDevices[] = - { - WACOM_DEVICE_P4("art", "ArtPad", WACOMDEVICE_ARTPAD, - NULL, ARTPAD_CAPS), - WACOM_DEVICE_P4("art2", "ArtPadII", WACOMDEVICE_ARTPADII, - xArtPadII, ARTPADII_CAPS), - WACOM_DEVICE_P4("dig", "Digitizer", WACOMDEVICE_DIGITIZER, - NULL, DIGITIZERII_CAPS), - WACOM_DEVICE_P4("dig2", "Digitizer II", WACOMDEVICE_DIGITIZERII, - xDigitizerII, DIGITIZERII_CAPS), - WACOM_DEVICE_P4("pp", "PenPartner", WACOMDEVICE_PENPARTNER, - xPenPartner, PENPARTNER_CAPS), - WACOM_DEVICE_P4("gr", "Graphire", WACOMDEVICE_GRAPHIRE, - xGraphire, GRAPHIRE_CAPS), - WACOM_DEVICE_P4("pl", "Cintiq (PL)", WACOMDEVICE_CINTIQ, - xCintiq, CINTIQ_CAPS), - WACOM_DEVICE_P5("int", "Intuos", WACOMDEVICE_INTUOS, - xIntuos, INTUOS_CAPS), - WACOM_DEVICE_P5("int2", "Intuos2", WACOMDEVICE_INTUOS2, - xIntuos2, INTUOS2_CAPS), - { NULL } - }; - - /* This one is reverse engineered at this point */ - static SERIALSUBTYPE xTabletPC[] = - { - TPC_SUBTYPE("tpc", "Tablet PC Screen", 1), - { NULL } - }; - - static SERIALDEVICE xtpcDevices[] = - { - TPC_DEVICE("tpc", "TabletPC", WACOMDEVICE_TPC, - xTabletPC, TABLETPC_CAPS), - { NULL } - }; - - static SERIALVENDOR xWacomVendor = - { "wacom", "Wacom", WACOMVENDOR_WACOM, xWacomDevices }; - - static SERIALVENDOR xtpcVendor = - { "Wacom", "Wacom", WACOMVENDOR_TPC, xtpcDevices }; - - static SERIALVENDOR* xVendors[] = - { - &xWacomVendor, - &xtpcVendor, - NULL - }; - -/***************************************************************************** -** Static Prototypes -*****************************************************************************/ - -static int SerialSendReset(SERIALTABLET* pSerial); -static int SerialSendStop(SERIALTABLET* pSerial); -static int SerialSendStart(SERIALTABLET* pSerial); - -static int SerialSend(SERIALTABLET* pSerial, const char* pszData); -static int SerialSendRaw(SERIALTABLET* pSerial, const void* pvData, - unsigned int uSize); -static int WacomFlush(SERIALTABLET* pSerial); -static int SerialSendRequest(SERIALTABLET* pSerial, const char* pszRequest, - char* pchResponse, unsigned int uSize); - -/***************************************************************************** -** Public Functions -*****************************************************************************/ - -typedef struct -{ - void (*pfnFree)(void* pv); -} DEVLIST_INTERNAL; - -static void SerialFreeDeviceList(void* pv) -{ - DEVLIST_INTERNAL* pInt = ((DEVLIST_INTERNAL*)pv) - 1; - free(pInt); -} - -int WacomGetSupportedSerialDeviceList(WACOMDEVICEREC** ppList, int* pnSize) -{ - int nIndex=0, nCnt=0; - DEVLIST_INTERNAL* pInt; - SERIALDEVICE* pDev; - SERIALVENDOR** ppVendor; - WACOMDEVICEREC* pRec; - - if (!ppList || !pnSize) { errno = EINVAL; return 1; } - - /* for each vendor, count up devices */ - for (ppVendor=xVendors; *ppVendor; ++ppVendor) - { - /* count up devices */ - for (pDev=(*ppVendor)->pDevices; pDev->pszName; ++pDev, ++nCnt) ; - } - - /* allocate enough memory to hold internal structure and all records */ - pInt = (DEVLIST_INTERNAL*)malloc(sizeof(DEVLIST_INTERNAL) + - (sizeof(WACOMDEVICEREC) * nCnt)); - - pInt->pfnFree = SerialFreeDeviceList; - pRec = (WACOMDEVICEREC*)(pInt + 1); - - /* for each vendor, add devices */ - for (ppVendor=xVendors; *ppVendor; ++ppVendor) - { - for (pDev=(*ppVendor)->pDevices; pDev->pszName; ++pDev, ++nIndex) - { - pRec[nIndex].pszName = pDev->pszName; - pRec[nIndex].pszDesc = pDev->pszDesc; - pRec[nIndex].pszVendorName = (*ppVendor)->pszName; - pRec[nIndex].pszVendorDesc = (*ppVendor)->pszDesc; - pRec[nIndex].pszClass = "serial"; - pRec[nIndex].model.uClass = WACOMCLASS_SERIAL; - pRec[nIndex].model.uVendor = (*ppVendor)->uVendor; - pRec[nIndex].model.uDevice = pDev->uDevice; - pRec[nIndex].model.uSubType = 0; - } - } - assert(nIndex == nCnt); - - *ppList = pRec; - *pnSize = nCnt; - return 0; -} - -unsigned int WacomGetSerialDeviceFromName(const char* pszName) -{ - SERIALDEVICE* pDev; - SERIALVENDOR** ppVendor; - - if (!pszName) { errno = EINVAL; return 0; } - - /* for each vendor, look for device */ - for (ppVendor=xVendors; *ppVendor; ++ppVendor) - { - /* count up devices */ - for (pDev=(*ppVendor)->pDevices; pDev->pszName; ++pDev) - { - if (strcasecmp(pszName,pDev->pszName) == 0) - return pDev->uDevice; - } - } - - errno = ENOENT; - return 0; -} - -static int SerialFindModel(WACOMMODEL* pModel, SERIALVENDOR** ppVendor, - SERIALDEVICE** ppDevice, SERIALSUBTYPE** ppSubType) -{ - SERIALVENDOR** ppPos; - SERIALDEVICE* pDev; - SERIALSUBTYPE* pSub; - - /* device type must be specified */ - if (!pModel) - { errno = EINVAL; return 1; } - - /* no device specified, nothing found. */ - if (!pModel->uDevice) - { - *ppVendor = NULL; - *ppDevice = NULL; - *ppSubType = NULL; - return 0; - } - - /* for each vendor */ - for (ppPos=xVendors; *ppPos; ++ppPos) - { - /* check vendor */ - if (!pModel->uVendor || (pModel->uVendor == (*ppPos)->uVendor)) - { - /* for each device */ - for (pDev=(*ppPos)->pDevices; pDev->pszName; ++pDev) - { - /* if device matches */ - if (pModel->uDevice == pDev->uDevice) - { - /* no subtype specified, use it */ - if (!pModel->uSubType) - { - *ppVendor = *ppPos; - *ppDevice = pDev; - *ppSubType = NULL; - return 0; - } - - /* for each subtype */ - for (pSub=pDev->pSubTypes; pSub->pszName; ++pSub) - { - /* if subtype matches */ - if (pModel->uSubType == pSub->uSubType) - { - *ppVendor = *ppPos; - *ppDevice = pDev; - *ppSubType = pSub; - return 0; - } - } - - /* wrong subtype? maybe try another vendor */ - if (!pModel->uVendor) break; - - /* otherwise, no match. */ - errno = ENOENT; - return 1; - } - } /* next device */ - - /* if vendor matches, but device does not, no match. */ - if (pModel->uVendor) - { - errno = ENOENT; - return 1; - } - } - } /* next vendor */ - - /* no match */ - errno = ENOENT; - return 1; -} - -WACOMTABLET WacomOpenSerialTablet(WACOMENGINE hEngine, int fd, - WACOMMODEL* pModel) -{ - SERIALTABLET* pSerial = NULL; - - /* Allocate tablet */ - pSerial = (SERIALTABLET*)malloc(sizeof(SERIALTABLET)); - memset(pSerial,0,sizeof(*pSerial)); - pSerial->tablet.Close = SerialClose; - pSerial->tablet.GetModel = SerialGetModel; - pSerial->tablet.GetVendorName = SerialGetVendorName; - pSerial->tablet.GetClassName = SerialGetClassName; - pSerial->tablet.GetDeviceName = SerialGetDeviceName; - pSerial->tablet.GetSubTypeName = SerialGetSubTypeName; - pSerial->tablet.GetModelName = SerialGetModelName; - pSerial->tablet.GetROMVer = SerialGetROMVer; - pSerial->tablet.GetCaps = SerialGetCaps; - pSerial->tablet.GetState = SerialGetState; - pSerial->tablet.GetFD = SerialGetFD; - pSerial->tablet.ReadRaw = SerialReadRaw; - pSerial->tablet.ParseData = SerialParseData; - - pSerial->hEngine = hEngine; - pSerial->fd = fd; - pSerial->state.uValueCnt = WACOMFIELD_MAX; - - /* remember what model was request */ - if (pModel) - pSerial->modelRequested = *pModel; - - if (SerialReset(pSerial,pModel)) - { - free(pSerial); - return NULL; - } - - return (WACOMTABLET)pSerial; -} - -static int SerialReset(SERIALTABLET* pSerial, WACOMMODEL* pModel) -{ - SERIALVENDOR* pVendor = NULL; - SERIALDEVICE* pDevice = NULL; - SERIALSUBTYPE* pSubType = NULL; - - /* If model is specified, break it down into vendor, device, and subtype */ - if (pModel && SerialFindModel(pModel,&pVendor,&pDevice,&pSubType)) - return 1; - - /* Set the tablet device */ - if (SerialSetDevice(pSerial,pVendor,pDevice,pSubType)) - return 1; - - /* configure the TTY for initial operation */ - if (SerialConfigTTY(pSerial)) - return 1; - - /* Identify the tablet */ - if (!pSerial->pfnIdent || pSerial->pfnIdent(pSerial)) - return 1; - - /* Initialize the tablet */ - if (!pSerial->pfnInit || pSerial->pfnInit(pSerial)) - return 1; - - /* Send start */ - SerialSendStart(pSerial); - - return 0; -} - -/***************************************************************************** -** Serial Tablet Functions -*****************************************************************************/ - -static int SerialConfigTTY(SERIALTABLET* pSerial) -{ - struct termios tios; - int nBaudRate = 9600; - - /* configure tty */ - if (isatty(pSerial->fd)) - { - /* set up default port parameters */ - if (tcgetattr (pSerial->fd, &tios)) - { - SerialError(pSerial,"Failed to get port params: %s", - strerror(errno)); - return 1; - } - - tios.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); - tios.c_oflag &= ~OPOST; - tios.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); - tios.c_cflag &= ~(CSIZE|PARENB); - tios.c_cflag |= CS8|CLOCAL; - tios.c_cflag &= ~(CSTOPB); /* 1 stop bit */ - tios.c_cflag &= ~(CSIZE); /* 8 data bits */ - tios.c_cflag |= CS8; - tios.c_cflag &= ~(PARENB); /* no parity */ - tios.c_iflag |= IXOFF; /* flow control XOff */ - tios.c_cc[VMIN] = 1; /* vmin value */ - tios.c_cc[VTIME] = 0; /* vtime value */ - - if (tcsetattr (pSerial->fd, TCSANOW, &tios)) - { - SerialError(pSerial,"Failed to set port params: %s", - strerror(errno)); - return 1; - } - - /* get minumum baud rate for given device, if specified */ - if (pSerial->pDevice) - nBaudRate = pSerial->pDevice->nMinBaudRate; - - /* set 38400 baud and reset */ - if (SerialResetAtBaud(pSerial,&tios,38400)) - return 1; - - /* if valid, set 19200 baud and reset */ - if ((nBaudRate <= 19200) && (SerialResetAtBaud(pSerial,&tios,19200))) - return 1; - - /* if valid, set 9600 baud and reset */ - if ((nBaudRate <= 9600) && (SerialResetAtBaud(pSerial,&tios,9600))) - return 1; - - /* lower than 9600 baud? for testing, maybe */ - if ((nBaudRate < 9600) && (SerialResetAtBaud(pSerial,&tios,nBaudRate))) - return 1; - } - else /* not tty */ - { - if (SerialSendReset(pSerial)) return 1; - } - - /* Send stop */ - if (SerialSendStop(pSerial) || WacomFlush(pSerial)) - return 1; - - return 0; -} - - -static int SerialSetDevice(SERIALTABLET* pSerial, SERIALVENDOR* pVendor, - SERIALDEVICE* pDevice, SERIALSUBTYPE* pSubType) -{ - pSerial->pVendor = pVendor; - pSerial->pDevice = pDevice; - pSerial->pSubType = pSubType; - - /* if we know the device, use its functions */ - if (pSerial->pDevice) - { - pSerial->pfnIdent = pSerial->pDevice->pfnIdent; - if (!pSerial->pfnIdent) { errno = EPERM; return 1; } - } - else - pSerial->pfnIdent = SerialIdentDefault; - - return 0; -} - -static int SerialIdentDefault(SERIALTABLET* pSerial) -{ - return SerialIdentWacom(pSerial); -} - -static int SerialIdentWacom(SERIALTABLET* pSerial) -{ - char* pszPos; - SERIALVENDOR* pVendor = &xWacomVendor; - SERIALDEVICE* pDev; - SERIALSUBTYPE* pSub; - char chResp[64]; - - /* send wacom identification request */ - if (SerialSendRequest(pSerial,"~#\r",chResp,sizeof(chResp))) - { - if (errno != ETIMEDOUT) return 1; - - /* try again, sometimes the first one gets garbled */ - if (SerialSendRequest(pSerial,"~#\r",chResp,sizeof(chResp))) - return 1; - } - - /* look through device table for information */ - for (pDev=pVendor->pDevices; pDev->pszName; ++pDev) - { - for (pSub=pDev->pSubTypes; pSub && pSub->pszName; ++pSub) - { - if (strncmp(chResp,pSub->pszIdent, strlen(pSub->pszIdent)) == 0) - { - pSerial->pVendor = pVendor; - pSerial->pDevice = pDev; - pSerial->pSubType = pSub; - pSerial->state.uValid = pDev->uCaps; - pSerial->uPacketLength = pDev->uPacketLength; - pSerial->pfnInit = pSub->pfnInit ? - pSub->pfnInit : SerialInitWacom; - - /* get version number */ - pszPos = chResp; - while (*pszPos) ++pszPos; - while ((pszPos > chResp) && (pszPos[-1] != 'V')) --pszPos; - if (sscanf(pszPos,"%d.%d-%d",&pSerial->nVerMajor, - &pSerial->nVerMinor,&pSerial->nVerRelease) != 3) - { - pSerial->nVerRelease = 0; - if (sscanf(pszPos,"%d.%d",&pSerial->nVerMajor, - &pSerial->nVerMinor) != 2) - { - errno = EINVAL; - SerialError(pSerial,"bad version number: %s",pszPos); - return 1; - } - } - return 0; - } - } - } - - SerialError(pSerial,"UNIDENTIFIED TABLET: %s",chResp); - return 1; -} - -static int SerialInitWacom(SERIALTABLET* pSerial) -{ - char chResp[32]; - - /* Request tablet dimensions */ - if (SerialSendRequest(pSerial,"~C\r",chResp,sizeof(chResp))) - return 1; - - /* parse position range */ - if (sscanf(chResp,"%d,%d", - &pSerial->state.values[WACOMFIELD_POSITION_X].nMax, - &pSerial->state.values[WACOMFIELD_POSITION_Y].nMax) != 2) - { - errno=EINVAL; - SerialError(pSerial,"Bad dimension response [%s]",chResp); - return 1; - } - - /* tablet specific initialization */ - switch (pSerial->pDevice->uDevice) - { - case WACOMDEVICE_PENPARTNER: - /* pressure mode */ - SerialSend(pSerial, "PH1\r"); - break; - - case WACOMDEVICE_INTUOS: - case WACOMDEVICE_INTUOS2: - /* multi-mode, max-rate */ - SerialSend(pSerial, "MT1\rID1\rIT0\r"); - } - - if (pSerial->pDevice->nProtocol == PROTOCOL_4) - { - /* multi-mode (MU), upper-origin (OC), all-macro (M0), - * no-macro1 (M1), max-rate (IT), no-inc (IN), - * stream-mode (SR), Z-filter (ZF) */ - -/* if (SerialSend(pSerial->fd, "MU1\rOC1\r~M0\r~M1\rIT0\rIN0\rSR\rZF1\r")) - return 1; - */ - - if (pSerial->nVerMajor == 1) - { - if (pSerial->nVerMinor >= 4) - { - /* enable tilt mode */ - if (SerialSend(pSerial,"FM1\r")) return 1; - - pSerial->pfnParse = SerialParseWacomIV_1_4; - pSerial->uPacketLength = 9; - pSerial->state.values[WACOMFIELD_PRESSURE].nMax = 255; - pSerial->state.values[WACOMFIELD_TILT_X].nMin = -64; - pSerial->state.values[WACOMFIELD_TILT_X].nMax = 63; - pSerial->state.values[WACOMFIELD_TILT_Y].nMin = -64; - pSerial->state.values[WACOMFIELD_TILT_Y].nMax = 63; - } - else if (pSerial->nVerMinor == 3) - { - pSerial->pfnParse = SerialParseWacomIV_1_3; - pSerial->state.values[WACOMFIELD_PRESSURE].nMax = 255; - } - else if (pSerial->nVerMinor == 2) - { - pSerial->pfnParse = SerialParseWacomIV_1_2; - pSerial->state.values[WACOMFIELD_PRESSURE].nMax = 255; - } - else if (pSerial->nVerMinor < 2) - { - pSerial->pfnParse = SerialParseWacomIV_1_2; - pSerial->state.values[WACOMFIELD_PRESSURE].nMax = 120; - } - } - } - else if (pSerial->pDevice->nProtocol == PROTOCOL_5) - { - pSerial->pfnParse = SerialParseWacomV; - pSerial->state.values[WACOMFIELD_PRESSURE].nMax = 1023; - pSerial->state.values[WACOMFIELD_ABSWHEEL].nMax = 1023; - pSerial->state.values[WACOMFIELD_ROTATION_Z].nMin = -900; - pSerial->state.values[WACOMFIELD_ROTATION_Z].nMax = 899; - pSerial->state.values[WACOMFIELD_THROTTLE].nMin = -1023; - pSerial->state.values[WACOMFIELD_THROTTLE].nMax = 1023; - pSerial->state.values[WACOMFIELD_TILT_X].nMin = -64; - pSerial->state.values[WACOMFIELD_TILT_X].nMax = 63; - pSerial->state.values[WACOMFIELD_TILT_Y].nMin = -64; - pSerial->state.values[WACOMFIELD_TILT_Y].nMax = 63; - } - else { errno=EINVAL; return 1; } - - return 0; -} - - -static int SerialIdentTabletPC(SERIALTABLET* pSerial) -{ - /* sanity check */ - if ((pSerial->pVendor != &xtpcVendor) || - (pSerial->pDevice == NULL)) { return EPERM; return 1; } - - /* use first one */ - pSerial->pSubType = pSerial->pDevice->pSubTypes; - - /* sanity check again */ - if (pSerial->pSubType->pszName == NULL) { return EPERM; return 1; } - - pSerial->state.uValid = pSerial->pDevice->uCaps; - pSerial->uPacketLength = pSerial->pDevice->uPacketLength; - pSerial->pfnInit = pSerial->pSubType->pfnInit; - pSerial->nVerMajor = 0; - pSerial->nVerMinor = 0; - pSerial->nVerRelease = 0; - - return 0; -} - -static int SerialInitTabletPC(SERIALTABLET* pSerial) -{ - pSerial->pfnParse = SerialParseTabletPC; - pSerial->state.values[WACOMFIELD_POSITION_X].nMax = 21136; - pSerial->state.values[WACOMFIELD_POSITION_Y].nMax = 15900; - pSerial->state.values[WACOMFIELD_PRESSURE].nMax = 255; - return 0; -} - -static int SerialParseWacomV(SERIALTABLET* pSerial, - const unsigned char* puchData, unsigned int uLength, - WACOMSTATE* pState) -{ - int x=0, y=0, rot=0, tiltx=0, tilty=0, wheel=0, - tool=WACOMTOOLTYPE_NONE, button=0, press=0, throttle=0, - nButtonValue; - - /* Wacom V - * Supports: 1024 pressure, eraser, 2 side-switch, tilt, throttle, wheel - * Limitation: no tilt */ - - if (uLength != 9) { errno=EINVAL; return 1; } - - /* in */ - if ((puchData[0] & 0xFC) == 0xC0) - { - int toolid = (((int)puchData[1]&0x7F) << 5) | - (((int)puchData[2]&0x7C) >> 2); - - int serial = ((((int)puchData[2] & 0x03) << 30) | - (((int)puchData[3] & 0x7f) << 23) | - (((int)puchData[4] & 0x7f) << 16) | - (((int)puchData[5] & 0x7f) << 9) | - (((int)puchData[6] & 0x7f) << 2) | - (((int)puchData[7] & 0x60) >> 5)); - - switch (toolid) - { - case 0x812: /* Intuos2 ink pen XP-110-00A */ - case 0x012: /* Inking pen */ - tool = WACOMTOOLTYPE_PENCIL; break; - - case 0x822: /* Intuos Pen GP-300E-01H */ - case 0x852: /* Intuos2 Grip Pen XP-501E-00A */ - case 0x842: /* added from Cheng */ - case 0x022: - tool = WACOMTOOLTYPE_PEN; break; - - case 0x832: /* Intuos2 stroke pen XP-120-00A */ - case 0x032: /* Stroke pen */ - tool = WACOMTOOLTYPE_BRUSH; break; - - case 0x007: /* 2D Mouse */ - case 0x09C: /* ?? Mouse */ - case 0x094: /* 4D Mouse */ - tool = WACOMTOOLTYPE_MOUSE; break; - - case 0x096: /* Lens cursor */ - tool = WACOMTOOLTYPE_LENS; break; - - case 0x82a: - case 0x85a: - case 0x91a: - case 0x0fa: /* Eraser */ - tool = WACOMTOOLTYPE_ERASER; break; - - case 0x112: /* Airbrush */ - tool = WACOMTOOLTYPE_AIRBRUSH; break; - - default: /* Unknown tool */ - tool = WACOMTOOLTYPE_PEN; break; - } - - pSerial->nToolID = toolid; - pSerial->state.values[WACOMFIELD_PROXIMITY].nValue = 1; - pSerial->state.values[WACOMFIELD_SERIAL].nValue = serial; - pSerial->state.values[WACOMFIELD_TOOLTYPE].nValue = tool; - return pState ? WacomCopyState(pState,&pSerial->state) : 0; - } - - /* out */ - if ((puchData[0] & 0xFE) == 0x80) - { - pSerial->nToolID = 0; - memset(&pSerial->state.values, 0, - pSerial->state.uValueCnt * sizeof(WACOMVALUE)); - return pState ? WacomCopyState(pState,&pSerial->state) : 0; - } - - /* pen data */ - if (((puchData[0] & 0xB8) == 0xA0) || ((puchData[0] & 0xBE) == 0xB4)) - { - x = ((((int)puchData[1] & 0x7f) << 9) | - (((int)puchData[2] & 0x7f) << 2) | - (((int)puchData[3] & 0x60) >> 5)); - y = ((((int)puchData[3] & 0x1f) << 11) | - (((int)puchData[4] & 0x7f) << 4) | - (((int)puchData[5] & 0x78) >> 3)); - tiltx = (puchData[7] & 0x3F); - tilty = (puchData[8] & 0x3F); - if (puchData[7] & 0x40) tiltx -= 0x40; - if (puchData[8] & 0x40) tilty -= 0x40; - - /* pen packet */ - if ((puchData[0] & 0xB8) == 0xA0) - { - press = ((((int)puchData[5] & 0x07) << 7) | ((int)puchData[6] & 0x7f)); - button = (press > 10) ? BIT(WACOMBUTTON_TOUCH) : 0; - button |= (puchData[0] & 0x02) ? BIT(WACOMBUTTON_STYLUS) : 0; - button |= (puchData[0] & 0x04) ? BIT(WACOMBUTTON_STYLUS2) : 0; - } - - /* 2nd airbrush packet */ - else - { - wheel = ((((int)puchData[5] & 0x07) << 7) | - ((int)puchData[6] & 0x7f)); - } - - pSerial->state.values[WACOMFIELD_POSITION_X].nValue = x; - pSerial->state.values[WACOMFIELD_POSITION_Y].nValue = y; - pSerial->state.values[WACOMFIELD_TILT_X].nValue = tiltx; - pSerial->state.values[WACOMFIELD_TILT_Y].nValue = tilty; - pSerial->state.values[WACOMFIELD_PRESSURE].nValue = press; - pSerial->state.values[WACOMFIELD_BUTTONS].nValue = button; - pSerial->state.values[WACOMFIELD_ABSWHEEL].nValue = wheel; - return pState ? WacomCopyState(pState,&pSerial->state) : 0; - } - - /* mouse packet */ - if (((puchData[0] & 0xBE) == 0xA8) || ((puchData[0] & 0xBE) == 0xB0)) - { - x = ((((int)puchData[1] & 0x7f) << 9) | - (((int)puchData[2] & 0x7f) << 2) | - (((int)puchData[3] & 0x60) >> 5)); - y = ((((int)puchData[3] & 0x1f) << 11) | - (((int)puchData[4] & 0x7f) << 4) | - (((int)puchData[5] & 0x78) >> 3)); - throttle = ((((int)puchData[5] & 0x07) << 7) | (puchData[6] & 0x7f)); - if (puchData[8] & 0x08) throttle = -throttle; - - /* 4D mouse */ - if (pSerial->nToolID == 0x094) - { - button = (((puchData[8] & 0x70) >> 1) | (puchData[8] & 0x07)); - } - /* lens cursor */ - else if (pSerial->nToolID == 0x096) - { - button = puchData[8] & 0x1F; - } - /* 2D mouse */ - else - { - button = (puchData[8] & 0x1C) >> 2; - wheel = - (puchData[8] & 1) + ((puchData[8] & 2) >> 1); - } - - pSerial->state.values[WACOMFIELD_POSITION_X].nValue = x; - pSerial->state.values[WACOMFIELD_POSITION_Y].nValue = y; - pSerial->state.values[WACOMFIELD_RELWHEEL].nValue = wheel; - pSerial->state.values[WACOMFIELD_THROTTLE].nValue = throttle; - - /* button values */ - nButtonValue = pSerial->state.values[WACOMFIELD_BUTTONS].nValue & - ~(BIT(WACOMBUTTON_LEFT) | - BIT(WACOMBUTTON_RIGHT) | BIT(WACOMBUTTON_MIDDLE) | - BIT(WACOMBUTTON_EXTRA) | BIT(WACOMBUTTON_SIDE)); - if (button & 1) nButtonValue |= BIT(WACOMBUTTON_LEFT); - if (button & 2) nButtonValue |= BIT(WACOMBUTTON_MIDDLE); - if (button & 4) nButtonValue |= BIT(WACOMBUTTON_RIGHT); - if (button & 8) nButtonValue |= BIT(WACOMBUTTON_EXTRA); - if (button & 16) nButtonValue |= BIT(WACOMBUTTON_SIDE); - pSerial->state.values[WACOMFIELD_BUTTONS].nValue = nButtonValue; - - return pState ? WacomCopyState(pState,&pSerial->state) : 0; - } - - /* 2nd 4D mouse packet */ - if ((puchData[0] & 0xBE) == 0xAA) - { - x = ((((int)puchData[1] & 0x7f) << 9) | - (((int)puchData[2] & 0x7f) << 2) | - (((int)puchData[3] & 0x60) >> 5)); - y = ((((int)puchData[3] & 0x1f) << 11) | - (((int)puchData[4] & 0x7f) << 4) | - (((int)puchData[5] & 0x78) >> 3)); - rot = ((((int)puchData[6] & 0x0f) << 7) | - ((int)puchData[7] & 0x7f)); - - /* FIX ROT */ - if (rot < 900) rot = -rot; - else rot = 1799 - rot; - - pSerial->state.values[WACOMFIELD_POSITION_X].nValue = x; - pSerial->state.values[WACOMFIELD_POSITION_Y].nValue = y; - pSerial->state.values[WACOMFIELD_ROTATION_Z].nValue = rot; - return pState ? WacomCopyState(pState,&pSerial->state) : 0; - } - - errno = EINVAL; - return 1; -} - -static int SerialParseWacomIV_1_4(SERIALTABLET* pSerial, - const unsigned char* puchData, unsigned int uLength, - WACOMSTATE* pState) -{ - /* Wacom IV, Rom 1.4 - * Supports: 256 pressure, eraser, 2 side-switch, tilt */ - - if ((uLength != 7) && (uLength != 9)) { errno=EINVAL; return 1; } - - if (SerialParseWacomIV_1_3(pSerial,puchData,7,pState)) - return 1; - - /* tilt mode */ - if (uLength == 9) - { - int tiltx, tilty; - - tiltx = puchData[7] & 0x3F; - tilty = puchData[8] & 0x3F; - if (puchData[7] & 0x40) tiltx -= 64; - if (puchData[8] & 0x40) tilty -= 64; - - pSerial->state.values[WACOMFIELD_TILT_X].nValue = tiltx; - pSerial->state.values[WACOMFIELD_TILT_Y].nValue = tilty; - - if (pState) - { - pState->values[WACOMFIELD_TILT_X].nValue = tiltx; - pState->values[WACOMFIELD_TILT_Y].nValue = tilty; - } - } - - return 0; -} - -static int SerialParseWacomIV_1_3(SERIALTABLET* pSerial, - const unsigned char* puchData, unsigned int uLength, - WACOMSTATE* pState) -{ - int x=0, y=0, prox=0, tool=WACOMTOOLTYPE_NONE, - button=0, press=0, stylus, eraser; - - /* Wacom IV, Rom 1.3 (ArtPadII) - * Supports: 256 pressure, eraser, 2 side-switch - * Limitation: no tilt */ - - if (uLength != 7) { errno=EINVAL; return 1; } - - prox = puchData[0] & 0x40 ? 1 : 0; - if (prox) - { - stylus = puchData[0] & 0x20 ? 1 : 0; - press = (puchData[6] & 0x3F) << 1 | ((puchData[3] & 0x4) >> 2); - press |= (puchData[6] & 0x40) ? 0 : 0x80; - eraser = (puchData[3] & 0x20) ? 1 : 0; - - if (stylus) - { - /* if entering proximity, choose eraser or stylus2 for bit */ - if (pSerial->state.values[WACOMFIELD_PROXIMITY].nValue == 0) - { - if (eraser) tool = WACOMTOOLTYPE_ERASER; - else tool = WACOMTOOLTYPE_PEN; - } - - /* otherwise, keep the last tool */ - else tool = pSerial->state.values[WACOMFIELD_TOOLTYPE].nValue; - - button = (press > 10) ? BIT(WACOMBUTTON_TOUCH) : 0; - - /* pen has 2 side-switch, eraser has none */ - if (tool == WACOMTOOLTYPE_PEN) - { - button |= (puchData[3] & 0x10) ? - BIT(WACOMBUTTON_STYLUS) : 0; - button |= (eraser) ? BIT(WACOMBUTTON_STYLUS2) : 0; - } - } - else - { - tool = WACOMTOOLTYPE_MOUSE; - button = (puchData[3] & 0x78) >> 3; /* not tested */ - } - - x = puchData[2] | ((int)puchData[1] << 7) | - (((int)puchData[0] & 0x3) << 14); - y = puchData[5] | ((int)puchData[4] << 7) | - (((int)puchData[3] & 0x3) << 14); - } - - /* set valid fields */ - pSerial->state.values[WACOMFIELD_PROXIMITY].nValue = prox; - pSerial->state.values[WACOMFIELD_TOOLTYPE].nValue = tool; - pSerial->state.values[WACOMFIELD_POSITION_X].nValue = x; - pSerial->state.values[WACOMFIELD_POSITION_Y].nValue = y; - pSerial->state.values[WACOMFIELD_PRESSURE].nValue = press; - pSerial->state.values[WACOMFIELD_BUTTONS].nValue = button; - - return pState ? WacomCopyState(pState,&pSerial->state) : 0; -} - -static int SerialParseWacomIV_1_2(SERIALTABLET* pSerial, - const unsigned char* puchData, unsigned int uLength, - WACOMSTATE* pState) -{ - int x=0, y=0, prox=0, tool=0, button=WACOMTOOLTYPE_NONE, - press=0, stylus; - - /* Wacom IV, Rom 1.2, 1.1, and 1.0 - * Supports: 256 pressure (120 for 1.1 and 1.0), multi-mode - * Limitation: no stylus2, no tilt, no eraser */ - - if (uLength != 7) { errno=EINVAL; return 1; } - - prox = puchData[0] & 0x40 ? 1 : 0; - if (prox) - { - stylus = puchData[0] & 0x20 ? 1 : 0; - if (pSerial->nVerMinor == 2) - press = ((puchData[6] & 0x3F) << 1) | ((puchData[3] & 0x4) >> 2) | - ((puchData[6] & 0x40) ? 0 : 0x80); - else - press = (puchData[6] & 0x3F) + ((puchData[6] & 0x40) ? 0 : 64); - - if (stylus) - { - tool = WACOMTOOLTYPE_PEN; - button = (press > 10) ? BIT(WACOMBUTTON_TOUCH) : 0; - button |= (puchData[3] & 0x10) ? BIT(WACOMBUTTON_STYLUS) : 0; - } - else - { - tool = WACOMTOOLTYPE_MOUSE; - button = (puchData[3] & 0x78) >> 3; /* not tested */ - } - - x = puchData[2] | ((int)puchData[1] << 7) | - (((int)puchData[0] & 0x3) << 14); - y = puchData[5] | ((int)puchData[4] << 7) | - (((int)puchData[3] & 0x3) << 14); - } - - /* set valid fields */ - pSerial->state.values[WACOMFIELD_PROXIMITY].nValue = prox; - pSerial->state.values[WACOMFIELD_TOOLTYPE].nValue = tool; - pSerial->state.values[WACOMFIELD_POSITION_X].nValue = x; - pSerial->state.values[WACOMFIELD_POSITION_Y].nValue = y; - pSerial->state.values[WACOMFIELD_PRESSURE].nValue = press; - pSerial->state.values[WACOMFIELD_BUTTONS].nValue = button; - - return pState ? WacomCopyState(pState,&pSerial->state) : 0; -} - -static int SerialParseTabletPC(SERIALTABLET* pSerial, - const unsigned char* puchData, unsigned int uLength, - WACOMSTATE* pState) -{ - int x=0, y=0, prox=0, tool=WACOMTOOLTYPE_NONE, - button=0, press=0, eraser; - - /* Tablet PC Supports: 256 pressure, eraser, 1/2 side-switch */ - - if (uLength != 9) { errno=EINVAL; return 1; } - - prox = puchData[0] & 0x20 ? 1 : 0; - if (prox) - { - eraser = (puchData[0] & 0x04) ? 1 : 0; - press = ((puchData[6] & 0x01) << 7) | (puchData[5] & 0x7F); - - /* tools are distinguishable */ - if (eraser) tool = WACOMTOOLTYPE_ERASER; - else tool = WACOMTOOLTYPE_PEN; - - button = (puchData[0] & 0x01) ? BIT(WACOMBUTTON_TOUCH) : 0; - - /* pen has side-switch(es), eraser has none */ - if (tool == WACOMTOOLTYPE_PEN) - { - button |= (puchData[0] & 0x02) ? - BIT(WACOMBUTTON_STYLUS) : 0; - button |= (puchData[0] & 0x04) ? - BIT(WACOMBUTTON_STYLUS2) : 0; - } - - x = (((int)puchData[6] & 0x60) >> 5) | - ((int)puchData[2] << 2) | - ((int)puchData[1] << 9); - y = (((int)puchData[6] & 0x18) >> 3) | - ((int)puchData[4] << 2) | - ((int)puchData[3] << 9); - } - - /* set valid fields */ - pSerial->state.values[WACOMFIELD_PROXIMITY].nValue = prox; - pSerial->state.values[WACOMFIELD_TOOLTYPE].nValue = tool; - pSerial->state.values[WACOMFIELD_POSITION_X].nValue = x; - pSerial->state.values[WACOMFIELD_POSITION_Y].nValue = y; - pSerial->state.values[WACOMFIELD_PRESSURE].nValue = press; - pSerial->state.values[WACOMFIELD_BUTTONS].nValue = button; - - return pState ? WacomCopyState(pState,&pSerial->state) : 0; -} - - - -/***************************************************************************** -** Internal Functions -*****************************************************************************/ - -static int SerialSendReset(SERIALTABLET* pSerial) -{ - SerialInfo(pSerial,"Sending reset"); - - /* reset to Wacom II-S command set, and factory defaults */ - if (SerialSend(pSerial,"\r$\r")) return 1; - usleep(250000); /* 250 milliseconds */ - - /* reset tablet to Wacom IV command set */ - if (SerialSend(pSerial,"#\r")) return 1; - usleep(75000); /* 75 milliseconds */ - - return 0; -} - -static int SerialSendStop(SERIALTABLET* pSerial) -{ - if (SerialSend(pSerial,"\rSP\r")) return 1; - usleep(100000); - return 0; -} - -static int SerialSendStart(SERIALTABLET* pSerial) -{ - return SerialSend(pSerial,"ST\r"); -} - -static int SerialSend(SERIALTABLET* pSerial, const char* pszMsg) -{ - return SerialSendRaw(pSerial,pszMsg,(unsigned)strlen(pszMsg)); -} - -static int SerialSendRaw(SERIALTABLET* pSerial, const void* pvData, - unsigned int uSize) -{ - int nXfer; - unsigned int uCnt=0; - unsigned char* puchData = (unsigned char*)pvData; - - while (uCnt < uSize) - { - nXfer = write(pSerial->fd,puchData+uCnt,uSize-uCnt); - if (nXfer <= 0) - { - SerialError(pSerial,"Failed to write to port: %s",strerror(errno)); - return 1; - } - uCnt += nXfer; - } - - return 0; -} - -static int WacomFlush(SERIALTABLET* pSerial) -{ - char ch[16]; - fd_set fdsRead; - struct timeval timeout; - - if (tcflush(pSerial->fd, TCIFLUSH) == 0) - return 0; - - timeout.tv_sec = 0; - timeout.tv_usec = 0; - - while (1) - { - FD_ZERO(&fdsRead); - FD_SET(pSerial->fd, &fdsRead); - if (select(FD_SETSIZE,&fdsRead,NULL,NULL,&timeout) <= 0) - break; - read(pSerial->fd,&ch,sizeof(ch)); - } - - return 0; -} - -static int SerialSendRequest(SERIALTABLET* pSerial, const char* pszRequest, - char* pchResponse, unsigned int uSize) -{ - int nXfer; - fd_set fdsRead; - unsigned int uLen, uCnt; - struct timeval timeout; - - uLen = strlen(pszRequest); - if (SerialSendRaw(pSerial,pszRequest,uLen)) return 1; - --uLen; - - if (uSize < uLen) - { - errno=EINVAL; - SerialError(pSerial,"Invalid size to SerialSendRequest: %u < %u", - uSize,uLen); - return 1; - } - - /* read until first header character */ - while (1) - { - timeout.tv_sec = 0; - timeout.tv_usec = 500000; - - FD_ZERO(&fdsRead); - FD_SET(pSerial->fd, &fdsRead); - if (select(FD_SETSIZE,&fdsRead,NULL,NULL,&timeout) <= 0) - { - errno = ETIMEDOUT; - return 1; - } - - nXfer = read(pSerial->fd,pchResponse,1); - if (nXfer <= 0) - { - SerialError(pSerial,"Truncated response header"); - return 1; - } - if (*pchResponse == *pszRequest) break; - SerialWarn(pSerial,"Discarding %02X", *((unsigned char*)pchResponse)); - } - - /* read response header */ - for (uCnt=1; uCnt<uLen; uCnt+=nXfer) - { - nXfer = read(pSerial->fd,pchResponse+uCnt,uLen-uCnt); - if (nXfer <= 0) - { - SerialError(pSerial,"Truncated response header (2)"); - return 1; - } - } - - /* check the header */ - if (strncmp(pszRequest,pchResponse,uLen) != 0) - { - SerialError(pSerial,"Incorrect response [%s,%s]", - pszRequest,pchResponse); - return 1; - } - - /* get the rest of the response */ - for (uCnt=0; uCnt<uSize; ++uCnt) - { - nXfer = read(pSerial->fd,pchResponse+uCnt,1); - if (nXfer <= 0) - { - SerialError(pSerial,"Failed to read response: %s",strerror(errno)); - return 1; - } - - /* stop on CR */ - if (pchResponse[uCnt] == '\r') - { - pchResponse[uCnt] = '\0'; - return 0; - } - } - - errno = EINVAL; - SerialError(pSerial,"Invalid response"); - return 1; -} - -/***************************************************************************** -** Virtual Functions -*****************************************************************************/ - -static void SerialClose(WACOMTABLET_PRIV* pTablet) -{ - SERIALTABLET* pSerial = (SERIALTABLET*)pTablet; - close(pSerial->fd); - free(pSerial); -} - -static WACOMMODEL SerialGetModel(WACOMTABLET_PRIV* pTablet) -{ - WACOMMODEL model = { 0 }; - SERIALTABLET* pSerial = (SERIALTABLET*)pTablet; - model.uClass = WACOMCLASS_SERIAL; - model.uVendor = pSerial->pVendor->uVendor; - model.uDevice = pSerial->pDevice->uDevice; - model.uSubType = pSerial->pSubType->uSubType; - return model; -} - -static const char* SerialGetVendorName(WACOMTABLET_PRIV* pTablet) -{ - SERIALTABLET* pSerial = (SERIALTABLET*)pTablet; - return pSerial->pVendor->pszDesc; -} - -static const char* SerialGetClassName(WACOMTABLET_PRIV* pTablet) -{ - return "Serial"; -} - -static const char* SerialGetDeviceName(WACOMTABLET_PRIV* pTablet) -{ - SERIALTABLET* pSerial = (SERIALTABLET*)pTablet; - return pSerial->pDevice->pszDesc; -} - -static const char* SerialGetSubTypeName(WACOMTABLET_PRIV* pTablet) -{ - SERIALTABLET* pSerial = (SERIALTABLET*)pTablet; - return pSerial->pSubType->pszName; -} - -static const char* SerialGetModelName(WACOMTABLET_PRIV* pTablet) -{ - SERIALTABLET* pSerial = (SERIALTABLET*)pTablet; - return pSerial->pSubType->pszDesc; -} - -static int SerialGetROMVer(WACOMTABLET_PRIV* pTablet, int* pnMajor, - int* pnMinor, int* pnRelease) -{ - SERIALTABLET* pSerial = (SERIALTABLET*)pTablet; - if (!pnMajor) { errno=EINVAL; return 1; } - *pnMajor = pSerial->nVerMajor; - if (pnMinor) *pnMinor = pSerial->nVerMinor; - if (pnRelease) *pnRelease = pSerial->nVerRelease; - return 0; -} - -static int SerialGetCaps(WACOMTABLET_PRIV* pTablet) -{ - SERIALTABLET* pSerial = (SERIALTABLET*)pTablet; - return pSerial->pDevice->uCaps; -} - -static int SerialGetState(WACOMTABLET_PRIV* pTablet, WACOMSTATE* pState) -{ - SERIALTABLET* pSerial = (SERIALTABLET*)pTablet; - return WacomCopyState(pState,&pSerial->state); -} - -static int SerialGetFD(WACOMTABLET_PRIV* pTablet) -{ - SERIALTABLET* pSerial = (SERIALTABLET*)pTablet; - return pSerial->fd; -} - -static int SerialReadRaw(WACOMTABLET_PRIV* pTablet, unsigned char* puchData, - unsigned int uSize) -{ - int nXfer; - fd_set fdsRead; - unsigned char* pPos, *pEnd; - struct timeval timeout; - unsigned int uCnt, uPacketLength; - SERIALTABLET* pSerial = (SERIALTABLET*)pTablet; - - if (!pSerial) { errno=EBADF; return 0; } - uPacketLength = pSerial->uPacketLength; - - /* check size of buffer */ - if (uSize < uPacketLength) { errno=EINVAL; return 0; } - - /* check for errors, reset after 3 */ - if (pSerial->nBitErrors > 3) - { - pSerial->nBitErrors = 0; - SerialWarn(pSerial,"Resetting tablet due to bit errors"); - (void)SerialReset(pSerial,&pSerial->modelRequested); - } - - timeout.tv_sec = 0; - timeout.tv_usec = 500000; /* 0.5 seconds for now */ - - for (uCnt=0; uCnt<uPacketLength; uCnt+=nXfer) - { - FD_ZERO(&fdsRead); - FD_SET(pSerial->fd, &fdsRead); - if (select(FD_SETSIZE,&fdsRead,NULL,NULL,&timeout) <= 0) - break; - - nXfer = read(pSerial->fd,puchData+uCnt,uPacketLength-uCnt); - if (nXfer <= 0) return nXfer; - - /* look for high-bit */ - pEnd = puchData + nXfer; - for (pPos=puchData; pPos<pEnd; ++pPos) - { - if (*pPos & 0x80) break; - } - - /* not where it was expected? fix it. */ - if (pPos != puchData) - { - ++pSerial->nBitErrors; - SerialWarn(pSerial,"Bad high bit, discarding %d bytes", - pPos - puchData); - - /* copy remaining bytes down, if any */ - memmove(puchData,pPos,(nXfer - (pPos-puchData))); - nXfer -= pPos - puchData; - } - } - - if (uCnt < uPacketLength) - { - errno = ETIMEDOUT; - return -1; - } - - return (signed)uCnt; -} - -static int SerialParseData(WACOMTABLET_PRIV* pTablet, - const unsigned char* puchData, unsigned int uLength, - WACOMSTATE* pState) -{ - int i; - SERIALTABLET* pSerial = (SERIALTABLET*)pTablet; - if (!pSerial) { errno=EBADF; return 1; } - - /* check synchronization */ - if (!(puchData[0] & 0x80)) - { - ++pSerial->nBitErrors; - SerialError(pSerial,"HIBIT FAIL"); - errno=EINVAL; - return 1; - } - for (i=1; i<uLength; ++i) - { - if (puchData[i] & 0x80) - { - ++pSerial->nBitErrors; - SerialError(pSerial,"LOBIT FAIL"); - SerialDump(pSerial,puchData,uLength); - errno=EINVAL; - return 1; - } - } - - /* reset bit error count */ - pSerial->nBitErrors = 0; - - /* dispatch to parser */ - if (pSerial->pfnParse) - return (*pSerial->pfnParse)(pSerial,puchData,uLength,pState); - - errno=EINVAL; - return 1; -} - -static int SerialResetAtBaud(SERIALTABLET* pSerial, struct termios* pTIOS, - int nBaud) -{ - /* conver baud rate to tios macro */ - int baudRate = B9600; - switch (nBaud) - { - case 38400: baudRate = B38400; break; - case 19200: baudRate = B19200; break; - case 9600: baudRate = B9600; break; - case 4800: baudRate = B4800; break; /* for testing, maybe */ - case 2400: baudRate = B2400; break; /* for testing, maybe */ - case 1200: baudRate = B1200; break; /* for testing, maybe */ - } - - SerialInfo(pSerial,"Setting baud rate to %d",nBaud); - - /* change baud rate */ - cfsetispeed(pTIOS, baudRate); - cfsetospeed(pTIOS, baudRate); - if (tcsetattr (pSerial->fd, TCSANOW, pTIOS)) - return 1; - - /* send reset command */ - return SerialSendReset(pSerial); -} - -/***************************************************************************** -** Log Functions -*****************************************************************************/ - -#define SERIALLOG(l) do { \ - va_list a; \ - va_start(a,pszFmt); \ - WacomLogV(pSerial->hEngine,l,pszFmt,a); \ - va_end(a); } while (0) - -static void SerialError(SERIALTABLET* pSerial, const char* pszFmt, ...) - { SERIALLOG(WACOMLOGLEVEL_ERROR); } -static void SerialWarn(SERIALTABLET* pSerial, const char* pszFmt, ...) - { SERIALLOG(WACOMLOGLEVEL_WARN); } -static void SerialInfo(SERIALTABLET* pSerial, const char* pszFmt, ...) - { SERIALLOG(WACOMLOGLEVEL_INFO); } - -static void SerialDump(SERIALTABLET* pSerial, const void* pvData, int nCnt) -{ - int i; - const unsigned char* pData = (const unsigned char*)pvData; - char chLine[80]; - unsigned int uAddr = 0; - int nPos = 0; - - while (nCnt > 0) - { - nPos = 0; - for (i=0; i<16; ++i) - { - if (i < nCnt) - nPos += snprintf(chLine+nPos,sizeof(chLine)-nPos, - "%02X",pData[i]); - else - nPos += snprintf(chLine+nPos,sizeof(chLine)-nPos, - " "); - } - nPos += snprintf(chLine+nPos,sizeof(chLine)-nPos," - "); - for (i=0; i<16; ++i) - { - if (i < nCnt) - nPos += snprintf(chLine+nPos,sizeof(chLine)-nPos, - "%c",isprint(pData[i]) ? pData[i] : '.'); - else - nPos += snprintf(chLine+nPos,sizeof(chLine)-nPos, - " "); - } - - WacomLog(pSerial->hEngine,WACOMLOGLEVEL_DEBUG,"%04X: %s",uAddr,chLine); - uAddr += 16; - nCnt -= 16; - pData += 16; - } -} - -/* NOT USED, YET -static void SerialCritical(SERIALTABLET* pSerial, const char* pszFmt, ...) - { SERIALLOG(WACOMLOGLEVEL_CRITICAL); } -static void SerialDebug(SERIALTABLET* pSerial, const char* pszFmt, ...) - { SERIALLOG(WACOMLOGLEVEL_DEBUG); } -static void SerialTrace(SERIALTABLET* pSerial, const char* pszFmt, ...) - { SERIALLOG(WACOMLOGLEVEL_TRACE); } -*/ diff --git a/src/util/wacserial.h b/src/util/wacserial.h deleted file mode 100755 index 1729744..0000000 --- a/src/util/wacserial.h +++ /dev/null @@ -1,32 +0,0 @@ -/***************************************************************************** -** wacserial.h -** -** Copyright (C) 2002,2003 - John E. Joganic -** -** 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 Lesser 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -****************************************************************************/ - -#ifndef __LINUXWACOM_WACSERIAL_H -#define __LINUXWACOM_WACSERIAL_H - -#include "wactablet.h" - -int WacomGetSupportedSerialDeviceList(WACOMDEVICEREC** ppList, int* pnSize); -unsigned int WacomGetSerialDeviceFromName(const char* pszName); -WACOMTABLET WacomOpenSerialTablet(WACOMENGINE hEngine, int fd, - WACOMMODEL* pModel); - -#endif /* __LINUXWACOM_WACSERIAL_H */ diff --git a/src/util/wactablet.c b/src/util/wactablet.c deleted file mode 100755 index 4f683b5..0000000 --- a/src/util/wactablet.c +++ /dev/null @@ -1,443 +0,0 @@ -/***************************************************************************** -** wactablet.c -** -** Copyright (C) 2002 - 2003 - John E. Joganic -** Copyright (C) 2004 - 2005 - Ping Cheng -** -** 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 Lesser 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -****************************************************************************/ - -#include "../include/util-config.h" - -#include "wactablet.h" -#include "wacserial.h" -#include "wacusb.h" - -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <memory.h> -#include <fcntl.h> -#include <unistd.h> -#include <assert.h> -#include <stdarg.h> - -#ifdef WCM_ENABLE_LINUXINPUT -#include <linux/input.h> -#endif - -typedef void (*FREEFUNC)(void* pv); - -typedef struct -{ - FREEFUNC pfnFree; -} CLSLIST_INTERNAL; - -typedef struct -{ - WACOMDEVICEREC* pSerialList; - WACOMDEVICEREC* pUSBList; - FREEFUNC pfnFree; -} DEVICELIST_INTERNAL; - -typedef struct _ENGINE_PRIV ENGINE_PRIV; - -struct _ENGINE_PRIV -{ - WACOMLOGFUNC pfnLog; - WACOMLOGLEVEL level; - char chLogBuf[1024]; -}; - -/***************************************************************************** -** Implementation -*****************************************************************************/ - -WACOMENGINE WacomInitEngine(void) -{ - ENGINE_PRIV* pEngine = NULL; - pEngine = (ENGINE_PRIV*)malloc(sizeof(ENGINE_PRIV)); - memset(pEngine,0,sizeof(*pEngine)); - pEngine->level = WACOMLOGLEVEL_WARN; - return (WACOMENGINE)pEngine; -} - -void WacomTermEngine(WACOMENGINE hEngine) -{ - ENGINE_PRIV* pEngine = (ENGINE_PRIV*)hEngine; - if (!pEngine) return; - - free(pEngine); -} - -void WacomSetLogFunc(WACOMENGINE hEngine, WACOMLOGFUNC pfnLog) -{ - ENGINE_PRIV* pEngine = (ENGINE_PRIV*)hEngine; - if (!pEngine) return; - pEngine->pfnLog = pfnLog; -} - -void WacomSetLogLevel(WACOMENGINE hEngine, WACOMLOGLEVEL level) -{ - ENGINE_PRIV* pEngine = (ENGINE_PRIV*)hEngine; - if (!pEngine) return; - - if (level < WACOMLOGLEVEL_CRITICAL) - level = WACOMLOGLEVEL_CRITICAL; - if (level > WACOMLOGLEVEL_TRACE) - level = WACOMLOGLEVEL_TRACE; - - pEngine->level = level; -} - -void WacomLogV(WACOMENGINE hEngine, WACOMLOGLEVEL level, const char* pszFmt, - va_list args) -{ - struct timeval tv; - ENGINE_PRIV* pEngine = (ENGINE_PRIV*)hEngine; - if (!pEngine || !pEngine->pfnLog || (pEngine->level < level)) return; - - gettimeofday(&tv,NULL); - - vsnprintf(pEngine->chLogBuf,sizeof(pEngine->chLogBuf),pszFmt,args); - pEngine->pfnLog(tv,level,pEngine->chLogBuf); -} - -void WacomLog(WACOMENGINE hEngine, WACOMLOGLEVEL level, const char* pszFmt, ...) -{ - va_list args; - va_start(args, pszFmt); - WacomLogV(hEngine,level,pszFmt,args); - va_end(args); -} - -static void FreeClassList(void* pv) -{ - CLSLIST_INTERNAL* pInt = ((CLSLIST_INTERNAL*)pv) - 1; - free(pInt); -} - -int WacomGetSupportedClassList(WACOMCLASSREC** ppList, int* pnSize) -{ - int nIndex=0, nCnt=0; - CLSLIST_INTERNAL* pInt; - WACOMCLASSREC* pRec; - - if (!ppList || !pnSize) { errno = EINVAL; return 1; } - - /* serial */ - ++nCnt; - - /* USB */ - #ifdef WCM_ENABLE_LINUXINPUT - ++nCnt; - #endif - - /* allocate enough memory to hold internal structure and all records */ - pInt = (CLSLIST_INTERNAL*)malloc(sizeof(CLSLIST_INTERNAL) + - (sizeof(WACOMCLASSREC) * nCnt)); - - pInt->pfnFree = FreeClassList; - pRec = (WACOMCLASSREC*)(pInt + 1); - - /* serial */ - pRec[nIndex].pszName = "serial"; - pRec[nIndex].pszDesc = "Serial TTY interface"; - pRec[nIndex].uDeviceClass = WACOMCLASS_SERIAL; - ++nIndex; - - /* USB */ - #ifdef WCM_ENABLE_LINUXINPUT - pRec[nIndex].pszName = "usb"; - pRec[nIndex].pszDesc = "Linux USB event interface"; - pRec[nIndex].uDeviceClass = WACOMCLASS_USB; - ++nIndex; - #endif - - assert(nIndex == nCnt); - *ppList = pRec; - *pnSize = nCnt; - return 0; -} - -static void FreeDeviceList(void* pv) -{ - DEVICELIST_INTERNAL* pInt = ((DEVICELIST_INTERNAL*)pv) - 1; - WacomFreeList(pInt->pSerialList); - WacomFreeList(pInt->pUSBList); - free(pInt); -} - -int WacomGetSupportedDeviceList(unsigned int uDeviceClass, - WACOMDEVICEREC** ppList, int* pnSize) -{ - int nSerialCnt=0, nUSBCnt=0, nTotalBytes; - WACOMDEVICEREC* pSerial=NULL, *pUSB=NULL, *pList; - DEVICELIST_INTERNAL* pInt; - - if (!ppList || !pnSize) { errno = EINVAL; return 1; } - - /* get serial list */ - if (((!uDeviceClass) || (uDeviceClass == WACOMCLASS_SERIAL)) && - WacomGetSupportedSerialDeviceList(&pSerial, &nSerialCnt)) return 1; - - /* get usb list */ - if (((!uDeviceClass) || (uDeviceClass == WACOMCLASS_USB)) && - WacomGetSupportedUSBDeviceList(&pUSB, &nUSBCnt)) - { - if (pSerial) WacomFreeList(pSerial); - return 1; - } - - /* need memory for duplicate records and list internal structure */ - nTotalBytes = sizeof(WACOMDEVICEREC) * (nSerialCnt + nUSBCnt) + - sizeof(DEVICELIST_INTERNAL); - - /* allocate memory */ - pInt = (DEVICELIST_INTERNAL*)malloc(nTotalBytes); - - /* copy initial list pointers */ - pInt->pSerialList = pSerial; - pInt->pUSBList = pUSB; - pInt->pfnFree = FreeDeviceList; - - /* copy records */ - pList = (WACOMDEVICEREC*)(pInt + 1); - if (pSerial) - memcpy(pList,pSerial,sizeof(WACOMDEVICEREC) * nSerialCnt); - if (pUSB) - memcpy(pList + nSerialCnt, pUSB, sizeof(WACOMDEVICEREC) * nUSBCnt); - - *ppList = pList; - *pnSize = nSerialCnt + nUSBCnt; - - return 0; -} - -void WacomFreeList(void* pvList) -{ - FREEFUNC pfnFree; - if (!pvList) return; - pfnFree = ((FREEFUNC*)pvList)[-1]; - (*pfnFree)(pvList); -} - -unsigned int WacomGetClassFromName(const char* pszName) -{ - if (strcasecmp(pszName, "serial") == 0) - return WACOMCLASS_SERIAL; - else if (strcasecmp(pszName, "usb") == 0) - return WACOMCLASS_USB; - return 0; -} - -unsigned int WacomGetDeviceFromName(const char* pszName, - unsigned int uDeviceClass) -{ - unsigned int uDeviceType = 0; - - if (!uDeviceClass || (uDeviceClass == WACOMCLASS_SERIAL)) - { - uDeviceType = WacomGetSerialDeviceFromName(pszName); - if (uDeviceType) return uDeviceType; - } - - if (!uDeviceClass || (uDeviceClass == WACOMCLASS_USB)) - { - uDeviceType = WacomGetUSBDeviceFromName(pszName); - if (uDeviceType) return uDeviceType; - } - - errno = ENOENT; - return 0; -} - -static int WacomIsSerial(int fd) -{ - return isatty(fd); -} - -static int WacomIsUSB(int fd) -{ -#ifdef WCM_ENABLE_LINUXINPUT - short sID[4]; - if (ioctl(fd,EVIOCGID,sID) < 0) return 0; - return 1; -#else - return 0; -#endif -} - -WACOMTABLET WacomOpenTablet(WACOMENGINE hEngine, const char* pszDevice, - WACOMMODEL* pModel) -{ - int fd, e; - WACOMTABLET hTablet = NULL; - unsigned int uClass = pModel ? pModel->uClass : 0; - - /* open device for read/write access */ - fd = open(pszDevice,O_RDWR); - if (fd < 0) - { - e = errno; - WacomLog(hEngine,WACOMLOGLEVEL_ERROR,"Failed to open %s: %s", - pszDevice, strerror(errno)); - errno = e; - return NULL; - } - - /* configure serial */ - if ((!uClass || (uClass == WACOMCLASS_SERIAL)) && WacomIsSerial(fd)) - { - hTablet = WacomOpenSerialTablet(hEngine,fd,pModel); - if (!hTablet) { e=errno; close(fd); errno=e; return NULL; } - } - - /* configure usb */ - else if ((!uClass || (uClass == WACOMCLASS_USB)) && WacomIsUSB(fd)) - { - hTablet = WacomOpenUSBTablet(hEngine,fd,pModel); - if (!hTablet) { e=errno; close(fd); errno=e; return NULL; } - } - - /* give up */ - else - { - close(fd); - errno = EINVAL; - return NULL; - } - - return hTablet; -} - -int WacomCopyState(WACOMSTATE* pDest, WACOMSTATE* pSrc) -{ - unsigned int uCnt; - if (!pSrc || !pDest || !pSrc->uValueCnt || !pDest->uValueCnt) - { errno=EINVAL; return 1; } - - /* copy valid bits over */ - pDest->uValid = pSrc->uValid; - - /* determine how many values to transfer */ - uCnt = (pDest->uValueCnt < pSrc->uValueCnt) ? - pDest->uValueCnt : pSrc->uValueCnt; - - /* copy them over */ - memcpy(pDest->values,pSrc->values,uCnt*sizeof(WACOMVALUE)); - - return 0; -} - -/***************************************************************************** -** Virtual Functions -*****************************************************************************/ - -void WacomCloseTablet(WACOMTABLET hTablet) -{ - WACOMTABLET_PRIV* pTablet = (WACOMTABLET_PRIV*)hTablet; - if (!pTablet || !pTablet->Close) return; - pTablet->Close(pTablet); -} - -WACOMMODEL WacomGetModel(WACOMTABLET hTablet) -{ - WACOMMODEL xBadModel = { 0 }; - WACOMTABLET_PRIV* pTablet = (WACOMTABLET_PRIV*)hTablet; - if (!pTablet || !pTablet->GetModel) { errno=EBADF; return xBadModel; } - return pTablet->GetModel(pTablet); -} - -const char* WacomGetVendorName(WACOMTABLET hTablet) -{ - WACOMTABLET_PRIV* pTablet = (WACOMTABLET_PRIV*)hTablet; - if (!pTablet || !pTablet->GetVendorName) { errno=EBADF; return NULL; } - return pTablet->GetVendorName(pTablet); -} - -const char* WacomGetClassName(WACOMTABLET hTablet) -{ - WACOMTABLET_PRIV* pTablet = (WACOMTABLET_PRIV*)hTablet; - if (!pTablet || !pTablet->GetClassName) { errno=EBADF; return NULL; } - return pTablet->GetClassName(pTablet); -} - -const char* WacomGetDeviceName(WACOMTABLET hTablet) -{ - WACOMTABLET_PRIV* pTablet = (WACOMTABLET_PRIV*)hTablet; - if (!pTablet || !pTablet->GetDeviceName) { errno=EBADF; return NULL; } - return pTablet->GetDeviceName(pTablet); -} - -const char* WacomGetSubTypeName(WACOMTABLET hTablet) -{ - WACOMTABLET_PRIV* pTablet = (WACOMTABLET_PRIV*)hTablet; - if (!pTablet || !pTablet->GetSubTypeName) { errno=EBADF; return NULL; } - return pTablet->GetSubTypeName(pTablet); -} - -const char* WacomGetModelName(WACOMTABLET hTablet) -{ - WACOMTABLET_PRIV* pTablet = (WACOMTABLET_PRIV*)hTablet; - if (!pTablet || !pTablet->GetModelName) { errno=EBADF; return NULL; } - return pTablet->GetModelName(pTablet); -} - -int WacomGetROMVersion(WACOMTABLET hTablet, int* pnMajor, int* pnMinor, - int* pnRelease) -{ - WACOMTABLET_PRIV* pTablet = (WACOMTABLET_PRIV*)hTablet; - if (!pTablet || !pTablet->GetROMVer) { errno=EBADF; return 0; } - return pTablet->GetROMVer(pTablet,pnMajor,pnMinor,pnRelease); -} - -int WacomGetCapabilities(WACOMTABLET hTablet) -{ - WACOMTABLET_PRIV* pTablet = (WACOMTABLET_PRIV*)hTablet; - if (!pTablet || !pTablet->GetCaps) { errno=EBADF; return 0; } - return pTablet->GetCaps(pTablet); -} - -int WacomGetState(WACOMTABLET hTablet, WACOMSTATE* pState) -{ - WACOMTABLET_PRIV* pTablet = (WACOMTABLET_PRIV*)hTablet; - if (!pTablet || !pTablet->GetState) { errno=EBADF; return 0; } - return pTablet->GetState(pTablet,pState); -} - -int WacomGetFileDescriptor(WACOMTABLET hTablet) -{ - WACOMTABLET_PRIV* pTablet = (WACOMTABLET_PRIV*)hTablet; - if (!pTablet || !pTablet->GetFD) { errno=EBADF; return -1; } - return pTablet->GetFD(pTablet); -} - -int WacomReadRaw(WACOMTABLET hTablet, unsigned char* puchData, - unsigned int uSize) -{ - WACOMTABLET_PRIV* pTablet = (WACOMTABLET_PRIV*)hTablet; - if (!pTablet || !pTablet->ReadRaw) { errno=EBADF; return 0; } - return pTablet->ReadRaw(pTablet,puchData,uSize); -} - -int WacomParseData(WACOMTABLET hTablet, const unsigned char* puchData, - unsigned int uLength, WACOMSTATE* pState) -{ - WACOMTABLET_PRIV* pTablet = (WACOMTABLET_PRIV*)hTablet; - if (!pTablet || !pTablet->ParseData) { errno=EBADF; return 0; } - return pTablet->ParseData(pTablet,puchData,uLength,pState); -} diff --git a/src/util/wactablet.h b/src/util/wactablet.h deleted file mode 100755 index 76d7a1b..0000000 --- a/src/util/wactablet.h +++ /dev/null @@ -1,328 +0,0 @@ -/***************************************************************************** -** wactablet.h -** -** Copyright (C) 2002 - 2004 - John E. Joganic -** Copyright (C) 2003 - 2008 - Ping Cheng -** -** 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 Lesser 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -****************************************************************************/ - -#ifndef __LINUXWACOM_WACTABLET_H -#define __LINUXWACOM_WACTABLET_H - -#include <stdarg.h> -#include <sys/time.h> - -#define WACOMVENDOR_UNKNOWN 0x0000 -#define WACOMVENDOR_WACOM 0x056A -#define WACOMVENDOR_TPC 0xFFFFFF01 - -#define WACOMCLASS_SERIAL 0x0001 -#define WACOMCLASS_USB 0x0002 - -#define WACOMDEVICE_UNKNOWN 0x0000 -#define WACOMDEVICE_ARTPAD 0x0001 -#define WACOMDEVICE_ARTPADII 0x0002 -#define WACOMDEVICE_DIGITIZER 0x0003 -#define WACOMDEVICE_DIGITIZERII 0x0004 -#define WACOMDEVICE_PENPARTNER 0x0005 -#define WACOMDEVICE_GRAPHIRE 0x0006 -#define WACOMDEVICE_GRAPHIRE2 0x0007 -#define WACOMDEVICE_GRAPHIRE3 0x0008 -#define WACOMDEVICE_GRAPHIRE4 0x0009 -#define WACOMDEVICE_INTUOS 0x000A -#define WACOMDEVICE_INTUOS2 0x000B -#define WACOMDEVICE_CINTIQ 0x000C -#define WACOMDEVICE_PTU 0x000D -#define WACOMDEVICE_VOLITO 0x000E -#define WACOMDEVICE_VOLITO2 0x000F -#define WACOMDEVICE_TPC 0x0010 -#define WACOMDEVICE_INTUOS3 0x0011 -#define WACOMDEVICE_CINTIQV5 0x0012 -#define WACOMDEVICE_MO 0x0013 - -typedef struct _WACOMMODEL WACOMMODEL; -struct _WACOMMODEL -{ - unsigned int uClass; - unsigned int uVendor; - unsigned int uDevice; - unsigned int uSubType; -}; - -#define WACOMTOOLTYPE_NONE 0x00 -#define WACOMTOOLTYPE_PEN 0x01 -#define WACOMTOOLTYPE_PENCIL 0x02 -#define WACOMTOOLTYPE_BRUSH 0x03 -#define WACOMTOOLTYPE_ERASER 0x04 -#define WACOMTOOLTYPE_AIRBRUSH 0x05 -#define WACOMTOOLTYPE_MOUSE 0x06 -#define WACOMTOOLTYPE_LENS 0x07 -#define WACOMTOOLTYPE_PAD 0x08 -#define WACOMTOOLTYPE_TOUCH 0x09 -#define WACOMTOOLTYPE_MAX 0x0A - -#define WACOMBUTTON_LEFT 0 -#define WACOMBUTTON_MIDDLE 1 -#define WACOMBUTTON_RIGHT 2 -#define WACOMBUTTON_EXTRA 3 -#define WACOMBUTTON_SIDE 4 -#define WACOMBUTTON_TOUCH 5 -#define WACOMBUTTON_STYLUS 6 -#define WACOMBUTTON_STYLUS2 7 -#define WACOMBUTTON_BT0 8 -#define WACOMBUTTON_BT1 9 -#define WACOMBUTTON_BT2 10 -#define WACOMBUTTON_BT3 11 -#define WACOMBUTTON_BT4 12 -#define WACOMBUTTON_BT5 13 -#define WACOMBUTTON_BT6 14 -#define WACOMBUTTON_BT7 15 -#define WACOMBUTTON_BT8 16 -#define WACOMBUTTON_BT9 17 -#define WACOMBUTTON_BT10 18 -#define WACOMBUTTON_BT11 19 -#define WACOMBUTTON_BT12 20 -#define WACOMBUTTON_BT13 21 -#define WACOMBUTTON_BT14 22 -#define WACOMBUTTON_BT15 23 -#define WACOMBUTTON_BT16 24 -#define WACOMBUTTON_BT17 25 -#define WACOMBUTTON_BT18 26 -#define WACOMBUTTON_BT19 27 -#define WACOMBUTTON_BT20 28 -#define WACOMBUTTON_BT21 29 -#define WACOMBUTTON_BT22 30 -#define WACOMBUTTON_BT23 31 -#define WACOMBUTTON_MAX 32 - -#define WACOMFIELD_TOOLTYPE 0 -#define WACOMFIELD_SERIAL 1 -#define WACOMFIELD_PROXIMITY 2 -#define WACOMFIELD_BUTTONS 3 -#define WACOMFIELD_POSITION_X 4 -#define WACOMFIELD_POSITION_Y 5 -#define WACOMFIELD_ROTATION_Z 6 -#define WACOMFIELD_DISTANCE 7 -#define WACOMFIELD_PRESSURE 8 -#define WACOMFIELD_TILT_X 9 -#define WACOMFIELD_TILT_Y 10 -#define WACOMFIELD_ABSWHEEL 11 -#define WACOMFIELD_RELWHEEL 12 -#define WACOMFIELD_THROTTLE 13 -#define WACOMFIELD_MAX 14 - -typedef struct -{ - int nValue; - int nMin; - int nMax; - int nReserved; -} WACOMVALUE; - -typedef struct -{ - unsigned int uValueCnt; /* This MUST be set to WACOMFIELD_MAX. */ - unsigned int uValid; /* Bit mask of WACOMFIELD_xxx bits. */ - WACOMVALUE values[WACOMFIELD_MAX]; -} WACOMSTATE; - -#define WACOMSTATE_INIT { WACOMFIELD_MAX } - -typedef struct -{ - const char* pszName; - const char* pszDesc; - unsigned int uDeviceClass; -} WACOMCLASSREC; - -typedef struct -{ - const char* pszName; - const char* pszDesc; - const char* pszVendorName; - const char* pszVendorDesc; - const char* pszClass; - WACOMMODEL model; -} WACOMDEVICEREC; - -typedef enum -{ - WACOMLOGLEVEL_NONE, - WACOMLOGLEVEL_CRITICAL, - WACOMLOGLEVEL_ERROR, - WACOMLOGLEVEL_WARN, - WACOMLOGLEVEL_INFO, - WACOMLOGLEVEL_DEBUG, - WACOMLOGLEVEL_TRACE, - WACOMLOGLEVEL_MAX -} WACOMLOGLEVEL; - -typedef void (*WACOMLOGFUNC)(struct timeval tv, WACOMLOGLEVEL level, - const char* pszLog); - -/***************************************************************************** -** Public structures -*****************************************************************************/ - -typedef struct { int __unused; } *WACOMENGINE; -typedef struct { int __unused; } *WACOMTABLET; - -/***************************************************************************** -** Public API -*****************************************************************************/ - - WACOMENGINE WacomInitEngine(void); - /* Initialize the tablet engine */ - - void WacomTermEngine(WACOMENGINE hEngine); - /* Shutdown the tablet engine */ - - void WacomSetLogFunc(WACOMENGINE hEngine, WACOMLOGFUNC pfnLog); - void WacomSetLogLevel(WACOMENGINE hEngine, WACOMLOGLEVEL level); - void WacomLogV(WACOMENGINE hEngine, WACOMLOGLEVEL level, - const char* pszFmt, va_list args); - void WacomLog(WACOMENGINE hEngine, WACOMLOGLEVEL level, - const char* pszFmt, ...); - /* Logging functions. Default log function does nothing. */ - - int WacomGetSupportedClassList(WACOMCLASSREC** ppList, int* pnSize); - /* Returns 0 on success. Pointer to class record list is returned to - * ppList, and size of list to pnSize. Use WacomFreeList to release. */ - - int WacomGetSupportedDeviceList(unsigned int uDeviceClass, - WACOMDEVICEREC** ppList, int* pnSize); - /* Returns 0 on success. If device class is specified, only devices - * of the request type are returned. A value of 0 will return all - * devices for all classes. Pointer to device record list is returned to - * ppList, and size of list to pnSize. Use WacomFreeList to release. */ - - void WacomFreeList(void* pvList); - /* Releases list memory. */ - - int WacomCopyState(WACOMSTATE* pDest, WACOMSTATE* pSrc); - /* Returns 0 on success. Copies tablet state structures. - * Source and destination structures must be properly initialized, - * particularly the uValueCnt field must be set WACOMFIELD_MAX. - * Returns 0 on success. */ - - unsigned int WacomGetClassFromName(const char* pszName); - /* Returns the device class for a given name. Returns 0, if unknown. */ - - unsigned int WacomGetDeviceFromName(const char* pszName, - unsigned int uDeviceClass); - /* Returns the device type for a given device name. If the - * device class is specified, only that class will be searched. - * Returns 0, if unknown. */ - - WACOMTABLET WacomOpenTablet(WACOMENGINE hEngine, - const char* pszDevice, WACOMMODEL* pModel); - /* Returns tablet handle on success, NULL otherwise. - * pszDevice is pathname to device. Model may be NULL; if any model - * parameters are 0, detection is automatic. */ - - void WacomCloseTablet(WACOMTABLET hTablet); - /* Releases all resource associated with tablet and closes device. */ - - WACOMMODEL WacomGetModel(WACOMTABLET hTablet); - /* Returns model (vendor, class, and device) of specified tablet. */ - - const char* WacomGetVendorName(WACOMTABLET hTablet); - /* Returns vendor name as human-readable string. String is valid as - * long as tablet handle is valid and does not need to be freed. */ - - const char* WacomGetClassName(WACOMTABLET hTablet); - /* Returns class name as human-readable string. String is valid as - * long as tablet handle is valid and does not need to be freed. */ - - const char* WacomGetDeviceName(WACOMTABLET hTablet); - /* Returns device name as human-readable string. String is valid as - * long as tablet handle is valid and does not need to be freed. */ - - const char* WacomGetSubTypeName(WACOMTABLET hTablet); - /* Returns subtype name as human-readable string. This is typically - * the model number (eg. ABC-1234). String is valid as long as tablet - * handle is valid and does not need to be freed. */ - - const char* WacomGetModelName(WACOMTABLET hTablet); - /* Returns model name as human-readable string. This is typically - * the full model name (eg. FooCo FooModel 9x12). String is valid as - * long as tablet handle is valid and does not need to be freed. */ - - int WacomGetROMVersion(WACOMTABLET hTablet, int* pnMajor, int* pnMinor, - int* pnRelease); - /* Returns 0 on success. ROM version of the tablet firmware is returned - * in major, minor, and release values. If the caller needs to - * distinguish between ROM versions to work around a bug, please consider - * submitting a patch to this library. All tablets should appear - * equivalent through this interface. This call is provided for - * information purposes. */ - - int WacomGetCapabilities(WACOMTABLET hTablet); - /* Returns bitmask of valid fields. Use (1 << WACOMFIELD_xxx) to - * translate field identifiers to bit positions. This API will only - * support 32 capabilities. */ - - int WacomGetState(WACOMTABLET hTablet, WACOMSTATE* pState); - /* Returns 0 on success. Tablet state is copied to specified structure. - * Data is only a snapshot of the device and may not accurately reflect - * the position of any specific tool. This is particularly true of - * multi-tool mode tablets. NOTE: pState must point to an initialized - * structure; the uValueCnt field must be correctly set to - * WACOMFIELD_MAX. */ - - int WacomGetFileDescriptor(WACOMTABLET hTablet); - /* Returns the file descriptor of the tablet or -1 on error. */ - - int WacomReadRaw(WACOMTABLET hTablet, unsigned char* puchData, - unsigned int uSize); - /* Returns number of bytes read, typically a single packet. Call will - * block. uSize should be the maximum size of the given data buffer. */ - - int WacomParseData(WACOMTABLET hTablet, const unsigned char* puchData, - unsigned int uLength, WACOMSTATE* pState); - /* Updates the tablet state from a given packet. If pState is specified, - * the tablet state is copied to the given structure. This structure - * must be correctly initialized; the uValueCnt member must be set to - * WACOMFIELD_MAX. Returns 0 on success. */ - -/***************************************************************************** -** Private structures -*****************************************************************************/ - -typedef struct _WACOMTABLET_PRIV WACOMTABLET_PRIV; - -struct _WACOMTABLET_PRIV -{ - void (*Close)(WACOMTABLET_PRIV* pTablet); - WACOMMODEL (*GetModel)(WACOMTABLET_PRIV* pTablet); - const char* (*GetVendorName)(WACOMTABLET_PRIV* pTablet); - const char* (*GetClassName)(WACOMTABLET_PRIV* pTablet); - const char* (*GetDeviceName)(WACOMTABLET_PRIV* pTablet); - const char* (*GetSubTypeName)(WACOMTABLET_PRIV* pTablet); - const char* (*GetModelName)(WACOMTABLET_PRIV* pTablet); - int (*GetROMVer)(WACOMTABLET_PRIV* pTablet, int* pnMajor, int* pnMinor, - int* pnRelease); - int (*GetCaps)(WACOMTABLET_PRIV* pTablet); - int (*GetState)(WACOMTABLET_PRIV* pTablet, WACOMSTATE* pState); - int (*GetFD)(WACOMTABLET_PRIV* pTablet); - int (*ReadRaw)(WACOMTABLET_PRIV* pTablet, unsigned char* puchData, - unsigned int uSize); - int (*ParseData)(WACOMTABLET_PRIV* pTablet, const unsigned char* puchData, - unsigned int uLength, WACOMSTATE* pState); -}; - -#endif /* __LINUXWACOM_WACTABLET_H */ diff --git a/src/util/wacusb.c b/src/util/wacusb.c deleted file mode 100755 index c83f7f4..0000000 --- a/src/util/wacusb.c +++ /dev/null @@ -1,1051 +0,0 @@ -/***************************************************************************** -** wacusb.c -** -** Copyright (C) 2002 - 2004 - John E. Joganic -** Copyright (C) 2003 - 2009 - Ping Cheng -** -** 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 Lesser 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -****************************************************************************/ - -#include "../include/util-config.h" - -#include "wacusb.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <assert.h> - -/***************************************************************************** -** Begin USB Linux Input Subsystem -*****************************************************************************/ - -#ifdef WCM_ENABLE_LINUXINPUT -#include <linux/input.h> - -#ifndef EV_MSC -#define EV_MSC 0x04 -#endif - -#ifndef MSC_SERIAL -#define MSC_SERIAL 0x00 -#endif - -#ifndef BTN_TOOL_DOUBLETAP -#define BTN_TOOL_DOUBLETAP 0x14d -#endif - -/***************************************************************************** -** Defines -*****************************************************************************/ - -/* from linux/input.h */ -#define BITS_PER_LONG (sizeof(long) * 8) -#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) -#define BIT(x) (1UL<<((x)%BITS_PER_LONG)) -#define LONG(x) ((x)/BITS_PER_LONG) -#define ISBITSET(x,y) ((x)[LONG(y)] & BIT(y)) - -#define MAX_CHANNELS 2 -#define MAX_USB_EVENTS 32 - -/***************************************************************************** -** Structures -*****************************************************************************/ - -typedef struct _USBSUBTYPE USBSUBTYPE; -typedef struct _USBDEVICE USBDEVICE; -typedef struct _USBVENDOR USBVENDOR; - -struct _USBSUBTYPE -{ - const char* pszName; - const char* pszDesc; - unsigned int uSubType; - unsigned int uProduct; -}; - -struct _USBDEVICE -{ - const char* pszName; - const char* pszDesc; - unsigned int uDevice; - USBSUBTYPE* pSubTypes; - unsigned int uChannelCnt; -}; - -struct _USBVENDOR -{ - const char* pszName; - const char* pszDesc; - unsigned int uVendor; - USBDEVICE* pDevices; -}; - -/***************************************************************************** -** USB Tablet object -*****************************************************************************/ - -typedef struct _USBTABLET USBTABLET; - -struct _USBTABLET -{ - WACOMTABLET_PRIV tablet; - WACOMENGINE hEngine; - int fd; - USBVENDOR* pVendor; - USBDEVICE* pDevice; - USBSUBTYPE* pSubType; - int nBus; - int nVersion; - WACOMSTATE state[MAX_CHANNELS]; - int nToolProx[MAX_CHANNELS]; - int nChannel; - int nLastToolSerial; - int nEventCnt; - struct input_event events[MAX_USB_EVENTS]; -}; - -/***************************************************************************** -** Autodetect pad key codes -*****************************************************************************/ - -static unsigned short padkey_codes [] = -{ - BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, - BTN_5, BTN_6, BTN_7, BTN_8, BTN_9, - BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, - BTN_BASE, BTN_BASE2, BTN_BASE3, - BTN_BASE4, BTN_BASE5, BTN_BASE6, - BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_SELECT -}; - -int gPadKeys [WACOMBUTTON_MAX]; -int gNumPadKeys; - -/***************************************************************************** -** Static Prototypes -*****************************************************************************/ - -static void USBClose(WACOMTABLET_PRIV* pTablet); -static WACOMMODEL USBGetModel(WACOMTABLET_PRIV* pTablet); -static const char* USBGetVendorName(WACOMTABLET_PRIV* pTablet); -static const char* USBGetClassName(WACOMTABLET_PRIV* pTablet); -static const char* USBGetDeviceName(WACOMTABLET_PRIV* pTablet); -static const char* USBGetSubTypeName(WACOMTABLET_PRIV* pTablet); -static const char* USBGetModelName(WACOMTABLET_PRIV* pTablet); -static int USBGetROMVer(WACOMTABLET_PRIV* pTablet, int* pnMajor, - int* pnMinor, int* pnRelease); -static int USBGetCaps(WACOMTABLET_PRIV* pTablet); -static int USBGetState(WACOMTABLET_PRIV* pTablet, WACOMSTATE* pState); -static int USBGetFD(WACOMTABLET_PRIV* pTablet); -static int USBReadRaw(WACOMTABLET_PRIV* pTablet, unsigned char* puchData, - unsigned int uSize); -static int USBParseData(WACOMTABLET_PRIV* pTablet, - const unsigned char* puchData, unsigned int uLength, - WACOMSTATE* pState); - -static int USBFindModel(USBTABLET* pUSB, unsigned int uVendor, - unsigned int uProduct); -static int USBIdentifyModel(USBTABLET* pUSB); - -/***************************************************************************** -** Globals -*****************************************************************************/ - - static USBSUBTYPE xPenPartner[] = - { - { "MODEL_PP_0405", "Wacom PenPartner", 1, 0x00 }, - { NULL } - }; - - static USBSUBTYPE xGraphire[] = - { - { "ET_0405", "Wacom Graphire", 1, 0x10 }, - { NULL } - }; - - static USBSUBTYPE xGraphire2[] = - { - { "ET_0405", "Wacom Graphire2 4x5", 1, 0x11 }, - { "ET_0507", "Wacom Graphire2 5x7", 2, 0x12 }, - { NULL } - }; - - static USBSUBTYPE xGraphire3[] = - { - { "ET_0405", "Wacom Graphire3 4x5", 1, 0x13 }, - { "ET_0608", "Wacom Graphire3 6x8", 2, 0x14 }, - { NULL } - }; - - static USBSUBTYPE xGraphire4[] = - { - { "CTE_440", "Wacom Graphire4 4x5", 1, 0x15 }, - { "CTE_640", "Wacom Graphire4 6x8", 2, 0x16 }, - { NULL } - }; - - static USBSUBTYPE xIntuos[] = - { - { "GD_0405-U", "Wacom Intuos 4x5", 1, 0x20 }, - { "GD_0608-U", "Wacom Intuos 6x8", 2, 0x21 }, - { "GD_0912-U", "Wacom Intuos 9x12", 3, 0x22 }, - { "GD_1212-U", "Wacom Intuos 12x12", 4, 0x23 }, - { "GD_1218-U", "Wacom Intuos 12x18", 5, 0x24 }, - { NULL } - }; - - static USBSUBTYPE xCintiq[] = - { - { "MODEL_PL400", "Wacom PL400", 1, 0x30 }, - { "MODEL_PL500", "Wacom PL500", 2, 0x31 }, - { "MODEL_PL600", "Wacom PL600", 3, 0x32 }, - { "MODEL_PL600SX", "Wacom PL600SX", 4, 0x33 }, - { "MODEL_PL550", "Wacom PL550", 5, 0x34 }, - { "MODEL_PL800", "Wacom PL800", 6, 0x35 }, - { "MODEL_PL700", "Wacom PL700", 7, 0x37 }, - { "MODEL_PL510", "Wacom PL510", 8, 0x38 }, - { "MODEL_DTU710", "Wacom PL710", 9, 0x39 }, - { "MODEL_DTF720", "Wacom DTF720", 10, 0xC0 }, - { "MODEL_DTF521", "Wacom DTF521", 11, 0xC4 }, - { "MODEL_DTU1931", "Wacom DTU1931", 12, 0xC7 }, - { NULL } - }; - - static USBSUBTYPE xIntuos2[] = - { - { "XD-0405-U", "Wacom Intuos2 4x5", 1, 0x41 }, - { "XD-0608-U", "Wacom Intuos2 6x8", 2, 0x42 }, - { "XD-0912-U", "Wacom Intuos2 9x12", 3, 0x43 }, - { "XD-1212-U", "Wacom Intuos2 12x12", 4, 0x44 }, - { "XD-1218-U", "Wacom Intuos2 12x18", 5, 0x45 }, - - /* fix for I2 6x8's reporting as 0x47 */ - { "XD-0608-U", "Wacom Intuos2 6x8", 2, 0x47 }, - - { NULL } - }; - - static USBSUBTYPE xVolito[] = - { - { "MODEL-VOL", "Wacom Volito", 1, 0x60 }, - { NULL } - }; - - static USBSUBTYPE xVolito2[] = - { - { "FT-0203-U", "Wacom PenStation", 1, 0x61 }, - { "CTF-420-U", "Wacom Volito2 4x5", 2, 0x62 }, - { "CTF-220-U", "Wacom Volito2 2x3", 3, 0x63 }, - { "CTF-421-U", "Wacom PenPartner2", 4, 0x64 }, - { "CTF_430-U", "Wacom Bamboo1", 5, 0x69 }, - { NULL } - }; - - static USBSUBTYPE xBamboo[] = - { - { "MTE_450", "Wacom Bamboo", 1, 0x65 }, - { "CTE_450", "Wacom BambooFun 4x5", 2, 0x17 }, - { "CTE_650", "Wacom BambooFun 6x8", 3, 0x18 }, - { "CTE_631", "Wacom Bamboo1 Medium", 4, 0x19 }, - { NULL } - }; - - static USBSUBTYPE xCintiqPartner[] = - { - { "PTU-600", "Wacom Cintiq Partner", 1, 0x03 }, - { NULL } - }; - - static USBSUBTYPE xTabletPC[] = - { - { "TPC-090", "Wacom Tablet PC90", 1, 0x90 }, - { "TPC-093", "Wacom Tablet PC93", 2, 0x93 }, - { "TPC-09A", "Wacom Tablet PC9A", 3, 0x9A }, - { NULL } - }; - - static USBSUBTYPE xCintiqV5[] = - { - { "DTZ-21ux", "Wacom Cintiq 21UX", 1, 0x3F }, - { "DTZ-20wsx", "Wacom Cintiq 20WSX", 2, 0xC5 }, - { "DTZ-12wx", "Wacom Cintiq 12WX", 3, 0xC6 }, - { NULL } - }; - - static USBSUBTYPE xIntuos3[] = - { - { "PTZ-430", "Wacom Intuos3 4x5", 1, 0xB0 }, - { "PTZ-630", "Wacom Intuos3 6x8", 2, 0xB1 }, - { "PTZ-930", "Wacom Intuos3 9x12", 3, 0xB2 }, - { "PTZ-1230", "Wacom Intuos3 12x12", 4, 0xB3 }, - { "PTZ-1231W", "Wacom Intuos3 12x19", 5, 0xB4 }, - { "PTZ-631W", "Wacom Intuos3 6x11", 6, 0xB5 }, - { "PTZ-431W", "Wacom Intuos3 4x6", 7, 0xB7 }, - { NULL } - }; - - static USBSUBTYPE xIntuos4[] = - { - { "PTK-440", "Wacom Intuos4 4x6", 1, 0xB8 }, - { "PTK-640", "Wacom Intuos4 6x9", 2, 0xB9 }, - { "PTK-840", "Wacom Intuos4 8x13", 3, 0xBA }, - { "PTZ-1240", "Wacom Intuos4 12x19", 4, 0xBB }, - { NULL } - }; - - static USBDEVICE xWacomDevices[] = - { - { "pp", "PenPartner", WACOMDEVICE_PENPARTNER, xPenPartner, 1 }, - { "gr", "Graphire", WACOMDEVICE_GRAPHIRE, xGraphire, 1 }, - { "gr2", "Graphire2", WACOMDEVICE_GRAPHIRE2, xGraphire2, 1 }, - { "gr3", "Graphire3", WACOMDEVICE_GRAPHIRE3, xGraphire3, 1 }, - { "gr4", "Graphire4", WACOMDEVICE_GRAPHIRE4, xGraphire4, 2 }, - { "int", "Intuos", WACOMDEVICE_INTUOS, xIntuos, 2 }, - { "int2", "Intuos2", WACOMDEVICE_INTUOS2, xIntuos2, 2 }, - { "int3", "Intuos3", WACOMDEVICE_INTUOS3, xIntuos3, 2 }, - { "int4", "Intuos4", WACOMDEVICE_INTUOS3, xIntuos4, 2 }, - { "ctq", "Cintiq (V5)", WACOMDEVICE_CINTIQV5, xCintiqV5, 2 }, - { "pl", "Cintiq (PL)", WACOMDEVICE_CINTIQ, xCintiq, 1 }, - { "ptu", "Cintiq Partner (PTU)", WACOMDEVICE_PTU, xCintiqPartner, 1 }, - { "vol", "Volito", WACOMDEVICE_VOLITO, xVolito, 1 }, - { "vol2", "Volito2", WACOMDEVICE_VOLITO2, xVolito2, 1 }, - { "mo", "Bamboo", WACOMDEVICE_MO, xBamboo, 2 }, - { "tpc", "Tablet PC", WACOMDEVICE_TPC, xTabletPC, 1 }, - { NULL } - }; - - static USBVENDOR xVendors[] = - { - { "wacom", "Wacom", WACOMVENDOR_WACOM, xWacomDevices }, - { NULL }, - }; - -/***************************************************************************** -** Public Functions -*****************************************************************************/ - -typedef struct -{ - void (*pfnFree)(void* pv); -} DEVLIST_INTERNAL; - -static void USBFreeDeviceList(void* pv) -{ - DEVLIST_INTERNAL* pInt = ((DEVLIST_INTERNAL*)pv) - 1; - free(pInt); -} - -int WacomGetSupportedUSBDeviceList(WACOMDEVICEREC** ppList, int* pnSize) -{ - int nIndex=0, nCnt=0; - DEVLIST_INTERNAL* pInt; - USBDEVICE* pDev; - USBVENDOR* pVendor; - WACOMDEVICEREC* pRec; - - if (!ppList || !pnSize) { errno = EINVAL; return 1; } - - /* for each vendor, count up devices */ - for (pVendor=xVendors; pVendor->pszName; ++pVendor) - { - /* count up devices */ - for (pDev=pVendor->pDevices; pDev->pszName; ++pDev, ++nCnt) ; - } - - /* allocate enough memory to hold internal structure and all records */ - pInt = (DEVLIST_INTERNAL*)malloc(sizeof(DEVLIST_INTERNAL) + - (sizeof(WACOMDEVICEREC) * nCnt)); - - pInt->pfnFree = USBFreeDeviceList; - pRec = (WACOMDEVICEREC*)(pInt + 1); - - /* for each vendor, add devices */ - for (pVendor=xVendors; pVendor->pszName; ++pVendor) - { - for (pDev=pVendor->pDevices; pDev->pszName; ++pDev, ++nIndex) - { - pRec[nIndex].pszName = pDev->pszName; - pRec[nIndex].pszDesc = pDev->pszDesc; - pRec[nIndex].pszVendorName = pVendor->pszName; - pRec[nIndex].pszVendorDesc = pVendor->pszDesc; - pRec[nIndex].pszClass = "usb"; - pRec[nIndex].model.uClass = WACOMCLASS_USB; - pRec[nIndex].model.uVendor = pVendor->uVendor; - pRec[nIndex].model.uDevice = pDev->uDevice; - pRec[nIndex].model.uSubType = 0; - } - } - assert(nIndex == nCnt); - - *ppList = pRec; - *pnSize = nCnt; - return 0; -} - -unsigned int WacomGetUSBDeviceFromName(const char* pszName) -{ - USBDEVICE* pDev; - USBVENDOR* pVendor; - - if (!pszName) { errno = EINVAL; return 0; } - - /* for each vendor, look for device */ - for (pVendor=xVendors; pVendor->pszName; ++pVendor) - { - /* count up devices */ - for (pDev=pVendor->pDevices; pDev->pszName; ++pDev) - { - if (strcasecmp(pszName,pDev->pszName) == 0) - return pDev->uDevice; - } - } - - errno = ENOENT; - return 0; -} - -WACOMTABLET WacomOpenUSBTablet(WACOMENGINE hEngine, int fd, WACOMMODEL* pModel) -{ - USBTABLET* pUSB = NULL; - - /* Allocate tablet */ - pUSB = (USBTABLET*)malloc(sizeof(USBTABLET)); - memset(pUSB,0,sizeof(*pUSB)); - pUSB->tablet.Close = USBClose; - pUSB->tablet.GetModel = USBGetModel; - pUSB->tablet.GetVendorName = USBGetVendorName; - pUSB->tablet.GetClassName = USBGetClassName; - pUSB->tablet.GetDeviceName = USBGetDeviceName; - pUSB->tablet.GetSubTypeName = USBGetSubTypeName; - pUSB->tablet.GetModelName = USBGetModelName; - pUSB->tablet.GetROMVer = USBGetROMVer; - pUSB->tablet.GetCaps = USBGetCaps; - pUSB->tablet.GetState = USBGetState; - pUSB->tablet.GetFD = USBGetFD; - pUSB->tablet.ReadRaw = USBReadRaw; - pUSB->tablet.ParseData = USBParseData; - pUSB->hEngine = hEngine; - pUSB->fd = fd; - - /* Identify and initialize the model */ - if (USBIdentifyModel(pUSB)) - { - WacomLog(pUSB->hEngine,WACOMLOGLEVEL_ERROR, - "Failed to identify model: %s",strerror(errno)); - free(pUSB); - return NULL; - } - - return (WACOMTABLET)pUSB; -} - -/***************************************************************************** -** Tablet Functions -*****************************************************************************/ - -static void USBClose(WACOMTABLET_PRIV* pTablet) -{ - USBTABLET* pUSB = (USBTABLET*)pTablet; - close(pUSB->fd); - free(pUSB); -} - -static WACOMMODEL USBGetModel(WACOMTABLET_PRIV* pTablet) -{ - WACOMMODEL model = { 0 }; - USBTABLET* pUSB = (USBTABLET*)pTablet; - model.uClass = WACOMCLASS_USB; - model.uVendor = pUSB->pVendor->uVendor; - model.uDevice = pUSB->pDevice->uDevice; - model.uSubType = pUSB->pSubType->uSubType; - return model; -} - -static int USBGetRange(USBTABLET* pUSB, unsigned long* pBits, int nAbsField, - unsigned int uField) -{ - int nAbs[5]; - - if (!ISBITSET(pBits,nAbsField)) - return 0; - if (ioctl(pUSB->fd, EVIOCGABS(nAbsField), nAbs) != 0) - return 1; - - pUSB->state[0].values[uField].nMin = nAbs[1]; - pUSB->state[0].values[uField].nMax = nAbs[2]; - pUSB->state[0].uValid |= BIT(uField); - return 0; -} - -static int USBFindModel(USBTABLET* pUSB, unsigned int uVendor, - unsigned int uProduct) -{ - USBVENDOR* pVendor = NULL; - USBDEVICE* pDev = NULL; - USBSUBTYPE* pSub = NULL; - - static USBSUBTYPE xUnkSub[] = - { - { "UNKNOWN", "Unknown", 1, 0x00 }, - { NULL } - }; - - static USBDEVICE xUnkDev[] = - { - { "unk", "Unknown", WACOMDEVICE_UNKNOWN, xUnkSub, MAX_CHANNELS }, - { NULL } - }; - - static USBVENDOR xUnkVendor = - { "unknown", "Unknown", WACOMVENDOR_UNKNOWN, xUnkDev }; - - for (pVendor=xVendors; pVendor->pszName; ++pVendor) - { - if (pVendor->uVendor == uVendor) - { - for (pDev=pVendor->pDevices; pDev->pszName; ++pDev) - { - for (pSub=pDev->pSubTypes; pSub->pszName; ++pSub) - { - if (pSub->uProduct == uProduct) - { - pUSB->pVendor = pVendor; - pUSB->pDevice = pDev; - pUSB->pSubType = pSub; - return 0; - } - } - } - - /* only one vendor of this type, so we're done */ - break; - } - } - - /* unknown vendor */ - pUSB->pVendor = &xUnkVendor; - pUSB->pDevice = pUSB->pVendor->pDevices; - pUSB->pSubType = pUSB->pDevice->pSubTypes; - return 0; -} - -static int USBIdentifyModel(USBTABLET* pUSB) -{ - int nCnt, chcnt; - short sID[4]; - unsigned int uVendor, uProduct; - unsigned long evbits[NBITS(EV_MAX)]; - unsigned long absbits[NBITS(ABS_MAX)]; - unsigned long relbits[NBITS(REL_MAX)]; - unsigned long keybits[NBITS(KEY_MAX)]; - - /* Get device name and id */ - if (ioctl(pUSB->fd,EVIOCGID,sID) < 0) - return 1; - - /* initialize state structure */ - pUSB->state[0].uValueCnt = WACOMFIELD_MAX; - - /* Get event types supported */ - nCnt = ioctl(pUSB->fd,EVIOCGBIT(0 /*EV*/,sizeof(evbits)),evbits); - if (nCnt < 0) - { - WacomLog(pUSB->hEngine,WACOMLOGLEVEL_ERROR, - "Failed to CGBIT ev: %s",strerror(errno)); - return 1; - } - assert(nCnt == sizeof(evbits)); - - /* absolute events */ - if (ISBITSET(evbits,EV_ABS)) - { - nCnt = ioctl(pUSB->fd,EVIOCGBIT(EV_ABS,sizeof(absbits)),absbits); - if (nCnt < 0) - { - WacomLog(pUSB->hEngine,WACOMLOGLEVEL_ERROR, - "Failed to CGBIT abs: %s",strerror(errno)); - return 1; - } - - /* the following line has problem on Debian systems - assert(nCnt == sizeof(absbits)); - */ - - if (USBGetRange(pUSB,absbits,ABS_X,WACOMFIELD_POSITION_X) || - USBGetRange(pUSB,absbits,ABS_Y,WACOMFIELD_POSITION_Y) || - USBGetRange(pUSB,absbits,ABS_RZ,WACOMFIELD_ROTATION_Z) || - USBGetRange(pUSB,absbits,ABS_DISTANCE,WACOMFIELD_DISTANCE) || - USBGetRange(pUSB,absbits,ABS_PRESSURE,WACOMFIELD_PRESSURE) || - USBGetRange(pUSB,absbits,ABS_TILT_X,WACOMFIELD_TILT_X) || - USBGetRange(pUSB,absbits,ABS_TILT_Y,WACOMFIELD_TILT_Y) || - USBGetRange(pUSB,absbits,ABS_WHEEL,WACOMFIELD_ABSWHEEL) || - USBGetRange(pUSB,absbits,ABS_THROTTLE,WACOMFIELD_THROTTLE)) - return 1; - - } - - /* relative events */ - if (ISBITSET(evbits,EV_REL)) - { - nCnt = ioctl(pUSB->fd,EVIOCGBIT(EV_REL,sizeof(relbits)),relbits); - if (nCnt < 0) - { - WacomLog(pUSB->hEngine,WACOMLOGLEVEL_ERROR, - "Failed to CGBIT rel: %s",strerror(errno)); - return 1; - } - assert(nCnt == sizeof(relbits)); - - if (ISBITSET(relbits,REL_WHEEL)) - { - pUSB->state[0].uValid |= BIT(WACOMFIELD_RELWHEEL); - pUSB->state[0].values[WACOMFIELD_RELWHEEL].nMin = -1; - pUSB->state[0].values[WACOMFIELD_RELWHEEL].nMax = 1; - } - } - - /* key events */ - gNumPadKeys = 0; - if (ISBITSET(evbits,EV_KEY)) - { - nCnt = ioctl(pUSB->fd,EVIOCGBIT(EV_KEY,sizeof(keybits)),keybits); - if (nCnt < 0) - { - WacomLog(pUSB->hEngine,WACOMLOGLEVEL_ERROR, - "Failed to CGBIT key: %s",strerror(errno)); - return 1; - } - assert(nCnt == sizeof(keybits)); - - /* button events */ - if (ISBITSET(keybits,BTN_LEFT) || - ISBITSET(keybits,BTN_RIGHT) || - ISBITSET(keybits,BTN_MIDDLE) || - ISBITSET(keybits,BTN_SIDE) || - ISBITSET(keybits,BTN_EXTRA)) - pUSB->state[0].uValid |= BIT(WACOMFIELD_BUTTONS); - - /* tool events */ - if (ISBITSET(keybits,BTN_TOOL_PEN) || - ISBITSET(keybits,BTN_TOOL_RUBBER) || - ISBITSET(keybits,BTN_TOOL_BRUSH) || - ISBITSET(keybits,BTN_TOOL_PENCIL) || - ISBITSET(keybits,BTN_TOOL_AIRBRUSH) || - ISBITSET(keybits,BTN_TOOL_FINGER) || - ISBITSET(keybits,BTN_TOOL_MOUSE) || - ISBITSET(keybits,BTN_TOOL_LENS) || - ISBITSET(keybits,BTN_TOOL_DOUBLETAP)) - pUSB->state[0].uValid |= BIT(WACOMFIELD_PROXIMITY) | - BIT(WACOMFIELD_TOOLTYPE); - - /* Detect button codes */ - for (nCnt = 0; nCnt < WACOMBUTTON_MAX; nCnt++) - if (ISBITSET (keybits, padkey_codes [nCnt])) - gPadKeys [gNumPadKeys++] = padkey_codes [nCnt]; - } - - /* set identification */ - pUSB->nBus = sID[0]; - uVendor = sID[1]; - uProduct = sID[2]; - pUSB->nVersion = sID[3]; - - if (USBFindModel(pUSB,uVendor,uProduct)) - return 1; - - /* add additional capabilities by device type */ - switch (pUSB->pDevice->uDevice) - { - case WACOMDEVICE_MO: - case WACOMDEVICE_GRAPHIRE4: - case WACOMDEVICE_INTUOS: - case WACOMDEVICE_INTUOS2: - case WACOMDEVICE_INTUOS3: - case WACOMDEVICE_CINTIQV5: - pUSB->state[0].uValid |= BIT(WACOMFIELD_SERIAL); - default: ; - } - - /* Initialize all channels with the same values */ - for(chcnt=1; chcnt<MAX_CHANNELS; chcnt++) - pUSB->state[chcnt] = pUSB->state[0]; - - return 0; -} - -static const char* USBGetVendorName(WACOMTABLET_PRIV* pTablet) -{ - USBTABLET* pUSB = (USBTABLET*)pTablet; - return pUSB->pVendor->pszDesc; -} - -static const char* USBGetClassName(WACOMTABLET_PRIV* pTablet) -{ - return "USB"; -} - -static const char* USBGetDeviceName(WACOMTABLET_PRIV* pTablet) -{ - USBTABLET* pUSB = (USBTABLET*)pTablet; - return pUSB->pDevice->pszDesc; -} - -static const char* USBGetSubTypeName(WACOMTABLET_PRIV* pTablet) -{ - USBTABLET* pUSB = (USBTABLET*)pTablet; - return pUSB->pSubType->pszName; -} - -static const char* USBGetModelName(WACOMTABLET_PRIV* pTablet) -{ - USBTABLET* pUSB = (USBTABLET*)pTablet; - return pUSB->pSubType->pszDesc; -} - -static int USBGetROMVer(WACOMTABLET_PRIV* pTablet, int* pnMajor, - int* pnMinor, int* pnRelease) -{ - USBTABLET* pUSB = (USBTABLET*)pTablet; - if (!pnMajor) { errno=EINVAL; return 1; } - - /* how is the version number broken down? - * mine says 0x115. is that 1.1.5 or 1.15? */ - *pnMajor = pUSB->nVersion >> 8; - *pnMinor = (pUSB->nVersion >> 4) & 0xF; - *pnRelease = (pUSB->nVersion & 0xF); - return 0; -} - -static int USBGetCaps(WACOMTABLET_PRIV* pTablet) -{ - USBTABLET* pUSB = (USBTABLET*)pTablet; - return pUSB->state[0].uValid; -} - -static int USBGetState(WACOMTABLET_PRIV* pTablet, WACOMSTATE* pState) -{ - USBTABLET* pUSB = (USBTABLET*)pTablet; - return WacomCopyState(pState,&pUSB->state[pUSB->nChannel]); -} - -static int USBGetFD(WACOMTABLET_PRIV* pTablet) -{ - USBTABLET* pUSB = (USBTABLET*)pTablet; - return pUSB->fd; -} - -static int USBReadRaw(WACOMTABLET_PRIV* pTablet, unsigned char* puchData, - unsigned int uSize) -{ - int nXfer; - unsigned int uCnt, uPacketLength; - USBTABLET* pUSB = (USBTABLET*)pTablet; - uPacketLength = sizeof(struct input_event); - - /* check size of buffer */ - if (uSize < uPacketLength) { errno=EINVAL; return 0; } - - for (uCnt=0; uCnt<uPacketLength; uCnt+=nXfer) - { - nXfer = read(pUSB->fd,puchData+uCnt,uPacketLength-uCnt); - if (nXfer <= 0) return nXfer; - } - - return (signed)uCnt; -} - -static int USBParseMSC(USBTABLET* pUSB, struct input_event* pEv) -{ - if (pEv->code == MSC_SERIAL && pEv->value) - pUSB->state[pUSB->nChannel].values[WACOMFIELD_SERIAL].nValue = pEv->value; - if (!pUSB->state[pUSB->nChannel].values[WACOMFIELD_PROXIMITY].nValue) - pUSB->state[pUSB->nChannel].values[WACOMFIELD_SERIAL].nValue = 0; - return 0; -} - -static int USBParseKEY(USBTABLET* pUSB, struct input_event* pEv) -{ - int i, button=-1, tool=0; - switch (pEv->code) - { - case BTN_LEFT: button = WACOMBUTTON_LEFT; break; - case BTN_RIGHT: button = WACOMBUTTON_RIGHT; break; - case BTN_MIDDLE: button = WACOMBUTTON_MIDDLE; break; - case BTN_SIDE: button = WACOMBUTTON_SIDE; break; - case BTN_EXTRA: button = WACOMBUTTON_EXTRA; break; - case BTN_TOUCH: button = WACOMBUTTON_TOUCH; break; - case BTN_STYLUS: button = WACOMBUTTON_STYLUS; break; - case BTN_STYLUS2: button = WACOMBUTTON_STYLUS2; break; - case BTN_TOOL_PEN: tool = WACOMTOOLTYPE_PEN; break; - case BTN_TOOL_PENCIL: tool = WACOMTOOLTYPE_PENCIL; break; - case BTN_TOOL_BRUSH: tool = WACOMTOOLTYPE_BRUSH; break; - case BTN_TOOL_RUBBER: tool = WACOMTOOLTYPE_ERASER; break; - case BTN_TOOL_AIRBRUSH: tool = WACOMTOOLTYPE_AIRBRUSH; break; - case BTN_TOOL_MOUSE: tool = WACOMTOOLTYPE_MOUSE; break; - case BTN_TOOL_FINGER: tool = WACOMTOOLTYPE_PAD; break; - case BTN_TOOL_LENS: tool = WACOMTOOLTYPE_LENS; break; - case BTN_TOOL_DOUBLETAP: tool = WACOMTOOLTYPE_TOUCH; break; - default: - for (i = 0; i < gNumPadKeys; i++) - if (pEv->code == gPadKeys [i]) - { - button = WACOMBUTTON_BT0 + i; - break; - } - } - - /* if button was specified */ - if (button != -1) - { - /* button state change */ - if (pEv->value) - pUSB->state[pUSB->nChannel].values[WACOMFIELD_BUTTONS].nValue |= BIT(button); - else - pUSB->state[pUSB->nChannel].values[WACOMFIELD_BUTTONS].nValue &= ~BIT(button); - } - - /* if a tool was specified */ - if (tool) - { - /* coming into proximity */ - if (pEv->value) - { - /* no prior tool in proximity */ - if (!(pUSB->nToolProx[pUSB->nChannel] & BIT(tool))) - { - pUSB->state[pUSB->nChannel].values[WACOMFIELD_PROXIMITY].nValue = 1; - } - - /* remember tool in prox */ - pUSB->nToolProx[pUSB->nChannel] |= BIT(tool); - pUSB->state[pUSB->nChannel].values[WACOMFIELD_TOOLTYPE].nValue = tool; - } - - /* otherwise, going out of proximity */ - else - { - /* forget tool in prox */ - if (pUSB->nToolProx[pUSB->nChannel] & BIT(tool)) - { - pUSB->nToolProx[pUSB->nChannel] &= ~BIT(tool); - } - - /* single input */ - if (!(pUSB->state[pUSB->nChannel].uValid & BIT(WACOMFIELD_SERIAL))) - pUSB->nToolProx[pUSB->nChannel] = 0; - - pUSB->state[pUSB->nChannel].values[WACOMFIELD_PROXIMITY].nValue = 0; - pUSB->state[pUSB->nChannel].values[WACOMFIELD_TOOLTYPE].nValue = 0; - - /* nobody left? out of proximity */ - if (!pUSB->nToolProx[pUSB->nChannel]) - memset(pUSB->state[pUSB->nChannel].values, 0, - pUSB->state[pUSB->nChannel].uValueCnt * sizeof(WACOMVALUE)); - /* otherwise, switch to next tool */ - else - { - for (i=WACOMTOOLTYPE_PEN; i<WACOMTOOLTYPE_MAX; ++i) - { - if (pUSB->nToolProx[pUSB->nChannel] & BIT(i)) - { - pUSB->state[pUSB->nChannel].values[WACOMFIELD_TOOLTYPE].nValue = i; - } - } - } - } /* out of prox */ - } /* end if tool */ - - return 0; -} - -static int USBParseABS(USBTABLET* pUSB, struct input_event* pEv) -{ - int field = 0; - switch (pEv->code) - { - case ABS_X: field = WACOMFIELD_POSITION_X; break; - case ABS_Y: field = WACOMFIELD_POSITION_Y; break; - case ABS_RZ: field = WACOMFIELD_ROTATION_Z; break; - case ABS_DISTANCE: field = WACOMFIELD_DISTANCE; break; - case ABS_PRESSURE: field = WACOMFIELD_PRESSURE; break; - case ABS_TILT_X: field = WACOMFIELD_TILT_X; break; - case ABS_TILT_Y: field = WACOMFIELD_TILT_Y; break; - case ABS_WHEEL: field = WACOMFIELD_ABSWHEEL; break; - case ABS_THROTTLE: field = WACOMFIELD_THROTTLE; break; - } - - if (field) - pUSB->state[pUSB->nChannel].values[field].nValue = pEv->value; - - return 0; -} - -static int USBParseREL(USBTABLET* pUSB, struct input_event* pEv) -{ - int field = 0; - switch (pEv->code) - { - case REL_WHEEL: field = WACOMFIELD_RELWHEEL; break; - } - - if (field) - pUSB->state[pUSB->nChannel].values[field].nValue = pEv->value; - - return 0; -} - -static int USBParseData(WACOMTABLET_PRIV* pTablet, - const unsigned char* puchData, unsigned int uLength, - WACOMSTATE* pState) -{ - int evcnt, chcnt; - USBTABLET* pUSB = (USBTABLET*)pTablet; - struct input_event* pEv = (struct input_event*)puchData; - if (uLength != sizeof(struct input_event)) return 1; - - /* store event until we receive a MSC_SERIAL/SYN_REPORT - * so we can figure out with channel to use */ - if (pUSB->nEventCnt >= MAX_USB_EVENTS) - { - /* no more buffer space */ - pUSB->nEventCnt = 0; - pUSB->nLastToolSerial = 0; - errno = ENOBUFS; - return -1; - } - pUSB->events[pUSB->nEventCnt++] = *pEv; - - if ((pEv->type == EV_MSC) && (pEv->code == MSC_SERIAL)) - { - /* store the serial for the tool for later use */ - pUSB->nLastToolSerial = pEv->value; -#ifdef EV_SYN - /* Kernel 2.4 uses MSC_SERIAL as an end-of-report, 2.6 - * don't so we're not done yet */ - return 0; - } - else if ((pEv->type == EV_SYN) && (pEv->code == SYN_REPORT)) - { - /* Kernel 2.6 used SYN_REPORT as an end-of-record, - * fall through */ -#endif - } - else - { - /* Not a MSC_SERIAL or SYN_REPORT, we're not done yet */ - return 0; - } - - /* Select channel here based on the serial number, tablets - * with only one channel will always use channel 0, so no - * check. - */ - if (pUSB->pDevice->uChannelCnt > 1) - { - pUSB->nChannel = -1; - /* Find existing channel */ - for (chcnt=0; chcnt<pUSB->pDevice->uChannelCnt; chcnt++) - { - if (pUSB->state[chcnt].values[WACOMFIELD_SERIAL].nValue == pUSB->nLastToolSerial) - { - pUSB->nChannel = chcnt; - break; - } - } - - /* Find en empty channel */ - if(pUSB->nChannel == -1) - { - for (chcnt=0; chcnt<pUSB->pDevice->uChannelCnt; chcnt++) - { - if(!pUSB->nToolProx[chcnt]) - { - pUSB->nChannel = chcnt; - break; - } - } - } - - /* no more channels?? */ - if(pUSB->nChannel == -1) - { - pUSB->nChannel = 0; - pUSB->nEventCnt = 0; - pUSB->nLastToolSerial = 0; - errno = ENOBUFS; - return -1; - } - } - - /* Channel found/allocated, lets process events */ - pUSB->state[pUSB->nChannel].values[WACOMFIELD_RELWHEEL].nValue = 0; - - for (evcnt=0; evcnt<pUSB->nEventCnt; evcnt++) - { - pEv = pUSB->events + evcnt; - /* dispatch event */ - switch (pEv->type) - { -#ifdef EV_SYN - case EV_SYN: /* kernel 2.6 */ -#endif - case EV_MSC: /* kernel 2.4 */ - if (USBParseMSC(pUSB,pEv)) return pEv->type; break; - case EV_KEY: if (USBParseKEY(pUSB,pEv)) return pEv->type; break; - case EV_ABS: if (USBParseABS(pUSB,pEv)) return pEv->type; break; - case EV_REL: if (USBParseREL(pUSB,pEv)) return pEv->type; break; - default: errno = EINVAL; return pEv->type; - } - } - - pUSB->nEventCnt = 0; - pUSB->nLastToolSerial = 0; - return pState ? WacomCopyState(pState,pUSB->state + pUSB->nChannel) : 0; -} - -/***************************************************************************** -** End USB Linux Input Subsystem -*****************************************************************************/ - -#else /* WCM_ENABLE_LINUXWACOM */ - -WACOMTABLET WacomOpenUSBTablet(WACOMENGINE hEngine, int fd, WACOMMODEL* pModel) -{ - errno = EPERM; - return NULL; -} - -unsigned int WacomGetUSBDeviceFromName(const char* pszName) -{ - errno = ENOENT; - return 0; -} - -int WacomGetSupportedUSBDeviceList(WACOMDEVICEREC** ppList, int* pnSize) -{ - if (!ppList || !pnSize) { errno = EINVAL; return 1; } - *ppList = NULL; - *pnSize = 0; - return 0; -} - -#endif /* WCM_ENABLE_LINUXWACOM */ diff --git a/src/util/wacusb.h b/src/util/wacusb.h deleted file mode 100755 index 9ab926a..0000000 --- a/src/util/wacusb.h +++ /dev/null @@ -1,31 +0,0 @@ -/***************************************************************************** -** wacusb.h -** -** Copyright (C) 2002, 2003 - John E. Joganic -** -** 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 Lesser 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -****************************************************************************/ - -#ifndef __LINUXWACOM_WACUSB_H -#define __LINUXWACOM_WACUSB_H - -#include "wactablet.h" - -int WacomGetSupportedUSBDeviceList(WACOMDEVICEREC** ppList, int* pnSize); -unsigned int WacomGetUSBDeviceFromName(const char* pszName); -WACOMTABLET WacomOpenUSBTablet(WACOMENGINE hEngine, int fd, WACOMMODEL* pModel); - -#endif /* __LINUXWACOM_WACUSB_H */ diff --git a/src/util/wcmAction.c b/src/util/wcmAction.c deleted file mode 100755 index cec7f61..0000000 --- a/src/util/wcmAction.c +++ /dev/null @@ -1,357 +0,0 @@ -/***************************************************************************** -** wcmAction.c -** -** Copyright (C) 2007 - 2008 - Ping Cheng -** -** 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 Lesser 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -** REVISION HISTORY -** 2007-02-06 0.0.1-pc - Support keystrokes -** 2008-01-17 0.0.2-pc - Add Display Toggle -** 2008-08-01 0.0.3-pc - Merge patch 1998051 (Yuri Shchedov) -** 2008-12-10 0.0.4-pc - Updated patch 1998051 for none KP buttons -*/ - -/* This pseudo-header file is included both from the X11 driver, and from - * tools (notably xsetwacom). The reason is to have the function defined - * in one place, to avoide desyncronization issues between two pieces of - * almost identical code. - */ - -#include "../include/Xwacom.h" -#include "wcmAction.h" -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <stdlib.h> -#include <X11/Xlib.h> - -static ACTIONCODE action_code [] = -{ - { "CORE", AC_CORE }, - { "KEY", AC_KEY }, - { "BUTTON", AC_BUTTON }, - { "MODETOGGLE", AC_MODETOGGLE }, - { "DBLCLICK", AC_DBLCLICK }, - { "DISPLAYTOGGLE", AC_DISPLAYTOGGLE } -}; - -static ACTIONCODE modifier_code [] = -{ - { "SHIFT", XK_Shift_L }, - { "CTRL", XK_Control_L }, - { "CONTROL", XK_Control_L }, - { "META", XK_Meta_L }, - { "ALT", XK_Alt_L }, - { "SUPER", XK_Super_L }, - { "HYPER", XK_Hyper_L } -}; - -static ACTIONCODE specific_code [] = -{ - { "F1", XK_F1 }, - { "F2", XK_F2 }, - { "F3", XK_F3 }, - { "F4", XK_F4 }, - { "F5", XK_F5 }, - { "F6", XK_F6 }, - { "F7", XK_F7 }, - { "F8", XK_F8 }, - { "F9", XK_F9 }, - { "F10", XK_F10 }, - { "F11", XK_F11 }, - { "F12", XK_F12 }, - { "Esc", XK_Escape }, - { "Tab", XK_Tab }, - { "CapsLock", XK_Caps_Lock }, - { "Pause", XK_Pause }, - { "ScrollLock", XK_Scroll_Lock }, - { "SysReq", XK_Sys_Req }, - { "Home", XK_Home }, - { "PageUp", XK_Page_Up }, - { "PageDown", XK_Page_Down }, - { "End", XK_End }, - { "Insert", XK_Insert }, - { "Delete", XK_Delete }, - { "Left", XK_Left }, - { "Up", XK_Up }, - { "Down", XK_Down }, - { "Right", XK_Right }, - { "BackSpace", XK_BackSpace }, - { "Enter", XK_Return }, - { "NumLock", XK_Num_Lock }, - { "space", XK_space }, - { "quotedbl", XK_quotedbl }, - { "backslash", XK_backslash }, - { "KPHome", XK_KP_Home }, - { "PgUp", XK_KP_Page_Up }, - { "PgDn", XK_KP_Page_Down }, - { "KPEnd", XK_KP_End }, - { "Ins", XK_KP_Insert }, - { "Del", XK_KP_Delete }, - { "KPLeft", XK_KP_Left }, - { "KPUp", XK_KP_Up }, - { "KPDown", XK_KP_Down }, - { "KPRight", XK_KP_Right }, - { "KPEnter", XK_KP_Enter }, - { "Plus", XK_KP_Add }, - { "Minus", XK_KP_Subtract}, - { "Divide", XK_KP_Divide }, - { "Multiply", XK_KP_Multiply }, - { "NumpadPlus", XK_KP_Add }, - { "NumpadMinus", XK_KP_Subtract}, - { "NumpadDivide", XK_KP_Divide }, - { "NumpadMultiply", XK_KP_Multiply }, - { "break", XK_Break }, - { "print", XK_Print } -}; - -static ACTIONCODE key_code [] = -{ - { "#", XK_numbersign }, - { "$", XK_dollar }, - { "%", XK_percent }, - { "&", XK_ampersand }, - { "'", XK_quoteright }, - { "(", XK_parenleft }, - { ")", XK_parenright }, - { "*", XK_asterisk }, - { "+", XK_plus }, - { ",", XK_comma }, - { "-", XK_minus }, - { ".", XK_period }, - { "/", XK_slash }, - { ":", XK_colon }, - { ";", XK_semicolon }, - { "<", XK_less }, - { "=", XK_equal }, - { ">", XK_greater }, - { "?", XK_question }, - { "@", XK_at }, - { "[", XK_bracketleft }, - { "]", XK_bracketright }, - { "^", XK_asciicircum }, - { "_", XK_underscore }, - { "`", XK_grave }, - { "{", XK_braceleft }, - { "}", XK_braceright }, - { "|", XK_bar }, - { "~", XK_asciitilde }, - { "!", XK_exclam } -}; - -static ACTIONCODE number_code [] = -{ - { "0", XK_0 }, - { "1", XK_1 }, - { "2", XK_2 }, - { "3", XK_3 }, - { "4", XK_4 }, - { "5", XK_5 }, - { "6", XK_6 }, - { "7", XK_7 }, - { "8", XK_8 }, - { "9", XK_9 }, - -}; - -void xf86WcmDecodeKey(char *ev, unsigned * entev, ACTIONCODE * code, int codesize, int * butev) -{ - int i, num_keys = ((*butev) & AC_NUM_KEYS) >> 20; - char keys[2] = " "; - int n = 0; - keys[0] = ev[0]; - if (code) - { - for (i = 0; i < codesize; i++) - { - if (keys[0] == code[i].keyword[0]) - n = code[i].value; - } - } - else - n = XStringToKeysym (keys); - - if (n) - entev[num_keys++] = n; - *butev = ((*butev) & AC_EVENT) | (num_keys << 20) - | (num_keys ? entev[0] : 0); -} - - -char * xf86WcmDecodeWord(char *ev, unsigned * entev, ACTIONCODE * code, int codesize, int * butev) -{ - int i, num_keys = ((*butev) & AC_NUM_KEYS) >> 20; - for (;;) - { - while (ev && (*ev == ' ' || *ev == '\t')) - ev++; - - for (i = 0; i < codesize; i++) - { - int sl = strlen (code [i].keyword); - if ( (strlen(ev) >= sl) && - (ev [sl] == 0 || ev [sl] == ' ' || ev [sl] == '\t') && - !strncasecmp (ev, code [i].keyword, sl)) - { - if (code [i].value & AC_CODE) - entev[num_keys++] = code [i].value; - else - (*butev) |= code [i].value; - - ev += sl; - if (!strlen(ev)) - i = codesize; - break; - } - } - - if (i >= codesize) - break; - } - *butev = ((*butev) & AC_EVENT) | (num_keys << 20) - | (num_keys ? entev[0] : 0); - return ev; -} - -int xf86WcmDecode (const char *dev, const char *but, const char *ev, unsigned * entev) -{ - int butev = 0, - codesize = sizeof (action_code) / sizeof (action_code [0]), - num_keys = (butev & AC_NUM_KEYS) >> 20; - char new_ev[256] ="", *ev_p; - - strcat(new_ev, ev); - ev_p = new_ev; - if (!strlen(ev)) - { - printf("xf86WcmDecodeAction No action defined\n"); - return 0; - } - - /* Get action type first */ - ev_p = xf86WcmDecodeWord(new_ev, entev, action_code, codesize, &butev); - switch (butev & AC_TYPE) - { - case AC_BUTTON: - if (strlen(ev_p)) - { - char *end; - int n = strtol (ev_p, &end, 0); - if (ev_p == end) - printf ("xf86WcmDecode %s: invalid %s value: button (%x) \"%s\". Ignore it (assign to 0)\n", - dev, but, butev, ev); - butev |= n; - } - case AC_MODETOGGLE: - case AC_DBLCLICK: - case AC_DISPLAYTOGGLE: - break; - case AC_KEY: - if (!strlen(ev_p)) - { - printf ("xf86WcmDecode %s: invalid %s value: button has no key defined.\n", dev, but); - return 0; - } - codesize = sizeof (modifier_code) / sizeof (modifier_code [0]); - ev_p = xf86WcmDecodeWord(ev_p, entev, modifier_code, codesize, &butev); - codesize = sizeof (specific_code) / sizeof (specific_code [0]); - ev_p = xf86WcmDecodeWord(ev_p, entev, specific_code, codesize, &butev); - - while(strlen(ev_p)) - { - if (ev_p[0] == ' ') - { - ev_p++; - codesize = sizeof (specific_code) / sizeof (specific_code [0]); - ev_p = xf86WcmDecodeWord(ev_p, entev, specific_code, codesize, &butev); - } - codesize = sizeof (key_code) / sizeof (key_code [0]); - num_keys = (butev & AC_NUM_KEYS) >> 20; - xf86WcmDecodeKey(ev_p, entev, key_code, codesize, &butev); - if (num_keys == ((butev & AC_NUM_KEYS) >> 20)) - { - codesize = sizeof (number_code) / sizeof (number_code [0]); - xf86WcmDecodeKey(ev_p, entev, number_code, codesize, &butev); - if (num_keys == ((butev & AC_NUM_KEYS) >> 20)) - xf86WcmDecodeKey(ev_p, entev, 0, 1, &butev); - } - ev_p++; - } - break; - } - return butev; -} - -int xf86WcmListMod(char** argv) -{ - int modsize = sizeof (modifier_code) / sizeof (modifier_code [0]), i; - if (*argv != NULL) - fprintf(stderr,"ListMod: Ignoring extraneous arguments (%s).\n", *argv); - - fprintf(stderr,"ListMod: %d modifiers are supported:\n\n", modsize); - for (i=0; i<modsize; i++) - fprintf(stderr,"\t%s\n", modifier_code[i].keyword); - - modsize = sizeof (specific_code) / sizeof (specific_code [0]); - fprintf(stderr,"\n\nListMod: %d special keys are supported. " - "For example: to send \", you need to use quotedbl:\n\n", modsize); - for (i=0; i<modsize; i++) - fprintf(stderr,"\t%s\n", specific_code[i].keyword); - - return 0; -} - -int xf86WcmGetString(unsigned keySym, char * kstring) -{ - int i = 0; - - kstring[0] = 0; - for (i=0; i<sizeof (action_code) / sizeof (action_code [0]); i++) - if (action_code[i].value == keySym) - { - strcat(kstring, action_code[i].keyword); - return 1; - } - for (i=0; i<sizeof (modifier_code) / sizeof (modifier_code [0]); i++) - if (modifier_code[i].value == keySym) - { - strcat(kstring, modifier_code[i].keyword); - return 1; - } - - for (i=0; i<sizeof (specific_code) / sizeof (specific_code [0]); i++) - if (specific_code[i].value == keySym) - { - strcat(kstring, specific_code[i].keyword); - return 1; - } - - for (i=0; i<sizeof (key_code) / sizeof (key_code [0]); i++) - if (key_code[i].value == keySym) - { - strcat(kstring, key_code[i].keyword); - return 1; - } - - for (i=0; i<sizeof (number_code) / sizeof (number_code [0]); i++) - if (number_code[i].value == keySym) - { - strcat(kstring, number_code[i].keyword); - return 1; - } - strcat(kstring, XKeysymToString((KeySym)keySym)); - return 1; -} diff --git a/src/util/wcmAction.h b/src/util/wcmAction.h deleted file mode 100755 index 1c84870..0000000 --- a/src/util/wcmAction.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************** -** wcmAction.h -** -** Copyright (C) 2006 - Andrew Zabolotny -** -** 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 Lesser 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -** REVISION HISTORY -** 2006-07-17 0.0.1-az - Initial release -*/ - -/* This pseudo-header file is included both from the X11 driver, and from - * tools (notably xsetwacom). The reason is to have the function defined - * in one place, to avoide desyncronization issues between two pieces of - * almost identical code. - */ - -#include "../include/Xwacom.h" - -typedef struct _ACTIONCODE ACTIONCODE; - -struct _ACTIONCODE -{ - const char *keyword; - unsigned value; -}; - -int xf86WcmDecode (const char *dev, const char *but, const char *ev, unsigned * entev); -int xf86WcmListMod(char** argv); -int xf86WcmGetString(unsigned keySym, char * kstring); diff --git a/src/util/xidump.c b/src/util/xidump.c deleted file mode 100755 index 51314d5..0000000 --- a/src/util/xidump.c +++ /dev/null @@ -1,1159 +0,0 @@ -/***************************************************************************** -** xidump.c -** -** Copyright (C) 2003 - 2004 - John E. Joganic -** Copyright (C) 2004 - 2009 - Ping Cheng -** -** 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 Lesser 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -** REVISION HISTORY -** 2003-02-23 0.0.1 - created for GTK1.2 -** 2003-03-07 0.0.2 - added input device code -** 2003-03-08 0.0.3 - added curses code -** 2003-03-21 0.0.4 - added conditional curses code -** 2003-03-21 0.5.0 - released in development branch -** 2003-04-07 0.5.1 - added pressure bar -** 2005-07-27 0.5.2 - remove unused GTK stuff [jg] -** 2005-11-11 0.7.1 - report tool ID and serial number -** 2006-05-05 0.7.4 - Removed older 2.6 kernels -** 2006-07-19 0.7.5 - Support buttons and keys combined -** 2007-01-10 0.7.7 - Don't list uninitialized tools -** 2008-05-06 0.8.0 - Support Xorg 7.3 or later -** 2008-12-31 0.8.2 - Support USB Tabket PCs -** 2009-03-06 0.8.3 - Support Intuos4 -** -****************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <time.h> -#include <sys/time.h> -#include <math.h> - -#define XIDUMP_VERSION "0.8.3" - -#include "../include/util-config.h" - -/***************************************************************************** -** XInput -*****************************************************************************/ - -#include <X11/Xlib.h> -#include <X11/extensions/XInput.h> -#include <X11/extensions/XIproto.h> -#include <X11/keysym.h> - - enum - { - INPUTEVENT_KEY_PRESS, - INPUTEVENT_KEY_RELEASE, - INPUTEVENT_FOCUS_IN, - INPUTEVENT_FOCUS_OUT, - INPUTEVENT_BTN_PRESS, - INPUTEVENT_BTN_RELEASE, - INPUTEVENT_PROXIMITY_IN, - INPUTEVENT_PROXIMITY_OUT, - INPUTEVENT_MOTION_NOTIFY, - INPUTEVENT_DEVICE_STATE_NOTIFY, - INPUTEVENT_DEVICE_MAPPING_NOTIFY, - INPUTEVENT_CHANGE_DEVICE_NOTIFY, - INPUTEVENT_DEVICE_POINTER_MOTION_HINT, - INPUTEVENT_DEVICE_BUTTON_MOTION, - INPUTEVENT_DEVICE_BUTTON1_MOTION, - INPUTEVENT_DEVICE_BUTTON2_MOTION, - INPUTEVENT_DEVICE_BUTTON3_MOTION, - INPUTEVENT_DEVICE_BUTTON4_MOTION, - INPUTEVENT_DEVICE_BUTTON5_MOTION, - - INPUTEVENT_MAX - }; - - int gnDevListCnt = 0; - XDeviceInfoPtr gpDevList = NULL; - int gnLastXError = 0; - int gnVerbose = 0; - int gnSuppress = 4; - int gnInputEvent[INPUTEVENT_MAX] = { 0 }; - -int ErrorHandler(Display* pDisp, XErrorEvent* pEvent) -{ - char chBuf[64]; - XGetErrorText(pDisp,pEvent->error_code,chBuf,sizeof(chBuf)); - fprintf(stderr,"X Error: %d %s\n", pEvent->error_code, chBuf); - gnLastXError = pEvent->error_code; - return 0; -} - -int GetLastXError(void) -{ - return gnLastXError; -} - -Display* InitXInput(void) -{ - Display* pDisp; - int nMajor, nFEV, nFER; - - pDisp = XOpenDisplay(NULL); - if (!pDisp) - { - fprintf(stderr,"Failed to connect to X server.\n"); - return NULL; - } - - XSetErrorHandler(ErrorHandler); - - XSynchronize(pDisp,1 /*sync on*/); - - if (!XQueryExtension(pDisp,INAME,&nMajor,&nFEV,&nFER)) - { - fprintf(stderr,"Server does not support XInput extension.\n"); - XCloseDisplay(pDisp); - return NULL; - } - - return pDisp; -} - -int ListDevices(Display* pDisp, const char* pszDeviceName) -{ - int i, j, k; - XDeviceInfoPtr pDev; - XAnyClassPtr pClass; - - /* get list of devices */ - if (!gpDevList) - { - gpDevList = (XDeviceInfoPtr) XListInputDevices(pDisp, &gnDevListCnt); - if (!gpDevList) - { - fprintf(stderr,"Failed to get input device list.\n"); - return 1; - } - } - - for (i=0; i<gnDevListCnt; ++i) - { - pDev = gpDevList + i; - - /* if device name is specified, skip other devices */ - if (pszDeviceName && strcasecmp(pDev->name, pszDeviceName)) - continue; - - if (pDev->num_classes) - printf("%-30s %s\n", - pDev->name, - (pDev->use == 0) ? "disabled" : - (pDev->use == IsXKeyboard) ? "keyboard" : - (pDev->use == IsXPointer) ? "pointer" : -#ifndef WCM_ISXEXTENSIONPOINTER - (pDev->use == IsXExtensionDevice) ? -#else - (pDev->use == IsXExtensionDevice || - pDev->use == IsXExtensionKeyboard || - pDev->use == IsXExtensionPointer) ? -#endif - "extension" : "unknown"); - - if (gnVerbose) - { - pClass = pDev->inputclassinfo; - for (j=0; j<pDev->num_classes; ++j) - { - switch (pClass->class) - { - case ButtonClass: - { - XButtonInfo* pBtn = (XButtonInfo*)pClass; - printf(" btn: num=%d\n",pBtn->num_buttons); - break; - } - - case FocusClass: - { - printf(" focus:\n"); - break; - } - - case KeyClass: - { - XKeyInfo* pKey = (XKeyInfo*)pClass; - printf(" key: min=%d, max=%d, num=%d\n", - pKey->min_keycode, - pKey->max_keycode, - pKey->num_keys); - break; - } - - case ValuatorClass: - { - XValuatorInfoPtr pVal = (XValuatorInfoPtr)pClass; - printf(" val: axes=%d mode=%s buf=%ld\n", - pVal->num_axes, - pVal->mode == Absolute ? "abs" : - pVal->mode == Relative ? "rel" : "unk", - pVal->motion_buffer); - for (k=0; k<pVal->num_axes; ++k) - { - printf(" axis[%d]: res=%d, min=%d, max=%d\n", - k, /* index */ - pVal->axes[k].resolution, - pVal->axes[k].min_value, - pVal->axes[k].max_value); - } - break; - } - - default: - printf(" unknown class\n" ); - } - - /* skip to next record */ - pClass = (XAnyClassPtr)((char*)pClass + pClass->length); - } - printf("\n"); - } - } - - return 0; -} - -XDeviceInfoPtr GetDevice(Display* pDisp, const char* pszDeviceName) -{ - int i; - - /* get list of devices */ - if (!gpDevList) - { - gpDevList = (XDeviceInfoPtr) XListInputDevices(pDisp, &gnDevListCnt); - if (!gpDevList) - { - fprintf(stderr,"Failed to get input device list.\n"); - return NULL; - } - } - - /* find device by name */ - for (i=0; i<gnDevListCnt; ++i) - { - if (!strcasecmp(gpDevList[i].name,pszDeviceName) && - gpDevList[i].num_classes) - return gpDevList + i; - } - - return NULL; -} - -static const char* GetEventName(int nType) -{ - static char xchBuf[64]; - - switch (nType) - { - case KeyPress: return "KeyPress"; - case KeyRelease: return "KeyRelease"; - case ButtonPress: return "ButtonPress"; - case ButtonRelease: return "ButtonRelease"; - case MotionNotify: return "MotionNotify"; - case EnterNotify: return "EnterNotify"; - case LeaveNotify: return "LeaveNotify"; - case FocusIn: return "FocusIn"; - case FocusOut: return "FocusOut"; - case KeymapNotify: return "KeymapNotify"; - case Expose: return "Expose"; - case GraphicsExpose: return "GraphicsExpose"; - case NoExpose: return "NoExpose"; - case VisibilityNotify: return "VisibilityNotify"; - case CreateNotify: return "CreateNotify"; - case DestroyNotify: return "DestroyNotify"; - case UnmapNotify: return "UnmapNotify"; - case MapNotify: return "MapNotify"; - case MapRequest: return "MapRequest"; - case ReparentNotify: return "ReparentNotify"; - case ConfigureNotify: return "ConfigureNotify"; - case ConfigureRequest: return "ConfigureRequest"; - case GravityNotify: return "GravityNotify"; - case ResizeRequest: return "ResizeRequest"; - case CirculateNotify: return "CirculateNotify"; - case CirculateRequest: return "CirculateRequest"; - case PropertyNotify: return "PropertyNotify"; - case SelectionClear: return "SelectionClear"; - case SelectionRequest: return "SelectionRequest"; - case SelectionNotify: return "SelectionNotify"; - case ColormapNotify: return "ColormapNotify"; - case ClientMessage: return "ClientMessage"; - case MappingNotify: return "MappingNotify"; - - default: - if (nType == gnInputEvent[INPUTEVENT_KEY_PRESS]) - return "XIKeyPress"; - else if (nType == gnInputEvent[INPUTEVENT_KEY_RELEASE]) - return "XIKeyRelease"; - else if (nType == gnInputEvent[INPUTEVENT_FOCUS_IN]) - return "XIFocusIn"; - else if (nType == gnInputEvent[INPUTEVENT_FOCUS_OUT]) - return "XIFocusOut"; - else if (nType == gnInputEvent[INPUTEVENT_BTN_PRESS]) - return "XIButtonPress"; - else if (nType == gnInputEvent[INPUTEVENT_BTN_RELEASE]) - return "XIButtonRelease"; - else if (nType == gnInputEvent[INPUTEVENT_PROXIMITY_IN]) - return "XIProximityIn"; - else if (nType == gnInputEvent[INPUTEVENT_PROXIMITY_OUT]) - return "XIProximityOut"; - else if (nType == gnInputEvent[INPUTEVENT_MOTION_NOTIFY]) - return "XIMotionNotify"; - else if (nType == gnInputEvent[INPUTEVENT_DEVICE_STATE_NOTIFY]) - return "XIDeviceStateNotify"; - else if (nType == gnInputEvent[INPUTEVENT_DEVICE_MAPPING_NOTIFY]) - return "XIDeviceMappingNotify"; - else if (nType == gnInputEvent[INPUTEVENT_CHANGE_DEVICE_NOTIFY]) - return "XIChangeDeviceNotify"; - else if (nType == gnInputEvent[INPUTEVENT_DEVICE_POINTER_MOTION_HINT]) - return "XIDevicePointerMotionHint"; - else if (nType == gnInputEvent[INPUTEVENT_DEVICE_BUTTON_MOTION]) - return "XIDeviceButtonMotion"; - else if (nType == gnInputEvent[INPUTEVENT_DEVICE_BUTTON1_MOTION]) - return "XIDeviceButton1Motion"; - else if (nType == gnInputEvent[INPUTEVENT_DEVICE_BUTTON2_MOTION]) - return "XIDeviceButton2Motion"; - else if (nType == gnInputEvent[INPUTEVENT_DEVICE_BUTTON3_MOTION]) - return "XIDeviceButton3Motion"; - else if (nType == gnInputEvent[INPUTEVENT_DEVICE_BUTTON4_MOTION]) - return "XIDeviceButton4Motion"; - else if (nType == gnInputEvent[INPUTEVENT_DEVICE_BUTTON5_MOTION]) - return "XIDeviceButton5Motion"; - } - - snprintf(xchBuf,sizeof(xchBuf),"Event_%d",nType); - return xchBuf; -} - - -/***************************************************************************** -** FORMAT -*****************************************************************************/ - -typedef enum -{ - FORMATTYPE_DEFAULT, - FORMATTYPE_ACCELERATION -} FORMATTYPE; - -typedef struct _FORMAT FORMAT; -struct _FORMAT -{ - const char* pszName; - FORMATTYPE type; -}; - - FORMAT gFormats[] = - { - { "default", FORMATTYPE_DEFAULT }, - { "accel", FORMATTYPE_ACCELERATION }, - { NULL } - }; - -/***************************************************************************** -** UI -*****************************************************************************/ - -typedef struct _UI UI; -struct _UI -{ - const char* pszName; - int (*Init)(void); - void (*Term)(void); - int (*Run)(Display* pDisp, XDeviceInfo* pDevInfo, FORMATTYPE fmt); -}; - -/***************************************************************************** -** Curses UI -*****************************************************************************/ - -#if WCM_ENABLE_NCURSES -#define USE_NCURSES 1 -#include <wacscrn.h> - - int gbCursesInit = 0; - -static void CursesTerm(void) -{ - if (gbCursesInit) - { - wacscrn_term(); - gbCursesInit = 0; - } -} - -static int CursesInit(void) -{ - if (!gbCursesInit) - { - gbCursesInit = 1; - wacscrn_init(); - atexit(CursesTerm); - } - return 0; -} - -static int CursesRun(Display* pDisp, XDeviceInfo* pDevInfo, FORMATTYPE fmt) -{ - int i, j, k, bDown, nBtn; - int nRow=0, nTitleRow, nPressRow, nProxRow, nFocusRow, nButtonRow, - nKeyRow, nValRow; - int nMaxPress=100, nMinPress=0; - int bTilt = 0; - char chBuf[1024]; - XEvent event; - XAnyEvent* pAny; - XValuatorInfoPtr pValInfo = NULL; - XAnyClassPtr pClass; - - /* Identify program and version */ - wacscrn_standout(); - for (i=0; i<80; ++i) wacscrn_output(nRow,i," "); - wacscrn_output(nRow,0,"xidump v" XIDUMP_VERSION); - wacscrn_normal(); - nRow += 2; - - /* get class info */ - pClass = pDevInfo->inputclassinfo; - for (j=0; j<pDevInfo->num_classes; ++j) - { - switch (pClass->class) - { - case ValuatorClass: - pValInfo = (XValuatorInfoPtr)pClass; - break; - } - - /* skip to next record */ - pClass = (XAnyClassPtr)((char*)pClass + pClass->length); - } - - /* display valuator related info */ - nTitleRow = nRow; - if (pValInfo) - { - snprintf(chBuf,sizeof(chBuf),"InputDevice: %s Valuators: %s",pDevInfo->name, - pValInfo->mode == Absolute ? "Absolute" : - pValInfo->mode == Relative ? "Relative" : "Unknown"); - wacscrn_output(nRow,0,chBuf); - nRow += 1; - - nValRow = nRow; - nRow += 6; - - wacscrn_output(nValRow+1 ,0," data:"); - wacscrn_output(nValRow+2 ,0," min:"); - wacscrn_output(nValRow+3 ,0," max:"); - wacscrn_output(nValRow+4 ,0," res:"); - - /* retain pressure range for pressure bar */ - nMaxPress = pValInfo->axes[2].max_value; - nMinPress = pValInfo->axes[2].min_value; - - /* Decide tilts or rotation/throttle */ - if ((pValInfo->axes[3].min_value == -64) && - (pValInfo->axes[4].min_value == -64)) - bTilt = 1; - - - for (k=0; k<pValInfo->num_axes && k<6; ++k) - { - wacscrn_output(nValRow,12 + k * 10, - k == 0 ? " x-axis " : - k == 1 ? " y-axis " : - k == 2 ? "pressure" : - k == 3 ? (bTilt ? " x-tilt " : "rotation" ) : - k == 4 ? (bTilt ? " y-tilt " : "throttle" ) : - k == 5 ? " wheel " : " error "); - - snprintf(chBuf,sizeof(chBuf),"%+06d", - pValInfo->axes[k].min_value); - wacscrn_output(nValRow+2,12 + k * 10, chBuf); - snprintf(chBuf,sizeof(chBuf),"%+06d", - pValInfo->axes[k].max_value); - wacscrn_output(nValRow+3,12 + k * 10, chBuf); - snprintf(chBuf,sizeof(chBuf),"%+06d", - pValInfo->axes[k].resolution); - wacscrn_output(nValRow+4,12 + k * 10, chBuf); - } - } - - nPressRow = nRow++; - - nProxRow = nRow++; - nFocusRow = nRow++; - nButtonRow = nRow++; - nKeyRow = nRow++; - - wacscrn_output(nProxRow, 0,"Proximity:"); - wacscrn_output(nFocusRow, 0," Focus:"); - wacscrn_output(nButtonRow,0," Buttons:"); - wacscrn_output(nKeyRow ,0," Keys:"); - - /* handle events */ - - while (1) - { - wacscrn_refresh(); - XNextEvent(pDisp,&event); - - pAny = (XAnyEvent*)&event; - /* printf("event: type=%s\n",GetEventName(pAny->type)); */ - - if (pAny->type == gnInputEvent[INPUTEVENT_PROXIMITY_IN]) - { - if (!pValInfo) - { - wacscrn_output(23,0,"Unexpected valuator data received."); - } - wacscrn_standout(); - wacscrn_output(nProxRow,12,"IN "); - wacscrn_normal(); - } - else if (pAny->type == gnInputEvent[INPUTEVENT_PROXIMITY_OUT]) - wacscrn_output(nProxRow,12,"OUT "); - else if (pAny->type == gnInputEvent[INPUTEVENT_FOCUS_IN]) - { - wacscrn_standout(); - wacscrn_output(nFocusRow,12,"IN "); - wacscrn_normal(); - } - else if (pAny->type == gnInputEvent[INPUTEVENT_FOCUS_OUT]) - wacscrn_output(nFocusRow,12,"OUT "); - else if (pAny->type == gnInputEvent[INPUTEVENT_MOTION_NOTIFY]) - { - XDeviceMotionEvent* pMove = (XDeviceMotionEvent*)pAny; - if (!pValInfo) - { - wacscrn_output(23,0,"Unexpected valuator data received."); - } - else - { - /* Device/tool ID can only be retrieved through the ToolID option - * of xsetwacom due to valuator backward compatibility concern - * - v = (pMove->axis_data[3]&0xffff0000) >> 16; - snprintf(chBuf, sizeof(chBuf), "%10d", v); - wacscrn_output(nTitleRow, 25, chBuf); - - * serial number can only be retrieved through the ToolSerial option - * of xsetwacom due to valuator backward compatibility concern - * - v = (pMove->axis_data[4]&0xffff0000) | - ((pMove->axis_data[5]&0xffff0000)>>16); - if ( v ) - { - snprintf(chBuf,sizeof(chBuf), "%12u", v); - wacscrn_output(nTitleRow,52,chBuf); - } - */ - - for (k=0; k<pValInfo->num_axes && k<3; ++k) - { - snprintf(chBuf, sizeof(chBuf), "%+06d", pMove->axis_data[k]); - wacscrn_output(nValRow+1, 12 + k * 10, chBuf); - - } - - for (k=3; k<pValInfo->num_axes && k<6; ++k) - { - snprintf(chBuf, sizeof(chBuf), "%+06d", - (short)(pMove->axis_data[k]&0xffff)); - wacscrn_output(nValRow+1, 12 + k * 10, chBuf); - - } - - /* pressure bar */ - { - char* c; - int s, nPos; - wacscrn_standout(); - nPos = pMove->axis_data[2]; - - if (nPos < nMinPress) - { - c = "<"; - nPos = 78; /* want full bar */ - } - else if (nPos > nMaxPress) - { - c = ">"; - nPos = 78; /* want full bar */ - } - else - { - c = "*"; - nPos = (nPos - nMinPress) * 78; - nPos /= (nMaxPress - nMinPress); - } - - for (s=0; s<nPos; ++s) - wacscrn_output(nPressRow,s,c); - wacscrn_normal(); - for (; s<78; ++s) - wacscrn_output(nPressRow,s," "); - } - } - } - else if ((pAny->type == gnInputEvent[INPUTEVENT_BTN_PRESS]) || - (pAny->type == gnInputEvent[INPUTEVENT_BTN_RELEASE])) - { - XDeviceButtonEvent* pBtn = (XDeviceButtonEvent*)pAny; - bDown = (pAny->type == gnInputEvent[INPUTEVENT_BTN_PRESS]); - nBtn = pBtn->button; - if ((nBtn < 1) || (nBtn > 5)) nBtn=6; - snprintf(chBuf,sizeof(chBuf),"%d-%s",pBtn->button, - bDown ? "DOWN" : "UP "); - if (bDown) wacscrn_standout(); - wacscrn_output(nButtonRow,12 + (nBtn-1) * 10,chBuf); - if (bDown) wacscrn_normal(); - } - else if ((pAny->type == gnInputEvent[INPUTEVENT_KEY_PRESS]) || - (pAny->type == gnInputEvent[INPUTEVENT_KEY_RELEASE])) - { - XDeviceKeyEvent* pKey = (XDeviceKeyEvent*)pAny; - bDown = (pAny->type == gnInputEvent[INPUTEVENT_KEY_PRESS]); - nBtn = pKey->keycode - 7; /* first key is always 8 */ - if ((nBtn < 1) || (nBtn > 5)) nBtn=6; - snprintf(chBuf,sizeof(chBuf),"%d-%s",pKey->keycode - 7, - bDown ? "DOWN" : "UP "); - if (bDown) wacscrn_standout(); - wacscrn_output(nKeyRow,12 + (nBtn-1) * 10,chBuf); - if (bDown) wacscrn_normal(); - } - else - { - snprintf(chBuf,sizeof(chBuf),"%ld - %-60s", - time(NULL), - GetEventName(pAny->type)); - wacscrn_output(22,0,chBuf); - } - } - - return 0; -} - - UI gCursesUI = { "curses", CursesInit, CursesTerm, CursesRun }; - -#else /* WCM_ENABLE_NCURSES */ -#define USE_NCURSES 0 -#endif /* !WCM_ENABLE_NCURSES */ - -/***************************************************************************** -** Raw UI -*****************************************************************************/ - -static int RawInit(void) -{ - return 0; -} - -static void RawTerm(void) -{ -} - -static int RawRunDefault(Display* pDisp, XDeviceInfo* pDevInfo) -{ - XEvent event; - XAnyEvent* pAny; - struct timeval tv; - double dStart, dNow; - - gettimeofday(&tv,NULL); - dStart = tv.tv_sec + (double)tv.tv_usec / 1E6; - - while (1) - { - XNextEvent(pDisp,&event); - - pAny = (XAnyEvent*)&event; - /* printf("event: type=%s\n",GetEventName(pAny->type)); */ - - /* display time */ - gettimeofday(&tv,NULL); - dNow = tv.tv_sec + (double)tv.tv_usec / 1E6; - printf("%.8f: ",(dNow - dStart)); - - if (pAny->type == gnInputEvent[INPUTEVENT_PROXIMITY_IN]) - printf("Proximity In\n"); - else if (pAny->type == gnInputEvent[INPUTEVENT_PROXIMITY_OUT]) - printf("Proximity Out\n"); - else if (pAny->type == gnInputEvent[INPUTEVENT_FOCUS_IN]) - printf("Focus In\n"); - else if (pAny->type == gnInputEvent[INPUTEVENT_FOCUS_OUT]) - printf("Focus Out\n"); - else if (pAny->type == gnInputEvent[INPUTEVENT_MOTION_NOTIFY]) - { - XDeviceMotionEvent* pMove = (XDeviceMotionEvent*)pAny; - - printf("Motion: x=%+6d y=%+6d p=%4d tx=%+4d ty=%+4d " - "w=%+5d \n", - pMove->axis_data[0], - pMove->axis_data[1], - pMove->axis_data[2], - (short)(pMove->axis_data[3]&0xffff), - (short)(pMove->axis_data[4]&0xffff), - (short)(pMove->axis_data[5]&0xffff)); - - } - else if ((pAny->type == gnInputEvent[INPUTEVENT_BTN_PRESS]) || - (pAny->type == gnInputEvent[INPUTEVENT_BTN_RELEASE])) - { - XDeviceButtonEvent* pBtn = (XDeviceButtonEvent*)pAny; - printf("Button: %d %s\n",pBtn->button, - pAny->type == gnInputEvent[INPUTEVENT_BTN_PRESS] ? - "DOWN" : "UP"); - } - else if ((pAny->type == gnInputEvent[INPUTEVENT_KEY_PRESS]) || - (pAny->type == gnInputEvent[INPUTEVENT_KEY_RELEASE])) - { - XDeviceKeyEvent* pKey = (XDeviceKeyEvent*)pAny; - printf("Key: %d %s\n", pKey->keycode - 7, - (pAny->type == gnInputEvent[INPUTEVENT_KEY_PRESS]) ? - "DOWN" : "UP"); - } - else - { - printf("Event: %s\n",GetEventName(pAny->type)); - } - - /* flush data to terminal */ - fflush(stdout); - } - - return 0; -} - -static int RawRunAccel(Display* pDisp, XDeviceInfo* pDevInfo) -{ - XEvent event; - XAnyEvent* pAny; - int prox=0, head=0, tail=0, points=0, prev=-1; - int x[16], y[16]; - double d[16], dd[16], vx[16], vy[16], ax[16], ay[16], - dx, dy, dvx, dvy, m, a; - - while (1) - { - XNextEvent(pDisp,&event); - pAny = (XAnyEvent*)&event; - - if (pAny->type == gnInputEvent[INPUTEVENT_PROXIMITY_IN]) - prox=1; - else if (pAny->type == gnInputEvent[INPUTEVENT_PROXIMITY_OUT]) - { prox=head=tail=points=0; prev=-1; } - else if (pAny->type == gnInputEvent[INPUTEVENT_MOTION_NOTIFY]) - { - XDeviceMotionEvent* pMove = (XDeviceMotionEvent*)pAny; - x[head] = pMove->axis_data[0]; - y[head] = pMove->axis_data[1]; - d[head] = (double)pMove->time; - - if (prev >= 0) - { - /* parametric deltas, velocity, and accel */ - dx = x[head] - x[prev]; - dy = y[head] - y[prev]; - - if ((abs(dx) < gnSuppress) && - (abs(dy) < gnSuppress)) continue; - - dd[head] = d[head] - d[prev]; - vx[head] = dd[head] ? (dx/dd[head]) : 0; - vy[head] = dd[head] ? (dy/dd[head]) : 0; - dvx = vx[head] - vx[prev]; - dvy = vy[head] - vy[prev]; - ax[head] = dd[head] ? (dvx/dd[head]) : 0; - ay[head] = dd[head] ? (dvy/dd[head]) : 0; - } - else - { - dx = dy = 0; - vx[head] = vy[head] = 0; - ax[head] = ay[head] = 0; - } - - ++points; - prev = head; - head = (head + 1) % 16; - if (head == tail) tail = (head + 1) % 16; - - /* compute magnitude and angle of velocity */ - m = sqrt(vx[prev]*vx[prev] + vy[prev]*vy[prev]), - a = atan2(vx[prev], -vy[prev]); - - printf("%8.0f: %4.0f " - "[%+4d %+4d] [%6.2f %6.2f] " - "[%+4.2f %+4.2f] (%6.2f %+3.0f)\n", - d[prev], dd[prev], - x[prev], y[prev], - vx[prev], vy[prev], - ax[prev], ay[prev], - m, a * 180 / M_PI); - } - - /* flush data to terminal */ - fflush(stdout); - } - - return 0; -} - -static int RawRun(Display* pDisp, XDeviceInfo* pDevInfo, FORMATTYPE fmt) -{ - switch (fmt) - { - case FORMATTYPE_ACCELERATION: - return RawRunAccel(pDisp,pDevInfo); - - default: - return RawRunDefault(pDisp,pDevInfo); - } -} - - UI gRawUI = { "raw", RawInit, RawTerm, RawRun }; - -/****************************************************************************/ - - UI* gpUIs[] = - { - /* Curses UI */ - #if USE_NCURSES - &gCursesUI, - #endif - - /* Raw UI is always available */ - &gRawUI, - NULL - }; - -/****************************************************************************/ - -void Usage(int rtn) -{ - int nCnt; - UI** ppUI; - FORMAT* pFmt; - FILE* f = rtn ? stderr : stdout; - - fprintf(f, "Usage: xidump [options] input_device\n" - " -h, --help - usage\n" - " -v, --verbose - verbose\n" - " -V, --version - version\n" - " -l, --list - list available input devices\n" - " -s, --suppress value - suppress changes less than value\n" - " -f, --format format_type - use specified format, see below\n" - " -u, --ui ui_type - use specified ui, see below\n" - "\n" - "Use --list option for input_device choices\n" - "UI types: "); - - /* output UI types */ - for (ppUI=gpUIs, nCnt=0; *ppUI!=NULL; ++ppUI, ++nCnt) - fprintf(f, "%s%s", nCnt ? ", " : "", (*ppUI)->pszName); - - fprintf(f,"\nFormat types: "); - - /* output format types */ - for (pFmt=gFormats, nCnt=0; pFmt->pszName!=NULL; ++pFmt, ++nCnt) - fprintf(f, "%s%s", nCnt ? ", " : "", pFmt->pszName); - - fprintf(f,"\n"); - exit(rtn); -} - -void Version(void) -{ - fprintf(stdout,"%s\n",XIDUMP_VERSION); -} - -void Fatal(const char* pszFmt, ...) -{ - va_list args; - va_start(args,pszFmt); - vfprintf(stderr,pszFmt,args); - va_end(args); - exit(1); -} - -/****************************************************************************/ - -int Run(Display* pDisp, UI* pUI, FORMATTYPE fmt, const char* pszDeviceName) -{ - int nRtn; - XDevice* pDev; - XDeviceInfoPtr pDevInfo; - Window wnd; - int nEventListCnt = 0; - XEventClass eventList[32]; - XEventClass cls; - - /* create a window to receive events */ - wnd = XCreateWindow(pDisp, - DefaultRootWindow(pDisp), /* parent */ - 0,0,10,10, /* placement */ - 0, /* border width */ - 0, /* depth */ - InputOutput, /* class */ - CopyFromParent, /* visual */ - 0, /* valuemask */ - NULL); /* attributes */ - - /* mapping appears to be necessary */ - XMapWindow(pDisp,wnd); - - /* get the device by name */ - pDevInfo = GetDevice(pDisp,pszDeviceName); - if (!pDevInfo) - { - fprintf(stderr,"Unable to find input device '%s'\n",pszDeviceName); - XDestroyWindow(pDisp,wnd); - return 1; - } - - /* open device */ - pDev = XOpenDevice(pDisp,pDevInfo->id); - if (!pDev) - { - fprintf(stderr,"Unable to open input device '%s'\n",pszDeviceName); - XDestroyWindow(pDisp,wnd); - return 1; - } - - /* key events */ - DeviceKeyPress(pDev,gnInputEvent[INPUTEVENT_KEY_PRESS],cls); - if (cls) eventList[nEventListCnt++] = cls; - DeviceKeyRelease(pDev,gnInputEvent[INPUTEVENT_KEY_RELEASE],cls); - if (cls) eventList[nEventListCnt++] = cls; - - /* focus events */ - DeviceFocusIn(pDev,gnInputEvent[INPUTEVENT_FOCUS_IN],cls); - if (cls) eventList[nEventListCnt++] = cls; - DeviceFocusOut(pDev,gnInputEvent[INPUTEVENT_FOCUS_OUT],cls); - if (cls) eventList[nEventListCnt++] = cls; - - /* button events */ - DeviceButtonPress(pDev,gnInputEvent[INPUTEVENT_BTN_PRESS],cls); - if (cls) eventList[nEventListCnt++] = cls; - DeviceButtonRelease(pDev,gnInputEvent[INPUTEVENT_BTN_RELEASE],cls); - if (cls) eventList[nEventListCnt++] = cls; - - /* proximity events */ - ProximityIn(pDev,gnInputEvent[INPUTEVENT_PROXIMITY_IN],cls); - if (cls) eventList[nEventListCnt++] = cls; - ProximityOut(pDev,gnInputEvent[INPUTEVENT_PROXIMITY_OUT],cls); - if (cls) eventList[nEventListCnt++] = cls; - - /* motion events */ - DeviceMotionNotify(pDev,gnInputEvent[INPUTEVENT_MOTION_NOTIFY],cls); - if (cls) eventList[nEventListCnt++] = cls; - - /* device state */ - DeviceStateNotify(pDev,gnInputEvent[INPUTEVENT_DEVICE_STATE_NOTIFY],cls); - if (cls) eventList[nEventListCnt++] = cls; - DeviceMappingNotify(pDev, - gnInputEvent[INPUTEVENT_DEVICE_MAPPING_NOTIFY],cls); - if (cls) eventList[nEventListCnt++] = cls; - ChangeDeviceNotify(pDev,gnInputEvent[INPUTEVENT_CHANGE_DEVICE_NOTIFY],cls); - if (cls) eventList[nEventListCnt++] = cls; - -#if 0 - /* this cuts the motion data down - not sure if this is useful */ - DevicePointerMotionHint(pDev, - gnInputEvent[INPUTEVENT_DEVICE_POINTER_MOTION_HINT],cls); - if (cls) eventList[nEventListCnt++] = cls; -#endif - - /* button motion */ - DeviceButtonMotion(pDev, - gnInputEvent[INPUTEVENT_DEVICE_BUTTON_MOTION],cls); - if (cls) eventList[nEventListCnt++] = cls; - DeviceButton1Motion(pDev, - gnInputEvent[INPUTEVENT_DEVICE_BUTTON1_MOTION],cls); - if (cls) eventList[nEventListCnt++] = cls; - DeviceButton2Motion(pDev, - gnInputEvent[INPUTEVENT_DEVICE_BUTTON2_MOTION],cls); - if (cls) eventList[nEventListCnt++] = cls; - DeviceButton3Motion(pDev, - gnInputEvent[INPUTEVENT_DEVICE_BUTTON3_MOTION],cls); - if (cls) eventList[nEventListCnt++] = cls; - DeviceButton4Motion(pDev, - gnInputEvent[INPUTEVENT_DEVICE_BUTTON4_MOTION],cls); - if (cls) eventList[nEventListCnt++] = cls; - DeviceButton5Motion(pDev, - gnInputEvent[INPUTEVENT_DEVICE_BUTTON5_MOTION],cls); - if (cls) eventList[nEventListCnt++] = cls; - - /* specify which events to report */ - /* XSelectInput(pDisp,wnd,0x00FFFFFF ^ PointerMotionHintMask); */ - /* XSelectExtensionEvent(pDisp,wnd,eventList,nEventListCnt); */ - - /* grab device - work whether pointer is in active window or not */ - XGrabDevice(pDisp,pDev,wnd, - 0, /* no owner events */ - nEventListCnt, eventList, /* events */ - GrabModeAsync, /* don't queue, give me whatever you got */ - GrabModeAsync, /* same */ - CurrentTime); - - /* fire up the UI */ - if ((nRtn=pUI->Init()) != 0) - fprintf(stderr,"failed to initialize UI\n"); - else - { - if ((nRtn=pUI->Run(pDisp,pDevInfo,fmt)) != 0) - fprintf(stderr,"failed to run UI\n"); - pUI->Term(); - } - - XUngrabDevice(pDisp,pDev,CurrentTime); - XFree(pDev); - XCloseDisplay(pDisp); - XDestroyWindow(pDisp,wnd); - - return nRtn; -} - -/***************************************************************************** -** main -*****************************************************************************/ - -int main(int argc, char** argv) -{ - int nRtn; - int bList = 0; - UI* pUI=NULL, **ppUI; - FORMAT* pFmt; - FORMATTYPE fmt=FORMATTYPE_DEFAULT; - const char* pa; - Display* pDisp = NULL; - const char* pszDeviceName = NULL; - char sCallString[256], serialNum[256], toolID[256]; - FILE* ptr; - - ++argv; - while ((pa = *(argv++)) != NULL) - { - if (pa[0] == '-') - { - if ((strcmp(pa,"-h") == 0) || (strcmp(pa,"--help") == 0)) - Usage(0); - else if ((strcmp(pa,"-v") == 0) || (strcmp(pa,"--verbose") == 0)) - ++gnVerbose; - else if ((strcmp(pa,"-V") == 0) || (strcmp(pa,"--version") == 0)) - { Version(); exit(0); } - else if ((strcmp(pa,"-l") == 0) || (strcmp(pa,"--list") == 0)) - bList = 1; - else if ((strcmp(pa,"-f") == 0) || (strcmp(pa,"--format") == 0)) - { - pa = *(argv++); - if (!pa) Fatal("Missing format argument\n"); - - /* find format by name */ - for (pFmt = gFormats; pFmt->pszName!=NULL; ++pFmt) - { - if (strcmp(pa,pFmt->pszName) == 0) - { - fmt = pFmt->type; - break; - } - } - - /* bad format type, die */ - if (!pFmt->pszName) - Fatal("Unknown format option %s\n",pa); - } - else if ((strcmp(pa,"-s") == 0) || (strcmp(pa,"--suppress") == 0)) - { - pa = *(argv++); - if (!pa) Fatal("Missing suppress argument\n"); - - gnSuppress = atoi(pa); - if (gnSuppress <= 0) - Fatal("Invalid suppress value\n"); - } - else if ((strcmp(pa,"-u") == 0) || (strcmp(pa,"--ui") == 0)) - { - pa = *(argv++); - if (!pa) Fatal("Missing ui argument\n"); - - /* find ui by name */ - pUI = NULL; - for (ppUI = gpUIs; *ppUI!=NULL; ++ppUI) - { - if (strcmp(pa,(*ppUI)->pszName) == 0) - pUI = *ppUI; - } - - /* bad ui type, die */ - if (!pUI) - Fatal("Unknown ui option %s; was it configured?\n",pa); - } - else - Fatal("Unknown option %s\n",pa); - } - else if (!pszDeviceName) - pszDeviceName = pa; - else - Fatal("Unknown argument %s\n",pa); - } - - /* device must be specified */ - if (!pszDeviceName && !bList) - { - fprintf(stderr,"input_device not specified\n"); - Usage(1); - } - - /* get tool ID and serial number from xsetwacom */ - if (pszDeviceName) - { - sprintf(sCallString, "xsetwacom get %s toolId", pszDeviceName); - if ((ptr = popen(sCallString, "r")) != NULL) - fgets(toolID, 32, ptr); - pclose(ptr); - sprintf(sCallString, "xsetwacom get %s ToolSerial", pszDeviceName); - if ((ptr = popen(sCallString, "r")) != NULL) - fgets(serialNum, 32, ptr); - pclose(ptr); - } - - /* default to first valid UI, if not specified */ - if (pUI == NULL) - pUI = gpUIs[0]; - - /* open connection to XServer with XInput */ - pDisp = InitXInput(); - if (!pDisp) exit(1); - - if (bList) - nRtn = ListDevices(pDisp,pszDeviceName); - else - nRtn = Run(pDisp,pUI,fmt,pszDeviceName); - - /* release device list */ - if (gpDevList) - XFreeDeviceList(gpDevList); - - XCloseDisplay(pDisp); - - return nRtn; -} diff --git a/src/util/xsetwacom.c b/src/util/xsetwacom.c deleted file mode 100755 index 4fcecb2..0000000 --- a/src/util/xsetwacom.c +++ /dev/null @@ -1,1354 +0,0 @@ -/***************************************************************************** -** xsetwacom.c -** -** Copyright (C) 2003 - John E. Joganic -** Copyright (C) 2004-2009 - Ping Cheng -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -** REVISION HISTORY -** 2003-05-02 0.0.1 - JEJ - created -** 2005-10-24 0.0.4 - PC - added Pad -** 2005-11-17 0.0.5 - PC - update mode code -** 2006-02-27 0.0.6 - PC - fixed a typo -** 2006-07-19 0.0.7 - PC - supports button and keys combined -** 2007-01-10 0.0.8 - PC - don't display uninitialized tools -** 2007-02-07 0.0.9 - PC - support keystrokes -** 2007-02-22 0.1.0 - PC - support wheels and strips -** 2007-04-12 0.1.1 - PC - Support CoreEvent on/off (need more work) -** 2007-05-18 0.1.2 - PC - Support DebugLevel options -** 2007-06-05 0.1.3 - PC - Support Suppress and TwinView options -** 2007-07-24 0.1.4 - PC - Support Screen_No option -** 2008-01-17 0.1.5 - PC - Add DISPLAYTOGGLE command -** 2008-03-24 0.1.6 - PC - Added Touch for serial Tablet PC (ISDv4) -** 2008-08-27 0.1.7 - PC - Added get XORGVER to xsetwacom -** 2009-02-27 0.1.8 - PC - Added LeftOf and AboveOf to TwinView -** 2009-05-18 0.1.9 - PC - Support get/set serial command -** 2009-07-14 0.2.0 - PC - Support Nvidia Xinerama setting -** -****************************************************************************/ - -#define XSETWACOM_VERSION "0.1.9" - -#include "../include/util-config.h" - -#include "wacomcfg.h" -#include "../include/Xwacom.h" /* give us raw access to parameter values */ -#include "wcmAction.h" - -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <string.h> -#include <memory.h> -#include <errno.h> -#include <assert.h> - -int gnVerbose = 0; -int gnLastXError = 0; -enum -{ - gfSIMPLE, - gfSHELL, - gfXCONF -} gGetFormat = gfSIMPLE; - -const char* gpszDisplayName = NULL; - -typedef struct _PARAMINFO PARAMINFO; - -typedef enum -{ - COMMAND_NONE, - COMMAND_LIST, - COMMAND_SET, - COMMAND_GET, - COMMAND_GETDEFAULT -} COMMAND; - -struct _PARAMINFO -{ - const char* pszParam; - const char* pszDesc; - int nParamID; - int bEmptyOK; - int bRange; - int nMin, nMax; - int nType; - int nDefault; -}; - -/***************************************************************************** -** Parameters -*****************************************************************************/ - -#define VALUE_REQUIRED 0 -#define VALUE_OPTIONAL 1 -#define RANGE 1 -#define SINGLE_VALUE 0 -#define PACKED_CURVE 1 -#define BOOLEAN_VALUE 2 -#define ACTION_VALUE 3 -#define TWO_VALUES 4 - -static const char* tv_char[] = -{ - "none", - "xinerama" - "vertical", - "horizontal", - "aboveof" - "leftof" - "NULL" -}; - -static const char* rt_char[] = -{ - "none", - "cw", - "ccw", - "half", - "NULL" -}; - -static PARAMINFO gParamInfo[] = -{ - { "TopX", - "Bounding rect left coordinate in tablet units. ", - XWACOM_PARAM_TOPX, VALUE_REQUIRED }, - - { "TopY", - "Bounding rect top coordinate in tablet units . ", - XWACOM_PARAM_TOPY, VALUE_REQUIRED }, - - { "BottomX", - "Bounding rect right coordinate in tablet units. ", - XWACOM_PARAM_BOTTOMX, VALUE_REQUIRED }, - - { "BottomY", - "Bounding rect bottom coordinate in tablet units. ", - XWACOM_PARAM_BOTTOMY, VALUE_REQUIRED }, - - { "Button1", - "X11 event to which button 1 should be mapped. ", - XWACOM_PARAM_BUTTON1, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 1 }, - - { "Button2", - "X11 event to which button 2 should be mapped. ", - XWACOM_PARAM_BUTTON2, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 2 }, - - { "Button3", - "X11 event to which button 3 should be mapped. ", - XWACOM_PARAM_BUTTON3, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 3 }, - - { "Button4", - "X11 event to which button 4 should be mapped. ", - XWACOM_PARAM_BUTTON4, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 4 }, - - { "Button5", - "X11 event to which button 5 should be mapped. ", - XWACOM_PARAM_BUTTON5, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 5 }, - - { "Button6", - "X11 event to which button 6 should be mapped. ", - XWACOM_PARAM_BUTTON6, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 6 }, - - { "Button7", - "X11 event to which button 7 should be mapped. ", - XWACOM_PARAM_BUTTON7, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 7 }, - - { "Button8", - "X11 event to which button 8 should be mapped. ", - XWACOM_PARAM_BUTTON8, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 8 }, - - { "Button9", - "X11 event to which button 9 should be mapped. ", - XWACOM_PARAM_BUTTON9, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 9 }, - - { "Button10", - "X11 event to which button 10 should be mapped. ", - XWACOM_PARAM_BUTTON10, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 10 }, - - { "Button11", - "X11 event to which button 11 should be mapped. ", - XWACOM_PARAM_BUTTON11, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 11 }, - - { "Button12", - "X11 event to which button 12 should be mapped. ", - XWACOM_PARAM_BUTTON12, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 12 }, - - { "Button13", - "X11 event to which button 13 should be mapped. ", - XWACOM_PARAM_BUTTON13, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 13 }, - - { "Button14", - "X11 event to which button 14 should be mapped. ", - XWACOM_PARAM_BUTTON14, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 14 }, - - { "Button15", - "X11 event to which button 15 should be mapped. ", - XWACOM_PARAM_BUTTON15, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 15 }, - - { "Button16", - "X11 event to which button 16 should be mapped. ", - XWACOM_PARAM_BUTTON16, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 16 }, - - { "Button17", - "X11 event to which button 17 should be mapped. ", - XWACOM_PARAM_BUTTON17, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 17 }, - - { "Button18", - "X11 event to which button 18 should be mapped. ", - XWACOM_PARAM_BUTTON18, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 18 }, - - { "Button19", - "X11 event to which button 19 should be mapped. ", - XWACOM_PARAM_BUTTON19, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 19 }, - - { "Button20", - "X11 event to which button 20 should be mapped. ", - XWACOM_PARAM_BUTTON20, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 20 }, - - { "Button21", - "X11 event to which button 21 should be mapped. ", - XWACOM_PARAM_BUTTON21, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 21 }, - - { "Button22", - "X11 event to which button 22 should be mapped. ", - XWACOM_PARAM_BUTTON22, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 22 }, - - { "Button23", - "X11 event to which button 23 should be mapped. ", - XWACOM_PARAM_BUTTON23, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 23 }, - { "Button24", - "X11 event to which button 24 should be mapped. ", - XWACOM_PARAM_BUTTON24, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 24 }, - - { "Button25", - "X11 event to which button 25 should be mapped. ", - XWACOM_PARAM_BUTTON25, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 25 }, - - { "Button26", - "X11 event to which button 26 should be mapped. ", - XWACOM_PARAM_BUTTON26, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 26 }, - - { "Button27", - "X11 event to which button 27 should be mapped. ", - XWACOM_PARAM_BUTTON27, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 27 }, - - { "Button28", - "X11 event to which button 28 should be mapped. ", - XWACOM_PARAM_BUTTON28, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 28 }, - - { "Button29", - "X11 event to which button 29 should be mapped. ", - XWACOM_PARAM_BUTTON29, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 29 }, - - { "Button30", - "X11 event to which button 30 should be mapped. ", - XWACOM_PARAM_BUTTON30, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 30 }, - - { "Button31", - "X11 event to which button 31 should be mapped. ", - XWACOM_PARAM_BUTTON31, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 31 }, - - { "Button32", - "X11 event to which button 32 should be mapped. ", - XWACOM_PARAM_BUTTON32, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 32 }, - - { "DebugLevel", - "Level of debugging trace for individual devices, " - "default is 0 (off). ", - XWACOM_PARAM_DEBUGLEVEL, VALUE_OPTIONAL, RANGE, - 0, 100, SINGLE_VALUE, 0 }, - - { "CommonDBG", - "Level of debugging statements applied to all devices " - "associated with the same tablet. \n\t\t default is 0 (off). ", - XWACOM_PARAM_COMMONDBG, VALUE_OPTIONAL, RANGE, - 0, 100, SINGLE_VALUE, 0 }, - - { "Suppress", - "Number of points trimmed, default is 2. ", - XWACOM_PARAM_SUPPRESS, VALUE_OPTIONAL, RANGE, - 0, 100, SINGLE_VALUE, 2 }, - - { "RawSample", - "Number of raw data used to filter the points, " - "default is 4. ", - XWACOM_PARAM_RAWSAMPLE, VALUE_OPTIONAL, RANGE, - 1, XWACOM_MAX_SAMPLES, SINGLE_VALUE, 4 }, - - { "Screen_No", - "Sets/gets screen number the tablet is mapped to, " - "default is -1. ", - XWACOM_PARAM_SCREEN_NO, VALUE_OPTIONAL, RANGE, - -1, 10, SINGLE_VALUE, -1 }, - - { "PressCurve", - "Bezier curve for pressure (default is 0 0 100 100). ", - XWACOM_PARAM_PRESSCURVE, VALUE_OPTIONAL, RANGE, - 0, 100, PACKED_CURVE, 0x00006464}, - - { "TwinView", - "Sets the mapping to TwinView xinerama/horizontal/vertical/leftof/aboveof/none. \n" - "\t\t Values = none, vertical, horizontal, leftof, aboveof, xinerama " - "(default is none).", - XWACOM_PARAM_TWINVIEW, VALUE_OPTIONAL, RANGE, - TV_NONE, TV_MAX, SINGLE_VALUE, TV_NONE }, - - { "Mode", - "Switches cursor movement mode (default is absolute/on). ", - XWACOM_PARAM_MODE, VALUE_OPTIONAL, RANGE, - 0, 1, BOOLEAN_VALUE, 1 }, - - { "TPCButton", - "Turns on/off Tablet PC buttons. " - "default is off for regular tablets, " - "on for Tablet PC. ", - XWACOM_PARAM_TPCBUTTON, VALUE_OPTIONAL, - RANGE, 0, 1, BOOLEAN_VALUE, 1 }, - - { "Touch", - "Turns on/off Touch events (default is enable/on). ", - XWACOM_PARAM_TOUCH, VALUE_OPTIONAL, - RANGE, 0, 1, BOOLEAN_VALUE, 1 }, - - { "Capacity", - "Touch sensitivity level (default is 3, " - "-1 for none capacitive tools). ", - XWACOM_PARAM_CAPACITY, VALUE_OPTIONAL, - RANGE, -1, 5, SINGLE_VALUE, 3 }, - - { "CursorProx", - "Sets cursor distance for proximity-out " - "in distance from the tablet. \n" - "\t\t (default is 10 for Intuos series, " - "42 for Graphire series). ", - XWACOM_PARAM_CURSORPROX, VALUE_OPTIONAL, RANGE, - 0, 255, SINGLE_VALUE, 47 }, - - { "Rotate", - "Sets the rotation of the tablet. " - "Values = NONE, CW, CCW, HALF (default is NONE). \n" - "\t\t Tablet mappings applied after this command will " - "be based on the new tablet orientation. ", - XWACOM_PARAM_ROTATE, VALUE_OPTIONAL, RANGE, - ROTATE_NONE, ROTATE_HALF, SINGLE_VALUE, ROTATE_NONE }, - - { "RelWUp", - "X11 event to which relative wheel up should be mapped. ", - XWACOM_PARAM_RELWUP, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 4 }, - - { "RelWDn", - "X11 event to which relative wheel down should be mapped. ", - XWACOM_PARAM_RELWDN, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 5 }, - - { "AbsWUp", - "X11 event to which absolute wheel up should be mapped. ", - XWACOM_PARAM_ABSWUP, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 4 }, - - { "AbsWDn", - "X11 event to which absolute wheel down should be mapped. ", - XWACOM_PARAM_ABSWDN, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 5 }, - - { "StripLUp", - "X11 event to which left strip up should be mapped. ", - XWACOM_PARAM_STRIPLUP, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 4 }, - - { "StripLDn", - "X11 event to which left strip down should be mapped. ", - XWACOM_PARAM_STRIPLDN, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 5 }, - - { "StripRUp", - "X11 event to which right strip up should be mapped. ", - XWACOM_PARAM_STRIPRUP, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 4 }, - - { "StripRDn", - "X11 event to which right strip down should be mapped. ", - XWACOM_PARAM_STRIPRDN, VALUE_OPTIONAL, 0, 0, 0, - ACTION_VALUE, 5 }, - - { "TVResolution0", - "Sets MetaModes option for TwinView Screen 0. ", - XWACOM_PARAM_TVRESOLUTION0, VALUE_OPTIONAL, RANGE, - 0, 6000, TWO_VALUES, 0 }, - - { "TVResolution1", - "Sets MetaModes option for TwinView Screen 1. ", - XWACOM_PARAM_TVRESOLUTION1, VALUE_OPTIONAL, RANGE, - 0, 6000, TWO_VALUES, 0 }, - - { "RawFilter", - "Enables and disables filtering of raw data, " - "default is true/on.", - XWACOM_PARAM_RAWFILTER, VALUE_OPTIONAL, RANGE, - 0, 1, BOOLEAN_VALUE, 1 }, - - { "SpeedLevel", - "Sets relative cursor movement speed (default is 6). ", - XWACOM_PARAM_SPEEDLEVEL, VALUE_OPTIONAL, RANGE, - 1, 11, SINGLE_VALUE, 6 }, - - { "ClickForce", - "Sets tip/eraser pressure threshold = ClickForce*MaxZ/100 " - "(default is 6)", - XWACOM_PARAM_CLICKFORCE, VALUE_OPTIONAL, RANGE, - 1, 21, SINGLE_VALUE, 6 }, - - { "Threshold", - "Sets tip/eraser pressure threshold directly to the pressure " - "(default is 6*MaxZ/100)", - XWACOM_PARAM_THRESHOLD, VALUE_REQUIRED }, - - { "Accel", - "Sets relative cursor movement acceleration " - "(default is 1)", - XWACOM_PARAM_ACCEL, VALUE_OPTIONAL, RANGE, - 1, 7, SINGLE_VALUE, 1 }, - - { "xyDefault", - "Resets the bounding coordinates to default in tablet units. ", - XWACOM_PARAM_XYDEFAULT, VALUE_OPTIONAL }, - - { "mmonitor", - "Turns on/off across monitor movement in " - "multi-monitor desktop, default is on ", - XWACOM_PARAM_MMT, VALUE_OPTIONAL, - RANGE, 0, 1, BOOLEAN_VALUE, 1 }, - - { "CoreEvent", - "Turns on/off device to send core event. " - "default is decided by X driver and xorg.conf ", - XWACOM_PARAM_COREEVENT, VALUE_OPTIONAL, - RANGE, 0, 1, BOOLEAN_VALUE }, - - { "STopX0", - "Screen 0 left coordinate in pixels. ", - XWACOM_PARAM_STOPX0, VALUE_REQUIRED }, - - { "STopY0", - "Screen 0 top coordinate in pixels. ", - XWACOM_PARAM_STOPY0, VALUE_REQUIRED }, - - { "SBottomX0", - "Screen 0 right coordinate in pixels. ", - XWACOM_PARAM_SBOTTOMX0, VALUE_REQUIRED }, - - { "SBottomY0", - "Screen 0 bottom coordinate in pixels. ", - XWACOM_PARAM_SBOTTOMY0, VALUE_REQUIRED }, - - { "STopX1", - "Screen 1 left coordinate in pixels. ", - XWACOM_PARAM_STOPX1, VALUE_REQUIRED }, - - { "STopY1", - "Screen 1 top coordinate in pixels. ", - XWACOM_PARAM_STOPY1, VALUE_REQUIRED }, - - { "SBottomX1", - "Screen 1 right coordinate in pixels. ", - XWACOM_PARAM_SBOTTOMX1, VALUE_REQUIRED }, - - { "SBottomY1", - "Screen 1 bottom coordinate in pixels. ", - XWACOM_PARAM_SBOTTOMY1, VALUE_REQUIRED }, - - { "STopX2", - "Screen 2 left coordinate in pixels. ", - XWACOM_PARAM_STOPX2, VALUE_REQUIRED }, - - { "STopY2", - "Screen 2 top coordinate in pixels. ", - XWACOM_PARAM_STOPY2, VALUE_REQUIRED }, - - { "SBottomX2", - "Screen 2 right coordinate in pixels. ", - XWACOM_PARAM_SBOTTOMX2, VALUE_REQUIRED }, - - { "SBottomY2", - "Screen 2 bottom coordinate in pixels. ", - XWACOM_PARAM_SBOTTOMY2, VALUE_REQUIRED }, - - { "STopX3", - "Screen 3 left coordinate in pixels. ", - XWACOM_PARAM_STOPX3, VALUE_REQUIRED }, - - { "STopY3", - "Screen 3 top coordinate in pixels. ", - XWACOM_PARAM_STOPY3, VALUE_REQUIRED }, - - { "SBottomX3", - "Screen 3 right coordinate in pixels. ", - XWACOM_PARAM_SBOTTOMX3, VALUE_REQUIRED }, - - { "SBottomY3", - "Screen 3 bottom coordinate in pixels. ", - XWACOM_PARAM_SBOTTOMY3, VALUE_REQUIRED }, - - { "STopX4", - "Screen 4 left coordinate in pixels. ", - XWACOM_PARAM_STOPX4, VALUE_REQUIRED }, - - { "STopY4", - "Screen 4 top coordinate in pixels. ", - XWACOM_PARAM_STOPY4, VALUE_REQUIRED }, - - { "SBottomX4", - "Screen 4 right coordinate in pixels. ", - XWACOM_PARAM_SBOTTOMX4, VALUE_REQUIRED }, - - { "SBottomY4", - "Screen 4 bottom coordinate in pixels. ", - XWACOM_PARAM_SBOTTOMY4, VALUE_REQUIRED }, - - { "STopX5", - "Screen 5 left coordinate in pixels. ", - XWACOM_PARAM_STOPX5, VALUE_REQUIRED }, - - { "STopY5", - "Screen 5 top coordinate in pixels. ", - XWACOM_PARAM_STOPY5, VALUE_REQUIRED }, - - { "SBottomX5", - "Screen 5 right coordinate in pixels. ", - XWACOM_PARAM_SBOTTOMX5, VALUE_REQUIRED }, - - { "SBottomY5", - "Screen 5 bottom coordinate in pixels. ", - XWACOM_PARAM_SBOTTOMY5, VALUE_REQUIRED }, - - { "STopX6", - "Screen 6 left coordinate in pixels. ", - XWACOM_PARAM_STOPX6, VALUE_REQUIRED }, - - { "STopY6", - "Screen 6 top coordinate in pixels. ", - XWACOM_PARAM_STOPY6, VALUE_REQUIRED }, - - { "SBottomX6", - "Screen 6 right coordinate in pixels. ", - XWACOM_PARAM_SBOTTOMX6, VALUE_REQUIRED }, - - { "SBottomY6", - "Screen 6 bottom coordinate in pixels. ", - XWACOM_PARAM_SBOTTOMY6, VALUE_REQUIRED }, - - { "STopX7", - "Screen 7 left coordinate in pixels. ", - XWACOM_PARAM_STOPX7, VALUE_REQUIRED }, - - { "STopY7", - "Screen 7 top coordinate in pixels. ", - XWACOM_PARAM_STOPY7, VALUE_REQUIRED }, - - { "SBottomX7", - "Screen 7 right coordinate in pixels. ", - XWACOM_PARAM_SBOTTOMX7, VALUE_REQUIRED }, - - { "SBottomY7", - "Screen 7 bottom coordinate in pixels. ", - XWACOM_PARAM_SBOTTOMY7, VALUE_REQUIRED }, - - { "ToolID", - "Returns the ID of the associated device. ", - XWACOM_PARAM_TOOLID, VALUE_REQUIRED }, - - { "ToolSerial", - "Returns the serial number of the associated device. ", - XWACOM_PARAM_TOOLSERIAL, VALUE_REQUIRED }, - - { "Serial", - "Returns/sets the serial number of the chosen device. ", - XWACOM_PARAM_SERIAL, VALUE_REQUIRED }, - - { "TabletID", - "Returns the tablet ID of the associated device. ", - XWACOM_PARAM_TID, VALUE_REQUIRED }, - - { "GetTabletID", - "Returns the tablet ID of the associated device. ", - XWACOM_PARAM_TID, VALUE_REQUIRED }, - - { "NumScreen", - "Returns number of screens configured for the desktop. ", - XWACOM_PARAM_NUMSCREEN, VALUE_REQUIRED }, - - { "XScaling", - "Returns the status of XSCALING is set or not. ", - XWACOM_PARAM_XSCALING, VALUE_REQUIRED }, - - { NULL } -}; - -/***************************************************************************** -** Implementation -*****************************************************************************/ - -void Usage(FILE* f) -{ - fprintf(f, - "Usage: xsetwacom [options] [command [arguments...]]\n" - "Options:\n" - " -h, --help - usage\n" - " -v, --verbose - verbose output\n" - " -V, --version - version info\n" - " -d, --display disp_name - override default display\n" - " -s, --shell - generate shell commands for 'get'\n" - " -x, --xconf - generate X.conf lines for 'get'\n"); - - fprintf(f, - "\nCommands:\n" - " list [dev|param] - display known devices, parameters \n" - " list mod - display supported modifier and specific keys for keystokes\n" - " set dev_name param [values...] - set device parameter by name\n" - " get dev_name param [param...] - get current device parameter(s) value by name\n" - " getdefault dev_name param [param...] - get device parameter(s) default value by name\n"); -} - -static int XError(Display* pDisp, XErrorEvent* pEvent) -{ - char chBuf[64]; - XGetErrorText(pDisp,pEvent->error_code,chBuf,sizeof(chBuf)); - fprintf(stderr,"X Error: %d %s\n", pEvent->error_code, chBuf); - gnLastXError = pEvent->error_code; - return 0; -} - -/*static int GetLastXError(void) -{ - return gnLastXError; -}*/ - -static void Error(int err, const char* pszText) -{ - fprintf(stderr,"Error (%d): %s\n",err,pszText); -} - -typedef struct { WACOMDEVICETYPE type; const char* pszText; } TYPEXLAT; - -static int ListDev(WACOMCONFIG *hConfig, char** argv) -{ - const char* pszType; - WACOMDEVICEINFO* pInfo; - unsigned int i, j, uCount; - - static TYPEXLAT xTypes[] = - { - { WACOMDEVICETYPE_CURSOR, "cursor" }, - { WACOMDEVICETYPE_STYLUS, "stylus" }, - { WACOMDEVICETYPE_ERASER, "eraser" }, - { WACOMDEVICETYPE_TOUCH, "touch" }, - { WACOMDEVICETYPE_PAD, "pad" } - }; - - if (*argv != NULL) - fprintf(stderr,"ListDev: Ignoring extraneous arguments.\n"); - - if (WacomConfigListDevices(hConfig,&pInfo,&uCount)) - return 1; - - for (i=0; i<uCount; ++i) - { - pszType = "unknown"; - for (j=0; j<sizeof(xTypes)/sizeof(*xTypes); ++j) - if (xTypes[j].type == pInfo[i].type) - pszType = xTypes[j].pszText; - - fprintf(stdout,"%-16s %-10s\n",pInfo[i].pszName,pszType); - } - - WacomConfigFree(pInfo); - return 0; -} - -static int ListParam(WACOMCONFIG *hConfig, char** argv) -{ - PARAMINFO* p; - - if (*argv != NULL) - fprintf(stderr,"ListParam: Ignoring extraneous arguments.\n"); - - for (p=gParamInfo; p->pszParam; ++p) - fprintf(stdout,"%-16s - %s\n", - p->pszParam, p->pszDesc); - - printf ("\nEvent description format:\n" - "[CORE] [EVENT TYPE] [MODIFIERS] [CODE]\n" - " CORE: Emit core events irrespective of the SendCoreEvents setting\n" - " EVENT TYPE: the type of event to emit:\n" - "\tKEY: Emit a key event\n" - "\tBUTTON: Emit a button event\n" - "\tDBLCLICK: Emit a double-click button event\n" - "\tMODETOGGLE: Toggle absolute/relative tablet mode\n"); - printf ("\tDISPLAYTOGGLE: Toggle cursor movement among screens\n" - "\t for the selected tool except pad which\n" - "\t applies to all tools asssociated with the tablet\n" - " Modifier: use \"xsetwacom list mod\"\n" - "\tto see a list of modifiers and specific keys\n" - " CODE: Button number if emit a button event \n" - "\tor specific keys and any other keys not listed as mod \n"); - printf ("Examples:\n" - " xsetwacom set stylus Button1 \"button 5\"\n" - "\t(emit mouse button 5 event)\n" - " xsetwacom set stylus Button3 \"dblclick 1\"\n" - "\t(emit mouse double left click event)\n" - " xsetwacom set pad Button2 \"core key ctrl alt F2\"\n" - "\t(emit ctrl + alt + F2 key event)\n" - " xsetwacom set pad Button3 \"core key quotedbl a space test space string quotedbl\"\n"); - printf ("\t(emit keystroke \"a test string\" event)\n" - " xsetwacom set pad Button3 \"core key quotedbl a test string quotedbl\"\n" - "\t(emit keystroke \"ateststring\" event)\n" - " xsetwacom set pad striplup \"core key up\"\n" - "\t(emit up arrow key event)\n" - " xsetwacom set pad stripldn \"core key down\"\n" - "\t(emit down arrow key event)\n"); - - return 0; -} - -static int List(WACOMCONFIG *hConfig, char** argv) -{ - if (*argv == NULL) - return ListDev(hConfig,argv); - - if (!strcmp(*argv,"dev")) - return ListDev(hConfig,argv+1); - - if (!strcmp(*argv,"param")) - return ListParam(hConfig,argv+1); - - if (!strcmp(*argv,"mod")) - return xf86WcmListMod(argv+1); - - fprintf(stderr,"List: Unknown argument '%s'\n",*argv); - return 1; -} - -static int Pack(int nCount, int* pnValues, int* pnResult, PARAMINFO* p) -{ - if (nCount == 4) - { - int i, check = 0; - for (i = 0; i<2; i++) - if ((pnValues[i] < p->nMin) || (pnValues[i]> p->nMax)) - check = 1; - if (!check) - if (((pnValues[0] + pnValues[3]) != p->nMax) - || ((pnValues[1] + pnValues[2]) != p->nMax)) - check = 1; - if (check) - { - fprintf(stderr,"Pack: Value for '%s' out of range " - "(%d - %d)\n", p->pszParam, p->nMin, p->nMax); - return 1; - } - - *pnResult = - ((pnValues[0] & 0xFF) << 24) | - ((pnValues[1] & 0xFF) << 16) | - ((pnValues[2] & 0xFF) << 8) | - (pnValues[3] & 0xFF); - return 0; - } - - fprintf(stderr, - "Set: Incorrect number of values for bezier curve.\n" - "Please check your values' format. \n" - "Bezier curve is specified by two control points x0,y0 and x1,y1\n" - "Ranges are 0 to 100 for each value corresponding to 0.00 to 1.00\n" - "A straight line would be: 0 0 100 100\n" - "A slightly depressed line might be: 15 0 100 85\n" - "A slightly amplified line might be: 0 15 85 100\n"); - - return 1; -} - -static int ReCount(int * nValues, const char * pszValues) -{ - int nCount = 0; - const char* pszEnd = pszValues; - const char* tmpValues; - - do - { - tmpValues = pszEnd; - if (strncasecmp(tmpValues,"0x",2) == 0) - nValues[nCount++] = strtol(tmpValues,(char **)&pszEnd,16); - else - nValues[nCount++] = strtol(tmpValues,(char **)&pszEnd,10); - } while (pszEnd != tmpValues && (*pszEnd != '\0') && pszEnd[0] == ' ' ); - - return nCount; -} - -static int ParseValues(int nCount, const char* pszValues, int* nValues, - int* nValue, unsigned * keys, PARAMINFO* p, const char * devName) -{ - if (p->nType == BOOLEAN_VALUE || - p->nType == SINGLE_VALUE || - p->nType == ACTION_VALUE) - { - if ((p->nType == BOOLEAN_VALUE) && - (!strcasecmp(pszValues,"on") || - !strcasecmp(pszValues,"true") || - !strcasecmp(pszValues,"enable") || - !strcasecmp(pszValues,"1") || - !strcasecmp(pszValues,"absolute"))) - *nValue = 1; - else if ((p->nType == BOOLEAN_VALUE) && - (!strcasecmp(pszValues,"off") || - !strcasecmp(pszValues,"false") || - !strcasecmp(pszValues,"disable") || - !strcasecmp(pszValues,"0") || - !strcasecmp(pszValues,"relative"))) - *nValue = 0; - else if (p->nType == ACTION_VALUE) - { - *nValue = xf86WcmDecode (devName, - p->pszParam, - pszValues, - keys); - } - else if (p->nType == SINGLE_VALUE) - { - if (p->nParamID == XWACOM_PARAM_TWINVIEW || - p->nParamID == XWACOM_PARAM_ROTATE) - { - int check = 0, j; - const char ** option_char = rt_char; - if (p->nParamID == XWACOM_PARAM_TWINVIEW) - option_char = tv_char; - for (j = p->nMin; j <= p->nMax; j++) - if (!strcasecmp(pszValues, option_char[j])) - { - check = 1; - *nValue = j; - } - if (!check) - { - fprintf(stderr,"ParseValues: Value '%s' is " - "invalid.\n", pszValues); - return 1; - } - } - else - *nValue = nValues[0]; - } - /* Is there a range and are we in it? */ - if (p->bRange && - ((*nValue < p->nMin) || (*nValue > p->nMax))) - { - fprintf(stderr,"ParseValues: Value for '%s' (%d) out of range " - "(%d - %d)\n", p->pszParam, *nValue, p->nMin, p->nMax); - return 1; - } - } - else if (p->nType == PACKED_CURVE) - { - if (nCount == 1) - nCount = ReCount(nValues, pszValues); - - if (Pack(nCount,nValues,nValue,p)) - return 1; - } - else if (p->nType == TWO_VALUES) - { - if (nCount == 1) - nCount = ReCount(nValues, pszValues); - - if (nCount != 2) - { - fprintf (stderr, "ParseValues: only two values allowed for %s. \n" - "Please check your values' format. \n", p->pszParam); - return 1; - } - *nValue = nValues [0] | (nValues [1] << 16); - } - else - { - fprintf(stderr,"ParseValues: Value (%s) for '%s' is " - "invalid.\n", pszValues, p->pszParam); - return 1; - } - return 0; -} - -static int Set(WACOMCONFIG * hConfig, char** argv) -{ - PARAMINFO* p; - WACOMDEVICE * hDev; - char* a, *pszEnd; - const char* pszValues[32]; - int nValues[4]; - const char* pszDevName = NULL; - const char* pszParam = NULL; - int i, nValue=0, nReturn, nCount = 0; - unsigned keys[256]; - - while ((a=*argv++) != NULL) - { - if (!pszDevName) pszDevName = a; - else if (!pszParam) pszParam = a; - else if (nCount < 4) pszValues[nCount++] = a; - else - { - fprintf(stderr,"Set: Unknown argument '%s'\n",a); - return 1; - } - } - /* No device or param? Error. */ - if (!pszDevName || !pszParam) - { Usage(stderr); return 1; } - - /* Find param. */ - for (p=gParamInfo; p->pszParam; ++p) - if (strcasecmp(p->pszParam,pszParam) == 0) - break; - - /* Unknown? Complain. */ - if (!p->pszParam) - { - fprintf(stderr,"Set: Unknown parameter '%s'\n",pszParam); - return 1; - } - - if (p->nParamID > XWACOM_PARAM_GETONLYPARAM) - { - fprintf(stderr,"Set: '%s' doesn't support set option.\n", - pszParam); - return 1; - } - - /* Set case correctly for error messages below. */ - pszParam = p->pszParam; - - /* If value is empty, do we support this? */ - if (!nCount && !p->bEmptyOK) - { - fprintf(stderr,"Set: Value for '%s' must be specified.\n", - pszParam); - return 1; - } - if (!nCount) - nValue = p->nDefault; - else - { - for (i=0; i<nCount; i++) - { - /* Convert value to 32 bit integer; hex OK, octal is not. */ - if (strncasecmp(pszValues[i],"0x",2) == 0) - nValues[i] = strtol(pszValues[i],&pszEnd,16); - else - nValues[i] = strtol(pszValues[i],&pszEnd,10); - } - if (p->nType == SINGLE_VALUE && nCount == 1 && - (*pszEnd == '\0')) /* numbers */ - { - nValue = nValues[0]; - /* Is there a range and are we in it? */ - if (p->bRange && - ((nValue < p->nMin) || (nValue > p->nMax))) - { - fprintf(stderr,"Set: Value for '%s' (%d) out of range " - "(%d - %d)\n", p->pszParam, nValue, p->nMin, p->nMax); - return 1; - } - } - else if ((strlen (pszValues[0]) > 255) || - ParseValues(nCount, pszValues[0], - nValues, &nValue, keys, p, pszDevName) ) - return 1; - } - - /* Looks good, send it. */ - if (gnVerbose) - printf("Set: sending %d %d (0x%X)\n",p->nParamID,nValue,nValue); - - /* Open device */ - hDev = WacomConfigOpenDevice(hConfig, pszDevName); - if (!hDev) - { - fprintf(stderr,"Set: Failed to open device '%s'\n", - pszDevName); - return 1; - } - - /* Send request */ - nReturn = WacomConfigSetRawParam(hDev, p->nParamID, nValue, keys); - - if (nReturn) - fprintf(stderr,"Set: Failed to set %s value for '%s'\n", - pszDevName, pszParam); - - /* Close device and return */ - (void)WacomConfigCloseDevice(hDev); - return nReturn ? 1 : 0; -} - -static void DisplayValue (WACOMDEVICE *hDev, const char *devname, PARAMINFO *p, - int disperr, int valu) -{ - int value = 0, sl = 0, i = 0; - char strval [200] = ""; - unsigned keys[256]; - if (WacomConfigGetRawParam (hDev, p->nParamID, &value, valu, keys)) - { - fprintf (stderr, "GetRawParam: Failed to get %s value for '%s'\n", - devname, p->pszParam); - return; - } - - switch (p->nType) - { - case SINGLE_VALUE: - if (p->nParamID == XWACOM_PARAM_TWINVIEW || - p->nParamID == XWACOM_PARAM_ROTATE) - { - const char ** option_char = rt_char; - if (p->nParamID == XWACOM_PARAM_TWINVIEW) - option_char = tv_char; - - snprintf (strval, sizeof (strval), - "%s", option_char[value] ); - } - else if (p->nParamID == XWACOM_PARAM_TOOLSERIAL) - snprintf (strval, sizeof (strval), "%u", value); - else - snprintf (strval, sizeof (strval), "%d", value); - break; - case PACKED_CURVE: - snprintf (strval, sizeof (strval), gGetFormat == gfXCONF ? - "%d,%d,%d,%d" : "%d %d %d %d", - (value >> 24) & 0xff, (value >> 16) & 0xff, - (value >> 8) & 0xff, value & 0xff); - break; - case TWO_VALUES: - snprintf (strval, sizeof (strval), gGetFormat == gfXCONF ? - "%d,%d" : "%d %d", - value & 0xffff, (value >> 16) & 0xffff); - break; - case BOOLEAN_VALUE: - snprintf (strval, sizeof (strval), "%s", value ? "on" : "off"); - break; - case ACTION_VALUE: - sl = 0; - if (value & AC_CORE) - sl += snprintf (strval + sl, sizeof (strval) - sl, "CORE "); - switch (value & AC_TYPE) - { - case AC_BUTTON: - sl += snprintf (strval + sl, sizeof (strval) - sl, "BUTTON "); - break; - case AC_KEY: - sl += snprintf (strval + sl, sizeof (strval) - sl, "KEY "); - break; - case AC_MODETOGGLE: - sl += snprintf (strval + sl, sizeof (strval) - sl, "MODETOGGLE "); - break; - case AC_DBLCLICK: - sl += snprintf (strval + sl, sizeof (strval) - sl, "DBLCLICK "); - break; - case AC_DISPLAYTOGGLE: - sl += snprintf (strval + sl, sizeof (strval) - sl, "DISPLAYTOGGLE "); - break; - } - if ((value & AC_TYPE) != AC_KEY) - { - sl += snprintf (strval + sl, sizeof (strval) - sl, "%d", - value & AC_CODE); - } - else if (!(value & AC_CODE)) - { - printf ("xsetwacom %s %s \"%s\" missing keystrokes \n", devname, p->pszParam, strval); - return; - } - else - { - char keyString[32]; - if (gGetFormat == gfXCONF) - { - printf ("Button keystroke is only an xsetwacom command \n"); - return; - } - if (!xf86WcmGetString(keys[0], keyString)) - { - printf ("Button keystroke key error \n"); - return; - } - i=0; - while (i<((value & AC_NUM_KEYS)>>20)) - { - if (!xf86WcmGetString(keys[i++], keyString)) - return; - - if (strlen(keyString) == 1) - sl += snprintf (strval + sl, sizeof (strval) - sl, "%s", keyString); - else - sl += snprintf (strval + sl, sizeof (strval) - sl, " %s ", keyString); - } - } - if (strval [sl - 1] == ' ') - strval [sl - 1] = 0; - break; - } - - switch (gGetFormat) - { - case gfSHELL: - if (p->nParamID < XWACOM_PARAM_GETONLYPARAM) - printf ("xsetwacom set %s %s \"%s\"\n", devname, p->pszParam, strval); - else - printf ("%s option is only an xsetwacom get command \n", p->pszParam); - break; - case gfXCONF: - if (p->nParamID > XWACOM_PARAM_NOXOPTION) - { - if (p->nParamID < XWACOM_PARAM_GETONLYPARAM) - printf ("%s is not an X configuration option \n", p->pszParam); - else - printf ("%s option is only an xsetwacom get command \n", p->pszParam); - } - else - { - if ((p->nParamID >= XWACOM_PARAM_BUTTON1) && - (p->nParamID <= XWACOM_PARAM_STRIPRDN) && - ((value & AC_TYPE) != AC_BUTTON)) - printf ("%s option is only an xsetwacom command \n", p->pszParam); - else - printf ("\tOption\t\"%s\"\t\"%s\"\n", p->pszParam, strval); - } - break; - default: - if ( (p->nType == ACTION_VALUE) && - (((value & AC_TYPE) == AC_KEY) || - ((value & AC_TYPE) == AC_MODETOGGLE) || - ((value & AC_TYPE) == AC_DBLCLICK) || - ((value & AC_TYPE) == AC_DISPLAYTOGGLE)) ) - printf ("%s\n", strval); - else - printf ("%d\n", value); - break; - } -} - -static int Get(WACOMCONFIG *hConfig, char **argv, int valu) -{ - WACOMDEVICE *hDev; - const char *devname; - - /* First argument is device name. */ - - if (!*argv) - { - fprintf(stderr,"Get: Expecting device name\n"); - return 1; - } - - /* Open device */ - devname = *argv++; - hDev = WacomConfigOpenDevice (hConfig, devname); - if (!hDev) - { - fprintf(stderr,"Get: Failed to open device '%s'\n", devname); - return 1; - } - - /* Interpret every following argument as parameter name - * and display its value. - */ - while (*argv) - { - PARAMINFO* p; - - for (p = gParamInfo; p->pszParam; ++p) - if (strcasecmp (p->pszParam, *argv) == 0) - break; - - /* Unknown? Complain. */ - if (!p->pszParam) - { - if (strcasecmp (*argv, "all") == 0) - { - for (p = gParamInfo; p->pszParam; ++p) - DisplayValue (hDev, devname, p, 0, valu); - argv++; - continue; - } - - fprintf (stderr,"Get: Unknown parameter '%s'\n", *argv); - return 1; - } - - /* no X option */ - if (p->nParamID > XWACOM_PARAM_NOXOPTION && gGetFormat == gfXCONF) - fprintf (stderr,"Get: parameter '%s' is only an xsetwacom command\n", *argv); - else - DisplayValue (hDev, devname, p, 1, valu); - argv++; - } - - /* Close device and return */ - WacomConfigCloseDevice (hDev); - - return 0; -} - -int DoCommand (COMMAND cmd, char** argv) -{ - int nReturn; - Display* pDisp; - WACOMCONFIG * hConf; - - pDisp = XOpenDisplay(gpszDisplayName); - if (!pDisp) - { - fprintf(stderr,"Failed to open display (%s)\n", - gpszDisplayName ? gpszDisplayName : ""); - return 1; - } - - XSetErrorHandler(XError); - XSynchronize(pDisp,1 /*sync on*/); - - hConf = WacomConfigInit(pDisp,Error); - if (!hConf) - { - fprintf(stderr,"Failed to init WacomConfig\n"); - XCloseDisplay(pDisp); - return 1; - } - - switch (cmd) - { - case COMMAND_LIST: - nReturn = List(hConf,argv); - break; - - case COMMAND_SET: - nReturn = Set(hConf,argv); - break; - - case COMMAND_GET: - nReturn = Get(hConf,argv,1); - break; - - case COMMAND_GETDEFAULT: - nReturn = Get(hConf,argv,3); - break; - - default: - assert(0); - } - - WacomConfigTerm(hConf); - XCloseDisplay(pDisp); - return nReturn; -} - -int main(int argc, char** argv) -{ - char* a; - - ++argv; - while ((a=*argv++) != NULL) - { - if (!strcmp(a,"-h") || !strcmp(a,"--help")) - { - Usage(stdout); - return 0; - } - else if (!strcmp(a,"-s") || !strcmp(a,"--shell")) - gGetFormat = gfSHELL; - else if (!strcmp(a,"-x") || !strcmp(a,"--xconf")) - gGetFormat = gfXCONF; - else if (!strcmp(a,"-v") || !strcmp(a,"--verbose")) - ++gnVerbose; - else if (!strcmp(a,"-V") || !strcmp(a,"--version")) - { - fprintf(stdout,"%s\n",XSETWACOM_VERSION); - return 0; - } - else if (!strcmp(a,"-d") || !strcmp(a,"--display")) - { - a = *argv++; - if (!a) - { - fprintf(stderr,"Missing display name\n"); - return 1; - } - gpszDisplayName = a; - } - - /* commands */ - else if (!strcmp(a,"list")) - return DoCommand(COMMAND_LIST,argv); - else if (!strcmp(a,"set")) - return DoCommand(COMMAND_SET,argv); - else if (!strcmp (a, "get")) - return DoCommand (COMMAND_GET,argv); - else if (!strcmp (a, "getdefault")) - return DoCommand (COMMAND_GETDEFAULT,argv); - else - { - fprintf(stderr,"Unknown command '%s'\n", a); - Usage(stderr); - return 1; - } - } - - Usage(stdout); - return 0; -} diff --git a/src/wacomxi/Makefile.am b/src/wacomxi/Makefile.am deleted file mode 100644 index 72cf866..0000000 --- a/src/wacomxi/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -AM_CFLAGS = -Wall - -# WacomXI Install -if WACOMXI_INSTALL -tcllibdir = $(libdir)/TkXInput -tcllib_HEADERS = pkgIndex.tcl -tcllib_LTLIBRARIES = libwacomxi.la -cpldir = $(bindir) -cpl_SCRIPTS = wacomcpl wacomcpl-exec -endif - -EXTRA_DIST = wacomcpl-exec - -# Source dependencies -libwacomxi_la_SOURCES = wacomxi.c wacomxi.h -libwacomxi_la_LDFLAGS = -no-undefined -libwacomxi_la_LIBADD = @WCM_WACOMXI_LIBS@ diff --git a/src/wacomxi/pkgIndex.tcl b/src/wacomxi/pkgIndex.tcl deleted file mode 100644 index c987d64..0000000 --- a/src/wacomxi/pkgIndex.tcl +++ /dev/null @@ -1,5 +0,0 @@ -# -# This file has been customized after generated by -# the "pkg_mkIndex" command. -# -package ifneeded LIBWACOMXI 1.0 [list tclPkgSetup $dir LIBWACOMXI 1.0 {{libwacomxi.so load {wacomxi::bindevent }}}] diff --git a/src/wacomxi/wacomcpl-exec b/src/wacomxi/wacomcpl-exec deleted file mode 100755 index 7dc4860..0000000 --- a/src/wacomxi/wacomcpl-exec +++ /dev/null @@ -1,1951 +0,0 @@ -#!/bin/bash -#\ -exec wish -f "$0" ${1+"$@"} -# -# wacomcpl-exec -- Wacom Control Panel Utility to Change Configuration Setting. -# -# Author : Ping Cheng -# Creation date : 04/05/2003 -# -# Based on calibrate 1998-99 Patrick Lecoanet -- -# -# This code is free software; you can redistribute it and/or -# modify it under the terms of the GNU Library General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This code 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 -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this code; if not, write to the Free -# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -# - -package require LIBWACOMXI - -set currentScreen 0 -set desktopWidth [ winfo screenwidth . ] -set desktopHeight [ winfo screenheight . ] -set screenWidth [ winfo screenwidth . ] -set screenHeight [ winfo screenheight . ] -set screenXBottom [ winfo screenwidth . ] -set screenYBottom [ winfo screenheight . ] - -set screenX_org 0 -set screenY_org 0 -set swapThresh 100 -set size 200 -set circle_size 10 -set line_size 30 - -set origin_x [ expr ($desktopWidth/2) - ($desktopWidth/4) ] -set origin_y [ expr ($desktopHeight/2) - ($desktopHeight/4) ] -set windowSize "540x300" - -set device "" -set deviceIndex 0 -set showHelp 0 -set modeToggleB 33 -set ignoreButton 34 -set doubleClickB 35 -set displayToggleB 36 -set keystrokeB 37 -set maxNumTablets 199 - -proc updateCurrentScreenInfo {} { - global device numScreens currentScreen - global screenXBottom screenYBottom screenX_org screenY_org - global getScreenInfo screenWidth screenHeight - - if { $numScreens($device) != 1 } { - set screenInfo $getScreenInfo($device,Screen$currentScreen) - set screenXBottom [ lindex $screenInfo 0 ] - set screenYBottom [ lindex $screenInfo 1 ] - set screenX_org [ lindex $screenInfo 2 ] - set screenY_org [ lindex $screenInfo 3 ] - set screenWidth abs([ expr $screenXBottom-$screenX_org ]) - set screenHeight abs([ expr $screenYBottom-$screenY_org ]) - } -} - -proc pad {name geometry} { - global size circle_size line_size - - set circleox [ expr $size/2-$circle_size/2 ] - set circleoy $circleox - set circlecx [ expr $circleox+$circle_size ] - set circlecy $circlecx - set vertx [ expr $size/2 ] - set vertoy [ expr ($size-$line_size)/2 ] - set vertcy [ expr $vertoy+$line_size ] - set horizox [ expr ($size-$line_size)/2 ] - set horizcx [ expr $horizox+$line_size ] - set horizy [ expr $size/2 ] - - toplevel $name - wm geometry $name $geometry - wm overrideredirect $name true - canvas $name.m -height $size -width $size -bg "#505075" - $name.m create oval $circleox $circleoy $circlecx $circlecy -outline white - $name.m create line $vertx $vertoy $vertx $vertcy -fill white - $name.m create line $horizox $horizy $horizcx $horizy -fill white - pack $name.m -} - -proc updateXinitrc {device option value} { - - if { ![ file exists ~/.xinitrc ] } { - if { [ file exists ~/.xsession ] } { - file copy -force ~/.xsession ~/.xsession.bak - file copy -force ~/.xsession /tmp/xsession1 - exec sed -e "/xsetwacom set $device $option /d" /tmp/xsession1 > /tmp/wacom - exec echo "xsetwacom set $device $option \"$value\"" > ~/.xsession - exec cat /tmp/wacom >> ~/.xsession - file delete -force /tmp/wacom /tmp/xsession1 - } else { - exec echo "xsetwacom set $device $option \"$value\"" > ~/.xinitrc - exec echo "# run the primary system script" >> ~/.xinitrc - exec echo ". /etc/X11/xinit/xinitrc" >> ~/.xinitrc - } - } else { - file copy -force ~/.xinitrc ~/.xinitrc.bak - file copy -force ~/.xinitrc /tmp/xinitrc1 - exec sed -e "/xsetwacom set $device $option /d" /tmp/xinitrc1 > /tmp/wacom - exec echo "xsetwacom set $device $option \"$value\"" > ~/.xinitrc - exec cat /tmp/wacom >> ~/.xinitrc - file delete -force /tmp/wacom /tmp/xinitrc1 - } - if { $option == "PressCurve" } { - set index 0 - set v1 [ lindex $value $index ] - for { set i 2 } { $i < 5 } { incr i 1 } { - set index [ expr $index+1 ] - set v$i [ lindex $value $index ] - } - exec xsetwacom set $device $option $v1 $v2 $v3 $v4 - } else { - exec xsetwacom set $device $option $value - } -} - -proc verifycalibResults { } { - global calibResults device getOptionDefault - - set tol_offset [expr ($getOptionDefault($device,BottomY) / 20)] - set tol_left [expr (($getOptionDefault($device,BottomY) / 2) - $tol_offset)] - set tol_right [expr (($getOptionDefault($device,BottomY) / 2) + $tol_offset)] - set tol_bottom [expr ($getOptionDefault($device,BottomY) - $tol_offset)] - - # set tablet Y values to normal when offset is by whole of the tablet size. - # Whole has to be first and we do it two times to make sure. - if { $calibResults(yDev,0) > $tol_bottom } { - set calibResults(yDev,0) [expr ($calibResults(yDev,0) - $getOptionDefault($device,BottomY))] - set calibResults(yDev,1) [expr ($calibResults(yDev,1) - $getOptionDefault($device,BottomY))] - } elseif { $calibResults(yDev,0) > $tol_bottom } { - set calibResults(yDev,0) [expr ($calibResults(yDev,0) - $getOptionDefault($device,BottomY))] - set calibResults(yDev,1) [expr ($calibResults(yDev,1) - $getOptionDefault($device,BottomY))] - } elseif { ($calibResults(yDev,0) > $tol_left) && ($calibResults(yDev,0) < $tol_right) } { - # set tablet Y values to normal when offset is by half tablet size - set calibResults(yDev,0) [expr ($calibResults(yDev,0) - ($getOptionDefault($device,BottomY) / 2))] - set calibResults(yDev,1) [expr ($calibResults(yDev,1) - ($getOptionDefault($device,BottomY) / 2))] - } - - set tol_offset [expr ($getOptionDefault($device,BottomX) / 20)] - set tol_left [expr (($getOptionDefault($device,BottomX) / 2) - $tol_offset)] - set tol_right [expr (($getOptionDefault($device,BottomX) / 2) + $tol_offset)] - set tol_bottom [expr ($getOptionDefault($device,BottomX) - $tol_offset)] - - # set tablet X values to normal when offset is by whole of the tablet size. - # Whole has to be first and we do it two times to make sure. - if { $calibResults(xDev,0) > $tol_bottom } { - set calibResults(xDev,0) [expr ($calibResults(xDev,0) - $getOptionDefault($device,BottomX))] - set calibResults(xDev,1) [expr ($calibResults(xDev,1) - $getOptionDefault($device,BottomX))] - } elseif { $calibResults(xDev,0) > $tol_bottom } { - set calibResults(xDev,0) [expr ($calibResults(xDev,0) - $getOptionDefault($device,BottomX))] - set calibResults(xDev,1) [expr ($calibResults(xDev,1) - $getOptionDefault($device,BottomX))] - } elseif { ($calibResults(xDev,0) > $tol_left) && ($calibResults(xDev,0) < $tol_right) } { - # set tablet X values to normal when offset is by half tablet size - set calibResults(xDev,0) [expr ($calibResults(xDev,0) - ($getOptionDefault($device,BottomX) / 2))] - set calibResults(xDev,1) [expr ($calibResults(xDev,1) - ($getOptionDefault($device,BottomX) / 2))] - } -} - -proc calibrationSequence {which xDev yDev} { - global device calibResults screenY_org screenX_org - global workingTags screenTags size numScreens - global swapThresh screenWidth screenHeight getOptionDefault - global getDeviceModel screenXBottom screenYBottom - global calibX_org calibY_org calibX_botm calibY_botm - - set scaling [exec xsetwacom get $device xscaling] - if { $scaling == 1 } { - set xNewDev [expr (($xDev - $calibX_org) * $getOptionDefault($device,BottomX))] - set xDev [expr ($xNewDev / ($calibX_botm - $calibX_org))] - set yNewDev [expr (($yDev - $calibY_org) * $getOptionDefault($device,BottomY))] - set yDev [expr ($yNewDev / ($calibY_botm - $calibY_org))] - } - - set calibResults(xDev,$which) $xDev - set calibResults(yDev,$which) $yDev - - if { $which == 0 } { - .topleft.m configure -background "#505075" - wacomxi::bindevent .topleft.m $device <ButtonRelease> "" - .bottomright.m configure -background "#df94df" - wacomxi::bindevent .bottomright.m $device <ButtonRelease> \ - {calibrationSequence 1 %0 %1} - } elseif { $which == 1 } { - .bottomright.m configure -background "#505075" - wacomxi::bindevent .bottomright.m $device <ButtonRelease> "" - set borderOffset [expr ($size / 2 )] - - # A direction verification of the click - set clickCheck 0 - set xDevMin $calibResults(xDev,0) - set xDevMax $calibResults(xDev,1) - set yDevMin $calibResults(yDev,0) - set yDevMax $calibResults(yDev,1) - if { $calibResults(xDev,1) < $calibResults(xDev,0) } { - set clickCheck 1 - set xDevMin $calibResults(xDev,1) - set xDevMax $calibResults(xDev,0) - } - if { $calibResults(yDev,1) < $calibResults(yDev,0) } { - set clickCheck 1 - set yDevMin $calibResults(yDev,1) - set yDevMax $calibResults(yDev,0) - } - - if { $clickCheck == 1 } { - messageWindow "Warning !!!" \ - "\n\nThere was something unusual in your calibration step.\n\ - If you are pretty sure that you have clicked on the center\n\ - of the pink crosshair, you are fine. Otherwise, try it again." - } - - # A starting point verification of the click. - verifycalibResults - - set widthDev [expr $calibResults(xDev,1) - $calibResults(xDev,0)] - set heightDev [expr $calibResults(yDev,1) - $calibResults(yDev,0)] - set widthX [expr $screenWidth-$size] - set heightX [expr $screenHeight-$size] - - set xDevMin [expr $xDevMin - ($borderOffset * $widthDev / $widthX)] - set xDevMax [expr $xDevMax + ($borderOffset * $widthDev / $widthX)] - set yDevMin [expr $yDevMin - ($borderOffset * $heightDev / $heightX)] - set yDevMax [expr $yDevMax + ($borderOffset * $heightDev / $heightX)] - - updateXinitrc $device topx $xDevMin - updateXinitrc $device topy $yDevMin - updateXinitrc $device bottomx $xDevMax - updateXinitrc $device bottomy $yDevMax - # send the same data to the associated eraser if it is a stylus - set type $getDeviceModel($device,type) - if { ![ string compare $type "stylus" ] } { - set eraser $getDeviceModel($device,eraser) - if { [ string compare $eraser $device ] && $eraser != "" } { - updateXinitrc $eraser topx $xDevMin - updateXinitrc $eraser topy $yDevMin - updateXinitrc $eraser bottomx $xDevMax - updateXinitrc $eraser bottomy $yDevMax - } - } - - destroy .topleft .bottomright - if { $numScreens($device) > 1 } { - .screen.list.label configure -text "" - bindtags .screen.list.list $screenTags - } else { - closeTabWindow - } - } -} - -proc Calibration {} { - global numScreens device screenTags getOption Option - global calibX_org calibY_org calibX_botm calibY_botm tvID - global screenX_org screenY_org screenXBottom screenYBottom - global screenWidth screenHeight - - # mainly to get the defaults - set Option(1) "TopX" - set Option(2) "TopY" - set Option(3) "BottomX" - set Option(4) "BottomY" - set Option(5) "Mode" - set Option(6) "TwinView" - - getDeviceOptionProc $device 6 - set mode $getOption($device,Mode) - set tvID $getOption($device,TwinView) - - if { $mode != 1 } { - disableButtons - messageWindow "Warning " "\n\nDevice $device is in relative mode. \n\ - You can calibrate $device only when it is in absolute mode. \n\ - Please swith $device's mode and try again. " - closeTabWindow - return - } - - if { $tvID == 1 } { # Nvidia Xinerama setup starts at (0,0) even when it is not in xorg.conf - set calibX_org 0 - set calibY_org 0 - set calibX_botm $screenWidth - set calibY_botm $screenHeight - } else { - set calibX_org $screenX_org - set calibY_org $screenY_org - set calibX_botm $screenXBottom - set calibY_botm $screenYBottom - } - - bindtags .workingDev.list . - if { $numScreens($device) > 1 } { - displayScreenList $device - set screenTags [ bindtags .screen.list.list] - .screen.list.title configure -text "Select $device associated Screen:" - wm state .screen normal - } else { - updateCurrentScreenInfo - startCalibration - } - disableButtons -} - -proc startCalibration {} { - global device size numScreens - global calibResults calibX_org calibY_org calibX_botm calibY_botm - - if { $numScreens($device) > 1 } { - bindtags .screen.list.list . - } - - set y_coor [ expr $calibY_botm-$size*(abs($calibY_botm)/$calibY_botm) ] - set x_coor [ expr $calibX_botm-$size*(abs($calibX_botm)/$calibX_botm) ] - pad .topleft +$calibX_org+$calibY_org - pad .bottomright +$x_coor+$y_coor - update - # - # Start calib sequence - catch {unset calibResults} - exec xsetwacom set $device xydefault - .topleft.m configure -background "#df94df" - wacomxi::bindevent .topleft.m $device <ButtonRelease> \ - {calibrationSequence 0 %0 %1} - helpWindow "Help Window " \ - "\n\nPlease click on the center of \n\ - the pink crosshair using $device \n\ - Please don't click on anything else \n\ - by $device before you finish" -} - -proc helpWindow { tString mString } { - global showHelp - - if { $showHelp } { - messageWindow $tString $mString - } -} - -proc messageWindow { tString mString } { - toplevel .mWindow - wm title .mWindow $tString - wm transient .mWindow . - text .mWindow.text -background gray -width 40 -height 10 - button .mWindow.dismiss -text "Dismiss" \ - -command "destroy .mWindow; set ok 1" - .mWindow.text insert end $mString - pack .mWindow.text .mWindow.dismiss - # - # Do some spiffy animation to draw attention ! - for { set i 0 } { $i < 10 } { incr i } { - after 100 - .mWindow.text configure -background white - update - after 100 - .mWindow.text configure -background gray - update - } - tkwait variable ok -} - -proc updateScreenList {} { - global currentScreen numScreens screenWidth screenHeight - global device screenX_org screenY_org origin_x origin_y - - if { $numScreens($device) > 1 } { - set cScreen [ .screen.list.list get anchor ] - for { set i 0 } { $i < $numScreens($device) } { incr i 1 } { - if { $cScreen == "Screen$i" } { - set currentScreen $i - set i $numScreens($device) - } - } - } - updateCurrentScreenInfo - set origin_x [ expr $screenX_org+$screenWidth/2-$screenWidth/4 ] - set origin_y [ expr $screenY_org+$screenHeight/2-$screenHeight/4 ] - wm geometry . =+$origin_x+$origin_y - .screen.list.label configure -text $cScreen - set o_x [ expr $origin_x+100 ] - set o_y [ expr $origin_y+20 ] - wm geometry .screen =+$o_x+$o_y - startCalibration -} - -proc disableButtons {} { - global bName numButton numStrips currentW currentb - - if { $currentb } { - for { set i 1 } { $i <= [ expr ($numButton+$numStrips) ] } { incr i 1 } { - .allothers.f.$i configure -state disabled - } - .allothers.f.ok configure -state disable - .allothers.f.default configure -state disable - .allothers.f.cancel configure -state disable - } else { - if { $bName(pressure) } { - .panel.pressure configure -state disabled - } - if { $bName(calibrate) } { - .panel.calibrate configure -state disabled - } - if { $bName(button) } { - .panel.button configure -state disabled - } - if { $bName(mapping) } { - .panel.mapping configure -state disabled - } - if { $bName(advanced) } { - .panel.advanced configure -state disabled - } - } -} - -proc getDeviceOptionProc { dev i } { - global getOption getOptionDefault Option oldKeys modeToggleB - global displayToggleB ignoreButton doubleClickB keystrokeB - global numStrips numControls numButton spName - - for { set j 1 } { $j < [ expr $i+1 ] } { incr j 1 } { - set value [ exec xsetwacom get $dev $Option($j) ] - set value1 [ exec xsetwacom getdefault $dev $Option($j) ] - if { ![ string compare -nocase -length 10 $Option($j) "PressCurve" ] } { - set getOption($dev,PressCurve) 4 - set getOptionDefault($dev,PressCurve) 4 - - set p0 [ expr ( $value >> 24) & 0xFF ] - set p1 [ expr ( $value >> 16) & 0xFF ] - if { ($p1 > 5) && ($p1 < 35) } { - set getOption($dev,PressCurve) 3 - } - if { ($p1 >= 35) && ($p1 < 65) } { - set getOption($dev,PressCurve) 2 - } - if { ($p1 >= 65) && ($p1 < 95) } { - set getOption($dev,PressCurve) 1 - } - if { ($p0 > 5) && ($p0 < 35) } { - set getOption($dev,PressCurve) 5 - } - if { ($p0 >= 35) && ($p0 < 65) } { - set getOption($dev,PressCurve) 6 - } - if { ($p0 >= 65) && ($p0 < 95) } { - set getOption($dev,PressCurve) 7 - } - } else { - set match 0 - # are they button/wheel/ring/strip? - for { set k 1 } { $k <= $numControls } { incr k 1 } { - if { ![string compare -nocase $Option($j) $spName($k)] } { - set match 1 - break - } - } - set getOption($dev,$Option($j)) $value - set getOptionDefault($dev,$Option($j)) $value1 - if { $match } { - if { ($value > $doubleClickB) || ($value == 0) } { - if { ![string compare -nocase -length 8 DBLCLICK $value ] } { - set getOption($dev,$Option($j)) $doubleClickB - } - if { ![string compare -nocase -length 4 CORE $value ] } { - set getOption($dev,$Option($j)) $keystrokeB - set oldKeys($Option($j)) $value - } - if { ![string compare -nocase -length 10 MODETOGGLE $value ] } { - set getOption($dev,$Option($j)) $modeToggleB - } - if { ![string compare -nocase -length 13 DISPLAYTOGGLE $value ] } { - set getOption($dev,$Option($j)) $displayToggleB - } - if { $value == 0 } { - set getOption($dev,$Option($j)) $ignoreButton - } - } - if { $value1 == 0 } { - set getOptionDefault($dev,$Option($j)) $ignoreButton - } - } - } - } -} - -proc updateDevice {} { - global device deviceIndex hasPad isLCD - global numScreens getDeviceModel hasTouch - - set olddev $device - set device [ .workingDev.list get anchor ] - set deviceIndex [ .workingDev.list index anchor ] - if { $device != $olddev && $olddev != ""} { - # - # Clear old state related to preceding device - # - wacomxi::bindevent . $device <ButtonPress> "" - wacomxi::bindevent . $device <ButtonRelease> "" - } - - if { $device != ""} { - # - # Update the entry indicator - # - .workingDev.label configure -text $device - set model $getDeviceModel($device,model) - set type $getDeviceModel($device,type) - destroy .panel - if { ![ string compare $type "pad" ] } { - if { $hasPad($model) } { - createPanel 0 1 0 0 - } - } elseif { ![ string compare $type "touch" ] } { - if { $hasTouch($model) } { - createPanel 1 0 0 1 - } - } elseif { $isLCD($model) } { - if { ![ string compare $type "stylus" ] } { - - createPanel 1 1 0 1 - } elseif { [ string compare $type "cursor" ] } { - createPanel 1 1 0 0 - } - } elseif { [ string compare $type "cursor" ] } { - createPanel 1 1 1 0 - } else { - createPanel 0 1 1 0 - } - } else { - # - # Update the entry indicator - # - .workingDev.label configure -text $device - } -} - -proc createDeviceList {} { - global getDeviceModel - - set infoString [exec xsetwacom list] - set index 0 - set devices "" - set dev [ lindex $infoString $index ] - while { $dev != "" } { - set index [ expr $index+1 ] - set type [ lindex $infoString $index ] - - if { [catch { exec xsetwacom get $dev TabletID } model] == 0} { - set getDeviceModel($dev,type) $type - set getDeviceModel($dev,model) $model - set devices "$devices $dev" - set index [ expr $index+1 ] - } - set dev [ lindex $infoString $index ] - } - - frame .workingDev - label .workingDev.title -text "Select the Device:" - label .workingDev.label -background gray - listbox .workingDev.list -width 16 -height 12 \ - -yscrollcommand ".workingDev.sb set" - scrollbar .workingDev.sb -width 10 \ - -command ".workingDev.list yview" - grid .workingDev.title -row 0 -column 0 -columnspan 3 -sticky we - grid .workingDev.label -row 1 -column 0 -columnspan 3 -sticky we - grid .workingDev.list -row 2 -column 0 - grid .workingDev.sb -row 2 -sticky nse - set flag 0 - foreach dev $devices { - # initial related erasers for styli - set getDeviceModel($dev,eraser) "" - } - foreach dev $devices { - .workingDev.list insert end $dev - createScreenList $dev - set type $getDeviceModel($dev,type) - if { ![string compare $type "eraser"] } { - set model $getDeviceModel($dev,model) - foreach dev1 $devices { - set type1 $getDeviceModel($dev1,type) - set model1 $getDeviceModel($dev1,model) - if { ( $model == $model1 ) - && ![string compare $type1 "stylus"] } { - set getDeviceModel($dev1,eraser) $dev - } - } - } - } - bind .workingDev.list <ButtonRelease-1> updateDevice -} - -proc createScreenList { dev } { - global numScreens currentScreen - global desktopHeight desktopWidth getScreenInfo - - set numScreens($dev) [ exec xsetwacom get $dev NumScreen ] - for { set i 0 } {$i < $numScreens($dev)} { incr i 1 } { - set s1 [ exec xsetwacom get $dev SBottomX$i ] - set s2 [ exec xsetwacom get $dev SBottomY$i ] - set s3 [ exec xsetwacom get $dev STopX$i ] - set s4 [ exec xsetwacom get $dev STopY$i ] - set getScreenInfo($dev,Screen$i) "$s1 $s2 $s3 $s4" - } -} - -proc screenCancel {} { - global screenTags - - closeTabWindow - destroy .topleft .bottomright .screen -} - -proc displayScreenList { dev } { - global numScreens currentScreen - - if { $numScreens($dev) <= 1 } { - return - } - toplevel .screen - wm title .screen "Screen List Window" - wm transient .screen . - wm geometry .screen =250x200 - wm state .screen withdraw - button .screen.cancel -text "Close" -command screenCancel - - frame .screen.list - label .screen.list.title -text "Select the Screen:" - label .screen.list.label -background gray - listbox .screen.list.list -width 12 -height 5 -yscrollcommand ".screen.list.sb set" - scrollbar .screen.list.sb -width 10 -command ".screen.list yview" - grid .screen.list.title -row 2 -column 0 -columnspan 3 -sticky we - grid .screen.list.label -row 3 -column 0 -columnspan 3 -sticky we - grid .screen.list.list -row 4 -column 0 - grid .screen.list.sb -row 4 -column 1 -sticky nse - for { set i 0 } { $i < $numScreens($dev) } { incr i } { - .screen.list.list insert end "Screen$i" - } - bind .screen.list.list <ButtonRelease-1> updateScreenList - grid .screen.cancel -row 10 - pack .screen.list .screen.cancel -} - -proc updateButton {} { - global device getDeviceModel sm getOption spName isLCD - global dm currentW oldKeys numButton cKeys numStrips startS - global modeToggleB ignoreButton doubleClickB keystrokeB - global displayToggleB - - set type $getDeviceModel($device,type) - set model $getDeviceModel($device,model) - - for { set i 1 } { $i <= [ expr ($numButton + $numStrips)] } { incr i 1 } { - set k $i - if { $i > $numButton } { - set k [ expr ($startS-1+$i) ] - } - switch [ $currentW.f.$i cget -text ] { - "Left" - { set j 1 - set v "Button 1" } - "Middle" - { set j 2 - set v "Button 2" } - "Right" - { set j 3 - set v "Button 3" } - "Fourth" - { set j 4 - set v "Button 4" } - "Fifth" - { set j 5 - set v "Button 5" } - "Left Double" - { set j $doubleClickB - set v "DBLCLICK 1" } - "Mode Toggle" - { set j $modeToggleB - set v "ModeToggle 1" } - "Display Toggle" - { set j $displayToggleB - set v "DisplayToggle 1" } - "KeyStroke" - { set j $keystrokeB - if { $cKeys($spName($k)) == "" } { - set v $oldKeys($spName($k)) - } else { - set v $cKeys($spName($k)) - set oldKeys($spName($k)) $cKeys($spName($k)) - } } - "Ignore" - { set j $ignoreButton - set v "Button $j" } - } - set getOption($device,$spName($k)) $j - updateXinitrc $device $spName($k) $v - - # reset key strokes - if { $j != $keystrokeB } { - set $oldKeys($spName($k)) "" - set cKeys($spName($k)) "" - } - } - - if { !$isLCD($model) && [string compare $type "pad"] } { - set mode [ $currentW.f.mode cget -text ] - updateXinitrc $device mode $mode - if { $mode == $dm(1) } { - set getOption($device,Mode) 0 - } else { - set getOption($device,Mode) 1 - } - } - - if { ![ string compare $type "stylus" ] } { - set smode [ $currentW.f.smode cget -text ] - if { $smode == $sm(1) } { - updateXinitrc $device TPCButton off - set getOption($device,TPCButton) 0 - } else { - updateXinitrc $device TPCButton on - set getOption($device,TPCButton) 1 - } - } - closeSubWindow -} - -proc defaultButton {} { - global db db1 db2 db3 db4 db5 db6 db7 db8 db9 db10 - global db11 db12 db13 db14 isLCD - global dm sm dmv smv numButton startS numStrips spName - global device getOptionDefault getDeviceModel - for { set i 1 } { $i <= $numButton } { incr i 1 } { - set db$i $db($getOptionDefault($device,$spName($i))) - } - - if { $startS } { - for { set i $startS } { $i <= [ expr ($startS+$numStrips-1) ] } { incr i 1 } { - set k [ expr ($numButton+$i-$startS+1) ] - set db$k $db($getOptionDefault($device,$spName($k))) - } - } - - set model $getDeviceModel($device,model) - set type $getDeviceModel($device,type) - - if { !$isLCD($model) && [ string compare $type "pad" ] } { - set dmv $dm([ expr $getOptionDefault($device,Mode)+1 ]) - } - - if { ![ string compare $type "stylus" ] } { - set smv $sm([ expr $getOptionDefault($device,TPCButton)+1 ]) - } -} - -proc getNumButton { type } { - global device Option numButton getDeviceModel numPadButtons - - set Option(1) "Button1" - set t 1 - if { [ string compare $type "eraser" ] } { - set Option(2) "Button2" - set Option(3) "Button3" - set t [ expr ($t+2) ] - if { [ string compare $type "stylus" ] } { - set Option(4) "Button4" - set Option(5) "Button5" - set t [ expr ($t+2) ] - } - if { ![ string compare $type "pad" ] } { - set model $getDeviceModel($device,model) - set t $numPadButtons($model) - for { set i 6 } { $i <= $t } { incr i 1 } { - set Option($i) "Button$i" - } - } - } - set numButton $t -} - -proc setspName {} { - global numButton spName startS device Option cKeys oldKeys - global numPadRelW numPadStrips numPadRings getDeviceModel - global numControls numStrips getOption - - for { set i 1 } { $i <= $numButton } { incr i 1 } { - set spName($i) Button$i - } - - set spName([expr ($numButton + 1) ]) "RelWUp" - set spName([expr ($numButton + 2) ]) "RelWDn" - set spName([expr ($numButton + 3) ]) "AbsWUp" - set spName([expr ($numButton + 4) ]) "AbsWDn" - set spName([expr ($numButton + 5) ]) "StripLUp" - set spName([expr ($numButton + 6) ]) "StripLDn" - set spName([expr ($numButton + 7) ]) "StripRUp" - set spName([expr ($numButton + 8) ]) "StripRDn" - - set numControls [expr ($numButton+8)] - for { set i 1 } { $i <= $numControls } { incr i 1 } { - set Option($i) $spName($i) - } - - # initial keys before we call getDeviceOptionProc - for { set i 1 } { $i <= $numControls } { incr i 1 } { - set oldKeys($spName($i)) "" - set cKeys($spName($i)) "" - } - - getDeviceOptionProc $device $numControls - - set s1 5 - set s2 8 - set model $getDeviceModel($device,model) - if { $numPadRelW($model) } { # G4 - set s1 1 - set s2 2 - } elseif { $numPadStrips($model) == 1 } { # I3 4x5 - set s1 5 - set s2 6 - } elseif { $numPadRings($model) } { # Bamboo - set s1 3 - set s2 4 - } - set startS $s1 - set numStrips [expr ($s2 - $s1) + 1] - -} - -proc initialButton {} { - global device Option numButton getDeviceModel - global spName numStrips - - set type $getDeviceModel($device,type) - set t $numButton - - if { [ string compare $type "pad" ] } { - set t [expr ($t+1)] - set Option($t) "Mode" - set t [expr ($t+1)] - set Option($t) "TPCButton" - } - getDeviceOptionProc $device $t - - if { [ string compare $type "pad" ] } { - displayMode - } - - # initial controls - setspName - - for { set i 1 } { $i <= $numButton } { incr i 1 } { - addMenu $i - } - - # then touch strip - if { ![ string compare $type "pad" ] } { - expressKeys - } else { - set numStrips 0 - } -} - -proc displayMode {} { - global device getDeviceModel sm smv - global dmv dm getOption currentW isLCD - - set model $getDeviceModel($device,model) - set type $getDeviceModel($device,type) - - if { !$isLCD($model) && [ string compare $type "pad" ] } { - set dmv $dm([ expr $getOption($device,Mode)+1 ]) - tk_optionMenu $currentW.f.mode dmv $dm(1) $dm(2) - label $currentW.f.modeL -text "Positioning Mode: " - grid $currentW.f.mode -row 4 -column 1 - grid $currentW.f.modeL -row 4 -column 0 - } - - if { ![ string compare $type "stylus" ] } { - set smv $sm([ expr $getOption($device,TPCButton)+1 ]) - tk_optionMenu $currentW.f.smode smv $sm(1) $sm(2) - label $currentW.f.smodeL -text "Side Switch Mode: " - grid $currentW.f.smode -row 4 -column 4 - grid $currentW.f.smodeL -row 4 -column 3 - } -} - -proc displaySubWindow { okF deF initial winID cbutton kcurrent} { - global currentb currentW wName currentk - - set currentb $cbutton - set currentk $kcurrent - if { $cbutton } { - set currentW .keystrokes - } else { - set currentW .allothers - } - toplevel $currentW - wm geometry $currentW =650x425 - wm title $currentW $wName($winID) - wm transient $currentW . - wm state $currentW normal - frame $currentW.f - button $currentW.f.ok -text "Ok" -command $okF - button $currentW.f.cancel -text "Cancel" -command closeSubWindow - - set columnN 0 - if { $deF != 0 } { - button $currentW.f.default -text "Default" -command $deF - grid $currentW.f.default -row 8 -column 0 -columnspan 3 -padx 10 -pady 10 - # - # Suppress tags on listboxes to prevent changing the - # device and disable other controls - bindtags .workingDev.list . - set columnN 4 - } - - disableButtons - $initial - - grid $currentW.f -row 0 -column 0 -sticky nw - grid $currentW.f.ok -row 8 -column [expr ($columnN + 4)] -columnspan 3 -padx 10 -pady 10 - grid $currentW.f.cancel -row 8 -column $columnN -columnspan 3 -padx 10 -pady 10 -} - -proc closeSubWindow {} { - global currentW - destroy $currentW - closeTabWindow -} - -proc closeTabWindow {} { - global bName workingTags currentW numButton - global currentb cKeys spName numStrips - - if { $bName(keystroke) } { - set bName(keystroke) 0 - set currentW .allothers - for { set i 1 } { $i <= [ expr ($numButton+$numStrips) ] } { incr i 1 } { - $currentW.f.$i configure -state normal - } - $currentW.f.default configure -state normal - $currentW.f.ok configure -state normal - $currentW.f.cancel configure -state normal - set currentb 0 - } else { - if { $bName(pressure) } { - .panel.pressure configure -state normal - } - if { $bName(calibrate) } { - .panel.calibrate configure -state normal - } - if { $bName(button) } { - .panel.button configure -state normal - } - if { $bName(mapping) } { - .panel.mapping configure -state normal - } - if { $bName(advanced) } { - .panel.advanced configure -state normal - } - for { set i 1 } { $i <= [ expr ($numButton+$numStrips) ] } { incr i 1 } { - set cKeys($spName($i)) "" - } - bindtags .workingDev.list $workingTags - } -} - -proc expressKeys { } { - global db db1 db2 db3 db4 db5 db6 db7 db8 db9 db10 - global db11 db12 db13 db14 startS - global currentW device numButton spName numStrips - global getDeviceModel cKeys oldKeys getOption - global displayToggleB ignoreButton keystrokeB - global numPadRings numPadStrips numPadAbsW numPadRelW - - set name(1) "Wheel Up" - set name(2) "Wheel Down" - set name(3) "Ring Anticlockwise" - set name(4) "Ring Clockwise" - set name(5) "Left Strip Up" - set name(6) "Left Strip Down" - set name(7) "Right Strip Up" - set name(8) "Right Strip Down" - - set s2 [expr ($startS + $numStrips) - 1] - for { set i $startS } { $i <= $s2 } { incr i 1 } { - set cur [ expr ($numButton + $i - $startS + 1) ] - set curOption [ expr ($numButton + $i) ] - set opt $getOption($device,$spName($curOption)) - if { $opt == "" } { set opt $ignoreButton } - - set db$cur $db($opt) - #reset keys - if { $opt != $keystrokeB } { - set cKeys($spName($curOption)) "" - set oldKeys($spName($curOption)) "" - } - set bmenu [ tk_optionMenu $currentW.f.$cur db$cur $db(1) $db(2) \ - $db(3) $db(4) $db(5) $db($ignoreButton) ] - $bmenu insert 7 radiobutton -label "$db($keystrokeB)" \ - -variable menvar -command "displaySubWindow \ - updateKeys 0 initialKeys 5 $cur $curOption" - - label $currentW.f.name$cur -text "$name($i): " - set t2 [expr ($numButton+1)/2+1] - set t1 0 - if { [expr ($s2 - $startS) > 1] } { - if { $i == [expr ($startS+1)] || \ - $i == [expr ($startS+3)] } { - set t2 [expr ($numButton+1)/2+2] - } - if { [expr ($i - $startS) > 1] } { - set t1 2 - } - } else { - if { [expr ($i - $startS) > 0] } { - set t1 2 - } - } - grid $currentW.f.$cur -row $t2 -column [expr $t1+1] - grid $currentW.f.name$cur -row $t2 -column $t1 - } -} - -proc addMenu { curb } { - global db db1 db2 db3 db4 db5 db6 db7 db8 db9 db10 - global db11 db12 db13 db14 currentW device spName - global getOption getDeviceModel cKeys oldKeys keystrokeB - global doubleClickB displayToggleB ignoreButton modeToggleB - - set model $getDeviceModel($device,model) - set type $getDeviceModel($device,type) - - set opt $getOption($device,$spName($curb)) - if { $opt == "" } { set opt $curb } - - set db$curb $db($opt) - #reset keys - if { $opt != $keystrokeB } { - set cKeys($spName($curb)) "" - set oldKeys($spName($curb)) "" - } - - if { [string compare $type "pad"] } { - set bmenu [ tk_optionMenu $currentW.f.$curb db$curb $db(1) $db(2) \ - $db(3) $db(4) $db(5) $db($doubleClickB) $db($modeToggleB) \ - $db($displayToggleB) $db($ignoreButton) ] - set i 9 - } else { - set bmenu [ tk_optionMenu $currentW.f.$curb db$curb $db(1) $db(2) \ - $db(3) $db(4) $db(5) $db($doubleClickB) $db($displayToggleB) \ - $db($ignoreButton) ] - set i 8 - } - - set i [expr ($i+1)] - $bmenu insert $i radiobutton -label "$db($keystrokeB)" \ - -variable menvar -command "displaySubWindow \ - updateKeys 0 initialKeys 5 $curb $curb" - - label $currentW.f.name$curb -text "Button $curb: " - set t2 [expr ($curb-1)/2] - if { [expr ($curb/2)] == [expr ($curb+1)/2] } { - set t1 2 - } else { - set t1 0 - } - - grid $currentW.f.$curb -row $t2 -column [expr ($t1+1)] - grid $currentW.f.name$curb -row $t2 -column $t1 -} - -proc initialT {} { - global device getDeviceModel currentW - global getOption getOptionDefault Option - - set Option(1) "TopX" - set Option(2) "TopY" - set Option(3) "BottomX" - set Option(4) "BottomY" - set Option(5) "SpeedLevel" - set Option(6) "Accel" - set Option(7) "Mode" - - getDeviceOptionProc $device 7 - - set mode $getOption($device,Mode) - frame $currentW.f.group -bd 10 -bg beige -width 150 -height 150 - - if { $mode == 1 } { - label $currentW.f.groupL -text "Mapping: " - for { set i 1 } { $i < 5 } { incr i 1 } { - addMapScale $i - } - } else { - label $currentW.f.groupL -text "Movement: " - label $currentW.f.group.l1 -text "SpeedLevel: " - grid $currentW.f.group.l1 -row 0 -column 6 - scale $currentW.f.group.scale1 -orient horizontal -length 100 \ - -from 1 -to 11 - grid $currentW.f.group.scale1 -row 0 -column 8 - $currentW.f.group.scale1 set $getOption($device,SpeedLevel) - label $currentW.f.group.l2 -text "Slow" - grid $currentW.f.group.l2 -row 1 -column 7 - label $currentW.f.group.l3 -text "Fast" - grid $currentW.f.group.l3 -row 1 -column 9 - label $currentW.f.group.l4 -text "Acceleration: " - grid $currentW.f.group.l4 -row 2 -column 6 - scale $currentW.f.group.scale2 -orient horizontal -length 100 \ - -from 1 -to 7 - grid $currentW.f.group.scale2 -row 2 -column 8 - $currentW.f.group.scale2 set $getOption($device,Accel) - label $currentW.f.group.l5 -text "Linear" - grid $currentW.f.group.l5 -row 3 -column 7 - label $currentW.f.group.l6 -text "High" - grid $currentW.f.group.l6 -row 3 -column 9 - } - - grid $currentW.f.group -row 0 -column 5 - grid $currentW.f.groupL -row 0 -column 2 -} - -proc addMapScale { t } { - global getOption Option getOptionDefault device currentW - - label $currentW.f.group.l$t -text "$Option($t): " - grid $currentW.f.group.l$t -row [ expr $t-1 ] -column 6 - set j $t - if { $j < 3 } { set j [expr $j+2] } - scale $currentW.f.group.scale$t -orient horizontal -length 200 \ - -from -200 -to [expr $getOptionDefault($device,$Option($j))+200] - grid $currentW.f.group.scale$t -row [ expr $t-1 ] -column 8 - $currentW.f.group.scale$t set $getOption($device,$Option($t)) -} - -proc updateT {} { - global getOption getOptionDefault Option device currentW - - set mode $getOption($device,Mode) - if { $mode == 1 } { - for { set i 1 } { $i < 5 } { incr i 1 } { - set value [ $currentW.f.group.scale$i get ] - updateXinitrc $device $Option($i) $value - set getOption($device,$Option($i)) $value - } - } else { - set value [ $currentW.f.group.scale1 get ] - updateXinitrc $device SpeedLevel $value - set value [ $currentW.f.group.scale2 get ] - updateXinitrc $device Accel $value - set getOption($device,Accel) $value - } - closeSubWindow -} - -proc defaultT {} { - global getOption getOptionDefault Option device currentW - - set mode $getOption($device,Mode) - if { $mode == 1 } { - for { set i 1 } { $i < 5 } { incr i 1 } { - $currentW.f.group.scale$i set $getOptionDefault($device,$Option($i)) - } - } else { - $currentW.f.group.scale1 set $getOptionDefault($device,SpeedLevel) - $currentW.f.group.scale2 set $getOptionDefault($device,Accel) - } -} - -proc initialTip {} { - global device getDeviceModel getOption Option currentW - - set Option(1) "PressCurve" - set Option(2) "ClickForce" - set Option(3) "RawSample" - set Option(4) "Suppress" - getDeviceOptionProc $device 4 - - frame $currentW.f.group -bd 10 -bg beige -width 150 -height 150 - label $currentW.f.group.groupl1 -text "Tip Sensitivity: " - grid $currentW.f.group.groupl1 -row 0 -column 0 - scale $currentW.f.group.scale1 -orient horizontal -length 100 \ - -from 1 -to 7 - grid $currentW.f.group.scale1 -row 0 -column 8 - set curve $getOption($device,PressCurve) - - $currentW.f.group.scale1 set $curve - label $currentW.f.group.l2 -text "Soft" - grid $currentW.f.group.l2 -row 1 -column 7 - label $currentW.f.group.l3 -text "Firm" - grid $currentW.f.group.l3 -row 1 -column 9 - - label $currentW.f.group.groupl2 -text "Click Force: " - grid $currentW.f.group.groupl2 -row 3 -column 0 - label $currentW.f.group.l4 -text "Low" - grid $currentW.f.group.l4 -row 4 -column 7 - label $currentW.f.group.l5 -text "High" - grid $currentW.f.group.l5 -row 4 -column 9 - scale $currentW.f.group.scale2 -orient horizontal -length 100 \ - -from 1 -to 21 - grid $currentW.f.group.scale2 -row 3 -column 8 - $currentW.f.group.scale2 set $getOption($device,ClickForce) - - label $currentW.f.group.groupl3 -text "Smoothness: " - grid $currentW.f.group.groupl3 -row 5 -column 0 - label $currentW.f.group.l6 -text "Low" - grid $currentW.f.group.l6 -row 6 -column 7 - label $currentW.f.group.l7 -text "High" - grid $currentW.f.group.l7 -row 6 -column 9 - scale $currentW.f.group.scale3 -orient horizontal -length 100 \ - -from 1 -to 20 - grid $currentW.f.group.scale3 -row 5 -column 8 - $currentW.f.group.scale3 set $getOption($device,RawSample) - - label $currentW.f.group.groupl4 -text "Suppress Points: " - grid $currentW.f.group.groupl4 -row 7 -column 0 - label $currentW.f.group.l8 -text "Low" - grid $currentW.f.group.l8 -row 8 -column 7 - label $currentW.f.group.l9 -text "High" - grid $currentW.f.group.l9 -row 8 -column 9 - scale $currentW.f.group.scale4 -orient horizontal -length 100 \ - -from 1 -to 20 - grid $currentW.f.group.scale4 -row 7 -column 8 - $currentW.f.group.scale4 set $getOption($device,Suppress) - - grid $currentW.f.group -row 0 -column 5 -} - -proc updateTip {} { - global device currentW - - switch [ $currentW.f.group.scale1 get ] { - 1 - { set curve "0 75 25 100" } - 2 - { set curve "0 50 50 100" } - 3 - { set curve "0 25 75 100" } - 4 - { set curve "0 0 100 100" } - 5 - { set curve "25 0 100 75" } - 6 - { set curve "50 0 100 50" } - 7 - { set curve "75 0 100 25" } - } - updateXinitrc $device PressCurve $curve - set getOption($device,PressCurve) $curve - updateXinitrc $device ClickForce [ $currentW.f.group.scale2 get ] - set getOption($device,ClickForce) [ $currentW.f.group.scale2 get ] - updateXinitrc $device RawSample [ $currentW.f.group.scale3 get ] - set getOption($device,RawSample) [ $currentW.f.group.scale3 get ] - updateXinitrc $device Suppress [ $currentW.f.group.scale4 get ] - set getOption($device,Suppress) [ $currentW.f.group.scale4 get ] - - closeSubWindow -} - -proc defaultTip {} { - global currentW - - $currentW.f.group.scale1 set 4 - $currentW.f.group.scale2 set 6 -} - -proc initialSet {} { - global device getDeviceModel getOption Option - global tvd tvID snd currentW - - # used by both TwinView and non TwinView multimonitor setup - label $currentW.f.sns -text "Display Mapping: " - - set Option(1) "NumScreen" - set Option(2) "TwinView" - set Option(3) "Screen_no" - getDeviceOptionProc $device 3 - - set numS $getOption($device,NumScreen) - set tvID $getOption($device,TwinView) - set snd $getOption($device,Screen_no) - - if { $snd == -1 } { - set snd "Desktop" - } else { - set snd "Screen$snd" - } - - if { $numS == 1 } { - set sn0 "Desktop" - set sn1 "Screen0" - set sn2 "Screen1" - tk_optionMenu $currentW.f.snsmenu snd $sn0 $sn1 $sn2 - } else { - set smenu [ tk_optionMenu $currentW.f.snsmenu snd "Desktop" ] - pack $currentW.f.snsmenu -side left - for { set i 0 } { $i < $numS } { incr i } { - $smenu insert $i radiobutton -label "Screen$i" \ - -variable smenvar -command \ - { global smenvar; set snd $smenvar } - } - } - - grid $currentW.f.sns -row 3 -column 0 - grid $currentW.f.snsmenu -row 3 -column 1 - if { $numS > 1 } { - $currentW.f.snsmenu configure -state normal - } else { - $currentW.f.snsmenu configure -state disable - } - - label $currentW.f.tv -text "TwinView Setup: " - set tv(0) "None" - set tv(1) "Xinerama" - set tv(2) "Vertical" - set tv(3) "Horizontal" - set tv(4) "AboveOf" - set tv(5) "LeftOf" - - for { set i 0 } { $i < 6 } { incr i 1 } { - if { $tvID == $i } { - set tvd $tv($i) - } - } - - tk_optionMenu $currentW.f.tvmenu tvd $tv(0) $tv(1) $tv(2) $tv(3) $tv(4) tv(5) - grid $currentW.f.tv -row 2 -column 0 - grid $currentW.f.tvmenu -row 2 -column 1 - - $currentW.f.tvmenu configure -state normal - if { $numS == 1 } { - label $currentW.f.message1 -text "Please click on \"Cancel\" " - label $currentW.f.message2 -text "if your Video card isn't from Nvidia." - grid $currentW.f.message1 -row 0 -column 0 - grid $currentW.f.message2 -row 0 -column 1 - } elseif { !$tvID } { - $currentW.f.tvmenu configure -state disable - } -} - -proc updateSet {} { - global device currentW tvd snd tvID - - set numS [ exec xsetwacom get $device NumScreen ] - - if { $numS > 1 } { - set sn [ $currentW.f.snsmenu cget -text ] - if { ![ string compare $sn "Desktop" ] } { - set sn -1 - } else { - for { set i 0 } { $i < $numS } { incr i 1 } { - if { $sn == "Screen$i" } { - set sn $i - } - } - } - updateXinitrc $device Screen_No $sn - set getOption($device,Screen_No) $sn - } - - set tv [ $currentW.f.tvmenu cget -text ] - if { ![ string compare $tv "None" ] } { - set tv 0 - } - if { ![ string compare $tv "Xinerama" ] } { - set tv 1 - } - if { ![ string compare $tv "Horizontal" ] } { - set tv 3 - } - if { ![ string compare $tv "Vertical" ] } { - set tv 2 - } - if { ![ string compare $tv "LeftOf" ] } { - set tv 5 - } - if { ![ string compare $tv "AboveOf" ] } { - set tv 4 - } - - if { $tv != $tvID } { - updateXinitrc $device TwinView $tv - set getOption($device,TwinView) $tv - } - - closeSubWindow -} - -proc defaultSet {} { - global tvd snd - - set tvd "None" - set snd "Desktop" -} - -proc initialKeys {} { - global device getDeviceModel getOption cKeys spName - global Option oldKeys currentW bName currentb currentk - - frame $currentW.f.panelt - set bName(keystroke) 1 - text $currentW.f.panelt.input -width 40 -height 10 \ - -yscrollcommand "$currentW.f.panelt.srl_y set" - - if { $cKeys($spName($currentk)) != "" } { - $currentW.f.panelt.input insert end $cKeys($spName($currentk)) - } else { - if { $oldKeys($spName($currentk)) != "" } { - $currentW.f.panelt.input insert end $oldKeys($spName($currentk)) - set cKeys($spName($currentk)) $oldKeys($spName($currentk)) - } - } - scrollbar $currentW.f.panelt.srl_y -width 10 -command \ - "$currentW.f.panelt.input yview" - label $currentW.f.panelt.title1 -text "Entered keystrokes (type the keys if they are not in the lists):" - grid $currentW.f.panelt.title1 -row 0 -column 0 -sticky we - grid $currentW.f.panelt.input -row 1 -column 0 -sticky we - grid $currentW.f.panelt.srl_y -row 1 -sticky nse - - frame $currentW.f.panel - set mod(1) "SHIFT" - set mod(2) "CTRL" - set mod(3) "ALT" - set mod(4) "META" - set mod(5) "SUPER" - set mod(6) "HYPER" - set mmenu [ tk_optionMenu $currentW.f.panel.modmenu mod0 "Modifiers" ] - pack $currentW.f.panel.modmenu -side left - label $currentW.f.panel.title2 -text "Select special keys below:" - grid $currentW.f.panel.title2 -row 0 -column 2 - grid $currentW.f.panel.modmenu -row 1 -column 2 - $mmenu delete 0 - for { set i 1 } { $i <= 6 } { incr i 1 } { - $mmenu insert $i radiobutton -label $mod($i) \ - -variable menvar -command \ - { $currentW.f.panelt.input insert end " "; \ - global menvar; \ - $currentW.f.panelt.input insert end $menvar; \ - $currentW.f.panelt.input insert end " " } - } - - set fk(1) "F1" - set fk(2) "F2" - set fk(3) "F3" - set fk(4) "F4" - set fk(5) "F5" - set fk(6) "F6" - set fk(7) "F7" - set fk(8) "F8" - set fk(9) "F9" - set fk(10) "F10" - set fk(11) "F11" - set fk(12) "F12" - set fmenu [ tk_optionMenu $currentW.f.panel.fmenu fk0 "Function Keys" ] - pack $currentW.f.panel.fmenu -side left - grid $currentW.f.panel.fmenu -row 2 -column 2 - $fmenu delete 0 - for { set i 1 } { $i <= 12 } { incr i 1 } { - $fmenu insert $i radiobutton -label $fk($i) \ - -variable fmenvar -command \ - { $currentW.f.panelt.input insert end " "; \ - global fmenvar; \ - $currentW.f.panelt.input insert end $fmenvar; \ - $currentW.f.panelt.input insert end " " } - } - - set fs(1) "quotedbl" - set fs(2) "Pause" - set fs(3) "ScrollLock" - set fs(4) "SysReq" - set fs(5) "End" - set fs(6) "Insert" - set fs(7) "Delete" - set fs(8) "Enter" - set fs(9) "Home" - set fs(10) "backslash" - set fs(11) "break" - set fs(12) "print" - set fsmenu [ tk_optionMenu $currentW.f.panel.fsmenu fs0 "Special Keys 1" ] - pack $currentW.f.panel.fsmenu -side left - grid $currentW.f.panel.fsmenu -row 3 -column 2 - $fsmenu delete 0 - for { set i 1 } { $i <= 12 } { incr i 1 } { - $fsmenu insert $i radiobutton -label $fs($i) \ - -variable fsmenvar -command \ - { $currentW.f.panelt.input insert end " "; \ - global fsmenvar; \ - $currentW.f.panelt.input insert end $fsmenvar; \ - $currentW.f.panelt.input insert end " " } - } - - set sk(1) "Esc" - set sk(2) "Tab" - set sk(3) "CapsLock" - set sk(4) "PageUp" - set sk(5) "PageDown" - set sk(6) "Left" - set sk(7) "Up" - set sk(8) "Down" - set sk(9) "Right" - set sk(10) "space" - set sk(11) "NumLock" - set sk(12) "BackSpace" - set skmenu [ tk_optionMenu $currentW.f.panel.skmenu sk0 "Special Keys 2" ] - pack $currentW.f.panel.skmenu -side left - grid $currentW.f.panel.skmenu -row 4 -column 2 - $skmenu delete 0 - for { set i 1 } { $i <= 12 } { incr i 1 } { - $skmenu insert $i radiobutton -label $sk($i) \ - -variable skmenvar -command \ - { $currentW.f.panelt.input insert end " "; \ - global skmenvar; \ - $currentW.f.panelt.input insert end $skmenvar; \ - $currentW.f.panelt.input insert end " " } - } - - set kp(1) "PgUp" - set kp(2) "PgDn" - set kp(3) "KPLeft" - set kp(4) "KPUp" - set kp(5) "KPDown" - set kp(6) "KPRight" - set kp(7) "Plus" - set kp(8) "Minus" - set kp(9) "Divide" - set kp(10) "Multiply" - set kp(11) "KPEnd" - set kp(12) "Ins" - set kp(13) "Del" - set kp(14) "KPEnter" - set kp(15) "KPHome" - set kpmenu [ tk_optionMenu $currentW.f.panel.kpmenu kp0 "KeyPad Keys" ] - pack $currentW.f.panel.kpmenu -side left - grid $currentW.f.panel.kpmenu -row 5 -column 2 - $kpmenu delete 0 - for { set i 1 } { $i <= 15 } { incr i 1 } { - $kpmenu insert $i radiobutton -label $kp($i) \ - -variable kpmenvar -command \ - { $currentW.f.panelt.input insert end " "; \ - global kpmenvar; \ - $currentW.f.panelt.input insert end $kpmenvar; \ - $currentW.f.panelt.input insert end " " } - } - - grid $currentW.f.panelt -row 0 -column 0 - grid $currentW.f.panel -row 0 -column 2 -} - -proc updateKeys {} { - global device oldKeys currentb cKeys spName currentW - global db db1 db2 db3 db4 db5 db6 db7 db8 db9 db10 - global db11 db12 db13 db14 currentk - global ignoreButton keystrokeB - - set keys [ $currentW.f.panelt.input get 1.0 end ] - - # remove newline characters - set index [ string last "\n" $keys ] - while { $index != -1 } { - set keys [ string replace $keys $index [expr ($index+1) ] ] - set index [ string last "\n" $keys ] - } - - if { $oldKeys($spName($currentk)) != $keys } { - if { [string compare -nocase -length 8 $keys "core key"] } { - set cKeys($spName($currentk)) "core key $keys" - } else { - set cKeys($spName($currentk)) $keys - } - } - - if { $cKeys($spName($currentk)) != "" } { - set db$currentb $db($keystrokeB) - } else { - set db$currentb $db($ignoreButton) - } - - if { [ string length $cKeys($spName($currentk)) ] > 240 } { - helpWindow "Help Window " \ - "\n\nYou have entered more 240 keys. \n\ - wacomcpl only accepts 240 keys. \n\ - Please reduce your keys. " - } else { - closeSubWindow - } -} - -proc touchState { theCButton } { - global device touchButton getDeviceModel - - set touchButton 0 - if { $touchButton == [exec xsetwacom get $device touch] } { - set touchButton 1 - } - checkbutton $theCButton -text "Disable Touch" -anchor w \ - -variable touchButton -state normal -command "switchTouch 0" -} - -proc initialTouch {} { - global device getDeviceModel currentW - global getOption getOptionDefault Option hasCapacity - - set model $getDeviceModel($device,model) - set Option(1) "Capacity" - set Option(2) "touch" - - getDeviceOptionProc $device 2 - - touchState $currentW.f.touch - grid $currentW.f.touch -row 0 -column 2 - - frame $currentW.f.group -bd 10 -bg beige -width 150 -height 150 - label $currentW.f.groupL -text "Sensitivity: " - grid $currentW.f.groupL -row 2 -column 6 - scale $currentW.f.group.scale -orient horizontal -length 100 \ - -from 1 -to 5 - grid $currentW.f.group.scale -row 2 -column 8 - $currentW.f.group.scale set $getOption($device,Capacity) - label $currentW.f.group.l11 -text "1" - grid $currentW.f.group.l11 -row 1 -column 7 - label $currentW.f.group.l21 -text "5" - grid $currentW.f.group.l21 -row 1 -column 9 - label $currentW.f.group.l1 -text "Low" - grid $currentW.f.group.l1 -row 3 -column 7 - label $currentW.f.group.l2 -text "High" - grid $currentW.f.group.l2 -row 3 -column 9 - - grid $currentW.f.touch -row 0 -column 2 - grid $currentW.f.group -row 2 -column 5 - grid $currentW.f.groupL -row 2 -column 2 -} - -proc updateTouch {} { - global currentW getOption device - - set value [ $currentW.f.group.scale get ] - if { $value != $getOption($device,Capacity) } { - updateXinitrc $device Capacity $value - set getOption($device,Capacity) $value - } - - switchTouch 1 - - closeSubWindow -} - -proc defaultTouch {} { - global touchButton currentW getOptionDefault device - - if { [ exec xsetwacom get $device touch ] != $getOptionDefault($device,touch) } { - set touchButton [ exec xsetwacom get $device touch ] - if { [ exec xsetwacom getdefault $device capacity ] < 0 } { - if { $touchButton == 0 } { - .panel.calibrate configure -state normal - } else { - .panel.calibrate configure -state disabled - } - } - } - - $currentW.f.group.scale set $getOptionDefault($device,Capacity) -} - -proc switchTouch { window } { - global device touchButton - - # don't send the command for touch with capacity - if { [ exec xsetwacom getdefault $device capacity ] >= 0 && $window == 0 } { - return - } - - if { $touchButton == [ exec xsetwacom get $device touch ] } { - if { $touchButton == 0 } { - .panel.calibrate configure -state normal - exec xsetwacom set $device touch 1 - updateXinitrc $device touch 1 - } else { - .panel.calibrate configure -state disabled - exec xsetwacom set $device touch 0 - updateXinitrc $device touch 0 - } - } -} - -proc createPanel { pressure button mapping calibrate } { - global bName device getOption getDeviceModel currentb - global wName startS Option hasCapacity touchButton - global hasCapacity - - frame .panel - set bName(pressure) $pressure - set bName(button) $button - set bName(mapping) $mapping - set bName(calibrate) $calibrate - set currentb 0 - set type $getDeviceModel($device,type) - - # buttons and expresskeys - getNumButton $type - setspName - set SN [ exec xsetwacom get $device ToolSerial ] - if { $SN && [string compare type "pad"] } { - set hexSN [format %X $SN] - label .panel.sn -text "Serial Number: $hexSN" - grid .panel.sn -row 0 -column 0 -columnspan 2 -padx 3 -pady 3 - } - - if { $calibrate } { - button .panel.calibrate -text "Calibration" \ - -command Calibration -state normal - grid .panel.calibrate -row 5 -column 3 -columnspan 2 -sticky news -padx 10 - } - if { $pressure } { - if { ![string compare $getDeviceModel($device,type) "touch"] } { - set model $getDeviceModel($device,model) - if { $hasCapacity($model) } { - set wName(1) "Touch" - button .panel.pressure -text $wName(1) \ - -state normal -command "displaySubWindow \ - updateTouch defaultTouch initialTouch 1 0 0" - if { [ exec xsetwacom get $device touch ] == 1 } { - .panel.calibrate configure -state normal - } else { - .panel.calibrate configure -state disable - } - } else { - touchState .panel.pressure - } - } else { - set wName(1) "Feel" - button .panel.pressure -text $wName(1) \ - -state normal -command "displaySubWindow \ - updateTip defaultTip initialTip 1 0 0" - } - grid .panel.pressure -row 5 -column 0 -columnspan 2 -sticky news -padx 10 - } - if { $button } { - if { ![string compare $getDeviceModel($device,type) "pad"] } { - button .panel.button -text $wName(6) \ - -state normal -command "displaySubWindow \ - updateButton defaultButton initialButton 6 0 $startS" - } else { - button .panel.button -text $wName(2) \ - -state normal -command "displaySubWindow \ - updateButton defaultButton initialButton 2 0 0" - } - grid .panel.button -row 6 -column 0 -columnspan 2 -sticky news -padx 10 - } - if { $mapping } { - button .panel.mapping -text $wName(3) \ - -state normal -command "displaySubWindow \ - updateT defaultT initialT 3 0 0" - grid .panel.mapping -row 6 -column 3 -columnspan 2 -sticky news -padx 10 - } - - set bName(advanced) 0 - if { [string compare $getDeviceModel($device,type) "touch"] && - [string compare $getDeviceModel($device,type) "pad"] } { #not a pad or touch - set Option(1) "Mode" - getDeviceOptionProc $device 1 - set mode $getOption($device,Mode) - if { ($pressure || $mapping) && $mode } { #and in absolute mode - set bName(advanced) 1 - button .panel.advanced -text $wName(4) \ - -state normal -command "displaySubWindow \ - updateSet defaultSet initialSet 4 0 0" - grid .panel.advanced -row 9 -column 2 -columnspan 2 -sticky news -padx 10 - } - } - - grid .panel -row 0 -column 1 -columnspan 8 -sticky news -padx 10 -pady 40 -} - -proc updateModelInfo { } { - global isLCD numPadButtons numPadRings hasPad hasTouch - global numPadStrips numPadAbsW numPadRelW hasCapacity - global maxNumTablets - - for { set i 0 } { $i <= $maxNumTablets } { incr i 1 } { - set isLCD($i) 0 - set numPadButtons($i) 0 - set numPadRings($i) 0 - set numPadStrips($i) 0 - set numPadAbsW($i) 0 - set numPadRelW($i) 0 - set hasPad($i) 0 - set hasTouch($i) 0 - set hasCapacity($i) 0 - } - #PL - for { set i 48} { $i <= 63 } { incr i 1 } { - set isLCD($i) 1 - } - #TabletPC - for { set i 144 } { $i <= 151 } { incr i 1 } { - set isLCD($i) 1 - } - - #Capacitive TabletPC - set hasCapacity(154) 1 - set hasCapacity(159) 1 - set isLCD(154) 1 - set isLCD(159) 1 - - #Cintiq - for { set i 192 } { $i <= 199 } { incr i 1 } { - set isLCD($i) 1 - } - - # G4 - set numPadButtons(21) 2 - set numPadButtons(22) 2 - set numPadRelW(21) 1 - set numPadRelW(22) 1 - # Bamboo Fun - set numPadButtons(23) 4 - set numPadRings(23) 1 - set numPadButtons(24) 4 - set numPadRings(24) 1 - #Cintiq 21UX - set numPadButtons(63) 8 - set numPadStrips(63) 2 - # Bamboo - for { set i 101 } { $i <= 105 } { incr i 1 } { - set numPadButtons($i) 4 - set numPadRings($i) 1 - } - # I3 - set numPadButtons(176) 4 - set numPadStrips(176) 1 - for { set i 177 } { $i <= 182 } { incr i 1 } { - set numPadButtons($i) 8 - set numPadStrips($i) 2 - } - set numPadButtons(183) 4 - set numPadStrips(183) 1 - - # Cintiq 20WSX - set numPadButtons(197) 10 - set numPadStrips(197) 2 - - # Hummingbird (Cintiq 12WX) - set numPadButtons(198) 10 - set numPadStrips(198) 2 - - set numPadButtons(184) 7 - set numPadRings(184) 1 - for { set i 185 } { $i <= 187 } { incr i 1 } { - set numPadButtons($i) 9 - set numPadRings($i) 1 - } - - for { set i 0 } { $i <= 198 } { incr i 1 } { - if { $numPadButtons($i) || $numPadRings($i) - || $numPadStrips($i) || $numPadAbsW($i) - || $numPadRelW($i) } { - set hasPad($i) 1 - } - } - - for { set i 0 } { $i <= 198 } { incr i 1 } { - if { $i == 147 || $i == 154 || $i == 159 } { - set hasTouch($i) 1 - } - } -} - -proc createControls { } { - global numScreens currentScreen cKeys spName - global desktopHeight desktopWidth oldKeys numStrips - global workingTags db dm sm wName bName numButton - global doubleClickB ignoreButton displayToggleB - global modeToggleB keystrokeB - - createDeviceList - updateModelInfo - - set db(1) "Left" - set db(2) "Middle" - set db(3) "Right" - set db(4) "Fourth" - set db(5) "Fifth" - set db(6) "Ignore" - set db(7) "Ignore" - set db(8) "Ignore" - set db(9) "Ignore" - set db(10) "Ignore" - set db($doubleClickB) "Left Double" - set db($modeToggleB) "Mode Toggle" - set db($displayToggleB) "Display Toggle" - set db($ignoreButton) "Ignore" - set db($keystrokeB) "KeyStroke" - set dm(1) "Relative" - set dm(2) "Absolute" - - set sm(1) "Side Switch Only" - set sm(2) "Side Switch + Tip" - - set bName(keystroke) 0 - set wName(1) "Feel" - set wName(2) "Tool Buttons" - set wName(3) "Tracking" - set wName(4) "Screen Mapping" - set wName(5) "Keystrokes" - set wName(6) "Tablet Controls" - - # up to the max number of buttons - set numButton 10 - set numStrips 4 - -# Real help will be supported later -# checkbutton .showHelp -text "Turn Help on" -anchor w \ -# -variable showHelp -state normal - - button .exit -text "Exit" -command "exit 0" -padx 40 - -# grid .showHelp -row 0 -column 2 -sticky nw -padx 30 - grid .exit -row 20 -column 2 -sticky news -padx 20 - grid .workingDev -row 0 -rowspan 25 -column 0 -sticky news -padx 20 - - set workingTags [ bindtags .workingDev.list] - - grid columnconfigure . 1 -weight 1 - grid rowconfigure . 7 -weight 5 -} - -createControls - -wm title . "Wacom Control Panel" -wm geometry . =$windowSize+$origin_x+$origin_y - -# -# Local Variables: -# mode: tcl -# End: -# diff --git a/src/wacomxi/wacomcpl.in b/src/wacomxi/wacomcpl.in deleted file mode 100755 index d137fcf..0000000 --- a/src/wacomxi/wacomcpl.in +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -#\ -# -# THIS FILE IS GENERATED FROM wacomcpl.in. -# Please make all changes to the original source file. -# -# Actual code is contained in wacomcpl-exec. -# -# Setup TCL Library Path to include WACOMXI installed directory. -# Alternatively, you can set this in your Tcl configuration yourself. -# -# JEJ - The TCLLIBPATH appears to be a Tcl list; I tried nested lists -# (eg. [list [list foo] bar]) and it seems to work as expected. -# Trailing space seems to be necessary. -# -WACOMXI_BINDIR=@WCM_PREFIX@/bin -WACOMXI_LIBDIR=@WCM_PREFIX@/lib -export TCLLIBPATH="[list $TCLLIBPATH $WACOMXI_LIBDIR ]" -echo "wacomcpl: using TCLLIBPATH=\"$TCLLIBPATH\"" -$WACOMXI_BINDIR/wacomcpl-exec diff --git a/src/wacomxi/wacomxi.c b/src/wacomxi/wacomxi.c deleted file mode 100644 index a08d9fb..0000000 --- a/src/wacomxi/wacomxi.c +++ /dev/null @@ -1,1850 +0,0 @@ -/* - * wacomxi.c -- Add X11 extended input handling capability for wacomcpl. - * - * Author : Ping Cheng - * Creation date : 04/05/2003 - * - * Based on xi.c 1998-99 Patrick Lecoanet -- - * - * This code is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This code 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this code; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <stdio.h> - -#include "wacomxi.h" - -/* - *---------------------------------------------------------------------- - * - * This code implements tcl commands that give access - * to additional input devices manipulation at the tcl level. - * - * The command 'bindevent' binds tcl scripts to xinput events - * occuring in a widget. - * - *---------------------------------------------------------------------- - */ - -#define CORE_KEYBOARD 1 -#define CORE_POINTER 2 - -static DisplayInfoStruct *display_infos = NULL; -static InProgress *pending_handlers = NULL; - -static void InvokeEventScript(ClientData client_data, XEvent *e); -static WindowInfoStruct *GetWindowInfo(Tk_Window w, int create); - - -/* - *---------------------------------------------------------------------- - * - * GetDisplayInfo -- - * Return all known information known about the display. - * This gets all the needed informations on the available devices - * including their name. - * This has the side effect (on the first call) of gathering from - * the server, all devices that are hooked on the display. - * - *---------------------------------------------------------------------- - */ -static DisplayInfoStruct * -GetDisplayInfo(Display *dpy) -{ - XDeviceInfoPtr device_list; - DisplayInfoStruct *info; - DeviceInfoStruct *device; - int i, axe, num_classes; - XAnyClassPtr any; - XKeyInfoPtr k; - XButtonInfoPtr b; - XValuatorInfoPtr v; - int dummy = 0; - - /*printf("Begin of GetDisplayInfo\n");*/ - - /* - * Lookup the display in the already known list. - */ - info = display_infos; - while (info) - { - if (dpy == info->display) - { - return info; - } - else - { - info = info->next; - } - } - /* - * Nothing found, make a new entry and fill it with all the available info. - */ - /* - * First ask if the server has made the xinput extension available. - */ - info = (DisplayInfoStruct *) ckalloc(sizeof(DisplayInfoStruct)); - info->next = display_infos; - display_infos = info; - info->has_xdevices = XQueryExtension(dpy, INAME, &dummy, - &info->event_base, &dummy); - info->display = dpy; - Tcl_InitHashTable(&info->per_wins, TCL_ONE_WORD_KEYS); - info->other_handlers = NULL; - info->frozen_handlers = NULL; - /* - * Then ask the device list. - */ - if (info->has_xdevices) - { - device_list = (XDeviceInfoPtr) XListInputDevices(dpy, &info->num_dev); - - if (info->num_dev) - { - info->devices = (DeviceInfoStruct *) - ckalloc(info->num_dev * sizeof(DeviceInfoStruct)); - - dummy = 0; - for (device = info->devices, i = 0; i < info->num_dev; i++, device++) - { - device->dpy_info = info; - device->xdev = NULL; - device->id = device_list[i].id; - device->name = Tk_GetUid(device_list[i].name); - device->core = ((device_list[i].use >= IsXExtensionDevice) ? 0 : - ((device_list[i].use == IsXPointer) ? CORE_POINTER : CORE_KEYBOARD)); - device->x_index = 0; - device->y_index = 1; - device->num_axes = 0; - device->num_keys = 0; - device->num_buttons = 0; - device->focusable = 0; - device->proximity = 0; - device->feedback = 0; - /* - * Setup each input class declared by the device. - */ - if (device_list[i].num_classes > 0) - { - num_classes = device_list[i].num_classes; - any = (XAnyClassPtr) device_list[i].inputclassinfo; - while (num_classes--) - { - switch (any->class) - { - case KeyClass: - k = (XKeyInfoPtr) any; - device->num_keys = k->num_keys; - break; - case ButtonClass: - b = (XButtonInfoPtr) any; - device->num_buttons = b->num_buttons; - break; - case ValuatorClass: - v = (XValuatorInfoPtr) any; - device->num_axes = v->num_axes; - device->axe_info = (AxeInfo*) - ckalloc(sizeof(AxeInfo)*v->num_axes); - device->history_size = v->motion_buffer; - for (axe = 0; axe < v->num_axes; axe++) - { - device->axe_info[axe].min_value = - v->axes[axe].min_value; - device->axe_info[axe].max_value = - v->axes[axe].max_value; - device->axe_info[axe].resolution = - v->axes[axe].resolution; - device->axe_info[axe].value = 0; - } - break; - default: - break; - } - any = (XAnyClassPtr) ((char *) any + any->length); - } - } - } - XFreeDeviceList(device_list); - } - else - { - info->has_xdevices = 0; - } - } - /*printf("End of GetDisplayInfo for device \n");*/ - return info; -} - -/* - *---------------------------------------------------------------------- - * - * LookupDeviceById -- - * Return a device record from the display and the id of - * the device on the display. This is typically used to - * retrieve a device record from an event. - * - *---------------------------------------------------------------------- - */ -static DeviceInfoStruct * -LookupDeviceById(Display *dpy, - XID device_id) -{ - DisplayInfoStruct *info; - int i; - - /*printf("LookupDeviceById \n");*/ - info = GetDisplayInfo(dpy); - for (i = 0; i < info->num_dev; i++) - { - if (info->devices[i].id == device_id) - { - return &info->devices[i]; - } - } - return NULL; -} - -/* - *---------------------------------------------------------------------- - * - * UpdateCoreMark -- - * Extended event handler bound to ChangeDevice events. - * - * It's purpose is to maintain the core bits (CORE_POINTER, - * CORE_KEYBOARD) in the device structs when the core devices - * change. - * This also implies that all handlers registered for the new - * core device are put on hold and all handlers put on hold for - * the previous core device are revived. - * - *---------------------------------------------------------------------- - */ -static void -UpdateCoreMark(ClientData client_data, - XEvent *e) -{ - XChangeDeviceNotifyEvent *cdne = (XChangeDeviceNotifyEvent *) e; - DeviceInfoStruct *device, *old_device = NULL; - DisplayInfoStruct *info; - int i, event_atype; - EventHandlerStruct *handlers, *h_prev, *h_next; - Tcl_HashEntry *entry; - Tcl_HashSearch search; - WindowInfoStruct *pw; - - /*printf("UpdateCoreMark: type=%d, win=0x%X\n", e->type, (int)e->xany.window);*/ - - device = LookupDeviceById(cdne->display, cdne->deviceid); - info = device->dpy_info; - for (i = 0; i < info->num_dev; i++) - { - if ((info->devices[i].core == CORE_POINTER) && - (cdne->request == NewPointer)) - { - old_device = &info->devices[i]; - old_device->core = 0; - /*printf("old pointer is %s\n", old_device->name);*/ - break; - } - else if ((info->devices[i].core == CORE_KEYBOARD) && - (cdne->request == NewKeyboard)) - { - old_device = &info->devices[i]; - old_device->core = 0; - break; - } - } - if (cdne->request == NewKeyboard) - { - device->core = CORE_KEYBOARD; - } - else if (cdne->request == NewPointer) - { - device->core = CORE_POINTER; - /*printf("new pointer is %s\n", device->name);*/ - } - - /* - * Try to unfreeze all handlers associated with the previous - * core device. - */ - for (handlers = info->frozen_handlers, h_prev = NULL; handlers != NULL; - handlers = h_next) - { - h_next = handlers->next; - if (handlers->device_id == old_device->id) - { - if (handlers == info->frozen_handlers) - { - info->frozen_handlers = handlers->next; - } - else - { - h_prev->next = handlers->next; - } - event_atype = info->event_atypes[handlers->type]; - if ((event_atype == CHANGE_DEVICE_EVENT) || - (event_atype == DEVICE_MAPPING_EVENT) || - (event_atype == DEVICE_STATE_EVENT)) - { - handlers->next = info->other_handlers; - info->other_handlers = handlers; - } - else - { - WindowInfoStruct *pw = GetWindowInfo(handlers->tkwin, 0); - handlers->next = pw->handlers; - pw->handlers = handlers; - } - } - else - { - h_prev = handlers; - } - } - /* - * Then try to freeze all handlers associated with the new - * core device. First traverse the other_handlers list and - * then all the per window handlers. - */ - for (handlers = info->other_handlers, h_prev = NULL; - handlers != NULL; handlers = h_next) - { - h_next = handlers->next; - if (handlers->device_id == device->id) - { - if (handlers == info->other_handlers) - { - info->other_handlers = handlers->next; - } - else - { - h_prev->next = handlers->next; - } - handlers->next = info->frozen_handlers; - info->frozen_handlers = handlers; - } - else - { - h_prev = handlers; - } - } - entry = Tcl_FirstHashEntry(&info->per_wins, &search); - while (entry) - { - pw = (WindowInfoStruct *) Tcl_GetHashValue(entry); - for (handlers = pw->handlers, h_prev = NULL; - handlers != NULL; handlers = h_next) - { - h_next = handlers->next; - if (handlers->device_id == device->id) - { - if (handlers == pw->handlers) - { - pw->handlers = handlers->next; - } - else - { - h_prev->next = handlers->next; - } - handlers->next = info->frozen_handlers; - info->frozen_handlers = handlers; - } - else - { - h_prev = handlers; - } - } - entry = Tcl_NextHashEntry(&search); - } - return; -} - -/* - *---------------------------------------------------------------------- - * - * GetDeviceInfo -- - * Get the device descriptor for the device named 'name' on - * the given window's display. The device is opened as needed. - * If no such device exists on the display the function returns - * NULL. - * - *---------------------------------------------------------------------- - */ -static DeviceInfoStruct * -GetDeviceInfo(Tk_Window tkwin, /* Used to get the display */ - Tk_Uid name) -{ - Display *dpy = Tk_Display(tkwin); - DisplayInfoStruct *info; - DeviceInfoStruct *device = NULL; - XInputClassInfo *classes; - int i, dummy; - - info = GetDisplayInfo(dpy); - /*printf("Begin GetDeviceInfo\n");*/ - for (i = 0; i < info->num_dev; i++) - { - if (info->devices[i].name == name) - { - device = &info->devices[i]; - } - } - if (device) - { - /* - * Open the xdevice if not already done and not currently - * a core device. - */ - /*printf("device=%s, id=%d\n", device->name, (int)device->id);*/ - if (!device->xdev && !device->core) - { - dummy = 0; - device->xdev = XOpenDevice(dpy, device->id); - if (device->xdev) - { - /* - * Process all declared input classes. This code finalizes - * the work done when getting the device list for the display. - * Some input classes are not reported until the device is open. - */ - for (i = 0, classes = device->xdev->classes; - i < device->xdev->num_classes; i++, classes++) - { - switch (classes->input_class) - { - case ButtonClass: - DeviceButtonRelease(device->xdev, - info->event_types[BUTTON_RELEASE], - device->event_classes[BUTTON_RELEASE]); - DeviceButtonPress(device->xdev, - info->event_types[BUTTON_PRESS], - device->event_classes[BUTTON_PRESS]); - info->event_atypes[(int)info-> - event_types[BUTTON_RELEASE]] = BUTTON_EVENT; - info->event_atypes[(int)info-> - event_types[BUTTON_PRESS]] = BUTTON_EVENT; - break; - case KeyClass: - DeviceKeyRelease(device->xdev, - info->event_types[KEY_RELEASE], - device->event_classes[KEY_RELEASE]); - DeviceKeyPress(device->xdev, - info->event_types[KEY_PRESS], - device->event_classes[KEY_PRESS]); - info->event_atypes[(int)info-> - event_types[KEY_RELEASE]] = KEY_EVENT; - info->event_atypes[(int)info-> - event_types[KEY_PRESS]] = KEY_EVENT; - break; - case ValuatorClass: - DeviceMotionNotify(device->xdev, - info->event_types[MOTION], - device->event_classes[MOTION]); - DevicePointerMotionHint(device->xdev, dummy, - device->event_classes[MOTION_HINT]); - info->event_types[MOTION_HINT] = - info->event_types[MOTION]; - info->event_atypes[(int)info-> - event_types[MOTION]] = MOTION_EVENT; - break; - case FocusClass: - device->focusable = 1; - DeviceFocusIn(device->xdev, - info->event_types[FOCUS_IN], - device->event_classes[FOCUS_IN]); - DeviceFocusOut(device->xdev, - info->event_types[FOCUS_OUT], - device->event_classes[FOCUS_OUT]); - info->event_atypes[(int)info-> - event_types[FOCUS_IN]] = FOCUS_EVENT; - info->event_atypes[(int)info-> - event_types[FOCUS_OUT]] = FOCUS_EVENT; - break; - case ProximityClass: - device->proximity = 1; - ProximityIn(device->xdev, - info->event_types[PROXIMITY_IN], - device->event_classes[PROXIMITY_IN]); - ProximityOut(device->xdev, - info->event_types[PROXIMITY_OUT], - device->event_classes[PROXIMITY_OUT]); - info->event_atypes[(int)info-> - event_types[PROXIMITY_OUT]] = PROXIMITY_EVENT; - info->event_atypes[(int)info-> - event_types[PROXIMITY_IN]] = PROXIMITY_EVENT; - break; - case FeedbackClass: - device->feedback = 1; - break; - } - } - /* - * If the device can report both valuators and buttons, it is - * possible to ask for these events. The event type is Motion. - */ - if (device->num_buttons && device->num_axes) - { - DeviceButtonMotion(device->xdev, dummy, - device->event_classes[BUTTON_MOTION]); - info->event_types[BUTTON_MOTION] = - info->event_types[MOTION]; - DeviceButton1Motion(device->xdev, dummy, - device->event_classes[B1_MOTION]); - info->event_types[B1_MOTION] = - info->event_types[MOTION]; - DeviceButton2Motion(device->xdev, dummy, - device->event_classes[B2_MOTION]); - info->event_types[B2_MOTION] = - info->event_types[MOTION]; - DeviceButton3Motion(device->xdev, dummy, - device->event_classes[B3_MOTION]); - info->event_types[B3_MOTION] = - info->event_types[MOTION]; - DeviceButton4Motion(device->xdev, dummy, - device->event_classes[B4_MOTION]); - info->event_types[B4_MOTION] = - info->event_types[MOTION]; - DeviceButton5Motion(device->xdev, dummy, - device->event_classes[B5_MOTION]); - info->event_types[B5_MOTION] = - info->event_types[MOTION]; - } - /* - * Setup the no-event class for this device. - */ - NoExtensionEvent(device->xdev, dummy, device->no_event_class); - /* - * Setup the ChangeDevice, DeviceMapping and DeviceState - * classes and types. - */ - ChangeDeviceNotify(device->xdev, - info->event_types[CHANGE_DEVICE], - device->event_classes[CHANGE_DEVICE]); - info->event_atypes[(int)info-> - event_types[CHANGE_DEVICE]] = CHANGE_DEVICE_EVENT; - DeviceMappingNotify(device->xdev, - info->event_types[DEVICE_MAPPING], - device->event_classes[DEVICE_MAPPING]); - info->event_atypes[(int)info-> - event_types[DEVICE_MAPPING]] = DEVICE_MAPPING_EVENT; - DeviceStateNotify(device->xdev, - info->event_types[DEVICE_STATE], - device->event_classes[DEVICE_STATE]); - info->event_atypes[(int)info-> - event_types[DEVICE_STATE]] = DEVICE_STATE_EVENT; - /* - * If the device has more than six valuators, allocate an - * array big enough to hold all the valuators of the device. - */ - if (device->num_axes) - { - device->valuator_cache = (int *) - ckalloc(device->num_axes*sizeof(int)); - } - else - { - device->valuator_cache = NULL; - } - /* - * Create an event handler on ChangeDevice - * to update the core field. - */ - Tk_CreateXiEventHandler(tkwin, - xi_event_names[CHANGE_DEVICE], - device->name, device, - UpdateCoreMark, NULL); - } - } - if (!device->xdev || device->core) - { - /* - * Open failed or access denied, return NULL to inform the caller. - */ - device = NULL; - } - } - /*printf("End of GetDeviceInfo\n");*/ - - return device; -} - -/* - *---------------------------------------------------------------------- - * - * GetEventIndex -- - * Given an event spec uid, the function return the corresponding - * event index, needed to retrieve the type and class values. - * If the string does not describe a valid event, the function - * return -1. - * - *---------------------------------------------------------------------- - */ -static int -GetEventIndex(Tk_Uid event_spec) -{ - int i; - - for (i = 0; i < NUM_XI_EVENTS; i++) - { - if (xi_event_names[i] == event_spec) - { - return i; - } - } - return -1; -} - -/* - *---------------------------------------------------------------------- - * - * DestroyPerWindow -- - * Called when a window is destroyed to cleanup the event handlers - * that remain registered. - * No care is taken to prevent a race with Tk_DispatchXiEvent - * since DestroyPerWindow is also triggered as an event handler - * and thus should not be active at the same time. This is unfor- - * tunately a _FALSE_ guess, DestroyNotify is generated internally - * and processed as soon as the destroy command is emitted. - * - *---------------------------------------------------------------------- - */ -static void -DestroyPerWindow(ClientData client_data, - XEvent *e) -{ - Tk_Window w = (Tk_Window) client_data; - DisplayInfoStruct *info; - EventScriptRecord *escripts, *es_next; - EventHandlerStruct *handlers, *h_next, *h_prev; - WindowInfoStruct *pw; - Tcl_HashEntry *he; - InProgress *ip; - - /*printf("Begin of DestroyPerWindow\n");*/ - if (e->type == DestroyNotify) - { - info = GetDisplayInfo(e->xany.display); - he = Tcl_FindHashEntry(&info->per_wins, (char *) w); - if (he) - { - pw = (WindowInfoStruct *) Tcl_GetHashValue(he); - for (handlers = pw->handlers; handlers != NULL; handlers = h_next) - { - h_next = handlers->next; - /* - * Need to see if Tk_DispatchXiEvent is not about to - * fire this handler. If it is, just abort the whole - * dispatch thread, the window is gone. - */ - for (ip = pending_handlers; ip != NULL; ip = ip->next) - { - if (ip->next_handler == (ClientData) handlers) - { - ip->next_handler = NULL; - } - } - ckfree((char *) handlers); - } - for (escripts = pw->scripts; escripts != NULL; escripts = es_next) - { - es_next = escripts->next; - ckfree(escripts->script); - ckfree((char *) escripts); - } - ckfree((char *) pw); - Tcl_DeleteHashEntry(he); - } - /* - * Scan through the 'special events' handlers. - */ - for (handlers = info->other_handlers, h_prev = NULL; - handlers != NULL; handlers = h_next) - { - h_next = handlers->next; - if (handlers->tkwin == w) - { - if (handlers == info->other_handlers) - { - info->other_handlers = h_next; - } - else - { - h_prev->next = h_next; - } - /* - * Need to see if Tk_DispatchXiEvent is not about to - * fire this handler. If it is, point it to the next. - */ - for (ip = pending_handlers; ip != NULL; ip = ip->next) - { - if (ip->next_handler == (ClientData) handlers) - { - ip->next_handler = h_next; - } - } - ckfree((char *) handlers); - } - else - { - h_prev = handlers; - } - } - /* - * Scan through the frozen handlers. - */ - for (handlers = info->frozen_handlers, h_prev = NULL; - handlers != NULL; handlers = h_next) - { - h_next = handlers->next; - if (handlers->tkwin == w) - { - if (handlers == info->frozen_handlers) - { - info->frozen_handlers = handlers->next; - } - else - { - h_prev->next = handlers->next; - } - ckfree((char *) handlers); - } - else - { - h_prev = handlers; - } - } - } - /*printf("End of DestroyPerWindow\n");*/ - return; -} - -/* - *---------------------------------------------------------------------- - * - * GetWindowInfo -- - * Return the handlers registered for the window. - * - *---------------------------------------------------------------------- - */ -static WindowInfoStruct * -GetWindowInfo(Tk_Window w, - int create) -{ - DisplayInfoStruct *info; - Tcl_HashEntry *he; - WindowInfoStruct *pw; - int new; - - /*printf("Begin of GetWindowInfo %d %s \n", create, (char *)w);*/ - - info = GetDisplayInfo(Tk_Display(w)); - he = Tcl_FindHashEntry(&info->per_wins, (char *) w); - if (he == NULL) - { - if (create) - { - pw = (WindowInfoStruct *) ckalloc(sizeof(WindowInfoStruct)); - pw->handlers = NULL; - pw->scripts = NULL; - he = Tcl_CreateHashEntry(&info->per_wins, (char *) w, &new); - Tcl_SetHashValue(he, pw); - Tk_CreateEventHandler(w, StructureNotifyMask, DestroyPerWindow, w); - } - else - { - pw = NULL; - } - return pw; - } - - /* printf("End of GetWindowInfo \n");*/ - return (WindowInfoStruct *) Tcl_GetHashValue(he); -} - -/* - *---------------------------------------------------------------------- - * - * SelectEvents -- - * Traverse all event handlers for a given window and collect - * all classes needed for correct event selection. With this, - * select the requested events on the window. This may also - * unselect as needed all events from a device. - * - *---------------------------------------------------------------------- - */ -static void -SelectEvents(Tk_Window w, - int no_event_class) -{ - /*printf("Begin SelectEvents\n");*/ - DisplayInfoStruct *info = GetDisplayInfo(Tk_Display(w)); - WindowInfoStruct *pw = GetWindowInfo(w, 0); - EventHandlerStruct *handlers; - int i, count = 0; - XEventClass *classes; - - if (no_event_class >= 0) - { - count++; - } - if (pw) - { - for (handlers = pw->handlers; handlers; handlers = handlers->next) - { - count += handlers->num_classes; - } - } - for (handlers = info->other_handlers; handlers; handlers = handlers->next) - { - if (handlers->tkwin == w) - { - count += handlers->num_classes; - } - } - - if (count == 0) return; - - classes = (XEventClass *) alloca(count * sizeof(XEventClass)); - count = 0; - if (no_event_class >= 0) - { - classes[count] = no_event_class; - count++; - } - if (pw) - { - for (handlers = pw->handlers; handlers; handlers = handlers->next) - { - for (i = 0; i < handlers->num_classes; i++, count++) - { - classes[count] = handlers->classes[i]; - } - } - } - for (handlers = info->other_handlers; handlers; handlers = handlers->next) - { - if (handlers->tkwin == w) - { - for (i = 0; i < handlers->num_classes; i++, count++) - { - classes[count] = handlers->classes[i]; - } - } - } - - XSelectExtensionEvent(Tk_Display(w), Tk_WindowId(w), - classes, count); - /*printf("End SelectEvents\n");*/ - return; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_CreateXiEventHandler -- - * Public function provided to declare an event handler for - * an event from a device on a window. The client can pass a - * procedure to be called and a data pointer that will be passed - * back to the procedure. - * - * If it is not possible to bind the event the function return - * 0 else it returns 1. - * - *---------------------------------------------------------------------- - */ -int -Tk_CreateXiEventHandler(Tk_Window w, - Tk_Uid event_spec, - Tk_Uid device_spec, - DeviceInfoStruct * device, - Tk_EventProc *proc, - ClientData client_data) -{ - int found, no_window; - int event_index, event_type, event_atype; - WindowInfoStruct *pw; - EventHandlerStruct *handlers, **handlers_head; - DisplayInfoStruct *info; - - /*printf("Begin Tk_CreateXiEventHandler\n");*/ - - info = device->dpy_info; - event_index = GetEventIndex(event_spec); - - if (event_index < 0) return 0; - - event_type = info->event_types[event_index]; - event_atype = info->event_atypes[event_type]; - if (((event_atype == KEY_EVENT) && !device->num_keys) || - ((event_atype == BUTTON_EVENT) && !device->num_buttons) || - ((event_atype == MOTION_EVENT) && !device->num_axes) || - ((event_atype == FOCUS_EVENT) && !device->focusable) || - ((event_atype == PROXIMITY_EVENT) && !device->proximity)) - { - return 0; - } - - /* - * Special case for events that do not report a window. - */ - no_window = ((event_atype == CHANGE_DEVICE_EVENT) || - (event_atype == DEVICE_MAPPING_EVENT) || - (event_atype == DEVICE_STATE_EVENT)); - - if (no_window) - { - handlers_head = &info->other_handlers; - } - else - { - pw = GetWindowInfo(w, 1); - handlers_head = &pw->handlers; - } - - /* - * Lookup if the proc is already installed with the same - * client_data for the same event and device. - */ - found = 0; - for (handlers = *handlers_head ; handlers; handlers = handlers->next) - { - if ((handlers->proc == proc) && - (handlers->client_data == client_data) && - (handlers->type == event_type) && - (handlers->device_id == device->id)) - { - found = 1; - break; - } - } - - if (!found) - { - handlers = (EventHandlerStruct *) ckalloc(sizeof(EventHandlerStruct)); - handlers->next = *handlers_head; - *handlers_head = handlers; - handlers->proc = proc; - handlers->client_data = client_data; - handlers->type = event_type; - handlers->device_id = device->id; - handlers->tkwin = w; - - if ((event_index == BUTTON_PRESS_GRAB) || - (event_index == BUTTON_PRESS_OWNER_GRAB)) - { - handlers->num_classes = 2; - handlers->classes[0] = device->event_classes[BUTTON_PRESS]; - handlers->classes[1] = device->event_classes[BUTTON_PRESS_GRAB]; - if (event_index == BUTTON_PRESS_OWNER_GRAB) - { - handlers->num_classes++; - handlers->classes[2] = - device->event_classes[BUTTON_PRESS_OWNER_GRAB]; - } - } - else if (event_index == MOTION_HINT) - { - handlers->num_classes = 2; - handlers->classes[0] = device->event_classes[MOTION]; - handlers->classes[1] = device->event_classes[MOTION_HINT]; - } - else - { - handlers->num_classes = 1; - handlers->classes[0] = device->event_classes[event_index]; - } - } - - /* - * Now we need to check if the widget window is created and - * if it is, select the right events. - */ - if (Tk_WindowId(w)) - { - SelectEvents(w, -1); - } - - /*printf("End Tk_CreateXiEventHandler return 1\n");*/ - return 1; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_DeleteXiEventHandler -- - * Public function provided to suppress an event handler for - * an event from a device on a window. The client pass a - * procedure and a data pointer to be matched. Only the handler - * matching all criteria will be removed. - * - *---------------------------------------------------------------------- - */ -void -Tk_DeleteXiEventHandler(Tk_Window w, - Tk_Uid event_spec, - Tk_Uid device_spec, - DeviceInfoStruct *device, - Tk_EventProc *proc, - ClientData client_data) -{ - WindowInfoStruct *pw; - int event_index, event_type, event_atype; - EventHandlerStruct *handlers, *prev, *next; - EventHandlerStruct **handlers_head; - InProgress *ip; - int no_window; - int device_in_use = 0; - - /*printf("Begin Tk_DeleteXiEventHandler\n");*/ - event_index = GetEventIndex(event_spec); - event_type = device->dpy_info->event_types[event_index]; - event_atype = device->dpy_info->event_atypes[event_type]; - - /* - * Special case for events that do not report a window. - */ - no_window = ((event_atype == CHANGE_DEVICE_EVENT) || - (event_atype == DEVICE_MAPPING_EVENT) || - (event_atype == DEVICE_STATE_EVENT)); - - if (no_window) - { - handlers_head = &device->dpy_info->other_handlers; - } - else - { - pw = GetWindowInfo(w, 0); - - if ( !pw ) return; - - handlers_head = &pw->handlers; - } - - for (handlers = *handlers_head, prev = NULL; - handlers != NULL; handlers = next) - { - if ((handlers->proc == proc) && - (handlers->client_data == client_data) && - (handlers->type == event_type) && - (handlers->device_id == device->id)) - { - /* Ok, found the handler we are looking for, but we need - * to check if Tk_DispatchXiEvent is not about to - * process the handler. If it is, skip to the next. - */ - next = handlers->next; - - for (ip = pending_handlers; ip != NULL; ip = ip->next) - { - if (ip->next_handler == (ClientData) handlers) - { - ip->next_handler = (ClientData) next; - } - } - /* - * Unlink and free the handler. - */ - if (handlers == *handlers_head) - { - *handlers_head = next; - } - else - { - prev->next = next; - } - ckfree((char *) handlers); - } - else - { - prev = handlers; - /* - * Record if the device will be still in use after the - * removal of this handler. - */ - next = handlers->next; - device_in_use = device_in_use || (handlers->device_id == device->id); - } - } - /* - * Now we need to check if the widget window is created and - * if it is, select the right events. - */ - /*printf("device in use %s, %d, no_event=%d\n", device->name, device_in_use, - device->no_event_class);*/ - if (Tk_WindowId(w)) - { - SelectEvents(w, device_in_use ? -1 : device->no_event_class); - } - return; - /*printf("End Tk_DeleteXiEventHandler\n");*/ -} - -/* - *---------------------------------------------------------------------- - * - * WacomxiGenericEventHandler -- - * The generic event handler that is used to hook this extension - * in Tk event machinery. - * If checks if the event is from the xinput extension and - * dispatchs it using Tk_DispatchXiEvent on the appropriate - * window. - * - *---------------------------------------------------------------------- - */ -static int -WacomxiGenericEventHandler(ClientData client_data, - XEvent *event) -{ - DisplayInfoStruct *info; - /*printf("Begin WacomxiGenericEventHandler \n");*/ - - info = GetDisplayInfo(event->xany.display); - if ((event->type >= info->event_base) && - (event->type < (info->event_base+IEVENTS))) - { - return Tk_DispatchXiEvent(event); - } - - /* Not able to dispatch return and let the standard system have a try. - */ - /*printf("End WacomxiGenericEventHandler 0 \n");*/ - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_DispatchXiEvent -- - * Public function provided to dispatch an xinput event to a - * window. The event must be an xinput event. - * - *---------------------------------------------------------------------- - */ -int -Tk_DispatchXiEvent(XEvent *e) -{ - WindowInfoStruct *pw; - Tk_Window tkwin; - InProgress ip; - EventHandlerStruct *handlers; - DisplayInfoStruct *info; - int hit = 0; - - /*printf("Begin Tk_DispatchXiEvent : %d\n", e->type);*/ - - /* - * Special case needed for ChangeDeviceEvent, DeviceMappingEvent - * and DeviceStateEvent because the window is not reported. - */ - if (e->xany.window) - { - tkwin = Tk_IdToWindow(e->xany.display, e->xany.window); - - if ( !tkwin ) return hit; - - pw = GetWindowInfo(tkwin, 0); - - if ( !pw ) return hit; - - handlers = pw->handlers; - } - else - { - info = GetDisplayInfo(e->xany.display); - handlers = info->other_handlers; - } - - ip.next_handler = NULL; - ip.next = pending_handlers; - pending_handlers = &ip; - for ( ; handlers != NULL; ) - { - if ((handlers->type == e->type) && - (handlers->device_id == ((XDeviceKeyEvent *) e)->deviceid)) - { - hit = 1; - ip.next_handler = (ClientData) handlers->next; - (*(handlers->proc))(handlers->client_data, e); - handlers = (EventHandlerStruct *) ip.next_handler; - } - else - { - handlers = handlers->next; - } - } - pending_handlers = pending_handlers->next; - - /*printf("End Tk_DispatchXiEvent\n");*/ - return hit; -} - - -/* - *---------------------------------------------------------------------- - * - * RemoveEventScript -- - * Delete a script associated with and event from a device. The - * server is asked to stop reporting this event in the window. - * - *---------------------------------------------------------------------- - */ -static void -RemoveEventScript(Tcl_Interp *interp, - Tk_Window tkwin, - DeviceInfoStruct *device, - Tk_Uid event_spec) -{ - WindowInfoStruct *pw = GetWindowInfo(tkwin, 0); - EventScriptRecord *escripts, *prev_escript; - - /*printf("Begin RemoveEventScript\n");*/ - /* - * No window info. The window has probably been destroyed. - */ - if ( !pw ) return; - - for (escripts = pw->scripts, prev_escript = NULL; - escripts != NULL; - prev_escript = escripts, escripts = escripts->next) - { - if ((escripts->device == device) && - (escripts->event_spec == event_spec) && - (escripts->interp == interp)) - { - /* - * Ok, found the script we are looking for. - * Unlink the script from the list. - */ - if (escripts == pw->scripts) - { - pw->scripts = escripts->next; - } - else - { - prev_escript->next = escripts->next; - } - Tk_DeleteXiEventHandler(tkwin, event_spec, device->name, device, - InvokeEventScript, (ClientData) escripts); - ckfree(escripts->script); - ckfree((char *) escripts); - break; - } - } - /*printf("End RemoveEventScript\n");*/ - return; -} - -/* - *---------------------------------------------------------------------- - * - * ExpandPercents -- - * Do the actual work of expanding the percents in a script. The - * code is an adaptation of the function of the same name in - * tkBind.c To be completed - * - *---------------------------------------------------------------------- - */ - -static void -ExpandPercents(Tk_Window tkwin, - DeviceInfoStruct *device, - XEvent *e, - char event_atype, - char *script, - Tcl_DString *exp_script) -{ - char *scan; - char num_buffer[NUM_SIZE]; - int space_needed, cvt_flags; - unsigned long number; - int length, i, x, y, width, height; - int k_b_v_p_flag = 0, k_b_flag = 0; - unsigned int device_state = 0; - int axes_count = 0, *axis_data = NULL; - - /*printf("Begin ExpandPercents\n");*/ - if ((event_atype == KEY_EVENT) || (event_atype == BUTTON_EVENT)) - { - k_b_flag = k_b_v_p_flag = 1; - device_state = ((XDeviceKeyEvent *) e)->device_state; - axes_count = ((XDeviceKeyEvent *) e)->axes_count; - axis_data = ((XDeviceKeyEvent *) e)->axis_data; - } - else if (event_atype == MOTION_EVENT) - { - k_b_v_p_flag = 1; - device_state = ((XDeviceMotionEvent *) e)->device_state; - axes_count = ((XDeviceMotionEvent *) e)->axes_count; - axis_data = ((XDeviceMotionEvent *) e)->axis_data; - } - else if (event_atype == PROXIMITY_EVENT) - { - k_b_v_p_flag = 1; - device_state = ((XProximityNotifyEvent *) e)->device_state; - axes_count = ((XProximityNotifyEvent *) e)->axes_count; - axis_data = ((XProximityNotifyEvent *) e)->axis_data; - } - - while (1) - { - /* - * Find everything up to the next % character and append it - * to the result string. - */ - for (scan = script; (*scan != 0) && (*scan != '%'); scan++) - { - /* Empty loop body. */ - } - if (scan != script) - { - Tcl_DStringAppend(exp_script, script, scan-script); - script = scan; - } - if (*script == 0) - { - break; - } - /* - * Script is on a percent sequence. Process it. - */ - number = 0; - scan = "??"; - switch (script[1]) - { - case '#': - number = e->xany.serial; - goto do_unsigned_number; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (k_b_v_p_flag) - { - int index = script[1]-'0'; - - if (index < axes_count) - { - if (axes_count > 6) - { - number = device->valuator_cache[index]; - } - else - { - number = axis_data[index]; - } - } - } - goto do_number; - case '*': - if (event_atype == MOTION_EVENT) - { - DeviceInfoStruct *devices = device->dpy_info->devices; - int num_devices = device->dpy_info->num_dev; - - /* - * Go through all known devices and look for a device - * id equal to the valuator value. If not found return - * the valuator value as an integer. - */ - for (i = 0; i < num_devices; i++) - { - if (devices[i].id == axis_data[0]) - { - scan = (char *)devices[i].name; - goto do_string; - } - } - number = axis_data[0]; - } - goto do_number; - case 'b': - if (event_atype == BUTTON_EVENT) - { - number = ((XDeviceButtonEvent *) e)->button; - } - goto do_unsigned_number; - case 'h': - if (event_atype == MOTION_EVENT) - { - number = ((XDeviceMotionEvent *) e)->is_hint; - } - goto do_unsigned_number; - case 'k': - if (event_atype == KEY_EVENT) - { - number = ((XDeviceKeyEvent *) e)->keycode; - } - goto do_unsigned_number; - case 's': - if (k_b_v_p_flag) - { - number = ((XDeviceButtonEvent *) e)->state; - } - goto do_unsigned_number; - case 't': - if (k_b_v_p_flag) - { - number = ((XDeviceButtonEvent *) e)->time; - } - else if (event_atype == FOCUS_EVENT) - { - number = ((XDeviceFocusChangeEvent *) e)->time; - } - else - { - /* The other 3 event types: - * Mapping, State & Change are compatible. - */ - number = ((XChangeDeviceNotifyEvent *) e)->time; - } - goto do_unsigned_number; - case 'x': - if (k_b_v_p_flag) - { - number = ((XDeviceButtonEvent *) e)->x; - } - goto do_unsigned_number; - case 'y': - if (k_b_v_p_flag) - { - number = ((XDeviceButtonEvent *) e)->y; - } - goto do_unsigned_number; - case 'C': - if (event_atype == CHANGE_DEVICE_EVENT) - { - XChangeDeviceNotifyEvent *cdne = (XChangeDeviceNotifyEvent *) e; - if (cdne->request == NewKeyboard) - { - scan = "NewKeyboard"; - } - else if (cdne->request == NewPointer) - { - scan = "NewPointer"; - } - } - goto do_string; - case 'D': - scan = (char *)device->name; - goto do_string; - case 'E': - number = e->xany.send_event; - goto do_unsigned_number; - case 'S': - if (k_b_v_p_flag) - { - number = device_state; - } - goto do_unsigned_number; - case 'T': - for (i = 0; i < NUM_XI_EVENTS; i++) - { - if (device->dpy_info->event_types[i] == e->type) - { - scan = (char *)xi_event_names[i]; - break; - } - } - goto do_string; - case 'W': - if (tkwin != NULL) - { - scan = Tk_PathName(tkwin); - } - goto do_string; - case 'X': - if (k_b_v_p_flag) - { - number = ((XDeviceButtonEvent *) e)->x_root; - if (tkwin != NULL) - { - Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); - number -= x; - } - } - goto do_unsigned_number; - case 'Y': - if (k_b_v_p_flag) - { - number = ((XDeviceButtonEvent *) e)->y_root; - if (tkwin != NULL) - { - Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); - number -= y; - } - } - goto do_unsigned_number; - default: - num_buffer[0] = script[1]; - num_buffer[1] = '\0'; - scan = num_buffer; - goto do_string; - } - - do_unsigned_number: - sprintf(num_buffer, "%lu", number); - scan = num_buffer; - goto do_string; - - do_number: - sprintf(num_buffer, "%ld", number); - scan = num_buffer; - - do_string: - space_needed = Tcl_ScanElement(scan, &cvt_flags); - length = Tcl_DStringLength(exp_script); - Tcl_DStringSetLength(exp_script, length + space_needed); - space_needed = Tcl_ConvertElement(scan, - Tcl_DStringValue(exp_script) + length, - cvt_flags | TCL_DONT_USE_BRACES); - Tcl_DStringSetLength(exp_script, length + space_needed); - script += 2; - } - return; - /*printf("End ExpandPercents\n");*/ -} - -/* - *---------------------------------------------------------------------- - * - * InvokeEventScript -- - * Invoke a script that has been registered for an event form an - * input device. Any % occuring in the script will be replaced by - * a string depending on the characters following the percent. - * The recognized % sequences are: - * - * %# The number of the last request processed by the - * server. - * %0-9 The value of valuator n (0-9). - * %* The name of the device (as encoded in a valuator - * by the switch virtual device). - * %b The button number for events related to buttons. - * %h The motion hint field from the event. - * %k The keycode for events related to keys. - * %s The state field from the event (the core that is). - * %t The time field from the event. - * %x The x coord of the core pointer. - * %y The y coord of the core pointer. - * %C The name of the core device that changed (only - * for DeviceChange events). - * %D The device name that has emitted the event. - * %E The send_event field from the event. - * %S The device state field from the event. - * %T The type field from the event, as an event name. - * %W The window receiving the event. - * %X The root window x coord of the core pointer. - * %Y The root window y coord of the core pointer. - * - * An unrecognized sequence is replaced by the sequence with - * the leading percent removed. - * - *---------------------------------------------------------------------- - */ -static void -InvokeEventScript(ClientData client_data, - XEvent *e) -{ - EventScriptRecord *escripts = (EventScriptRecord *) client_data; - DeviceInfoStruct *device; - Tcl_Interp *interp = escripts->interp; - int result; - char event_atype; - Tcl_DString exp_script; - int i, try_to_merge = 0; - int first_axis = 0, axes_count = 0; - int *axis_data = NULL; - - device = LookupDeviceById(((XDeviceKeyEvent *) e)->display, - ((XDeviceKeyEvent *) e)->deviceid); - event_atype = device->dpy_info->event_atypes[e->type]; - /* - * If the event is a key, button, motion or proximity event, - * try to merge events emitted to report more than 6 valuators. - * It is assumed that an event train can't be mixed with another - * from the same device. - */ - if ((event_atype == BUTTON_EVENT) || (event_atype == KEY_EVENT)) - { - first_axis = ((XDeviceKeyEvent *) e)->first_axis; - axes_count = ((XDeviceKeyEvent *) e)->axes_count; - axis_data = ((XDeviceKeyEvent *) e)->axis_data; - try_to_merge = 1; - } - else if (event_atype == MOTION_EVENT) - { - first_axis = ((XDeviceMotionEvent *) e)->first_axis; - axes_count = ((XDeviceMotionEvent *) e)->axes_count; - axis_data = ((XDeviceMotionEvent *) e)->axis_data; - try_to_merge = 1; - } - else if (event_atype == PROXIMITY_EVENT) - { - first_axis = ((XProximityNotifyEvent *) e)->first_axis; - axes_count = ((XProximityNotifyEvent *) e)->axes_count; - axis_data = ((XProximityNotifyEvent *) e)->axis_data; - try_to_merge = 1; - } - - if (try_to_merge) - { - if (axes_count > 6) - { - /* - * Cache the axes reported in this event. - */ - for (i = first_axis; i < axes_count; i++) - { - device->valuator_cache[i] = axis_data[i-first_axis]; - } - /* - * If this isn't the last event, wait for the others. - */ - if (axes_count > (first_axis+6)) return; - } - } - - Tcl_Preserve((ClientData) interp); - Tcl_DStringInit(&exp_script); - ExpandPercents(escripts->tkwin, device, e, event_atype, - escripts->script, &exp_script); - /* - * Get the content of the escript before triggering - * the script. It may destroy the binding before returning - * and we might still need the info in case of error. - */ - result = Tcl_GlobalEval(interp, Tcl_DStringValue(&exp_script)); - Tcl_DStringFree(&exp_script); - if (result != TCL_OK) - { - Tcl_BackgroundError(interp); - } - Tcl_Release((ClientData) interp); - /*printf("End InvokeEventScript\n");*/ - return; -} - -/* - *---------------------------------------------------------------------- - * - * AddEventScript -- - * Register a script to be invoked when an event is received in a - * window from a device. The server is asked to report the event - * on the window. - * - * If it is not possible to bind the event the function return - * 0 else it returns 1. - * - *---------------------------------------------------------------------- - */ -static int -AddEventScript(Tcl_Interp *interp, - Tk_Window tkwin, - DeviceInfoStruct *device, - Tk_Uid event_spec, - char *script) -{ - WindowInfoStruct *pw = GetWindowInfo(tkwin, 1); - DeviceInfoStruct * dinfo = GetDeviceInfo(tkwin, device->name); - EventScriptRecord *escripts = NULL; - - /*printf("Begin of AddEventScript\n");*/ - - /* - * Try to see if a script is already registered with the - * same combination of device, event and interp. - */ - - for (escripts = pw->scripts; escripts != NULL; escripts = escripts->next) - { - if ((escripts->device == device) && - (escripts->event_spec == event_spec) && - (escripts->interp == interp)) - { - ckfree(escripts->script); - escripts->script = NULL; - break; - } - } - /* - * The event/device combo has no script already registered. Create - * a new record and register with the server. The InvokeEventScript - * function will be called with the script record as parameter when - * an event of this type/device will be received on the window. - */ - if (escripts == NULL) - { - escripts = (EventScriptRecord *) ckalloc(sizeof(EventScriptRecord)); - escripts->device = device; - escripts->tkwin = tkwin; - escripts->event_spec = event_spec; - escripts->interp = interp; - if (!Tk_CreateXiEventHandler(tkwin, event_spec, device->name, dinfo, - InvokeEventScript, (ClientData) escripts)) - { - ckfree((char *) escripts); - return 0; - } - escripts->next = pw->scripts; - pw->scripts = escripts; - } - /* - * Setup the script in the record. - */ - escripts->script = ckalloc(strlen(script) + 1); - strcpy(escripts->script, script); - - /*printf("End of AddEventScript\n");*/ - return 1; -} - -/* - *---------------------------------------------------------------------- - * - * WacomxiBindEventCmd -- - * Implements the 'bindevent' tcl command. - * - *---------------------------------------------------------------------- - */ -static int -WacomxiBindEventCmd(ClientData clientData, - Tcl_Interp *interp, - int argc, - char **argv) -{ - Tk_Window mainwin = (Tk_Window) clientData; - Tk_Window tkwin; - DeviceInfoStruct *device; - int len; - Tk_Uid event_spec; - - if ((argc != 4) && (argc != 5)) - { - Tcl_AppendResult(interp, "wrong # of arguments, should be \"", - argv[0], "win device event ?script?\"", (char *) NULL); - return TCL_ERROR; - } - tkwin = Tk_NameToWindow(interp, argv[1], mainwin); - - if ( !tkwin ) return TCL_ERROR; - - device = GetDeviceInfo(tkwin, Tk_GetUid(argv[2])); - if (!device) - { - Tcl_AppendResult(interp, "unknown device \"", argv[2], - "\" or it is currently a core device", (char *) NULL); - return TCL_ERROR; - } - - len = strlen(argv[3]); - if ((argv[3][0] != '<') || (argv[3][len-1] != '>')) - { - Tcl_AppendResult(interp, - "invalid event specification, should perhaps be <", - argv[3], ">", (char *) NULL); - return TCL_ERROR; - } - argv[3][len-1] = 0; - event_spec = Tk_GetUid(&argv[3][1]); - argv[3][len-1] = '>'; - - /* - * Asked to return the script associated with the widget/event. - * Lookup the scripts associated with window and in this list - * the script associated with the given event. - */ - if (argc == 4) - { - WindowInfoStruct *pw = GetWindowInfo(tkwin, 1); - EventScriptRecord *escripts; - - for (escripts = pw->scripts; escripts != NULL; escripts = escripts->next) - { - if ((escripts->device == device) && - (escripts->event_spec == event_spec) && - (escripts->interp == interp)) - { - Tcl_SetResult(interp, (char *)escripts->script, TCL_STATIC); - break; - } - } - return TCL_OK; - } - /* - * The script is the empty string, remove the event binding. - */ - if (!argv[4][0]) - { - RemoveEventScript(interp, tkwin, device, event_spec); - return TCL_OK; - } - /* - * Add or override the event binding if the event can be - * reported by the device. Else report an error. - */ - if (!AddEventScript(interp, tkwin, device, event_spec, argv[4])) - { - Tcl_AppendResult(interp, "Event \"", argv[3], - "\" can't be reported by device \"", argv[2], - "\"", (char *) NULL); - return TCL_ERROR; - } - return TCL_OK; -} - - -int -Libwacomxi_Init(Tcl_Interp *interp) -{ - static int setup_done = 0; - int i; - - if (!Tk_MainWindow(interp)) { - Tcl_AppendResult(interp, - "... Xinput package need Tk to run.", - (char *) NULL); - return TCL_ERROR; - } - - if (!setup_done) { - setup_done = 1; - Tk_CreateGenericHandler(WacomxiGenericEventHandler, NULL); - } - - Tcl_CreateCommand(interp, - "wacomxi::bindevent", - (Tcl_CmdProc *)WacomxiBindEventCmd, - (ClientData) Tk_MainWindow(interp), - (Tcl_CmdDeleteProc *) NULL); - - /* - * Convert events names into uids for speed and ease of use. - */ - for (i = 0; i < NUM_XI_EVENTS; i++) - { - xi_event_names[i] = Tk_GetUid(xi_event_names[i]); - } - - return Tcl_PkgProvide(interp, "LIBWACOMXI", "1.0"); -} diff --git a/src/wacomxi/wacomxi.h b/src/wacomxi/wacomxi.h deleted file mode 100644 index 1b63444..0000000 --- a/src/wacomxi/wacomxi.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * wacomxi.h -- Add X11 extended input handling capability for wacomcpl. - * - * Author : Ping Cheng - * Creation date : 04/05/2003 - * - */ - -/* - * Based on xi.h 1998-99 Patrick Lecoanet -- - * - * This code is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This code 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this code; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _WacomXi_H -#define _WacomXi_H - -#include <X11/extensions/XInput.h> -/* - * Included to obtain the number of events used by the xinput - * extension. - */ -#include <X11/extensions/XIproto.h> -#include <X11/Xlib.h> -#include <tk.h> - -/* - * These constants are used to represent fixed - * event types. These types are computed by - * mapping event types send by each server. The - * mapping is done by a table maintained for - * each server. - */ -#define KEY_EVENT 1 -#define BUTTON_EVENT 2 -#define MOTION_EVENT 3 -#define FOCUS_EVENT 4 -#define PROXIMITY_EVENT 5 -#define CHANGE_DEVICE_EVENT 6 -#define DEVICE_MAPPING_EVENT 7 -#define DEVICE_STATE_EVENT 8 - -/* - * These constants must be kept in sync with the - * xi_event_names array. - */ -#define KEY_PRESS 0 -#define KEY_RELEASE 1 -#define BUTTON_PRESS 2 -#define BUTTON_PRESS_GRAB 3 -#define BUTTON_PRESS_OWNER_GRAB 4 -#define BUTTON_RELEASE 5 -#define MOTION 6 -#define MOTION_HINT 7 -#define BUTTON_MOTION 8 -#define B1_MOTION 9 -#define B2_MOTION 10 -#define B3_MOTION 11 -#define B4_MOTION 12 -#define B5_MOTION 13 -#define FOCUS_IN 14 -#define FOCUS_OUT 15 -#define PROXIMITY_IN 16 -#define PROXIMITY_OUT 17 -#define DEVICE_STATE 18 -#define DEVICE_MAPPING 19 -#define CHANGE_DEVICE 20 - -#define NUM_XI_EVENTS 21 -#define NUM_EVENTS 256 /* Core limit of the protocol */ - -#define NUM_SIZE 50 - -static Tk_Uid xi_event_names[NUM_XI_EVENTS] = { - "KeyPress", - "KeyRelease", - "ButtonPress", - "ButtonPressGrab", - "ButtonPressOwnerGrab", - "ButtonRelease", - "Motion", - "MotionHint", - "ButtonMotion", - "B1Motion", - "B2Motion", - "B3Motion", - "B4Motion", - "B5Motion", - "FocusIn", - "FocusOut", - "ProximityIn", - "ProximityOut", - "DeviceState", - "DeviceMapping", - "ChangeDevice", -}; - -typedef struct _EventHandlerStruct { - Tk_EventProc *proc; - ClientData client_data; - int type; - XID device_id; - int num_classes; - int classes[3]; - Tk_Window tkwin; - struct _EventHandlerStruct *next; -} EventHandlerStruct; - -typedef struct _EventScriptRecord { - struct _DeviceInfoStruct *device; - Tk_Uid event_spec; - Tk_Window tkwin; - Tcl_Interp *interp; - char *script; - struct _EventScriptRecord *next; -} EventScriptRecord; - -typedef struct _AxeInfo { - int min_value; - int max_value; - int resolution; - int value; -} AxeInfo; - -typedef struct _WindowInfoStruct { - EventHandlerStruct *handlers; - EventScriptRecord *scripts; -} WindowInfoStruct; - -typedef struct _InProgress { - ClientData next_handler; /* Next handler in search. */ - struct _InProgress *next; /* Next higher nested search. */ -} InProgress; - -typedef struct _DeviceInfoStruct { - struct _DisplayInfoStruct *dpy_info; - XDevice *xdev; - Tk_Uid name; - XID id; - char core; /* If the device is the core keyboard or pointer */ - unsigned char x_index; /* index of valuator corresponding to core X */ - unsigned char y_index; /* index of valuator corresponding to core Y */ - int num_axes; - int num_keys; - int num_buttons; - char focusable; /* True if the device can be explicitly focused */ - char proximity; /* True if the device can emit proximity events */ - char feedback; /* True if the device has some feedback control */ - int mode; /* ABSOLUTE or RELATIVE */ - int history_size; - Time last_motion_time; - - AxeInfo *axe_info; - int *valuator_cache; /* Used to store valuators if the device reports - * more than six axes. The array is allocated - * dynamically to match the number of axes. */ - int event_classes[NUM_XI_EVENTS]; - int no_event_class; -} DeviceInfoStruct; - -typedef struct _DisplayInfoStruct { - char has_xdevices; /* Non zero if some devices are available - * (other than core devices). */ - Display *display; /* The display that is described. */ - DeviceInfoStruct *devices; /* The device list */ - int num_dev; - char event_types[NUM_XI_EVENTS]; - char event_atypes[NUM_EVENTS]; /* Mapping from server local event types - * to absolutes types independant from - * servers. */ - int event_base; /* The first event type reported by the - * xinput extension on this server. */ - Tcl_HashTable per_wins; /* Records for all handlers per windows on - * this display. */ - EventHandlerStruct *other_handlers; /* The handlers associated with events not - * reported relative to a window. */ - EventHandlerStruct *frozen_handlers; /* The handlers on hold because theirs - * devices are currently core devices. */ - struct _DisplayInfoStruct *next; -} DisplayInfoStruct; - -int Tk_CreateXiEventHandler(Tk_Window, Tk_Uid, Tk_Uid, DeviceInfoStruct *, Tk_EventProc *, - ClientData); -void Tk_DeleteXiEventHandler(Tk_Window, Tk_Uid, Tk_Uid, DeviceInfoStruct *, Tk_EventProc *, - ClientData); -int Tk_DispatchXiEvent(XEvent *); -int LibwacomXi_Init(Tcl_Interp *interp); - -#endif |