Pārlūkot izejas kodu

Basic support for QEMU Extended Key Events

This adds the basic infrastructure and handshake for the QEMU
Extended Key Events extension. No viewer or server makes use of
the extra functionality yet though.
tags/v1.8.90
Pierre Ossman pirms 7 gadiem
vecāks
revīzija
5ae282135f

+ 5
- 0
common/rfb/CMsgHandler.cxx Parādīt failu

@@ -75,6 +75,11 @@ void CMsgHandler::endOfContinuousUpdates()
cp.supportsContinuousUpdates = true;
}

void CMsgHandler::supportsQEMUKeyEvent()
{
cp.supportsQEMUKeyEvent = true;
}

void CMsgHandler::framebufferUpdateStart()
{
}

+ 1
- 0
common/rfb/CMsgHandler.h Parādīt failu

@@ -55,6 +55,7 @@ namespace rfb {
virtual void setName(const char* name);
virtual void fence(rdr::U32 flags, unsigned len, const char data[]);
virtual void endOfContinuousUpdates();
virtual void supportsQEMUKeyEvent();
virtual void serverInit() = 0;

virtual void readAndDecodeRect(const Rect& r, int encoding,

+ 2
- 0
common/rfb/CMsgReader.cxx Parādīt failu

@@ -111,6 +111,8 @@ void CMsgReader::readMsg()
break;
case pseudoEncodingLEDState:
readLEDState();
case pseudoEncodingQEMUKeyEvent:
handler->supportsQEMUKeyEvent();
break;
default:
readRect(Rect(x, y, x+w, y+h), encoding);

+ 21
- 6
common/rfb/CMsgWriter.cxx Parādīt failu

@@ -21,6 +21,7 @@
#include <rfb/msgTypes.h>
#include <rfb/fenceTypes.h>
#include <rfb/encodings.h>
#include <rfb/qemuTypes.h>
#include <rfb/Exception.h>
#include <rfb/PixelFormat.h>
#include <rfb/Rect.h>
@@ -88,6 +89,7 @@ void CMsgWriter::writeSetEncodings(int preferredEncoding, bool useCopyRect)
encodings[nEncodings++] = pseudoEncodingLastRect;
encodings[nEncodings++] = pseudoEncodingContinuousUpdates;
encodings[nEncodings++] = pseudoEncodingFence;
encodings[nEncodings++] = pseudoEncodingQEMUKeyEvent;

if (Decoder::supported(preferredEncoding)) {
encodings[nEncodings++] = preferredEncoding;
@@ -215,13 +217,26 @@ void CMsgWriter::writeFence(rdr::U32 flags, unsigned len, const char data[])
endMsg();
}

void CMsgWriter::keyEvent(rdr::U32 key, bool down)
void CMsgWriter::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down)
{
startMsg(msgTypeKeyEvent);
os->writeU8(down);
os->pad(2);
os->writeU32(key);
endMsg();
if (!cp->supportsQEMUKeyEvent || !keycode) {
/* This event isn't meaningful without a valid keysym */
if (!keysym)
return;

startMsg(msgTypeKeyEvent);
os->writeU8(down);
os->pad(2);
os->writeU32(keysym);
endMsg();
} else {
startMsg(msgTypeQEMUClientMessage);
os->writeU8(qemuExtendedKeyEvent);
os->writeU16(down);
os->writeU32(keysym);
os->writeU32(keycode);
endMsg();
}
}



+ 1
- 1
common/rfb/CMsgWriter.h Parādīt failu

@@ -55,7 +55,7 @@ namespace rfb {

// InputHandler implementation

virtual void keyEvent(rdr::U32 key, bool down);
virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
virtual void pointerEvent(const Point& pos, int buttonMask);
virtual void clientCutText(const char* str, rdr::U32 len);


+ 6
- 2
common/rfb/ConnParams.cxx Parādīt failu

@@ -35,8 +35,9 @@ ConnParams::ConnParams()
supportsLocalCursorWithAlpha(false),
supportsDesktopResize(false), supportsExtendedDesktopSize(false),
supportsDesktopRename(false), supportsLastRect(false),
supportsLEDState(false), supportsSetDesktopSize(false),
supportsFence(false), supportsContinuousUpdates(false),
supportsLEDState(false), supportsQEMUKeyEvent(false),
supportsSetDesktopSize(false), supportsFence(false),
supportsContinuousUpdates(false),
compressLevel(2), qualityLevel(-1), fineQualityLevel(-1),
subsampling(subsampleUndefined), name_(0), verStrPos(0),
ledState_(ledUnknown)
@@ -109,6 +110,7 @@ void ConnParams::setEncodings(int nEncodings, const rdr::S32* encodings)
supportsExtendedDesktopSize = false;
supportsLocalXCursor = false;
supportsLastRect = false;
supportsQEMUKeyEvent = false;
compressLevel = -1;
qualityLevel = -1;
fineQualityLevel = -1;
@@ -145,6 +147,8 @@ void ConnParams::setEncodings(int nEncodings, const rdr::S32* encodings)
break;
case pseudoEncodingLEDState:
supportsLEDState = true;
case pseudoEncodingQEMUKeyEvent:
supportsQEMUKeyEvent = true;
break;
case pseudoEncodingFence:
supportsFence = true;

+ 1
- 0
common/rfb/ConnParams.h Parādīt failu

@@ -97,6 +97,7 @@ namespace rfb {
bool supportsDesktopRename;
bool supportsLastRect;
bool supportsLEDState;
bool supportsQEMUKeyEvent;

bool supportsSetDesktopSize;
bool supportsFence;

+ 1
- 1
common/rfb/InputHandler.h Parādīt failu

@@ -31,7 +31,7 @@ namespace rfb {
class InputHandler {
public:
virtual ~InputHandler() {}
virtual void keyEvent(rdr::U32 key, bool down) {}
virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down) {}
virtual void pointerEvent(const Point& pos, int buttonMask) {}
virtual void clientCutText(const char* str, int len) {}
};

+ 5
- 0
common/rfb/SConnection.cxx Parādīt failu

@@ -278,6 +278,11 @@ void SConnection::setEncodings(int nEncodings, const rdr::S32* encodings)
SMsgHandler::setEncodings(nEncodings, encodings);
}

void SConnection::supportsQEMUKeyEvent()
{
writer()->writeQEMUKeyEvent();
}

void SConnection::versionReceived()
{
}

+ 1
- 0
common/rfb/SConnection.h Parādīt failu

@@ -73,6 +73,7 @@ namespace rfb {

virtual void setEncodings(int nEncodings, const rdr::S32* encodings);

virtual void supportsQEMUKeyEvent();

// Methods to be overridden in a derived class


+ 9
- 1
common/rfb/SMsgHandler.cxx Parādīt failu

@@ -41,11 +41,13 @@ void SMsgHandler::setPixelFormat(const PixelFormat& pf)

void SMsgHandler::setEncodings(int nEncodings, const rdr::S32* encodings)
{
bool firstFence, firstContinuousUpdates, firstLEDState;
bool firstFence, firstContinuousUpdates, firstLEDState,
firstQEMUKeyEvent;

firstFence = !cp.supportsFence;
firstContinuousUpdates = !cp.supportsContinuousUpdates;
firstLEDState = !cp.supportsLEDState;
firstQEMUKeyEvent = !cp.supportsQEMUKeyEvent;

cp.setEncodings(nEncodings, encodings);

@@ -57,6 +59,8 @@ void SMsgHandler::setEncodings(int nEncodings, const rdr::S32* encodings)
supportsContinuousUpdates();
if (cp.supportsLEDState && firstLEDState)
supportsLEDState();
if (cp.supportsQEMUKeyEvent && firstQEMUKeyEvent)
supportsQEMUKeyEvent();
}

void SMsgHandler::supportsLocalCursor()
@@ -75,6 +79,10 @@ void SMsgHandler::supportsLEDState()
{
}

void SMsgHandler::supportsQEMUKeyEvent()
{
}

void SMsgHandler::setDesktopSize(int fb_width, int fb_height,
const ScreenSet& layout)
{

+ 5
- 0
common/rfb/SMsgHandler.h Parādīt failu

@@ -80,6 +80,11 @@ namespace rfb {
// server state.
virtual void supportsLEDState();

// supportsQEMUKeyEvent() is called the first time we detect that the
// client wants the QEMU Extended Key Event extension. The default
// handler will send a pseudo-rect back, signalling server support.
virtual void supportsQEMUKeyEvent();

ConnParams cp;
};
}

+ 28
- 1
common/rfb/SMsgReader.cxx Parādīt failu

@@ -19,6 +19,7 @@
#include <stdio.h>
#include <rdr/InStream.h>
#include <rfb/msgTypes.h>
#include <rfb/qemuTypes.h>
#include <rfb/Exception.h>
#include <rfb/util.h>
#include <rfb/SMsgHandler.h>
@@ -78,6 +79,9 @@ void SMsgReader::readMsg()
case msgTypeClientCutText:
readClientCutText();
break;
case msgTypeQEMUClientMessage:
readQEMUMessage();
break;
default:
fprintf(stderr, "unknown message type %d\n", msgType);
throw Exception("unknown message type");
@@ -184,7 +188,7 @@ void SMsgReader::readKeyEvent()
bool down = is->readU8();
is->skip(2);
rdr::U32 key = is->readU32();
handler->keyEvent(key, down);
handler->keyEvent(key, 0, down);
}

void SMsgReader::readPointerEvent()
@@ -214,3 +218,26 @@ void SMsgReader::readClientCutText()
handler->clientCutText(ca.buf, len);
}

void SMsgReader::readQEMUMessage()
{
int subType = is->readU8();
switch (subType) {
case qemuExtendedKeyEvent:
readQEMUKeyEvent();
break;
default:
throw Exception("unknown QEMU submessage type %d", subType);
}
}

void SMsgReader::readQEMUKeyEvent()
{
bool down = is->readU16();
rdr::U32 keysym = is->readU32();
rdr::U32 keycode = is->readU32();
if (!keycode) {
vlog.error("Key event without keycode - ignoring");
return;
}
handler->keyEvent(keysym, keycode, down);
}

+ 3
- 0
common/rfb/SMsgReader.h Parādīt failu

@@ -55,6 +55,9 @@ namespace rfb {
void readPointerEvent();
void readClientCutText();

void readQEMUMessage();
void readQEMUKeyEvent();

SMsgHandler* handler;
rdr::InStream* is;
};

+ 34
- 1
common/rfb/SMsgWriter.cxx Parādīt failu

@@ -39,7 +39,7 @@ SMsgWriter::SMsgWriter(ConnParams* cp_, rdr::OutStream* os_)
needSetDesktopSize(false), needExtendedDesktopSize(false),
needSetDesktopName(false), needSetCursor(false),
needSetXCursor(false), needSetCursorWithAlpha(false),
needLEDState(false)
needLEDState(false), needQEMUKeyEvent(false)
{
}

@@ -207,6 +207,16 @@ bool SMsgWriter::writeLEDState()
return true;
}

