]> git.zarvox.org Git - libtouchmouse.git/commitdiff
Reorganize directory tree, add a Qt graphical demo.
authorDrew Fisher <drew.m.fisher@gmail.com>
Fri, 11 Nov 2011 23:25:18 +0000 (15:25 -0800)
committerDrew Fisher <drew.m.fisher@gmail.com>
Fri, 11 Nov 2011 23:25:18 +0000 (15:25 -0800)
I'll probably have to redo some more CMake stuff to make the Qt demo
optional.

Signed-off-by: Drew Fisher <drew.m.fisher@gmail.com>
14 files changed:
CMakeLists.txt
examples/CMakeLists.txt [new file with mode: 0644]
examples/consoledemo/CMakeLists.txt [new file with mode: 0644]
examples/consoledemo/consoledemo.c [moved from examples/consoledemo.c with 99% similarity]
examples/qtview/CMakeLists.txt [new file with mode: 0644]
examples/qtview/main.cpp [new file with mode: 0644]
examples/qtview/mousepoller.cpp [new file with mode: 0644]
examples/qtview/mousepoller.h [new file with mode: 0644]
examples/qtview/mousethread.cpp [new file with mode: 0644]
examples/qtview/mousethread.h [new file with mode: 0644]
examples/qtview/mouseviewer.cpp [new file with mode: 0644]
examples/qtview/mouseviewer.h [new file with mode: 0644]
libtouchmouse/libtouchmouse.h
src/touchmouse.c

index a799fe487a44e28971449dea25e4255fb5bcf7dc..570592fceadf3dd1f140307a364ac8f76dcb22a1 100644 (file)
@@ -35,13 +35,10 @@ set(CMAKE_C_FLAGS "-Wall -ggdb")
 # Build library
 add_library(touchmouse SHARED ${LIBSRC})
 
-# Build demo
-add_executable(consoledemo examples/consoledemo.c)
 if(WIN32)
        target_link_libraries(touchmouse setupapi)
-       target_link_libraries(consoledemo touchmouse setupapi)
-elseif(NOT APPLE)
-       target_link_libraries(consoledemo touchmouse usb-1.0 pthread rt)
-else()
-       target_link_libraries(consoledemo touchmouse)
 endif()
+
+# Build examples
+add_subdirectory(examples)
+
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
new file mode 100644 (file)
index 0000000..df42089
--- /dev/null
@@ -0,0 +1,4 @@
+
+add_subdirectory(consoledemo)
+add_subdirectory(qtview)
+
diff --git a/examples/consoledemo/CMakeLists.txt b/examples/consoledemo/CMakeLists.txt
new file mode 100644 (file)
index 0000000..cebf5d1
--- /dev/null
@@ -0,0 +1,10 @@
+
+add_executable(consoledemo consoledemo.c)
+if(WIN32)
+       target_link_libraries(consoledemo touchmouse setupapi)
+elseif(NOT APPLE)
+       target_link_libraries(consoledemo touchmouse usb-1.0 pthread rt)
+else()
+       target_link_libraries(consoledemo touchmouse)
+endif()
+
similarity index 99%
rename from examples/consoledemo.c
rename to examples/consoledemo/consoledemo.c
index 78fc0dc09fe5e707a4b1d359f091fa1773a0995c..220257090885c95e55a9fd57903270723a3402e7 100644 (file)
@@ -81,7 +81,7 @@ int main(void) {
        }
 
        // Poll device for image updates.
