Make wheelsourceplugin actually read JS events (currently just prints out)
authorJames Ausmus <james.ausmus@intel.com>
Thu, 23 Aug 2012 19:23:07 +0000 (12:23 -0700)
committerJames Ausmus <james.ausmus@intel.com>
Thu, 23 Aug 2012 19:23:07 +0000 (12:23 -0700)
Signed-off-by: James Ausmus <james.ausmus@intel.com>
plugins/wheel/CMakeLists.txt
plugins/wheel/wheelplugin.cpp

index 77bd497..b140059 100644 (file)
@@ -1,6 +1,11 @@
 
 include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs})
 
+pkg_check_modules(giounix REQUIRED gio-unix-2.0)
+set(link_libraries ${link_libraries} ${giounix_LIBRARIES})
+#set(include_dirs ${include_dirs} ${giounix_INCLUDE_DIRS})
+include_directories(${giounix_INCLUDE_DIRS})
+
 set(wheelsourceplugin_headers wheelplugin.h)
 set(wheelsourceplugin_sources wheelplugin.cpp)
 
index 601824b..a59319b 100644 (file)
@@ -23,7 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 #include <boost/assert.hpp>
 #include <glib.h>
 
-
+#include <gio/gunixinputstream.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -45,12 +45,13 @@ public:
        WheelPrivate();
        ~WheelPrivate();
 
-       int fd;
-       char doShutdown;
-       char isShutdown;
+       void gotData(GAsyncResult *res);
 
 private:
-//     boost::thread pollThread;
+       struct js_event jsEvent;
+       GInputStream *gis;
+       int *axis;
+       char *button;
 
 };
 
@@ -150,48 +151,87 @@ void WheelSourcePlugin::unsubscribeToPropertyChanges(VehicleProperty::Property p
 //PIMPL:
 
 
-void pollJS(WheelPrivate *wp)
+void readCallback(GObject *srcObj, GAsyncResult *res, gpointer userData)
 {
-       if (!wp) {
-               throw std::runtime_error("NULL WheelPrivate in pollJS!");
-               return;
+       if (!userData) {
+               throw std::runtime_error("Got a null WheelPrivate in the Read Callback!");
        }
-       while (!wp->doShutdown) {
-               
-       }
-       wp->isShutdown = 1;
+
+       WheelPrivate *wp = (WheelPrivate *)userData;
+       wp->gotData(res);
+
 }
 
 WheelPrivate::WheelPrivate()
-:fd(-1), isShutdown(0), doShutdown(0)
+:gis(nullptr), axis(nullptr), button(nullptr)
 {
 
-       unsigned char axes = 0;
-       unsigned char buttons = 0;
+       unsigned char numAxes = 0;
+       unsigned char numButtons = 0;
        int version = 0;
+       int fd;
        char name[JSNAMELEN] = "Unknown";
 
 
        //FIXME: Support config file with joystick device mapping, button/axis mappings, etc.
-       if ((this->fd = open("/dev/input/js0", O_RDONLY)) < 0) {
+       if ((fd = open("/dev/input/js0", O_RDONLY)) < 0) {
                throw std::runtime_error("Could not find a joystick class device!");    //FIXME: Later, don't throw, watch input devices, and jump on to any JS devices that appear
                return;
        }
 
        ioctl(fd, JSIOCGVERSION, &version);
-       ioctl(fd, JSIOCGAXES, &axes);
-       ioctl(fd, JSIOCGBUTTONS, &buttons);
+       ioctl(fd, JSIOCGAXES, &numAxes);
+       ioctl(fd, JSIOCGBUTTONS, &numButtons);
        ioctl(fd, JSIOCGNAME(JSNAMELEN), name);
 
        cout << "Driver version: " << (version >> 16) << "." << ((version >> 8) & 0xFF) << "." << (version & 0xFF) << "\n";
        cout << "JS Name: " << name << "\n";
-       cout << "JS Axes/Buttons: " << (int)axes << "/" << (int)buttons << "\n";
-       cout << "Starting polling thread...\n";
+       cout << "JS Axes/Buttons: " << (int)numAxes << "/" << (int)numButtons << "\n";
+       cout << "Converting FD to GIO Input Stream...\n";
+       this->axis = (int *)calloc(numAxes, sizeof(int));
+       this->button = (char *)calloc(numButtons, sizeof(char));
+       this->gis = g_unix_input_stream_new(fd, TRUE);
+       g_input_stream_read_async(this->gis, &this->jsEvent, sizeof(struct js_event), G_PRIORITY_DEFAULT, nullptr, &readCallback, this);
        
 }
 
 WheelPrivate::~WheelPrivate()
 {
-       if (this->fd != -1)
-               close(fd);
+       
+       if (this->gis)
+               g_input_stream_close_async(this->gis, G_PRIORITY_DEFAULT, NULL, NULL, NULL);
+}
+
+void WheelPrivate::gotData(GAsyncResult *res)
+{
+       GError *gerror = NULL;
+       int size = g_input_stream_read_finish(this->gis, res, &gerror);
+
+       if (res < 0) {
+               throw std::runtime_error(gerror->message);
+               g_error_free(gerror);
+       }
+       if (size != sizeof(struct js_event)) {
+               cout << "Only read " << size << " bytes from js device - should have been " << sizeof(struct js_event) << " bytes!";
+               throw std::runtime_error("Bad read from JS device!");
+               return;
+
+       } else {
+               switch (this->jsEvent.type & ~JS_EVENT_INIT) {
+                       case JS_EVENT_BUTTON:
+                               this->button[this->jsEvent.number] = this->jsEvent.value;
+                               cout << "Got button event, btn# " << (int)this->jsEvent.number << ", val " << this->jsEvent.value << "\n";
+                               break;
+                       case JS_EVENT_AXIS:
+                               this->axis[this->jsEvent.number] = this->jsEvent.value;
+                               cout << "Got axis event, axis# " << (int)this->jsEvent.number << ", val " << this->jsEvent.value << "\n";
+                               break;
+                       default:
+                               cout << "Got JS event that wasn't button or axis!\n";
+                               break;
+               }
+       }
+
+       g_input_stream_read_async(this->gis, &this->jsEvent, sizeof(struct js_event), G_PRIORITY_DEFAULT, nullptr, &readCallback, this);
 }
+