bool SMsgWriter::writeQEMUKeyEvent()
{
if (!cp->supportsQEMUKeyEvent)
return false;

needQEMUKeyEvent = true;

return true;
}

bool SMsgWriter::needFakeUpdate()
{
if (needSetDesktopName)
@@ -215,6 +225,8 @@ bool SMsgWriter::needFakeUpdate()
return true;
if (needLEDState)
return true;
if (needQEMUKeyEvent)
return true;
if (needNoDataUpdate())
return true;

@@ -265,6 +277,8 @@ void SMsgWriter::writeFramebufferUpdateStart(int nRects)
nRects++;
if (needLEDState)
nRects++;
if (needQEMUKeyEvent)
nRects++;
}

os->writeU16(nRects);
@@ -385,6 +399,11 @@ void SMsgWriter::writePseudoRects()
writeLEDStateRect(cp->ledState());
needLEDState = false;
}

if (needQEMUKeyEvent) {
writeQEMUKeyEventRect();
needQEMUKeyEvent = false;
}
}

void SMsgWriter::writeNoDataRects()
@@ -565,3 +584,17 @@ void SMsgWriter::writeLEDStateRect(rdr::U8 state)
os->writeU32(pseudoEncodingLEDState);
os->writeU8(state);
}

void SMsgWriter::writeQEMUKeyEventRect()
{
if (!cp->supportsQEMUKeyEvent)
throw Exception("Client does not support QEMU extended key events");
if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
throw Exception("SMsgWriter::writeQEMUKeyEventRect: nRects out of sync");

os->writeS16(0);
os->writeS16(0);
os->writeU16(0);
os->writeU16(0);
os->writeU32(pseudoEncodingQEMUKeyEvent);
}

