summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp
diff options
context:
space:
mode:
authorKevin Krammer <kevin.krammer.qnx@kdab.com>2012-03-22 13:54:00 +0100
committerQt by Nokia <qt-info@nokia.com>2012-03-22 16:47:06 +0100
commit29518b04a619fdd7784e88eebe687fb87ae8a8b5 (patch)
treefdca58a2cd29a33e7c4100d2111025118aeb1692 /src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp
parent1a414cbc2664621431028593ea7b6de3e730d556 (diff)
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. Similar to "de-threading" of the navigator event handling in 9dc86ac0f2d019f93665c1ae0e3c2cd33fd88bce Change-Id: I994dceed07312a3846737c8bea34cffa4ab408f1 Reviewed-by: Sean Harmer <sh@theharmers.co.uk> Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
Diffstat (limited to 'src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp')
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp165
1 files changed, 81 insertions, 84 deletions
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp b/src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp
index 9d7fe92660..20c89d3e32 100644
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp
+++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp
@@ -46,6 +46,8 @@
#include <QtGui/QPlatformWindow>
#include <QtCore/QDebug>
+#include <QtCore/QSocketNotifier>
+#include <QtCore/private/qcore_unix_p.h>
#include <errno.h>
#include <fcntl.h>
@@ -65,17 +67,17 @@ static QQnxVirtualKeyboard *s_instance = 0;
// Huge hack for keyboard shadow (see QNX PR 88400). Should be removed ASAP.
#define KEYBOARD_SHADOW_HEIGHT 8
-QQnxVirtualKeyboard::QQnxVirtualKeyboard() :
- m_encoder(NULL),
- m_decoder(NULL),
- m_buffer(NULL),
- m_height(0),
- m_fd(-1),
- m_keyboardMode(Default),
- m_visible(false),
- m_locale(QLatin1String("en_US"))
+QQnxVirtualKeyboard::QQnxVirtualKeyboard()
+ : m_encoder(0),
+ m_decoder(0),
+ m_buffer(0),
+ m_height(0),
+ m_fd(-1),
+ m_keyboardMode(Default),
+ m_visible(false),
+ m_locale(QLatin1String("en_US")),
+ m_readNotifier(0)
{
- connect();
}
QQnxVirtualKeyboard::~QQnxVirtualKeyboard()
@@ -88,12 +90,24 @@ QQnxVirtualKeyboard& QQnxVirtualKeyboard::instance()
{
if (!s_instance) {
s_instance = new QQnxVirtualKeyboard();
- 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 QQnxVirtualKeyboard::start()
+{
+#ifdef QQNXVIRTUALKEYBOARD_DEBUG
+ qDebug() << "QQNX: starting keyboard event processing";
+#endif
+ if (!connect())
+ return;
+}
+
/* static */
void QQnxVirtualKeyboard::destroy()
{
@@ -105,35 +119,28 @@ void QQnxVirtualKeyboard::destroy()
void QQnxVirtualKeyboard::close()
{
- if (m_fd) {
- // any reads will fail after we close the fd, which is basically what we want.
- ::close(m_fd);
- }
-
- // Wait for the thread to die (should be immediate), then continue the cleanup.
- wait();
+ delete m_readNotifier;
+ m_readNotifier = 0;
- if (m_fd) {
+ if (m_fd != -1) {
+ ::close(m_fd);
m_fd = -1;
}
-
- if (m_decoder)
- {
+ if (m_decoder) {
pps_decoder_cleanup(m_decoder);
delete m_decoder;
- m_decoder = NULL;
+ m_decoder = 0;
}
- if (m_encoder)
- {
+ if (m_encoder) {
pps_encoder_cleanup(m_encoder);
delete m_encoder;
- m_encoder = NULL;
+ m_encoder = 0;
}
delete [] m_buffer;
- m_buffer = NULL;
+ m_buffer = 0;
}
bool QQnxVirtualKeyboard::connect()
@@ -165,7 +172,8 @@ bool QQnxVirtualKeyboard::connect()
if (!queryPPSInfo())
return false;
- start();
+ m_readNotifier = new QSocketNotifier(m_fd, QSocketNotifier::Read);
+ QObject::connect(m_readNotifier, SIGNAL(activated(int)), this, SLOT(ppsDataReady()));
return true;
}
@@ -192,74 +200,63 @@ void QQnxVirtualKeyboard::notifyClientActiveStateChange(bool active)
hideKeyboard();
}
-void QQnxVirtualKeyboard::run()
-{
- ppsDataReady();
-}
-
void QQnxVirtualKeyboard::ppsDataReady()
{
- while (1) {
- ssize_t nread = read(m_fd, m_buffer, ms_bufferSize - 1);
+ ssize_t nread = qt_safe_read(m_fd, m_buffer, ms_bufferSize - 1);
#ifdef QQNXVIRTUALKEYBOARD_DEBUG
- qDebug() << "QQNX: keyboardMessage size: " << nread;
+ qDebug() << "QQNX: 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<size_t>(nread) > ms_bufferSize - 1) {
- qCritical("QQnxVirtualKeyboard: Keyboard buffer size too short; need %u.", nread + 1);
- break;
- }
+ // nread is the real space necessary, not the amount read.
+ if (static_cast<size_t>(nread) > ms_bufferSize - 1) {
+ qCritical("QQnxVirtualKeyboard: Keyboard buffer size too short; need %u.", nread + 1);
+ connect(); // reconnect
+ return;
+ }
- m_buffer[nread] = 0;
- pps_decoder_parse_pps_str(m_decoder, m_buffer);
- pps_decoder_push(m_decoder, NULL);
+ m_buffer[nread] = 0;
+ pps_decoder_parse_pps_str(m_decoder, m_buffer);
+ pps_decoder_push(m_decoder, NULL);
#ifdef QQNXVIRTUALKEYBOARD_DEBUG
- pps_decoder_dump_tree(m_decoder, stderr);
+ pps_decoder_dump_tree(m_decoder, stderr);
#endif
- const char *value;
- if (pps_decoder_get_string(m_decoder, "error", &value) == PPS_DECODER_OK) {
- qCritical("QQnxVirtualKeyboard: Keyboard PPS decoder error: %s", value ? value : "[null]");
- continue;
- }
-
- if (pps_decoder_get_string(m_decoder, "msg", &value) == PPS_DECODER_OK) {
- if (strcmp(value, "show") == 0) {
- const bool oldVisible = m_visible;
- m_visible = true;
- handleKeyboardStateChangeMessage(true);
- if (oldVisible != m_visible)
- emit visibilityChanged(m_visible);
- } else if (strcmp(value, "hide") == 0) {
- const bool oldVisible = m_visible;
- m_visible = false;
- handleKeyboardStateChangeMessage(false);
- if (oldVisible != m_visible)
- emit visibilityChanged(m_visible);
- } else if (strcmp(value, "info") == 0)
- handleKeyboardInfoMessage();
- else if (strcmp(value, "connect") == 0) { }
- else
- qCritical("QQnxVirtualKeyboard: Unexpected keyboard PPS msg value: %s", value ? value : "[null]");
- } else if (pps_decoder_get_string(m_decoder, "res", &value) == PPS_DECODER_OK) {
- if (strcmp(value, "info") == 0)
- handleKeyboardInfoMessage();
- else
- qCritical("QQnxVirtualKeyboard: Unexpected keyboard PPS res value: %s", value ? value : "[null]");
- } else
- qCritical("QQnxVirtualKeyboard: Unexpected keyboard PPS message type");
+ const char *value;
+ if (pps_decoder_get_string(m_decoder, "error", &value) == PPS_DECODER_OK) {
+ qCritical("QQnxVirtualKeyboard: Keyboard PPS decoder error: %s", value ? value : "[null]");
+ return;
}
-#ifdef QQNXVIRTUALKEYBOARD_DEBUG
- qDebug() << "QQNX: exiting keyboard thread";
-#endif
-
- if (m_decoder)
- pps_decoder_cleanup(m_decoder);
+ if (pps_decoder_get_string(m_decoder, "msg", &value) == PPS_DECODER_OK) {
+ if (strcmp(value, "show") == 0) {
+ const bool oldVisible = m_visible;
+ m_visible = true;
+ handleKeyboardStateChangeMessage(true);
+ if (oldVisible != m_visible)
+ emit visibilityChanged(m_visible);
+ } else if (strcmp(value, "hide") == 0) {
+ const bool oldVisible = m_visible;
+ m_visible = false;
+ handleKeyboardStateChangeMessage(false);
+ if (oldVisible != m_visible)
+ emit visibilityChanged(m_visible);
+ } else if (strcmp(value, "info") == 0)
+ handleKeyboardInfoMessage();
+ else if (strcmp(value, "connect") == 0) { }
+ else
+ qCritical("QQnxVirtualKeyboard: Unexpected keyboard PPS msg value: %s", value ? value : "[null]");
+ } else if (pps_decoder_get_string(m_decoder, "res", &value) == PPS_DECODER_OK) {
+ if (strcmp(value, "info") == 0)
+ handleKeyboardInfoMessage();
+ else
+ qCritical("QQnxVirtualKeyboard: Unexpected keyboard PPS res value: %s", value ? value : "[null]");
+ } else
+ qCritical("QQnxVirtualKeyboard: Unexpected keyboard PPS message type");
}
void QQnxVirtualKeyboard::handleKeyboardInfoMessage()