From febdc08ebbc6565522be4e4c000bacd260f5c6e0 Mon Sep 17 00:00:00 2001 From: Kevin Krammer Date: Thu, 22 Mar 2012 17:46:17 +0100 Subject: Make QNX virtual keyboard handling main event loop driven Refactor from polling in an endless loop running in a separate thread to using a QSocketNotifier working on the main thread. Backport of 29518b04a619fdd7784e88eebe687fb87ae8a8b5 Change-Id: I8993b874f1543d5e85b0911c81a7a9ec072e5160 Reviewed-by: Sean Harmer Reviewed-by: Robin Burchell --- .../platforms/blackberry/qbbvirtualkeyboard.cpp | 157 ++++++++++----------- .../platforms/blackberry/qbbvirtualkeyboard.h | 19 ++- 2 files changed, 90 insertions(+), 86 deletions(-) diff --git a/src/plugins/platforms/blackberry/qbbvirtualkeyboard.cpp b/src/plugins/platforms/blackberry/qbbvirtualkeyboard.cpp index f32d21a3c5..3022dc8acb 100644 --- a/src/plugins/platforms/blackberry/qbbvirtualkeyboard.cpp +++ b/src/plugins/platforms/blackberry/qbbvirtualkeyboard.cpp @@ -42,6 +42,8 @@ #include "qbbvirtualkeyboard.h" #include +#include +#include #include #include #include @@ -64,18 +66,18 @@ static QBBVirtualKeyboard* s_instance = NULL; // Huge hack for keyboard shadow (see QNX PR 88400). Should be removed ASAP. #define KEYBOARD_SHADOW_HEIGHT 8 -QBBVirtualKeyboard::QBBVirtualKeyboard() : - mEncoder(NULL), - mDecoder(NULL), - mBuffer(NULL), - mHeight(0), - mFd(-1), - mKeyboardMode(Default), - mVisible(false), - mLanguageId(QString::fromLatin1("en")), - mCountryId(QString::fromLatin1("US")) +QBBVirtualKeyboard::QBBVirtualKeyboard() + : mEncoder(0), + mDecoder(0), + mBuffer(0), + mHeight(0), + mFd(-1), + mKeyboardMode(Default), + mVisible(false), + mLanguageId(QString::fromLatin1("en")), + mCountryId(QString::fromLatin1("US")), + mReadNotifier(0) { - connect(); } QBBVirtualKeyboard::~QBBVirtualKeyboard() @@ -88,12 +90,25 @@ QBBVirtualKeyboard& QBBVirtualKeyboard::instance() { if (!s_instance) { s_instance = new QBBVirtualKeyboard(); - s_instance->start(); - } + + // delay invocation of start() to the time the event loop is up and running + // needed to have the QThread internals of the main thread properly initialized + QMetaObject::invokeMethod(s_instance, "start", Qt::QueuedConnection); + } return *s_instance; } +void QBBVirtualKeyboard::start() +{ +#ifdef QBBVIRTUALKEYBOARD_DEBUG + qDebug() << "QBB: starting keyboard event processing"; +#endif + + if (!connect()) + return; +} + /* static */ void QBBVirtualKeyboard::destroy() { @@ -105,35 +120,29 @@ void QBBVirtualKeyboard::destroy() void QBBVirtualKeyboard::close() { - if (mFd) { + delete mReadNotifier; + mReadNotifier = 0; + + if (mFd != -1) { // any reads will fail after we close the fd, which is basically what we want. ::close(mFd); - } - - // Wait for the thread to die (should be immediate), then continue the cleanup. - wait(); - - if (mFd) { mFd = -1; } - - if (mDecoder) - { + if (mDecoder) { pps_decoder_cleanup(mDecoder); delete mDecoder; - mDecoder = NULL; + mDecoder = 0; } - if (mEncoder) - { + if (mEncoder) { pps_encoder_cleanup(mEncoder); delete mEncoder; - mEncoder = NULL; + mEncoder = 0; } delete [] mBuffer; - mBuffer = NULL; + mBuffer = 0; } bool QBBVirtualKeyboard::connect() @@ -165,7 +174,8 @@ bool QBBVirtualKeyboard::connect() if (!queryPPSInfo()) return false; - start(); + mReadNotifier = new QSocketNotifier(mFd, QSocketNotifier::Read); + QObject::connect(mReadNotifier, SIGNAL(activated(int)), this, SLOT(ppsDataReady())); return true; } @@ -192,68 +202,57 @@ void QBBVirtualKeyboard::notifyClientActiveStateChange(bool active) hideKeyboard(); } -void QBBVirtualKeyboard::run() -{ - ppsDataReady(); -} - void QBBVirtualKeyboard::ppsDataReady() { - forever { - ssize_t nread = read(mFd, mBuffer, sBufferSize - 1); + ssize_t nread = qt_safe_read(mFd, mBuffer, sBufferSize - 1); #ifdef QBBVIRTUALKEYBOARD_DEBUG - qDebug() << "QBB: keyboardMessage size: " << nread; + qDebug() << "QBB: keyboardMessage size: " << nread; #endif - if (nread < 0) - break; + if (nread < 0) { + connect(); // reconnect + return; + } - // nread is the real space necessary, not the amount read. - if (static_cast(nread) > sBufferSize - 1) { - qCritical("QBBVirtualKeyboard: Keyboard buffer size too short; need %u.", nread + 1); - break; - } + // nread is the real space necessary, not the amount read. + if (static_cast(nread) > sBufferSize - 1) { + qCritical("QBBVirtualKeyboard: Keyboard buffer size too short; need %u.", nread + 1); + connect(); // reconnect + return; + } - mBuffer[nread] = 0; - pps_decoder_parse_pps_str(mDecoder, mBuffer); - pps_decoder_push(mDecoder, NULL); + mBuffer[nread] = 0; + pps_decoder_parse_pps_str(mDecoder, mBuffer); + pps_decoder_push(mDecoder, NULL); #ifdef QBBVIRTUALKEYBOARD_DEBUG - pps_decoder_dump_tree(mDecoder, stderr); + pps_decoder_dump_tree(mDecoder, stderr); #endif - const char* value; - if (pps_decoder_get_string(mDecoder, "error", &value) == PPS_DECODER_OK) { - qCritical("QBBVirtualKeyboard: Keyboard PPS decoder error: %s", value ? value : "[null]"); - continue; - } - - if (pps_decoder_get_string(mDecoder, "msg", &value) == PPS_DECODER_OK) { - if (strcmp(value, "show") == 0) { - mVisible = true; - handleKeyboardStateChangeMessage(true); - } else if (strcmp(value, "hide") == 0) { - mVisible = false; - handleKeyboardStateChangeMessage(false); - } else if (strcmp(value, "info") == 0) - handleKeyboardInfoMessage(); - else if (strcmp(value, "connect") == 0) { } - else - qCritical("QBBVirtualKeyboard: Unexpected keyboard PPS msg value: %s", value ? value : "[null]"); - } else if (pps_decoder_get_string(mDecoder, "res", &value) == PPS_DECODER_OK) { - if (strcmp(value, "info") == 0) - handleKeyboardInfoMessage(); - else - qCritical("QBBVirtualKeyboard: Unexpected keyboard PPS res value: %s", value ? value : "[null]"); - } else - qCritical("QBBVirtualKeyboard: Unexpected keyboard PPS message type"); + const char* value; + if (pps_decoder_get_string(mDecoder, "error", &value) == PPS_DECODER_OK) { + qCritical("QBBVirtualKeyboard: Keyboard PPS decoder error: %s", value ? value : "[null]"); + return; } -#ifdef QBBVIRTUALKEYBOARD_DEBUG - qDebug() << "QBB: exiting keyboard thread"; -#endif - - if (mDecoder) - pps_decoder_cleanup(mDecoder); + if (pps_decoder_get_string(mDecoder, "msg", &value) == PPS_DECODER_OK) { + if (strcmp(value, "show") == 0) { + mVisible = true; + handleKeyboardStateChangeMessage(true); + } else if (strcmp(value, "hide") == 0) { + mVisible = false; + handleKeyboardStateChangeMessage(false); + } else if (strcmp(value, "info") == 0) + handleKeyboardInfoMessage(); + else if (strcmp(value, "connect") == 0) { } + else + qCritical("QBBVirtualKeyboard: Unexpected keyboard PPS msg value: %s", value ? value : "[null]"); + } else if (pps_decoder_get_string(mDecoder, "res", &value) == PPS_DECODER_OK) { + if (strcmp(value, "info") == 0) + handleKeyboardInfoMessage(); + else + qCritical("QBBVirtualKeyboard: Unexpected keyboard PPS res value: %s", value ? value : "[null]"); + } else + qCritical("QBBVirtualKeyboard: Unexpected keyboard PPS message type"); } void QBBVirtualKeyboard::handleKeyboardInfoMessage() diff --git a/src/plugins/platforms/blackberry/qbbvirtualkeyboard.h b/src/plugins/platforms/blackberry/qbbvirtualkeyboard.h index bedcbe02ce..c0c13d10da 100644 --- a/src/plugins/platforms/blackberry/qbbvirtualkeyboard.h +++ b/src/plugins/platforms/blackberry/qbbvirtualkeyboard.h @@ -42,18 +42,21 @@ #include #include -#include +#include #include #include #include #include +class QSocketNotifier; + QT_BEGIN_NAMESPACE /* Shamelessly copied from the browser - this should be rewritten once we have a proper PPS wrapper class */ -class QBBVirtualKeyboard : QThread +class QBBVirtualKeyboard : public QObject { + Q_OBJECT public: // NOTE: Not all the following keyboard modes are currently used. // Default - Regular Keyboard @@ -80,6 +83,12 @@ public: QString languageId() const { return mLanguageId; } QString countryId() const { return mCountryId; } +public Q_SLOTS: + void start(); + +private Q_SLOTS: + void ppsDataReady(); + private: QBBVirtualKeyboard(); virtual ~QBBVirtualKeyboard(); @@ -93,6 +102,7 @@ private: bool mVisible; QString mLanguageId; QString mCountryId; + QSocketNotifier *mReadNotifier; // Path to keyboardManager in PPS. static const char *sPPSPath; @@ -101,7 +111,6 @@ private: // Will be called internally if needed. bool connect(); void close(); - void ppsDataReady(); bool queryPPSInfo(); void handleKeyboardStateChangeMessage(bool visible); void handleKeyboardInfoMessage(); @@ -115,10 +124,6 @@ private: void addSymbolModeOptions(); void addPhoneModeOptions(); void addPinModeOptions(); - - // QThread overrides - virtual void run(); - }; #endif /* VIRTUALKEYBOARD_H_ */ -- cgit v1.2.1