From fc1802a17bc5c074673cbd2778334cc7ddae9cd8 Mon Sep 17 00:00:00 2001 From: Kalle Viironen Date: Thu, 9 Feb 2012 10:12:33 +0200 Subject: Updated HID drivers for INTEGRITY This patch icnludes new INTEGRITY keyboard and mouse drivers. Task-number:QTBUG-24175 Change-Id: Ifbb01357a601c44bab5961cdfe82d1c7bd44b889 Reviewed-by: Rolland Dudemaine Reviewed-by: Harald Fernengel --- src/gui/embedded/qkbdintegrity_qws.cpp | 245 ++++++++++++++++++++++--------- src/gui/embedded/qmouseintegrity_qws.cpp | 231 +++++++++++++++-------------- 2 files changed, 298 insertions(+), 178 deletions(-) diff --git a/src/gui/embedded/qkbdintegrity_qws.cpp b/src/gui/embedded/qkbdintegrity_qws.cpp index ad4be91..c58c176 100644 --- a/src/gui/embedded/qkbdintegrity_qws.cpp +++ b/src/gui/embedded/qkbdintegrity_qws.cpp @@ -45,10 +45,9 @@ #include #include #include -#include - #include - +#include +#include //=========================================================================== @@ -58,6 +57,70 @@ QT_BEGIN_NAMESPACE // INTEGRITY keyboard // +static const struct KeyMapEntryStruct { + int key; + QChar qchar; +} keyMap[] = { + { 0, 0 }, + { Qt::Key_Escape, 0 }, + { Qt::Key_1, '1' }, + { Qt::Key_2, '2' }, + { Qt::Key_3, '3' }, + { Qt::Key_4, '4' }, + { Qt::Key_5, '5' }, + { Qt::Key_6, '6' }, + { Qt::Key_7, '7' }, + { Qt::Key_8, '8' }, + { Qt::Key_9, '9' }, + { Qt::Key_0, '0' }, + { Qt::Key_Minus, '-' }, + { Qt::Key_Equal, '=' }, + { Qt::Key_Backspace, 0 }, + { Qt::Key_Tab, '\t' }, + { Qt::Key_Q, 'q' }, + { Qt::Key_W, 'w' }, + { Qt::Key_E, 'e' }, + { Qt::Key_R, 'r' }, + { Qt::Key_T, 't' }, + { Qt::Key_Y, 'y' }, + { Qt::Key_U, 'u' }, + { Qt::Key_I, 'i' }, + { Qt::Key_O, 'o' }, + { Qt::Key_P, 'p' }, + { Qt::Key_BraceLeft, '{' }, + { Qt::Key_BraceRight, '}' }, + { Qt::Key_Enter, '\n' }, + { Qt::Key_Control, 0 }, + { Qt::Key_A, 'a' }, + { Qt::Key_S, 's' }, + { Qt::Key_D, 'd' }, + { Qt::Key_F, 'f' }, + { Qt::Key_G, 'g' }, + { Qt::Key_H, 'h' }, + { Qt::Key_J, 'j' }, + { Qt::Key_K, 'k' }, + { Qt::Key_L, 'l' }, + { Qt::Key_Semicolon, ';' }, + { Qt::Key_Apostrophe, '\'' }, + { Qt::Key_Dead_Grave, 0 }, + { Qt::Key_Shift, 0 }, + { Qt::Key_Backslash, '\\' }, + { Qt::Key_Z, 'z' }, + { Qt::Key_X, 'x' }, + { Qt::Key_C, 'c' }, + { Qt::Key_V, 'v' }, + { Qt::Key_B, 'b' }, + { Qt::Key_N, 'n' }, + { Qt::Key_M, 'm' }, + { Qt::Key_Comma, ',' }, + { Qt::Key_NumberSign, '.' }, + { Qt::Key_Slash, '/' }, + { Qt::Key_Shift, 0 }, + { Qt::Key_Asterisk, '*' }, + { Qt::Key_Alt, 0 }, +}; + + class QIntKeyboardListenThread; class QWSIntKbPrivate : public QObject @@ -67,16 +130,13 @@ class QWSIntKbPrivate : public QObject public: QWSIntKbPrivate(QWSKeyboardHandler *, const QString &device); ~QWSIntKbPrivate(); - void dataReady(int amount) { emit kbdDataAvailable(amount); } - uint8_t scancodebuf[32 /* USB_SCANCODE_BUF_LEN */ ]; - uint8_t rxpost; - uint8_t rxack; + void dataReady(uint32_t keycode, bool pressed) { emit kbdDataAvailable(keycode, pressed); } Q_SIGNALS: - void kbdDataAvailable(int amount); + void kbdDataAvailable(uint32_t keycode, bool pressed); private Q_SLOTS: - void readKeyboardData(int amount); + void readKeyboardData(uint32_t keycode, bool pressed); private: QWSKeyboardHandler *handler; @@ -87,11 +147,15 @@ class QIntKeyboardListenThread : public QThread protected: QWSIntKbPrivate *imp; bool loop; + QList handleList; + QList actList; + Semaphore loopsem; public: QIntKeyboardListenThread(QWSIntKbPrivate *im) : QThread(), imp(im) {}; ~QIntKeyboardListenThread() {}; + bool setup(QString driverName, uint32_t index); void run(); - void stoploop() { loop = false; }; + void stoploop() { loop = false; ReleaseSemaphore(loopsem); }; }; @@ -106,78 +170,124 @@ QWSIntKeyboardHandler::~QWSIntKeyboardHandler() delete d; } -//void QWSIntKeyboardHandler::processKeyEvent(int keycode, bool isPress, -// bool autoRepeat) -//{ -// QWSKeyboardHandler::processKeyEvent(keycode, isPress, autoRepeat); -//} +bool QIntKeyboardListenThread::setup(QString driverName, uint32_t index) +{ + int i; + int devices; + Error driverError, deviceError; + HIDDriver *driver; + HIDHandle handle; + /* FIXME : take a list of driver names/indexes for setup */ + devices = 0; + i = 0; + do { + driverError = gh_hid_get_driver(i, &driver); + if (driverError == Success) { + int j = 0; + do { + deviceError = gh_hid_init_device(driver, j, &handle); + if (deviceError == Success) { + int32_t type; + /* only accept non-pointing devices */ + deviceError = gh_hid_get_setting(handle, HID_SETTING_CAPABILITIES, &type); + if ((deviceError == Success) && !(type & HID_TYPE_AXIS)) { + handleList.append(handle); + devices++; + } else + gh_hid_close(handle); + j++; + } + } while (deviceError == Success); + i++; + } + } while (driverError == Success); + return (devices > 0); +} void QIntKeyboardListenThread::run(void) { - Error E; - Buffer b; - Connection kbdc; - bool waitforresource = true; + Value id; + HIDEvent event; + Activity loopact; + QPoint currentpos(0,0); + Qt::MouseButtons currentbutton = Qt::NoButton; + Qt::KeyboardModifiers keymod; + + /* first create all Activities for the main loop. + * We couldn't do this in setup() because this Task is different */ + Activity act; + int i = 0; + foreach (HIDHandle h, handleList) { + CheckSuccess(CreateActivity(CurrentTask(), 2, false, i, &act)); + actList.append(act); + i++; + CheckSuccess(gh_hid_async_wait_for_event(h, act)); + } + + /* setup a Semaphore used to watch for a request for exit */ + CheckSuccess(CreateSemaphore(0, &loopsem)); + CheckSuccess(CreateActivity(CurrentTask(), 2, false, 0, &loopact)); + CheckSuccess(AsynchronousReceive(loopact, (Object)loopsem, NULL)); + + loop = true; do { - E = RequestResource((Object*)&kbdc, - "USBKeyboardClient", "!systempassword"); - if (E == Success) { - loop = false; - } else { - E = RequestResource((Object*)&kbdc, - "KeyboardClient", "!systempassword"); - if (E == Success) { - waitforresource = false; + Boolean nokeynotify = false; + uint32_t num_events = 1; + WaitForActivity(&id); + if (loop) { + while (gh_hid_get_event(handleList.at(id), &event, &num_events) == Success) { + if (event.type == HID_TYPE_KEY) { + switch (event.index) { + case HID_KEY_LEFTALT: + case HID_KEY_RIGHTALT: + if (event.value) + keymod |= Qt::AltModifier; + else + keymod &= ~Qt::AltModifier; + break; + case HID_KEY_LEFTSHIFT: + case HID_KEY_RIGHTSHIFT: + if (event.value) + keymod |= Qt::ShiftModifier; + else + keymod &= ~Qt::ShiftModifier; + break; + case HID_KEY_LEFTCTRL: + case HID_KEY_RIGHTCTRL: + if (event.value) + keymod |= Qt::ControlModifier; + else + keymod &= ~Qt::ControlModifier; + break; + default: + break; + } + QEvent::Type type; + if (event.value) + type = QEvent::KeyPress; + else + type = QEvent::KeyRelease; + //QWindowSystemInterface::handleKeyEvent(0, type, + //keyMap[event.index].key, keymod, keyMap[event.index].qchar); + imp->dataReady(event.index, event.value); + } } - } - if (waitforresource) - ::sleep(1); - } while (loop && waitforresource); - if (!loop) - return; - b.BufferType = DataBuffer | LastBuffer; - b.Length = sizeof(imp->scancodebuf); - b.TheAddress = (Address)imp->scancodebuf; - do { - b.Transferred = 0; - b.TheAddress = (Address)imp->scancodebuf + imp->rxpost; - CheckSuccess(SynchronousReceive(kbdc, &b)); - imp->rxpost += b.Transferred; - if (imp->rxpost >= 32 /* USB_SCANCODE_BUF_LEN */) - imp->rxpost = 0; - if (imp->rxpost == (imp->rxack + b.Transferred) % 32 /* USB_SCANCODE_BUF_LEN */) { - imp->kbdDataAvailable(b.Transferred); + CheckSuccess(gh_hid_async_wait_for_event(handleList.at(id), actList.at(id))); } } while (loop); + QThread::exit(0); } -void QWSIntKbPrivate::readKeyboardData(int amount) +void QWSIntKbPrivate::readKeyboardData(uint32_t keycode, bool pressed) { - uint16_t keycode; - do { - if (scancodebuf[rxack] == 0xe0) { - keycode = scancodebuf[rxack] << 8; - rxack++; - if (rxack >= 32 /* USB_SCANCODE_BUF_LEN */) - rxack = 0; - } else { - keycode = 0; - } - - handler->processKeycode(keycode + (scancodebuf[rxack] & 0x7f), - (scancodebuf[rxack] & 0x80) == 0, - scancodebuf[rxack] == 2); - rxack++; - if (rxack >= 32 /* USB_SCANCODE_BUF_LEN */) - rxack = 0; - } while (rxack != rxpost); + handler->processKeycode(keycode, pressed, false); } QWSIntKbPrivate::QWSIntKbPrivate(QWSKeyboardHandler *h, const QString &device) : handler(h) { - connect(this, SIGNAL(kbdDataAvailable(int)), this, SLOT(readKeyboardData(int))); + connect(this, SIGNAL(kbdDataAvailable(uint32_t, bool)), this, SLOT(readKeyboardData(uint32_t, bool))); this->handler = handler; - rxack = rxpost = 0; + qDebug("Opening INTEGRITY keyboard"); kbdthread = new QIntKeyboardListenThread(this); kbdthread->start(); } @@ -189,7 +299,6 @@ QWSIntKbPrivate::~QWSIntKbPrivate() delete kbdthread; } - QT_END_NAMESPACE #include "qkbdintegrity_qws.moc" diff --git a/src/gui/embedded/qmouseintegrity_qws.cpp b/src/gui/embedded/qmouseintegrity_qws.cpp index e7f1c51..939a598 100644 --- a/src/gui/embedded/qmouseintegrity_qws.cpp +++ b/src/gui/embedded/qmouseintegrity_qws.cpp @@ -45,24 +45,11 @@ #include #include #include -#include - #include +#include -typedef Address MOUSEHandler; -typedef struct MOUSEMessageStruct -{ - Value x; - Value y; - Value z; - Value buttons; -} MOUSEMessage; - -static Error MOUSE_Init(MOUSEHandler *handler, Boolean *isabsolute); -static Error MOUSE_SynchronousGetPosition(MOUSEHandler handler, MOUSEMessage *msg, - Boolean absolute); -static Error MOUSE_ShouldFilter(MOUSEHandler handler, Boolean *filter); +#include QT_BEGIN_NAMESPACE @@ -82,7 +69,6 @@ public: bool waitforread; bool suspended; QIntMouseListenThread *mousethread; - private: QIntMouseHandler *handler; }; @@ -92,14 +78,17 @@ class QIntMouseListenThread : public QThread protected: QIntMousePrivate *imp; bool loop; + QList handleList; + QList actList; + Semaphore loopsem; public: QIntMouseListenThread(QIntMousePrivate *im) : QThread(), imp(im) {}; ~QIntMouseListenThread() {}; void run(); - void stoploop() { loop = false; }; + bool setup(QString driverName, uint32_t index); + void stoploop() { loop = false; ReleaseSemaphore(loopsem); }; }; - QIntMouseHandler::QIntMouseHandler(const QString &driver, const QString &device) : QObject(), QWSCalibratedMouseHandler(driver, device) { @@ -109,6 +98,7 @@ QIntMouseHandler::QIntMouseHandler(const QString &driver, const QString &device) d->calibrated = (test != transform(test)); + d->mousethread->setup(QString(), 0); d->mousethread->start(); } @@ -133,9 +123,9 @@ void QIntMouseHandler::readMouseData(int x, int y, int buttons) d->waitforread = false; if (d->suspended) return; - if (d->calibrated) { + if (d->calibrated) sendFiltered(QPoint(x, y), buttons); - } else { + else { QPoint pos; pos = transform(QPoint(x, y)); limitToScreen(pos); @@ -153,27 +143,125 @@ void QIntMouseHandler::calibrate(const QWSPointerCalibrationData *data) QWSCalibratedMouseHandler::calibrate(data); } +bool QIntMouseListenThread::setup(QString driverName, uint32_t index) +{ + int i; + int devices; + Error driverError, deviceError; + HIDDriver *driver; + HIDHandle handle; + /* FIXME : take a list of driver names/indexes for setup */ + devices = 0; + i = 0; + do { + driverError = gh_hid_get_driver(i, &driver); + if (driverError == Success) { + int j = 0; + do { + deviceError = gh_hid_init_device(driver, j, &handle); + if (deviceError == Success) { + int32_t type; + /* only accept pointing devices */ + deviceError = gh_hid_get_setting(handle, HID_SETTING_CAPABILITIES, &type); + if ((deviceError == Success) && (type & HID_TYPE_AXIS)) { + handleList.append(handle); + devices++; + } else + gh_hid_close(handle); + j++; + } + } while (deviceError == Success); + i++; + } + } while (driverError == Success); + return (devices > 0); +} + void QIntMouseListenThread::run(void) { - MOUSEHandler handler; - MOUSEMessage msg; - Boolean filter; - Boolean isabsolute; + Value id; + HIDEvent event; + Activity loopact; + QPoint currentpos(0,0); + Qt::MouseButtons currentbutton = Qt::NoButton; + Qt::KeyboardModifiers keymod; + + /* first create all Activities for the main loop. + * We couldn't do this in setup() because this Task is different */ + Activity act; + int i = 0; + foreach (HIDHandle h, handleList) { + CheckSuccess(CreateActivity(CurrentTask(), 2, false, i, &act)); + actList.append(act); + i++; + CheckSuccess(gh_hid_async_wait_for_event(h, act)); + } + + /* setup a Semaphore used to watch for a request for exit */ + CheckSuccess(CreateSemaphore(0, &loopsem)); + CheckSuccess(CreateActivity(CurrentTask(), 2, false, 0, &loopact)); + CheckSuccess(AsynchronousReceive(loopact, (Object)loopsem, NULL)); + loop = true; - CheckSuccess(MOUSE_Init(&handler, &isabsolute)); - CheckSuccess(MOUSE_ShouldFilter(handler, &filter)); - if (!filter) - imp->calibrated = false; - imp->waitforread = false; do { - MOUSE_SynchronousGetPosition(handler, &msg, isabsolute); - imp->dataReady(msg.x, msg.y, msg.buttons); + uint32_t num_events = 1; + + WaitForActivity(&id); + if (loop) { + while (gh_hid_get_event(handleList.at(id), &event, &num_events) == Success) { + if (event.type == HID_TYPE_AXIS) { + switch (event.index) { + case HID_AXIS_ABSX: + currentpos.setX(event.value); + break; + case HID_AXIS_ABSY: + currentpos.setY(event.value); + break; + case HID_AXIS_RELX: + currentpos.setX(currentpos.x() + event.value); + break; + case HID_AXIS_RELY: + currentpos.setY(currentpos.y() + event.value); + break; + default: + break; + } + } else if (event.type == HID_TYPE_KEY) { + switch (event.index) { + case HID_BUTTON_LEFT: + if (event.value) + currentbutton |= Qt::LeftButton; + else + currentbutton &= ~Qt::LeftButton; + break; + case HID_BUTTON_MIDDLE: + if (event.value) + currentbutton |= Qt::MiddleButton; + else + currentbutton &= ~Qt::MiddleButton; + break; + case HID_BUTTON_RIGHT: + if (event.value) + currentbutton |= Qt::RightButton; + else + currentbutton &= ~Qt::RightButton; + break; + } + } else if (event.type == HID_TYPE_SYNC) { + /* sync events are sent by mouses and not by keyboards. + * this should probably be changed */ + imp->dataReady(currentpos.x(), currentpos.y(), currentbutton); + //QWindowSystemInterface::handleMouseEvent(0, currentpos, currentpos, currentbutton); + } + } + CheckSuccess(gh_hid_async_wait_for_event(handleList.at(id), actList.at(id))); + } } while (loop); + CloseSemaphore(loopsem); QThread::exit(0); } -QIntMousePrivate::QIntMousePrivate(QIntMouseHandler *handler) - : QObject() +QIntMousePrivate::QIntMousePrivate(QIntMouseHandler *handler) : QObject() { this->handler = handler; suspended = false; @@ -191,81 +279,4 @@ QT_END_NAMESPACE #include "qmouseintegrity_qws.moc" -typedef struct USBMouseStruct -{ - Connection mouseconn; - Buffer mousemsg[2]; - Value x; - Value y; -} USBMouse; - -USBMouse mousedev; - -Error MOUSE_Init(MOUSEHandler *handler, Boolean *isabsolute) -{ - Error E; - bool loop = true; - memset((void*)&mousedev, 0, sizeof(USBMouse)); - mousedev.mousemsg[0].BufferType = DataImmediate; - mousedev.mousemsg[1].BufferType = DataImmediate | LastBuffer; - do { - E = RequestResource((Object*)&mousedev.mouseconn, - "MouseClient", "!systempassword"); - if (E == Success) { - *isabsolute = true; - loop = false; - } else { - E = RequestResource((Object*)&mousedev.mouseconn, - "USBMouseClient", "!systempassword"); - if (E == Success) { - *isabsolute = false; - loop = false; - } - } - if (loop) - sleep(1); - } while (loop); - *handler = (MOUSEHandler)&mousedev; - return Success; -} - -Error MOUSE_SynchronousGetPosition(MOUSEHandler handler, MOUSEMessage *msg, - Boolean isabsolute) -{ - signed long x; - signed long y; - USBMouse *mdev = (USBMouse *)handler; - mdev->mousemsg[0].Transferred = 0; - mdev->mousemsg[1].Transferred = 0; - SynchronousReceive(mdev->mouseconn, mdev->mousemsg); - if (isabsolute) { - x = (signed long)mdev->mousemsg[0].Length; - y = (signed long)mdev->mousemsg[1].TheAddress; - } else { - x = mdev->x + (signed long)mdev->mousemsg[0].Length; - y = mdev->y + (signed long)mdev->mousemsg[1].TheAddress; - } - if (x < 0) - mdev->x = 0; - else - mdev->x = x; - if (y < 0) - mdev->y = 0; - else - mdev->y = y; - msg->x = mdev->x; - msg->y = mdev->y; - msg->buttons = mdev->mousemsg[0].TheAddress; - return Success; -} - -Error MOUSE_ShouldFilter(MOUSEHandler handler, Boolean *filter) -{ - if (filter == NULL) - return Failure; - *filter = false; - return Success; -} - #endif // QT_NO_QWS_MOUSE_INTEGRITY - -- cgit v0.12