Commit 76670ec8 authored by Alberto Mardegan's avatar Alberto Mardegan
Browse files

VncClient: add forwarding of input events

parent d83ff5a3
......@@ -27,6 +27,7 @@ Project {
Group {
prefix: "src/"
files: [
"key_mapping.h",
"main.cpp",
"scaler.cpp",
"scaler.h",
......
static struct UnicodeKeyEntry {
uint16_t unicode;
uint32_t xKey;
} unicodeToX11[] = {
{ 0x20AC, XK_EuroSign },
// Cyrillic symbols
{ 0x0410, XK_Cyrillic_A }, // capital letter a
{ 0x0430, XK_Cyrillic_a }, // small letter a
{ 0x0411, XK_Cyrillic_BE }, // capital letter be
{ 0x0431, XK_Cyrillic_be }, // small letter be
{ 0x0412, XK_Cyrillic_VE }, // capital letter ve
{ 0x0432, XK_Cyrillic_ve }, // small letter ve
{ 0x0413, XK_Cyrillic_GHE }, // capital letter ghe
{ 0x0433, XK_Cyrillic_ghe }, // small letter ghe
{ 0x0414, XK_Cyrillic_DE }, // capital letter de
{ 0x0434, XK_Cyrillic_de }, // small letter de
{ 0x0415, XK_Cyrillic_IE }, // capital letter ie
{ 0x0435, XK_Cyrillic_ie }, // small letter ie
{ 0x0401, XK_Cyrillic_IO }, // capital letter io
{ 0x0451, XK_Cyrillic_io }, // small letter io
{ 0x0416, XK_Cyrillic_ZHE }, // capital letter zhe
{ 0x0436, XK_Cyrillic_zhe }, // small letter zhe
{ 0x0417, XK_Cyrillic_ZE }, // capital letter ze
{ 0x0437, XK_Cyrillic_ze }, // small letter ze
{ 0x0418, XK_Cyrillic_I }, // capital letter i
{ 0x0438, XK_Cyrillic_i }, // small letter i
{ 0x0419, XK_Cyrillic_SHORTI }, // capital letter short i
{ 0x0439, XK_Cyrillic_shorti }, // small letter short i
{ 0x041A, XK_Cyrillic_KA }, // capital letter ka
{ 0x043A, XK_Cyrillic_ka }, // small letter ka
{ 0x041B, XK_Cyrillic_EL }, // capital letter el
{ 0x043B, XK_Cyrillic_el }, // small letter el
{ 0x041C, XK_Cyrillic_EM }, // capital letter em
{ 0x043C, XK_Cyrillic_em }, // small letter em
{ 0x041D, XK_Cyrillic_EN }, // capital letter en
{ 0x043D, XK_Cyrillic_en }, // small letter en
{ 0x041E, XK_Cyrillic_O }, // capital letter o
{ 0x043E, XK_Cyrillic_o }, // small letter o
{ 0x041F, XK_Cyrillic_PE }, // capital letter pe
{ 0x043F, XK_Cyrillic_pe }, // small letter pe
{ 0x0420, XK_Cyrillic_ER }, // capital letter er
{ 0x0440, XK_Cyrillic_er }, // small letter er
{ 0x0421, XK_Cyrillic_ES }, // capital letter es
{ 0x0441, XK_Cyrillic_es }, // small letter es
{ 0x0422, XK_Cyrillic_TE }, // capital letter te
{ 0x0442, XK_Cyrillic_te }, // small letter te
{ 0x0423, XK_Cyrillic_U }, // capital letter u
{ 0x0443, XK_Cyrillic_u }, // small letter u
{ 0x0424, XK_Cyrillic_EF }, // capital letter ef
{ 0x0444, XK_Cyrillic_ef }, // small letter ef
{ 0x0425, XK_Cyrillic_HA }, // capital letter ha
{ 0x0445, XK_Cyrillic_ha }, // small letter ha
{ 0x0426, XK_Cyrillic_TSE }, // capital letter tse
{ 0x0446, XK_Cyrillic_tse }, // small letter tse
{ 0x0427, XK_Cyrillic_CHE }, // capital letter che
{ 0x0447, XK_Cyrillic_che }, // small letter che
{ 0x0428, XK_Cyrillic_SHA }, // capital letter sha
{ 0x0448, XK_Cyrillic_sha }, // small letter sha
{ 0x0429, XK_Cyrillic_SHCHA }, // capital letter shcha
{ 0x0449, XK_Cyrillic_shcha }, // small letter shcha
{ 0x042A, XK_Cyrillic_HARDSIGN }, // capital letter hard sign
{ 0x044A, XK_Cyrillic_hardsign }, // small letter hard sign
{ 0x042B, XK_Cyrillic_YERU }, // capital letter yeru
{ 0x044B, XK_Cyrillic_yeru }, // small letter yeru
{ 0x042C, XK_Cyrillic_SOFTSIGN }, // capital letter soft sign
{ 0x044C, XK_Cyrillic_softsign }, // small letter soft sign
{ 0x042D, XK_Cyrillic_E }, // capital letter e
{ 0x044D, XK_Cyrillic_e }, // small letter e
{ 0x042E, XK_Cyrillic_YU }, // capital letter yu
{ 0x044E, XK_Cyrillic_yu }, // small letter yu
{ 0x042F, XK_Cyrillic_YA }, // capital letter ya
{ 0x044F, XK_Cyrillic_ya }, // small letter ya
// знаки для современных славянских языков
{ 0x0402, XK_Serbian_DJE }, // Ђ capital letter dje (serbocroatian)
{ 0x0452, XK_Serbian_dje }, // ђ small letter dje (serbocroatian)
{ 0x0403, XK_Macedonia_GJE }, // Ѓ capital letter gje
{ 0x0453, XK_Macedonia_gje }, // ѓ small letter gje
{ 0x0404, XK_Ukrainian_IE }, // Є capital letter ukrainian ie
{ 0x0454, XK_Ukrainian_ie }, // є small letter ukrainian ie
{ 0x0405, XK_Cyrillic_DZHE }, // Ѕ capital letter dze
{ 0x0455, XK_Cyrillic_dzhe }, // ѕ small letter dze
{ 0x0406, XK_Ukrainian_I }, // І capital letter byelorussian-ukrainian i
{ 0x0456, XK_Ukrainian_i }, // і small letter byelorussian-ukrainian i
{ 0x0407, XK_Ukrainian_YI }, // Ї capital letter yi (ukrainian)
{ 0x0457, XK_Ukrainian_yi }, // ї small letter yi (ukrainian)
{ 0x0408, XK_Cyrillic_JE }, // Ј capital letter je
{ 0x0458, XK_Cyrillic_je }, // ј small letter je
{ 0x0409, XK_Cyrillic_LJE }, // Љ capital letter lje
{ 0x0459, XK_Cyrillic_lje }, // љ small letter lje
{ 0x040A, XK_Cyrillic_NJE }, // Њ capital letter nje
{ 0x045A, XK_Cyrillic_nje }, // њ small letter nje
{ 0x040B, XK_Serbian_TSHE }, // Ћ capital letter tshe (serbocroatian)
{ 0x045B, XK_Serbian_tshe }, // ћ small letter tshe (serbocroatian)
{ 0x040C, XK_Macedonia_KJE }, // Ќ capital letter kje
{ 0x045C, XK_Macedonia_kje }, // ќ small letter kje
//{ 0x040D, XK_Cyrillic_ }, // Ѝ capital letter i with grave
//{ 0x045D, XK_Cyrillic_ }, // ѝ small letter i with grave
{ 0x040E, XK_Byelorussian_SHORTU }, // Ў capital letter short u (byelorussian)
{ 0x045E, XK_Byelorussian_shortu }, // ў small letter short u (byelorussian)
{ 0x040F, XK_Cyrillic_DZHE }, // Џ capital letter dzhe
{ 0x045F, XK_Cyrillic_dzhe }, // џ small letter dzhe
// { 0x0490, XK_ }, // Ґ capital letter ghe with upturn
// { 0x0491, XK_ }, // ґ small letter ghe with upturn
{ 0, 0}
};
......@@ -22,12 +22,14 @@
#include <QByteArrayList>
#include <QDebug>
#include <QImage>
#include <QKeyEvent>
#include <QList>
#include <QMouseEvent>
#include <QPointF>
#include <QQuickItem>
#include <QScopedPointer>
#include <QSocketNotifier>
#define XK_CYRILLIC
#include <rfb/rfbclient.h>
using namespace LomiriVNC;
......@@ -49,6 +51,8 @@ public:
static rfbBool mallocFrameBuffer(rfbClient* client);
static int qtToRfb(Qt::MouseButtons buttons);
static uint32_t qCharToVnc(QChar c);
static uint32_t qKeyToVnc(int key);
void onUpdate(int x, int y, int w, int h);
void onResize();
......@@ -58,6 +62,9 @@ public:
void onSocketActivated();
void sendKeyEvent(QChar c);
void sendKeyEvent(QKeyEvent *keyEvent, bool pressed);
void sendKeyEvent(uint32_t code, bool pressed);
void sendMouseEvent(const QPointF &pos, Qt::MouseButtons buttons);
private:
......@@ -133,6 +140,98 @@ int VncClientPrivate::qtToRfb(Qt::MouseButtons buttons)
return ret;
}
#include "key_mapping.h"
uint32_t VncClientPrivate::qCharToVnc(QChar c)
{
uint32_t code = 0;
if (char latin1 = c.toLatin1()) {
code = XK_a + latin1 - 'a';
}
if (code == 0) {
uint16_t unicode = c.unicode();
for (UnicodeKeyEntry *i = unicodeToX11; i->unicode != 0; i++) {
if (i->unicode == unicode) {
code = i->xKey;
break;
}
}
qDebug() << "char" << c << "unicode" << code;
}
return code;
}
uint32_t VncClientPrivate::qKeyToVnc(int key)
{
uint32_t code = 0;
if (key >= Qt::Key_0 && key <= Qt::Key_9) {
code = XK_0 + key - Qt::Key_0;
} else if (key >= Qt::Key_A && key <= Qt::Key_Z) {
code = XK_a + key - Qt::Key_A;
} else if (key >= Qt::Key_F1 && key <= Qt::Key_F35) {
code = XK_F1 + key - Qt::Key_F1;
} else {
switch (key) {
case Qt::Key_Escape: code = XK_Escape; break;
case Qt::Key_Tab: code = XK_Tab; break;
case Qt::Key_Backspace: code = XK_BackSpace; break;
case Qt::Key_Return:
case Qt::Key_Enter:
code = XK_Return;
break;
case Qt::Key_Insert: code = XK_Insert; break;
case Qt::Key_Delete: code = XK_Delete; break;
case Qt::Key_Pause: code = XK_Pause; break;
case Qt::Key_Print: code = XK_Print; break;
case Qt::Key_SysReq: code = XK_Sys_Req; break;
case Qt::Key_Clear: code = XK_Clear; break;
case Qt::Key_Home: code = XK_Home; break;
case Qt::Key_End: code = XK_End; break;
case Qt::Key_Left: code = XK_Left; break;
case Qt::Key_Up: code = XK_Up; break;
case Qt::Key_Right: code = XK_Right; break;
case Qt::Key_Down: code = XK_Down; break;
case Qt::Key_PageUp: code = XK_Page_Up; break;
case Qt::Key_PageDown: code = XK_Page_Down; break;
case Qt::Key_Shift: code = XK_Shift_L; break;
case Qt::Key_Control: code = XK_Control_L; break;
case Qt::Key_Meta: code = XK_Meta_L; break;
case Qt::Key_Alt: code = XK_Alt_L; break;
case Qt::Key_AltGr: code = XK_Alt_R; break;
case Qt::Key_CapsLock: code = XK_Caps_Lock; break;
case Qt::Key_NumLock: code = XK_Num_Lock; break;
case Qt::Key_ScrollLock: code = XK_Scroll_Lock; break;
case Qt::Key_Super_L: code = XK_Super_L; break;
case Qt::Key_Super_R: code = XK_Super_R; break;
case Qt::Key_Menu: code = XK_Menu; break;
case Qt::Key_Hyper_L: code = XK_Hyper_L; break;
case Qt::Key_Hyper_R: code = XK_Hyper_R; break;
case Qt::Key_Help: code = XK_Help; break;
case Qt::Key_Exclam: code = XK_exclam; break;
case Qt::Key_QuoteDbl: code = XK_quotedbl; break;
case Qt::Key_NumberSign: code = XK_numbersign; break;
case Qt::Key_Dollar: code = XK_dollar; break;
case Qt::Key_Percent: code = XK_percent; break;
case Qt::Key_Ampersand: code = XK_ampersand; break;
case Qt::Key_Apostrophe: code = XK_apostrophe; break;
case Qt::Key_ParenLeft: code = XK_parenleft; break;
case Qt::Key_ParenRight: code = XK_parenright; break;
case Qt::Key_Asterisk: code = XK_asterisk; break;
case Qt::Key_Plus: code = XK_plus; break;
case Qt::Key_Comma: code = XK_comma; break;
case Qt::Key_Minus: code = XK_minus; break;
case Qt::Key_Period: code = XK_period; break;
case Qt::Key_Slash: code = XK_slash; break;
default:
qWarning() << "Unsupported key:" << key;
}
}
return code;
}
void VncClientPrivate::onUpdate(int x, int y, int w, int h)
{
Q_UNUSED(x);
......@@ -233,6 +332,29 @@ void VncClientPrivate::onSocketActivated()
}
}
void VncClientPrivate::sendKeyEvent(QChar c)
{
uint32_t code = qCharToVnc(c);
sendKeyEvent(code, true);
sendKeyEvent(code, false);
}
void VncClientPrivate::sendKeyEvent(QKeyEvent *keyEvent, bool pressed)
{
// TODO handle modifiers
uint32_t code = qKeyToVnc(keyEvent->key());
sendKeyEvent(code, pressed);
}
void VncClientPrivate::sendKeyEvent(uint32_t code, bool pressed)
{
if (Q_UNLIKELY(!m_client)) {
qWarning() << "Not connected";
return;
}
SendKeyEvent(m_client, code, pressed);
}
void VncClientPrivate::sendMouseEvent(const QPointF &pos,
Qt::MouseButtons buttons)
{
......@@ -287,6 +409,18 @@ void VncClient::disconnect()
return d->disconnect();
}
void VncClient::sendKeyEvent(QChar c)
{
Q_D(VncClient);
return d->sendKeyEvent(c);
}
void VncClient::sendKeyEvent(QKeyEvent *keyEvent, bool pressed)
{
Q_D(VncClient);
return d->sendKeyEvent(keyEvent, pressed);
}
void VncClient::sendMouseEvent(const QPointF &pos, Qt::MouseButtons buttons)
{
Q_D(VncClient);
......
......@@ -24,6 +24,7 @@
#include <QScopedPointer>
class QImage;
class QKeyEvent;
class QPointF;
class QQuickItem;
......@@ -48,6 +49,8 @@ public:
Q_INVOKABLE bool connectToServer(const QString &host);
Q_INVOKABLE void disconnect();
void sendKeyEvent(QChar c);
void sendKeyEvent(QKeyEvent *keyEvent, bool pressed);
Q_INVOKABLE void sendMouseEvent(const QPointF &pos,
Qt::MouseButtons buttons);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment