TOBI SignalServer  0.1
/home/breidi/Dropbox/signalserver/src/hardware/mouse_linux.cpp
00001 /*
00002     This file is part of the TOBI SignalServer.
00003 
00004     Commercial Usage
00005     Licensees holding valid Graz University of Technology Commercial
00006     licenses may use this file in accordance with the Graz University
00007     of Technology Commercial License Agreement provided with the
00008     Software or, alternatively, in accordance with the terms contained in
00009     a written agreement between you and Graz University of Technology.
00010 
00011     --------------------------------------------------
00012 
00013     GNU General Public License Usage
00014     Alternatively, this file may be used under the terms of the GNU
00015     General Public License version 3.0 as published by the Free Software
00016     Foundation and appearing in the file gpl.txt included in the
00017     packaging of this file.  Please review the following information to
00018     ensure the GNU General Public License version 3.0 requirements will be
00019     met: http://www.gnu.org/copyleft/gpl.html.
00020 
00021     In case of GNU General Public License Usage ,the TOBI SignalServer
00022     is distributed in the hope that it will be useful,
00023     but WITHOUT ANY WARRANTY; without even the implied warranty of
00024     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025     GNU General Public License for more details.
00026 
00027     You should have received a copy of the GNU General Public License
00028     along with the TOBI SignalServer. If not, see <http://www.gnu.org/licenses/>.
00029 
00030     Copyright 2010 Graz University of Technology
00031     Contact: SignalServer@tobi-project.org
00032 */
00033 
00034 #ifndef _WIN32
00035 
00036 #include "hardware/mouse_linux.h"
00037 #include <string>
00038 
00039 namespace tobiss
00040 {
00041 
00042 const HWThreadBuilderTemplateRegistratorWithoutIOService<Mouse> Mouse::FACTORY_REGISTRATOR_ ("mouse");
00043 
00044 Mouse::Mouse(ticpp::Iterator<ticpp::Element> hw)
00045 : MouseBase(hw)
00046 {
00047   int ret = blockKernelDriver();
00048   if(ret)
00049     throw(std::runtime_error("MouseBase::initMouse -- Mouse device could not be connected (check rights)!"));
00050 
00051   struct libusb_device_descriptor desc;
00052 
00053 
00054   struct libusb_device* dev = libusb_get_device(dev_handle_);
00055   if(dev == 0)
00056     throw(std::runtime_error("MouseBase::initMouse -- Failed to get device pointer!"));
00057 
00058   int r = libusb_get_device_descriptor( dev, &desc);
00059   if(r < 0)
00060     throw(std::runtime_error("MouseBase::initMouse -- Failed to get device descriptor!"));
00061 
00062   std::string name;
00063   unsigned char str[256];
00064 
00065   ret = 0;
00066   ret = libusb_get_string_descriptor_ascii(dev_handle_, desc.iManufacturer, str, sizeof(str) );
00067   if(ret)
00068   {
00069     name += " -- ";
00070     name.append( reinterpret_cast<char*>(str));
00071   }
00072   ret = libusb_get_string_descriptor_ascii(dev_handle_, desc.iProduct, str, sizeof(str) );
00073   if(ret)
00074   {
00075     name += ", ";
00076     name.append( reinterpret_cast<char*>(str));
00077   }
00078 
00079   name += " (vid/pid: " + boost::lexical_cast<std::string>(vid_);
00080   name += "/"  + boost::lexical_cast<std::string>(pid_) + ")";
00081 
00082 
00083 //  cout << " --> Mouse ID: " << id_ << ",  Name: " << name_;
00084 //  cout<<", vid: "<<vid_<<", pid: "<<pid_<<endl;
00085 
00086   setType("Mouse" + name);
00087 }
00088 
00089 //-----------------------------------------------------------------------------
00090 
00091 Mouse::~Mouse()
00092 {
00093   running_ = false;
00094   async_acqu_thread_->join();
00095   if(async_acqu_thread_)
00096     delete async_acqu_thread_;
00097   freeKernelDriver();
00098 }
00099 
00100 //-----------------------------------------------------------------------------
00101 
00102 int Mouse::blockKernelDriver()
00103 {
00104   int ret;
00105   // setup interface
00106   ret = libusb_init(&ctx_);
00107   if(ret < 0)
00108     return -1;
00109 
00110   // create an interface to the right usb device
00111   dev_handle_ = libusb_open_device_with_vid_pid(ctx_, vid_, pid_);
00112   if(dev_handle_ == NULL)
00113     return -2;
00114 
00115   if(libusb_kernel_driver_active(dev_handle_, 0) == 1)
00116     libusb_detach_kernel_driver(dev_handle_, 0);
00117 
00118   ret = libusb_claim_interface(dev_handle_, 0);
00119   if(ret)
00120     return -3;
00121 
00122   return 0;
00123 }
00124 
00125 //-----------------------------------------------------------------------------
00126 
00127 int Mouse::freeKernelDriver()
00128 {
00129   int ret;
00130   ret = libusb_release_interface(dev_handle_, 0);
00131   if(ret)
00132     return -1;
00133   ret = libusb_attach_kernel_driver(dev_handle_, 0);
00134   if(ret)
00135     return -2;
00136   libusb_close(dev_handle_);
00137   libusb_exit(ctx_);
00138   return 0;
00139 }
00140 
00141 //-----------------------------------------------------------------------------
00142 
00143 
00144 
00145 void Mouse::acquireData()
00146 {
00147   while(running_)
00148   {
00149     bool unchanged = false;
00150     boost::unique_lock<boost::shared_mutex> lock(rw_);
00151     int actual_length;
00152     unsigned char async_data_[10];
00153     int r = libusb_interrupt_transfer(dev_handle_, usb_port_, async_data_,
00154                                       sizeof(async_data_), &actual_length, 100);
00155 
00156     if(r == LIBUSB_ERROR_TIMEOUT)
00157     {
00158       //cout<<"   Mouse: Timeout!"<<endl;
00159       unchanged = true;
00160     }
00161     else if (r == LIBUSB_ERROR_NO_DEVICE)
00162     {
00163       lock.unlock();
00164       throw(std::runtime_error("Mouse::acquireData -- Mouse device could not be read! Check usb-port!"));
00165     }
00166     else if(r<0)
00167     {
00168       lock.unlock();
00169       throw(std::runtime_error("Mouse::acquireData -- Mouse device could not be read! Problem with libusb!"));
00170     }
00171     if(!unchanged)
00172     {
00173       async_data_buttons_ = static_cast<int>(static_cast<char>(async_data_[0]));
00174       async_data_x_ = static_cast<int>(static_cast<char>(async_data_[1]));
00175       async_data_y_ = static_cast<int>(static_cast<char>(async_data_[2]));
00176     }
00177     lock.unlock();
00178   }
00179 }
00180 
00181 //-----------------------------------------------------------------------------
00182 
00183 
00184 }
00185 #endif //__linux__
 All Data Structures Files Functions Variables