linux-input/test/test.cpp

Go to the documentation of this file.
00001 /*
00002  * test.cpp
00003  *
00004  * Copyright (C) 2009  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  * Simple test for linux-input source devices.
00008  */
00009 
00010 // includes --------------------------------------------------------------------
00011 #include <time.h>
00012 
00013 #include <iostream>
00014 
00015 #include "linux-input/linux-input.h"
00016 #include "perf/perf.h"
00017 
00018 
00019 ////////////////////////////////////////////////////////////////////////////////
00020 //
00021 //      static helper methods
00022 //
00023 ////////////////////////////////////////////////////////////////////////////////
00024 
00025 static int
00026 getIntDigits
00027 (
00028 IN int x
00029 )
00030 throw()
00031 {
00032         if (x <= 9)
00033                 return 1;
00034 
00035         int nDigits = 1;
00036         while (x > 10) {
00037                 x /= 10;
00038                 nDigits++;
00039         }
00040 
00041         return nDigits;
00042 }
00043 
00044 
00045 
00046 static int
00047 getPotDigits
00048 (
00049 IN int min,
00050 IN int max
00051 )
00052 throw()
00053 {
00054         int minDigits = 0;
00055         if (min < 0) {
00056                 minDigits = getIntDigits(-min) + 1;
00057         }
00058         int maxDigits = getIntDigits(max);
00059 
00060         if (minDigits > maxDigits) {
00061                 return minDigits;
00062         }
00063         return maxDigits;
00064 }
00065 
00066 
00067 static void
00068 printPot
00069 (
00070 IN int idx,
00071 IN const gamepad::pot_value_t& pv
00072 )
00073 throw()
00074 {
00075         int valDigits = getPotDigits(pv.minSeen, pv.maxSeen);
00076 
00077 //      DPRINTF("Pot min=%d, max=%d", pv.minSeen, pv.maxSeen);
00078 
00079         const int bufsize = 64;
00080         char format[bufsize];
00081 
00082 //      snprintf(format, bufsize, "%%d:%%%dd ", valDigits);
00083         snprintf(format, bufsize, "%%%dd ", valDigits);
00084 //      DPRINTF("  format string: '%s'", format);
00085 
00086 //      printf(format, idx, pv.value);
00087         printf(format, pv.value);
00088 /*      if (phase & 1) {
00089                 // show min
00090                 if (gamepad::pot_value_t::eStartMin == pv.minSeen) {
00091                         printf("X");
00092                 } else {
00093                         printf("%d", pv.minSeen);
00094                 }
00095         } else {
00096                 // show max
00097                 if (gamepad::pot_value_t::eStartMax == pv.maxSeen) {
00098                         printf("X");
00099                 } else {
00100                         printf("%d", pv.maxSeen);
00101                 }
00102         }
00103         printf(" "); */
00104 }
00105 
00106 
00107 
00108 static void
00109 doTest
00110 (
00111 void
00112 )
00113 {
00114         // create factory object
00115         bool wantForceFeedbackEvenThoughExtremelyDangerous = true;
00116         smart_ptr<gamepad::SourceDeviceFactory> factory =
00117             gamepad::getLinuxInputSourceDeviceFactory(
00118                 wantForceFeedbackEvenThoughExtremelyDangerous);
00119         ASSERT_THROW(factory,
00120             "failed to create linux input source device factory");
00121 
00122         // see if there are any linux joystic devices
00123         int nDevices = factory->getCount();
00124         DPRINTF("Found %d linux joystick source devices", nDevices);
00125         ASSERT_THROW(nDevices > 0, "Bad or no joystick devices found?");
00126 
00127 #if 1
00128         // loop through all devices and get info!
00129         for (int i = 0; i < nDevices; ++i) {
00130                 smart_ptr<gamepad::SourceDevice> device =
00131                     factory->getSourceDevice(i);
00132                 ASSERT_THROW(device, "Should have a device here");
00133 
00134                 // dump the names
00135                 DPRINTF("Device %d: '%s'", i, device->getPublicName());
00136                 DPRINTF("  unique ID: '%s'", device->getUniqueId());
00137 
00138                 DPRINTF("  state: %d", device->getState());
00139                 DPRINTF("  total potentiometers: %d", device->getNumPots());
00140                 DPRINTF("  total buttons: %d", device->getNumButtons());
00141         }
00142 #endif
00143 
00144         // okay, get the first device
00145         smart_ptr<gamepad::SourceDevice> device = factory->getSourceDevice(0);
00146         ASSERT_THROW(device, "should have a device");
00147 
00148         // set up sleep interval
00149         const int desiredHz = 100;
00150         long msPoll = 1000 / desiredHz;
00151         DPRINTF("Want sampling at %d Hz, so polling every %ld ms",
00152             desiredHz, msPoll);
00153         ASSERT_THROW(desiredHz > 1, "Need a higher sampling frequency!");
00154         struct timespec ts;
00155         ts.tv_sec = 0;
00156         ts.tv_nsec = msPoll * 1000 * 1000;      // 1ms = 10e6 ns
00157 
00158         // how often do we see if the device is still connected?
00159         const int connectedHz = 5;
00160         int checkCounter = desiredHz / connectedHz;
00161         DPRINTF("Checking connection status every %d iterations",
00162             checkCounter);
00163         int counter = 0;
00164 
00165 /*
00166         // Jan 2011: removing all force feedback support for now
00167         // default rumble values
00168         uint16_t loFreq = 0x5000;
00169         uint16_t hiFreq = 0x5000;
00170         int nRumble = device->getNumRumblers();
00171         DPRINTF("Found %d rumblers", nRumble);
00172         if (device->getNumButtons() < nRumble) {
00173                 nRumble = device->getNumButtons();
00174         }
00175  */
00176 
00177         int nCols = 100;                // assume 100 columns for display
00178         int nCharsPerPot = (nCols / device->getNumPots()) - 1;
00179         if (nCharsPerPot > 6) {
00180                 nCharsPerPot = 6;
00181         }
00182         if (nCharsPerPot < 2) {
00183                 nCharsPerPot = 2;
00184         }
00185 //      char potFormat[64];
00186 //      sprintf(potFormat, "%%d:%%d:%%d ");
00187 //      DPRINTF("Potentiometer format: '%s'", potFormat);
00188 
00189         // now loop and read
00190         DPRINTF("\n\nDetach the device to stop the program!\n");
00191         while (gamepad::eDevice_Detached != device->getState()) {
00192                 nanosleep(&ts, NULL);
00193 
00194                 counter++;
00195                 if (counter >= checkCounter) {
00196                         counter = 0;
00197                         factory->getCount();
00198                 }
00199 
00200                 device->poll();
00201                 printf("\r");
00202                 for (int i = 0; i < device->getNumPots(); ++i) {
00203                         const gamepad::pot_value_t& pv = device->getPotValue(i);
00204                         printPot(i, pv);
00205 //                      printf(potFormat, pv.minSeen, pv.value, pv.maxSeen);
00206                 }
00207 
00208                 printf(" pressed:");
00209                 bool needLinefeed = false;
00210                 for (int i = 0; i < device->getNumButtons(); ++i) {
00211                         if (gamepad::eButtonWasPushed & device->getButtonValue(i)) {
00212                                 printf(" b%d", i);
00213                                 needLinefeed = true;
00214                         }
00215                 }
00216                 if (needLinefeed) {
00217                         printf("\n");
00218                 }
00219 
00220 /*
00221                 for (int i = 0; i < nRumble; ++i) {
00222                         int duration = -1;
00223                         if (gamepad::eButtonWasPushed & device->getButtonValue(i))
00224                                 duration = 2000;
00225                         if (gamepad::eButtonWasReleased & device->getButtonValue(i))
00226                                 duration = 0;
00227                         if (duration < 0)
00228                                 continue;       // skip button
00229 
00230                         uint16_t hi = (i % 2) ? hiFreq : 0;
00231                         uint16_t lo = (hi) ? 0 : loFreq;
00232                         device->playRumble(i, hi, lo, duration);
00233                 }
00234  */
00235         }
00236         printf("\n");
00237         DPRINTF("Device appears to be detached--exiting!");
00238 }
00239 
00240 
00241 
00242 ////////////////////////////////////////////////////////////////////////////////
00243 //
00244 //      entry point
00245 //
00246 ////////////////////////////////////////////////////////////////////////////////
00247 
00248 int
00249 main
00250 (
00251 IN int argc,
00252 IN const char * argv[]
00253 )
00254 {
00255         int retval = 0;
00256 
00257         try {
00258                 perf::Timer timer("overall timer");
00259 
00260                 doTest();
00261 
00262         } catch (std::exception& e) {
00263                 DPRINTF("EXCEPTION: %s", e.what());
00264                 retval = 1;
00265         }
00266 
00267         perf::dumpTimingSummary(std::cerr);
00268 
00269         return retval;
00270 }
00271 
00272