+ 5
- 0
common/rfb/SMsgWriter.h Parādīt failu

@@ -85,6 +85,9 @@ namespace rfb {
// Same for LED state message
bool writeLEDState();

// And QEMU keyboard event handshake
bool writeQEMUKeyEvent();

// needFakeUpdate() returns true when an immediate update is needed in
// order to flush out pseudo-rectangles to the client.
bool needFakeUpdate();
@@ -135,6 +138,7 @@ namespace rfb {
int hotspotX, int hotspotY,
const rdr::U8* data);
void writeLEDStateRect(rdr::U8 state);
void writeQEMUKeyEventRect();

ConnParams* cp;
rdr::OutStream* os;
@@ -150,6 +154,7 @@ namespace rfb {
bool needSetXCursor;
bool needSetCursorWithAlpha;
bool needLEDState;
bool needQEMUKeyEvent;

typedef struct {
rdr::U16 reason, result;

+ 31
- 30
common/rfb/VNCSConnectionST.cxx Parādīt failu

@@ -103,7 +103,7 @@ VNCSConnectionST::~VNCSConnectionST()
std::set<rdr::U32>::iterator i;
for (i=pressedKeys.begin(); i!=pressedKeys.end(); i++) {
vlog.debug("Releasing key 0x%x on client disconnect", *i);
server->desktop->keyEvent(*i, false);
server->desktop->keyEvent(*i, 0, false);
}
if (server->pointerClient == this)
server->pointerClient = 0;
@@ -538,12 +538,12 @@ public:
~VNCSConnectionSTShiftPresser() {
if (pressed) {
vlog.debug("Releasing fake Shift_L");
desktop->keyEvent(XK_Shift_L, false);
desktop->keyEvent(XK_Shift_L, 0, false);
}
}
void press() {
vlog.debug("Pressing fake Shift_L");
desktop->keyEvent(XK_Shift_L, true);
desktop->keyEvent(XK_Shift_L, 0, true);
pressed = true;
}
SDesktop* desktop;
@@ -552,32 +552,32 @@ public:

// keyEvent() - record in the pressedKeys which keys were pressed. Allow
// multiple down events (for autorepeat), but only allow a single up event.
void VNCSConnectionST::keyEvent(rdr::U32 key, bool down) {
void VNCSConnectionST::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down) {
lastEventTime = time(0);
server->lastUserInputTime = lastEventTime;
if (!(accessRights & AccessKeyEvents)) return;
if (!rfb::Server::acceptKeyEvents) return;

if (down)
vlog.debug("Key pressed: 0x%x", key);
vlog.debug("Key pressed: 0x%x / 0x%x", keysym, keycode);
else
vlog.debug("Key released: 0x%x", key);
vlog.debug("Key released: 0x%x / 0x%x", keysym, keycode);

// Remap the key if required
if (server->keyRemapper) {
rdr::U32 newkey;
newkey = server->keyRemapper->remapKey(key);
if (newkey != key) {
newkey = server->keyRemapper->remapKey(keysym);
if (newkey != keysym) {
vlog.debug("Key remapped to 0x%x", newkey);
key = newkey;
keysym = newkey;
}
}

// Avoid lock keys if we don't know the server state
if ((server->ledState == ledUnknown) &&
((key == XK_Caps_Lock) ||
(key == XK_Num_Lock) ||
(key == XK_Scroll_Lock))) {
((keysym == XK_Caps_Lock) ||
(keysym == XK_Num_Lock) ||
(keysym == XK_Scroll_Lock))) {
vlog.debug("Ignoring lock key (e.g. caps lock)");
return;
}
@@ -587,7 +587,7 @@ void VNCSConnectionST::keyEvent(rdr::U32 key, bool down) {
if (!cp.supportsLEDState) {
// Always ignore ScrollLock as we don't have a heuristic
// for that
if (key == XK_Scroll_Lock) {
if (keysym == XK_Scroll_Lock) {
vlog.debug("Ignoring lock key (e.g. caps lock)");
return;
}
@@ -596,32 +596,32 @@ void VNCSConnectionST::keyEvent(rdr::U32 key, bool down) {
// CapsLock synchronisation heuristic
// (this assumes standard interaction between CapsLock the Shift
// keys and normal characters)
if (((key >= XK_A) && (key <= XK_Z)) ||
((key >= XK_a) && (key <= XK_z))) {
if (((keysym >= XK_A) && (keysym <= XK_Z)) ||
((keysym >= XK_a) && (keysym <= XK_z))) {
bool uppercase, shift, lock;

uppercase = (key >= XK_A) && (key <= XK_Z);
uppercase = (keysym >= XK_A) && (keysym <= XK_Z);
shift = pressedKeys.find(XK_Shift_L) != pressedKeys.end() ||
pressedKeys.find(XK_Shift_R) != pressedKeys.end();
lock = server->ledState & ledCapsLock;

if (lock == (uppercase == shift)) {
vlog.debug("Inserting fake CapsLock to get in sync with client");
server->desktop->keyEvent(XK_Caps_Lock, true);
server->desktop->keyEvent(XK_Caps_Lock, false);
server->desktop->keyEvent(XK_Caps_Lock, 0, true);
server->desktop->keyEvent(XK_Caps_Lock, 0, false);
}
}

// NumLock synchronisation heuristic
// (this is more cautious because of the differences between Unix,
// Windows and macOS)
if (((key >= XK_KP_Home) && (key <= XK_KP_Delete)) ||
((key >= XK_KP_0) && (key <= XK_KP_9)) ||
(key == XK_KP_Separator) || (key == XK_KP_Decimal)) {
if (((keysym >= XK_KP_Home) && (keysym <= XK_KP_Delete)) ||
((keysym >= XK_KP_0) && (keysym <= XK_KP_9)) ||
(keysym == XK_KP_Separator) || (keysym == XK_KP_Decimal)) {
bool number, shift, lock;

number = ((key >= XK_KP_0) && (key <= XK_KP_9)) ||
(key == XK_KP_Separator) || (key == XK_KP_Decimal);
number = ((keysym >= XK_KP_0) && (keysym <= XK_KP_9)) ||
(keysym == XK_KP_Separator) || (keysym == XK_KP_Decimal);
shift = pressedKeys.find(XK_Shift_L) != pressedKeys.end() ||
pressedKeys.find(XK_Shift_R) != pressedKeys.end();
lock = server->ledState & ledNumLock;
@@ -638,8 +638,8 @@ void VNCSConnectionST::keyEvent(rdr::U32 key, bool down) {
//
} else if (lock == (number == shift)) {
vlog.debug("Inserting fake NumLock to get in sync with client");
server->desktop->keyEvent(XK_Num_Lock, true);
server->desktop->keyEvent(XK_Num_Lock, false);
server->desktop->keyEvent(XK_Num_Lock, 0, true);
server->desktop->keyEvent(XK_Num_Lock, 0, false);
}
}
}
@@ -647,19 +647,20 @@ void VNCSConnectionST::keyEvent(rdr::U32 key, bool down) {

// Turn ISO_Left_Tab into shifted Tab.
VNCSConnectionSTShiftPresser shiftPresser(server->desktop);
if (key == XK_ISO_Left_Tab) {
if (keysym == XK_ISO_Left_Tab) {
if (pressedKeys.find(XK_Shift_L) == pressedKeys.end() &&
pressedKeys.find(XK_Shift_R) == pressedKeys.end())
shiftPresser.press();
key = XK_Tab;
keysym = XK_Tab;
}

if (down) {
pressedKeys.insert(key);
pressedKeys.insert(keysym);
} else {
if (!pressedKeys.erase(key)) return;
if (!pressedKeys.erase(keysym))
return;
}
server->desktop->keyEvent(key, down);
server->desktop->keyEvent(keysym, keycode, down);
}

void VNCSConnectionST::clientCutText(const char* str, int len)

+ 1
- 1
common/rfb/VNCSConnectionST.h Parādīt failu

@@ -136,7 +136,7 @@ namespace rfb {
virtual void clientInit(bool shared);
virtual void setPixelFormat(const PixelFormat& pf);
virtual void pointerEvent(const Point& pos, int buttonMask);
virtual void keyEvent(rdr::U32 key, bool down);
virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
virtual void clientCutText(const char* str, int len);
virtual void framebufferUpdateRequest(const Rect& r, bool incremental);
virtual void setDesktopSize(int fb_width, int fb_height,

+ 1
- 0
common/rfb/encodings.h Parādīt failu

@@ -40,6 +40,7 @@ namespace rfb {
const int pseudoEncodingFence = -312;
const int pseudoEncodingContinuousUpdates = -313;
const int pseudoEncodingCursorWithAlpha = -314;
const int pseudoEncodingQEMUKeyEvent = -258;

// TightVNC-specific
const int pseudoEncodingLastRect = -224;

+ 2
- 0
common/rfb/msgTypes.h Parādīt failu

@@ -45,5 +45,7 @@ namespace rfb {
const int msgTypeClientFence = 248;

const int msgTypeSetDesktopSize = 251;

const int msgTypeQEMUClientMessage = 255;
}
#endif

+ 25
- 0
common/rfb/qemuTypes.h Parādīt failu

@@ -0,0 +1,25 @@
/* Copyright 2017 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#ifndef __RFB_QEMUTYPES_H__
#define __RFB_QEMUTYPES_H__

namespace rfb {
const int qemuExtendedKeyEvent = 0;
const int qemuAudio = 1;
}
#endif

+ 2
- 2
unix/x0vncserver/x0vncserver.cxx Parādīt failu

@@ -295,10 +295,10 @@ public:
#endif
}

virtual void keyEvent(rdr::U32 key, bool down) {
virtual void keyEvent(rdr::U32 keysym, rdr::U32 xtcode, bool down) {
#ifdef HAVE_XTEST
if (!haveXtest) return;
int keycode = XKeysymToKeycode(dpy, key);
int keycode = XKeysymToKeycode(dpy, keysym);
if (keycode)
XTestFakeKeyEvent(dpy, keycode, down, CurrentTime);
#endif

+ 1
- 1
unix/xserver/hw/vnc/XserverDesktop.cc Parādīt failu

@@ -771,7 +771,7 @@ void XserverDesktop::grabRegion(const rfb::Region& region)
}
}

void XserverDesktop::keyEvent(rdr::U32 keysym, bool down)
void XserverDesktop::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down)
{
vncKeyboardEvent(keysym, down);
}

+ 1
- 1
unix/xserver/hw/vnc/XserverDesktop.h Parādīt failu

@@ -89,7 +89,7 @@ public:

// rfb::SDesktop callbacks
virtual void pointerEvent(const rfb::Point& pos, int buttonMask);
virtual void keyEvent(rdr::U32 key, bool down);
virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
virtual void clientCutText(const char* str, int len);
virtual rfb::Point getFbSize() { return rfb::Point(width(), height()); }
virtual unsigned int setScreenLayout(int fb_width, int fb_height,

+ 6
- 6
vncviewer/Viewport.cxx Parādīt failu

@@ -709,8 +709,8 @@ void Viewport::handleKeyPress(int keyCode, rdr::U32 keySym)
if (ctrlPressed && altPressed) {
vlog.debug("Faking release of AltGr (Ctrl_L+Alt_R)");
try {
cc->writer()->keyEvent(XK_Control_L, false);
cc->writer()->keyEvent(XK_Alt_R, false);
cc->writer()->keyEvent(XK_Control_L, 0, false);
cc->writer()->keyEvent(XK_Alt_R, 0, false);
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(e.str());
@@ -732,7 +732,7 @@ void Viewport::handleKeyPress(int keyCode, rdr::U32 keySym)
#endif

try {
cc->writer()->keyEvent(keySym, true);
cc->writer()->keyEvent(keySym, 0, true);
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(e.str());
@@ -743,8 +743,8 @@ void Viewport::handleKeyPress(int keyCode, rdr::U32 keySym)
if (ctrlPressed && altPressed) {
vlog.debug("Restoring AltGr state");
try {
cc->writer()->keyEvent(XK_Control_L, true);
cc->writer()->keyEvent(XK_Alt_R, true);
cc->writer()->keyEvent(XK_Control_L, 0, true);
cc->writer()->keyEvent(XK_Alt_R, 0, true);
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(e.str());
@@ -777,7 +777,7 @@ void Viewport::handleKeyRelease(int keyCode)
#endif

try {
cc->writer()->keyEvent(iter->second, false);
cc->writer()->keyEvent(iter->second, 0, false);
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
exit_vncviewer(e.str());

+ 2
- 2
win/rfb_win32/SDisplay.cxx Parādīt failu

@@ -280,12 +280,12 @@ void SDisplay::pointerEvent(const Point& pos, int buttonmask) {
}
}

void SDisplay::keyEvent(rdr::U32 key, bool down) {
void SDisplay::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down) {
// - Check that the SDesktop doesn't need restarting
if (isRestartRequired())
restartCore();
if (kbd)
kbd->keyEvent(key, down);
kbd->keyEvent(keysym, keycode, down);
}

bool SDisplay::checkLedState() {

+ 1
- 1
win/rfb_win32/SDisplay.h Parādīt failu

@@ -66,7 +66,7 @@ namespace rfb {
virtual void start(VNCServer* vs);
virtual void stop();
virtual void pointerEvent(const Point& pos, int buttonmask);
virtual void keyEvent(rdr::U32 key, bool down);
virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
virtual void clientCutText(const char* str, int len);
virtual Point getFbSize();


+ 1
- 1
win/rfb_win32/SInput.cxx Parādīt failu

@@ -321,7 +321,7 @@ win32::SKeyboard::SKeyboard()
}


void win32::SKeyboard::keyEvent(rdr::U32 keysym, bool down)
void win32::SKeyboard::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down)
{
for (unsigned int i = 0; i < sizeof(keysymToAscii) / sizeof(keysymToAscii_t); i++) {
if (keysymToAscii[i].keysym == keysym) {

+ 1
- 1
win/rfb_win32/SInput.h Parādīt failu

@@ -53,7 +53,7 @@ namespace rfb {
class SKeyboard {
public:
SKeyboard();
void keyEvent(rdr::U32 key, bool down);
void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
static BoolParameter deadKeyAware;
private:
std::map<rdr::U32,rdr::U8> vkMap;

Notiek ielāde…
Atcelt
Saglabāt