aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2017-05-16 14:33:43 +0200
committerPierre Ossman <ossman@cendio.se>2017-08-28 13:54:30 +0200
commit16e1dcb85cbfe467e38ec053060a7e4fc908795e (patch)
treee5f42d45d156f017ad2465eb0639bef628d6a8eb /common
parentbdbad2aff959ae392714c18f4ce72f55c4ba6813 (diff)
downloadtigervnc-16e1dcb85cbfe467e38ec053060a7e4fc908795e.tar.gz
tigervnc-16e1dcb85cbfe467e38ec053060a7e4fc908795e.zip
Track keys based on client supplied key codes
This makes it easier to provide more sane events to the backend code even with crazy clients.
Diffstat (limited to 'common')
-rw-r--r--common/rfb/VNCSConnectionST.cxx50
-rw-r--r--common/rfb/VNCSConnectionST.h4
2 files changed, 44 insertions, 10 deletions
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index be496e73..674c3922 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -100,11 +100,18 @@ VNCSConnectionST::~VNCSConnectionST()
(closeReason.buf) ? closeReason.buf : "");
// Release any keys the client still had pressed
- 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, 0, false);
+ while (!pressedKeys.empty()) {
+ rdr::U32 keysym, keycode;
+
+ keysym = pressedKeys.begin()->second;
+ keycode = pressedKeys.begin()->first;
+ pressedKeys.erase(pressedKeys.begin());
+
+ vlog.debug("Releasing key 0x%x / 0x%x on client disconnect",
+ keysym, keycode);
+ server->desktop->keyEvent(keysym, keycode, false);
}
+
if (server->pointerClient == this)
server->pointerClient = 0;
@@ -553,6 +560,8 @@ 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 keysym, rdr::U32 keycode, bool down) {
+ rdr::U32 lookup;
+
lastEventTime = time(0);
server->lastUserInputTime = lastEventTime;
if (!(accessRights & AccessKeyEvents)) return;
@@ -648,18 +657,43 @@ void VNCSConnectionST::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down) {
// Turn ISO_Left_Tab into shifted Tab.
VNCSConnectionSTShiftPresser shiftPresser(server->desktop);
if (keysym == XK_ISO_Left_Tab) {
- if (pressedKeys.find(XK_Shift_L) == pressedKeys.end() &&
- pressedKeys.find(XK_Shift_R) == pressedKeys.end())
+ std::map<rdr::U32, rdr::U32>::const_iterator iter;
+ bool shifted;
+
+ shifted = false;
+ for (iter = pressedKeys.begin(); iter != pressedKeys.end(); ++iter) {
+ if ((iter->second == XK_Shift_L) ||
+ (iter->second == XK_Shift_R)) {
+ shifted = true;
+ break;
+ }
+ }
+
+ if (!shifted)
shiftPresser.press();
+
keysym = XK_Tab;
}
+ // We need to be able to track keys, so generate a fake index when we
+ // aren't given a keycode
+ if (keycode == 0)
+ lookup = 0x80000000 | keysym;
+ else
+ lookup = keycode;
+
+ // We force the same keysym for an already down key for the
+ // sake of sanity
+ if (pressedKeys.find(lookup) != pressedKeys.end())
+ keysym = pressedKeys[lookup];
+
if (down) {
- pressedKeys.insert(keysym);
+ pressedKeys[lookup] = keysym;
} else {
- if (!pressedKeys.erase(keysym))
+ if (!pressedKeys.erase(lookup))
return;
}
+
server->desktop->keyEvent(keysym, keycode, down);
}
diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h
index 9c58331e..d3bec93f 100644
--- a/common/rfb/VNCSConnectionST.h
+++ b/common/rfb/VNCSConnectionST.h
@@ -27,7 +27,7 @@
#ifndef __RFB_VNCSCONNECTIONST_H__
#define __RFB_VNCSCONNECTIONST_H__
-#include <set>
+#include <map>
#include <rfb/SConnection.h>
#include <rfb/SMsgWriter.h>
#include <rfb/VNCServerST.h>
@@ -210,7 +210,7 @@ namespace rfb {
Region cuRegion;
EncodeManager encodeManager;
- std::set<rdr::U32> pressedKeys;
+ std::map<rdr::U32, rdr::U32> pressedKeys;
time_t lastEventTime;
time_t pointerEventTime;