Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

phLinuxJoystick.cpp

Go to the documentation of this file.
00001 #include <sys/ioctl.h>
00002 #include <sys/time.h>
00003 #include <sys/types.h>
00004 #include <stdlib.h>
00005 #include <fcntl.h>
00006 #include <unistd.h>
00007 #include <stdio.h>
00008 #include <errno.h>
00009 #include <string.h>
00010 
00011 #include <linux/joystick.h>
00012 
00013 #include <phLinuxJoystick.h>
00014 #include <phbase.h>
00015 
00016 /* ------------------------------------------------------------------------ */
00017 phLinuxJoystick::phLinuxJoystick(const char *path)
00018 {
00019     phFUNCTION("phLinuxJoystick::phLinuxJoystick")
00020     int locked = 0;
00021 
00022     phTHIS_LOOSE_LOCK(locked);
00023 
00024     this->setName("phLinuxJoystick");
00025 
00026     this->m_path        = NULL;
00027     this->m_path_size   = 0;
00028     this->m_fd          = 0;
00029     this->m_axis_count  = 0;
00030     this->m_button_count= 0;
00031     memset(this->m_name,0,phLinuxJoystick_NAMELENGTH);
00032     this->m_ver_maj = 0;
00033     this->m_ver_min = 0;
00034     this->m_ver_rev = 0;
00035     
00036 
00037     rc = this->setPath(path);
00038     phPRINT_RC(rc,NULL,"this->setPath");
00039 
00040 error:
00041     phTHIS_LOOSE_UNLOCK(locked);
00042 }
00043 /* ------------------------------------------------------------------------ */
00044 phLinuxJoystick::~phLinuxJoystick()
00045 {
00046     phFUNCTION("phLinuxJoystick::~phLinuxJoystick")
00047     int locked = 0;
00048 
00049     phTHIS_LOOSE_LOCK(locked);
00050   
00051     if (this->isRunning())
00052     {
00053         this->stop();
00054     }
00055 
00056     if (this->isOpen())
00057     {
00058         this->close();
00059     }
00060    
00061     phFree(this->m_path);
00062     this->m_path_size = 0;
00063     this->m_fd = 0;
00064     this->m_axis_count  = 0;
00065     this->m_button_count= 0;
00066     memset(this->m_name,0,phLinuxJoystick_NAMELENGTH);
00067     this->m_ver_maj = 0;
00068     this->m_ver_min = 0;
00069     this->m_ver_rev = 0;
00070     this->m_data.reset();
00071    
00072     phTHIS_LOOSE_UNLOCK(locked);
00073 }
00074 
00075 /* ------------------------------------------------------------------------ */
00076 int phLinuxJoystick::wakeup()
00077 {
00078     phFUNCTION("phLinuxJoystick::wakeup")
00079     int flags = 0;
00080 
00081     if (this->isOpen())
00082     {
00083         flags = fcntl(this->m_fd,F_GETFL,0);
00084         phCHECK_RC(flags,"fcntl:F_GETFL","fcntl failed to get fd flags");
00085     
00086         flags |= O_NONBLOCK;
00087     
00088         rc = fcntl(this->m_fd,F_SETFL,flags);
00089         phCHECK_RC(rc,"fcntl:F_SETFL","fcntl failed to set fd flags");
00090     }
00091     return phSUCCESS;
00092 error:
00093     return phFAIL;
00094 }
00095 
00096 /* ------------------------------------------------------------------------ */
00097 int phLinuxJoystick::run()
00098 {
00099     phFUNCTION("phLinuxJoystick::run")
00100     const int       readsize    = sizeof(struct js_event);
00101     int             locked      = 0;
00102     struct js_event js;  
00103     int             flags       = 0;
00104     
00105     rc = this->open();
00106     phCHECK_RC(rc,NULL,"this->open() failed");
00107     
00108     flags = fcntl(this->m_fd,F_GETFL,0);
00109     phCHECK_RC(flags,"fcntl:F_GETFL","fcntl failed to get fd flags");
00110     
00111     flags |= O_NONBLOCK;
00112     
00113     rc = fcntl(this->m_fd,F_SETFL,flags);
00114     phCHECK_RC(rc,"fcntl:F_SETFL","fcntl failed to set fd flags");
00115     
00116     rc = this->signal_running();
00117     phPRINT_RC(rc,NULL,"this->signal_running");
00118 
00119     while (this->isRunning())
00120     {
00121         phTHIS_LOOSE_LOCK(locked);
00122             
00123         rc = 0;
00124         memset(&js,0,readsize);
00125         errno = 0;
00126 
00127         rc = read( this->m_fd, &js, readsize );
00128         if ((rc != readsize) && (rc != -1))
00129         {
00130             phPRINT_RC(-1,"read","read returned number != %d",readsize);
00131         }
00132         if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
00133         {
00134             phTHIS_LOOSE_UNLOCK(locked);
00135             phMSleep(10);//yieldThread();
00136             continue;
00137         }
00138         phPRINT_RC(rc,"read","read failed");
00139         if (rc < 0)
00140         {
00141             this->setRunning(0);
00142             phTHIS_LOOSE_UNLOCK(locked);
00143             continue;
00144         }
00145 
00146         /*
00147         phPROGRESS("%d : %d : %d : %d\n",
00148                  rc,js.type,js.number,js.value);
00149         */
00150         if (rc == readsize)
00151         {
00152             if (js.type & JS_EVENT_INIT)
00153                 this->m_data.disableNotify();
00154 
00155             switch(js.type & ~JS_EVENT_INIT) 
00156             {
00157                 case JS_EVENT_BUTTON:
00158                     rc = this->m_data.setButton(js.number,js.value);
00159                     phPRINT_RC(rc,NULL,"this->m_data.setButton(js.number,js.value)");
00160                     break;
00161                 case JS_EVENT_AXIS:
00162                     rc = this->m_data.setAxis(js.number,js.value);
00163                     phPRINT_RC(rc,NULL,"this->m_data.setAxis(js.number,js.value)");
00164                     break;
00165             }
00166             
00167             if (js.type & JS_EVENT_INIT)
00168                 this->m_data.enableNotify();
00169         }
00170         
00171         phTHIS_LOOSE_UNLOCK(locked);
00172 
00173         phMSleep(1);//yieldThread();
00174     }
00175 
00176     rc = this->close();
00177     phPRINT_RC(rc,NULL,"this->close");
00178 
00179     return phSUCCESS;
00180 error:
00181     phTHIS_ERROR_UNLOCK(locked);
00182     
00183     rc = this->signal_running();
00184     phPRINT_RC(rc,NULL,"this->signal_running");
00185 
00186     return 1;
00187 }
00188 
00189 /* ------------------------------------------------------------------------ */
00190 int phLinuxJoystick::isOpen()
00191 {
00192     return (this->m_fd > 0) ? 1 : 0;
00193 }
00194 
00195 /* ------------------------------------------------------------------------ */
00196 int phLinuxJoystick::open()
00197 {
00198     phFUNCTION("phLinuxJoystick::open")
00199     int         locked          = 0;
00200     int         fd              = 0;
00201     int32_t     version         = 0;
00202     int8_t      version_major   = 0;
00203     int8_t      version_minor   = 0;
00204     int8_t      version_rev     = 0;
00205 
00206     phTHIS_LOCK(locked);
00207         
00208     fd = ::open(this->m_path, O_RDONLY);
00209     phCHECK_RC(fd,"open","open(%s,O_RDONLY)",this->m_path);
00210 
00211     this->m_fd = fd;
00212 
00213     rc = ioctl(fd, JSIOCGVERSION,&version);
00214     phCHECK_RC(rc,"ioctl","ioctl(%d,JSIOCGVERSION)",fd);
00215 
00216     version_major   = version >> 16;
00217     version_minor   = (version >> 8) & 0xFF;;
00218     version_rev     = (version) & 0xFF;;
00219 
00220     if (version_major < 0)
00221     {
00222         phCHECK_RC(-1,NULL,"JSIOCGVERSION return %d:%d:%d - version too old.",
00223                  version_major,version_minor,version_rev);
00224     }
00225     
00226     this->m_ver_maj = version_major;
00227     this->m_ver_min = version_minor;
00228     this->m_ver_rev = version_rev;
00229         
00230     rc = ioctl(fd, JSIOCGAXES,&(this->m_axis_count));
00231     phCHECK_RC(rc,"ioctl","ioctl(%d,JSIOCGAXES)",fd);
00232 
00233     rc = ioctl(fd, JSIOCGBUTTONS,&(this->m_button_count));
00234     phCHECK_RC(rc,"ioctl","ioctl(%d,JSIOCGBUTTONS)",fd);
00235 
00236     rc = ioctl(fd, JSIOCGNAME(phLinuxJoystick_NAMELENGTH),this->m_name);
00237     phCHECK_RC(rc,"ioctl","ioctl(%d,JSIOCGNAME(phLinuxJoystick_NAMELENGTH))",fd);
00238 
00239     rc = this->m_data.set(this->m_axis_count,NULL,
00240                           this->m_button_count,NULL);
00241     phCHECK_RC(rc,NULL,"this->(phJoystickData)m_data.set(%d,NULL,%d,NULL)",
00242              this->m_axis_count, this->m_button_count);
00243 
00244     phTHIS_UNLOCK(locked);
00245 
00246     return phSUCCESS;
00247     
00248 error:
00249     if (this->isOpen())
00250     {
00251         rc = this->close();
00252         phPRINT_RC(rc,NULL,"this->close()");
00253     }
00254     phTHIS_ERROR_UNLOCK(locked);
00255 
00256     return phFAIL;
00257 }
00258 
00259 /* ------------------------------------------------------------------------ */
00260 int phLinuxJoystick::close()
00261 {
00262     phFUNCTION("phLinuxJoystick::close")
00263     int locked = 0;
00264 
00265     phTHIS_LOCK(locked);
00266 
00267     if (this->m_fd > 0)
00268     {
00269         rc = ::close(this->m_fd);
00270         phPRINT_RC(rc,"close","close failed");
00271 
00272         this->m_fd = 0;
00273         this->m_axis_count = 0;
00274         this->m_button_count = 0;
00275         memset(this->m_name,0,phLinuxJoystick_NAMELENGTH);
00276         this->m_ver_maj = 0;
00277         this->m_ver_min = 0;
00278         this->m_ver_rev = 0;
00279         this->m_data.reset();
00280     }
00281     
00282     phTHIS_UNLOCK(locked);
00283 
00284     return phSUCCESS;
00285     
00286 error:
00287     phTHIS_ERROR_UNLOCK(locked);
00288 
00289     return phFAIL;
00290 }
00291 
00292 /* ------------------------------------------------------------------------ */
00293 int phLinuxJoystick::setPath(const char *path)
00294 {
00295     phFUNCTION("phLinuxJoystick::setPath")
00296     int locked = 0;
00297 
00298     phTHIS_LOCK(locked);
00299     
00300     if (path != NULL)
00301     {
00302         rc = phStringCopy(path,255,
00303                 &(this->m_path),
00304                 &(this->m_path_size),
00305                 "/dev/js0");
00306         phCHECK_RC(rc,NULL,"phStringCopy failed.");
00307     }
00308     else
00309     {
00310         rc = phStringCopy("/dev/js0",255,
00311                 &(this->m_path),
00312                 &(this->m_path_size),
00313                 "/dev/js0");
00314         phCHECK_RC(rc,NULL,"phStringCopy failed.");
00315     }
00316 
00317     phTHIS_UNLOCK(locked);
00318 
00319     return phSUCCESS;
00320     
00321 error:
00322     phTHIS_ERROR_UNLOCK(locked);
00323 
00324     return phFAIL;
00325 }
00326 
00327 /* ------------------------------------------------------------------------ */
00328 const char *phLinuxJoystick::getPath()
00329 {
00330     return (const char *)this->m_path;
00331 }
00332 
00333 /* ------------------------------------------------------------------------ */
00334 uint8_t phLinuxJoystick::getVersionMajor()
00335 {
00336     return this->m_ver_maj;
00337 }
00338 
00339 /* ------------------------------------------------------------------------ */
00340 uint8_t phLinuxJoystick::getVersionMinor()
00341 {
00342     return this->m_ver_min;
00343 }
00344 
00345 /* ------------------------------------------------------------------------ */
00346 uint8_t phLinuxJoystick::getVersionRevision()
00347 {
00348     return this->m_ver_rev;
00349 }
00350 
00351 /* ------------------------------------------------------------------------ */
00352 uint8_t phLinuxJoystick::getAxisCount()
00353 {
00354     return this->m_axis_count;
00355 }
00356 
00357 /* ------------------------------------------------------------------------ */
00358 uint8_t phLinuxJoystick::getButtonCount()
00359 {
00360     return this->m_button_count;
00361 }
00362 
00363 /* ------------------------------------------------------------------------ */
00364 const char *phLinuxJoystick::getName()
00365 {
00366     return (const char *)this->m_name;
00367 }
00368 
00369 /* ------------------------------------------------------------------------ */
00370 int phLinuxJoystick::getData( phJoystickData &data )
00371 {
00372     phFUNCTION("phLinuxJoystick::getData")
00373     int locked = 0;
00374 
00375     phTHIS_LOCK(locked);
00376 
00377     data.copyData(this->m_data);
00378     
00379     phTHIS_UNLOCK(locked);
00380 
00381     return phSUCCESS;
00382     
00383 error:
00384     phTHIS_ERROR_UNLOCK(locked);
00385 
00386     return phFAIL;
00387 }
00388 
00389 /* ------------------------------------------------------------------------ */
00390 phJoystickData *phLinuxJoystick::getSource()
00391 {
00392     return &(this->m_data);
00393 }




Copyright (C) 2002 - 2007 Philip D.S. Thoren ( pthoren@users.sourceforge.net )
University Of Massachusetts at Lowell
Robotics Lab
SourceForge.net Logo

Generated on Sat Jun 16 02:44:07 2007 for phission by  doxygen 1.4.4