-       int i;
+       int i = 0;
        while(i < 100) {
                res = touchmouse_process_events_timeout(dev, -1); // -1 means infinite timeout
                i++;
diff --git a/examples/qtview/CMakeLists.txt b/examples/qtview/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8e7a2f4
--- /dev/null
@@ -0,0 +1,20 @@
+
+find_package(Qt4 REQUIRED QtCore QtGui)
+include(${QT_USE_FILE})
+include_directories(${QT_INCLUDES})
+
+set (QTVIEW_HEADERS mousepoller.h mouseviewer.h)
+set (QTVIEW_SOURCES mousepoller.cpp mouseviewer.cpp main.cpp)
+
+QT4_WRAP_CPP(QTVIEW_MOC_OUTFILES ${QTVIEW_HEADERS} )
+
+add_executable(qtview ${QTVIEW_SOURCES} ${QTVIEW_MOC_OUTFILES})
+if(WIN32)
+       target_link_libraries(qtview touchmouse ${QT_LIBRARIES} setupapi)
+elseif(NOT APPLE)
+       target_link_libraries(qtview touchmouse ${QT_LIBRARIES} usb-1.0 pthread rt)
+else()
+       target_link_libraries(qtview touchmouse ${QT_LIBRARIES})
+endif()
+
+
diff --git a/examples/qtview/main.cpp b/examples/qtview/main.cpp
new file mode 100644 (file)
index 0000000..6113a32
--- /dev/null
@@ -0,0 +1,20 @@
+#include <QApplication>
+#include "mousepoller.h"
+#include "mouseviewer.h"
+
+int main(int argc, char** argv) {
+       QApplication* app = new QApplication(argc, argv);
+
+       MousePoller* poller = new MousePoller();
+
+       MouseViewer* viewer = new MouseViewer();
+       QObject::connect(poller, SIGNAL(mouseUpdate(QByteArray,QDateTime)),
+                       viewer, SLOT(imageUpdate(QByteArray,QDateTime)));
+       viewer->resize(15 * 12, 13 * 12 );
+       viewer->show();
+       poller->startPolling();
+       
+       int retval = app->exec();
+       poller->stopPolling();
+       return retval;
+}
diff --git a/examples/qtview/mousepoller.cpp b/examples/qtview/mousepoller.cpp
new file mode 100644 (file)
index 0000000..12fc9a8
--- /dev/null
@@ -0,0 +1,110 @@
+#include "mousepoller.h"
+#include <QTimer>
+#include <libtouchmouse/libtouchmouse.h>
+#include <QDebug>
+
+MousePoller::MousePoller(int index, QObject* parent) : QObject(parent) {
+       touchmouse_okay = false;
+       timer = new QTimer(this);
+       timer->setInterval(1);
+       connect(timer, SIGNAL(timeout()),
+                       this, SLOT(pollMouse()));
+       int res;
+       res = touchmouse_init();
+       if (res != 0) {
+               qDebug() << "Failed to initialize libtouchmouse";
+       }
+       int devs_found = 0;
+       touchmouse_device_info* devs = touchmouse_enumerate_devices();
+       touchmouse_device_info* d = devs;
+       while(d) {
+               d = d->next;
+               devs_found++;
+       }
+       if (devs_found < index) {
+               qDebug() << "Didn't see enough Touchmouse devices to open device" << index;
+               touchmouse_free_enumeration(devs);
+               return;
+       }
+       dev = NULL;
+       d = devs;
+       for(int i = 0; i < index ; i++) {
+               d = d->next;
+       }
+       res = touchmouse_open(&dev, d);
+       touchmouse_free_enumeration(devs);
+       if (res != 0) {
+               qDebug() << "Failed to open Touchmouse device";
+               return;
+       }
+       res = touchmouse_set_image_update_callback(dev, MousePoller::callback);
+       if (res != 0) {
+               qDebug() << "Failed to set Touchmouse device to full updates mode";
+               return;
+       }
+       res = touchmouse_set_device_userdata(dev, this);
+       if (res != 0) {
+               qDebug() << "Failed to set device userdata";
+               return;
+       }
+       touchmouse_okay = true;
+}
+
+MousePoller::~MousePoller() {
+       touchmouse_close(dev);
+       touchmouse_shutdown();
+}
+
+void MousePoller::callback(touchmouse_callback_info *cbdata) {
+       //qDebug() << "static callback triggered";
+       MousePoller* poller = static_cast<MousePoller*>(cbdata->userdata);
+       poller->memberCallback(cbdata);
+}
+
+void MousePoller::memberCallback(touchmouse_callback_info *cbdata) {
+       QByteArray ba((const char*)cbdata->image, 195);
+       // TODO: aggregate timestamps using mouse clock for precision.
+       QDateTime timestamp = QDateTime::currentDateTime();
+       emit mouseUpdate(ba, timestamp);
+}
+
+void MousePoller::pollMouse() {
+       int res;
+       res = touchmouse_process_events_timeout(dev, 0);
+       if (res < 0) {
+               if (res != -1) // -1 is returned on recoverable errors, -2 is a fatal hid_read failure
+                       // TODO: make an error enumeration
+                       touchmouse_okay = false;
+       }
+}
+
+void MousePoller::startPolling() {
+       if (touchmouse_okay) {
+               int res;
+               res = touchmouse_set_device_mode(dev, TOUCHMOUSE_RAW_IMAGE);
+               if (res != 0) {
+                       qDebug() << "Failed to enable full image updates";
+                       touchmouse_okay = false;
+                       return;
+               }
+               timer->start();
+       } else {
+               qDebug() << "MousePoller::startPolling() called, but libtouchmouse not okay";
+       }
+}
+
+void MousePoller::stopPolling() {
+       if (touchmouse_okay) {
+               int res;
+               res = touchmouse_set_device_mode(dev, TOUCHMOUSE_DEFAULT);
+               if (res != 0) {
+                       qDebug() << "Failed to disable full image updates";
+                       touchmouse_okay = false;
+                       return;
+               }
+               timer->stop();
+       } else {
+               qDebug() << "MousePoller::stopPolling() called, but libtouchmouse not okay";
+       }
+}
+
diff --git a/examples/qtview/mousepoller.h b/examples/qtview/mousepoller.h
new file mode 100644 (file)
index 0000000..9a2a7d4
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef __MOUSEPOLLER_H__
+#define __MOUSEPOLLER_H__
+
+#include <QObject>
+#include <QByteArray>
+#include <QDateTime>
+#include <libtouchmouse/libtouchmouse.h>
+
+class QTimer;
+
+class MousePoller : public QObject {
+       Q_OBJECT
+public:
+       MousePoller(int index = 0, QObject* parent = 0);
+       ~MousePoller();
+       static void callback(touchmouse_callback_info *cbdata);
+       void memberCallback(touchmouse_callback_info* cbdata);
+
+public slots:
+       void startPolling();
+       void stopPolling();
+       void pollMouse();
+
+signals:
+       void mouseUpdate(QByteArray image, QDateTime timestamp);
+
+private:
+       QTimer* timer;
+       touchmouse_device *dev;
+       bool touchmouse_okay;
+};
+
+#endif // __MOUSEPOLLER_H__
diff --git a/examples/qtview/mousethread.cpp b/examples/qtview/mousethread.cpp
new file mode 100644 (file)
index 0000000..1e4425d
--- /dev/null
@@ -0,0 +1,8 @@
+#include "mousethread.h"
+
+MouseThread::MouseThread(QObject* parent) : QThread(parent) {
+       shutdownRequested = false;
+       moveToThread(this);
+}
+
+
diff --git a/examples/qtview/mousethread.h b/examples/qtview/mousethread.h
new file mode 100644 (file)
index 0000000..342f10a
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef __MOUSETHREAD_H__
+#define __MOUSETHREAD_H__
+
+#include <QThread>
+
+class MouseThread : public QThread {
+       Q_OBJECT
+public:
+       MouseThread(QObject* parent = 0);
+       ~MouseThread();
+
+       void run();
+public slots:
+       void shutdown();
+private:
+       bool shutdownRequested;
+};
+
+#endif // __MOUSETHREAD_H__
+
diff --git a/examples/qtview/mouseviewer.cpp b/examples/qtview/mouseviewer.cpp
new file mode 100644 (file)
index 0000000..d91c79d
--- /dev/null
@@ -0,0 +1,39 @@
+#include "mouseviewer.h"
+#include <QPainter>
+#include <QPaintEvent>
+#include <QDebug>
+
+MouseViewer::MouseViewer(QWidget* parent) : QWidget(parent) {
+       lastImage.resize(195);
+       // Blank initial image
+       for(int i = 0 ; i < 195; i++) {
+               lastImage[i] = 0;
+       }
+}
+
+MouseViewer::~MouseViewer() {
+
+}
+
+void MouseViewer::paintEvent(QPaintEvent* e) {
+       Q_UNUSED(e)
+       QPainter p(this);
+       if (lastImage.size() == 195) {
+               for(int row = 0; row < 13; row++) {
+                       for(int col = 0; col < 15 ; col++) {
+                               unsigned char value = uchar(lastImage[row*15 + col]);
+                               QColor c(value, value, value);
+                               p.setBrush(c);
+                               p.drawRect(width() * col / 15, height() * row / 13, width() / 15, height() / 13);
+                       }
+               }
+       } else {
+               qDebug() << "paintEvent, but no image yet";
+       }
+}
+
+void MouseViewer::imageUpdate(QByteArray image, QDateTime timestamp) {
+       // Ignoring timestamp, lah de dah
+       lastImage = image;
+       update();
+}
diff --git a/examples/qtview/mouseviewer.h b/examples/qtview/mouseviewer.h
new file mode 100644 (file)
index 0000000..16167b7
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef __MOUSEVIEWER_H__
+#define __MOUSEVIEWER_H__
+
+#include <QWidget>
+#include <QByteArray>
+#include <QDateTime>
+
+class QPaintEvent;
+
+class MouseViewer : public QWidget {
+       Q_OBJECT
+public:
+       MouseViewer(QWidget* parent = 0);
+       ~MouseViewer();
+       void paintEvent(QPaintEvent* e);
+public slots:
+       void imageUpdate(QByteArray image, QDateTime timestamp);
+private:
+       QByteArray lastImage;
+};
+
+#endif // __MOUSEVIEWER_H__
index 1d38ea17600c6663b2cd81cc99d790cbda483924..9655e47d5c1ad176842853c795baceed9b052fc8 100644 (file)
        #endif
 #endif
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 // Types:
 struct touchmouse_device_;
 typedef struct touchmouse_device_ touchmouse_device;
@@ -65,4 +69,8 @@ TOUCHMOUSEAPI int touchmouse_set_device_userdata(touchmouse_device *dev, void *u
 // milliseconds > 0 means "fetch data.  Trigger a callback if the data arrives within <arg> milliseconds, otherwise return."
 TOUCHMOUSEAPI int touchmouse_process_events_timeout(touchmouse_device *dev, int milliseconds);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* __LIBTOUCHMOUSE_H__ */
index 765802d5d167d67df643941c0c74ca3b000033b6..8202ce2f895d74c813400c74cedb4b7eebef1a9e 100644 (file)
@@ -341,6 +341,7 @@ int touchmouse_process_events_timeout(touchmouse_device *dev, int milliseconds)
        uint64_t deadline;
        if(milliseconds == -1) {
                deadline = (uint64_t)(-1);
+               printf("Got infinite timeout\n");
        } else {
                deadline = mono_timer_nanos() + (milliseconds * 1000000);
        }
@@ -353,25 +354,25 @@ int touchmouse_process_events_timeout(touchmouse_device *dev, int milliseconds)
                res = hid_read_timeout(dev->dev, data, 255, (deadline - nanos) / 1000000 );
                if (res < 0 ) {
                        fprintf(stderr, "hid_read() failed: %d\n", res);
-                       return -1;
+                       return -2;
                } else if (res > 0) {
                        // Dump contents of transfer
-                       printf("Got reply: %d bytes:", res);
-                       int j;
-                       for(j = 0; j < res; j++) {
-                               printf(" %02X", data[j]);
-                       }
-                       printf("\n");
+                       //printf("Got reply: %d bytes:", res);
+                       //int j;
+                       //for(j = 0; j < res; j++) {
+                       //      printf(" %02X", data[j]);
+                       //}
+                       //printf("\n");
                        // Interpret contents.
                        report* r = (report*)data;
                        // We only care about report ID 39 (0x27), which should be 32 bytes long
                        if (res == 32 && r->report_id == 0x27) {
-                               printf("Timestamp: %02X\t%02X bytes:", r->timestamp, r->length - 1);
+                               //printf("Timestamp: %02X\t%02X bytes:", r->timestamp, r->length - 1);
                                int t;
-                               for(t = 0; t < r->length - 1; t++) {
-                                       printf(" %02X", r->data[t]);
-                               }
-                               printf("\n");
+                               //for(t = 0; t < r->length - 1; t++) {
+                               //      printf(" %02X", r->data[t]);
+                               //}
+                               //printf("\n");
                                // Reset the decoder if we've seen one timestamp already from earlier
                                // transfers, and this one doesn't match.
                                if (first_timestamp_read && r->timestamp != last_timestamp) {
@@ -394,7 +395,7 @@ int touchmouse_process_events_timeout(touchmouse_device *dev, int milliseconds)
                                                return 0;
                                        }
                                        if (res == DECODER_ERROR) {
-                                               fprintf(stderr, "Caught error in decoder, aborting!\n");
+                                               fprintf(stderr, "Caught error in decoder, aborting decode!\n");
                                                reset_decoder(dev);
                                                return -1;
                                        }
@@ -410,7 +411,7 @@ int touchmouse_process_events_timeout(touchmouse_device *dev, int milliseconds)
                                                return 0;
                                        }
                                        if (res == DECODER_ERROR) {
-                                               fprintf(stderr, "Caught error in decoder, aborting!\n");
+                                               fprintf(stderr, "Caught error in decoder, aborting decode!\n");
                                                reset_decoder(dev);
                                                return -1;
                                        }