This is mainly a copy of XKeysymToString() from libX11. We've also added a wrapper that still gives a string, even if there is no name for the requested keysym. This grows the binaries a bit, but not with any extreme amount so is hopefully worth it to get better debug logging.pull/1705/head
@@ -32,6 +32,7 @@ | |||
#include <rfb/CMsgWriter.h> | |||
#include <rfb/CSecurity.h> | |||
#include <rfb/Decoder.h> | |||
#include <rfb/KeysymStr.h> | |||
#include <rfb/Security.h> | |||
#include <rfb/SecurityClient.h> | |||
#include <rfb/CConnection.h> |
@@ -24,6 +24,7 @@ add_library(rfb STATIC | |||
JpegCompressor.cxx | |||
JpegDecompressor.cxx | |||
KeyRemapper.cxx | |||
KeysymStr.c | |||
LogWriter.cxx | |||
Logger.cxx | |||
Logger_file.cxx |
@@ -0,0 +1,108 @@ | |||
/* | |||
Copyright 1990, 1998 The Open Group | |||
Permission to use, copy, modify, distribute, and sell this software and its | |||
documentation for any purpose is hereby granted without fee, provided that | |||
the above copyright notice appear in all copies and that both that | |||
copyright notice and this permission notice appear in supporting | |||
documentation. | |||
The above copyright notice and this permission notice shall be included in | |||
all copies or substantial portions of the Software. | |||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
Except as contained in this notice, the name of The Open Group shall not be | |||
used in advertising or otherwise to promote the sale, use or other dealings | |||
in this Software without prior written authorization from The Open Group. | |||
*/ | |||
#ifdef HAVE_CONFIG_H | |||
#include <config.h> | |||
#endif | |||
#include <stdlib.h> | |||
#include "keysymdef.h" | |||
#include "KeysymStr.h" | |||
#define NEEDKTABLE | |||
#define NEEDVTABLE | |||
#include "ks_tables.h" | |||
static const char *_XKeysymToString(unsigned ks) | |||
{ | |||
if (!ks || (ks & ((unsigned long) ~0x1fffffff)) != 0) | |||
return ((char *)NULL); | |||
if (ks == XK_VoidSymbol) | |||
ks = 0; | |||
if (ks <= 0x1fffffff) | |||
{ | |||
unsigned char val1 = ks >> 24; | |||
unsigned char val2 = (ks >> 16) & 0xff; | |||
unsigned char val3 = (ks >> 8) & 0xff; | |||
unsigned char val4 = ks & 0xff; | |||
int i = ks % VTABLESIZE; | |||
int h = i + 1; | |||
int n = VMAXHASH; | |||
int idx; | |||
while ((idx = hashKeysym[i])) | |||
{ | |||
const unsigned char *entry = &_XkeyTable[idx]; | |||
if ((entry[0] == val1) && (entry[1] == val2) && | |||
(entry[2] == val3) && (entry[3] == val4)) | |||
return ((char *)entry + 4); | |||
if (!--n) | |||
break; | |||
i += h; | |||
if (i >= VTABLESIZE) | |||
i -= VTABLESIZE; | |||
} | |||
} | |||
if (ks >= 0x01000100 && ks <= 0x0110ffff) { | |||
unsigned val = ks & 0xffffff; | |||
char *s; | |||
int i; | |||
if (val & 0xff0000) | |||
i = 10; | |||
else | |||
i = 6; | |||
s = malloc(i); | |||
if (s == NULL) | |||
return s; | |||
i--; | |||
s[i--] = '\0'; | |||
for (; i; i--){ | |||
unsigned char val1 = val & 0xf; | |||
val >>= 4; | |||
if (val1 < 10) | |||
s[i] = '0'+ val1; | |||
else | |||
s[i] = 'A'+ val1 - 10; | |||
} | |||
s[i] = 'U'; | |||
return s; | |||
} | |||
return ((char *) NULL); | |||
} | |||
const char* KeySymName(unsigned keysym) | |||
{ | |||
const char* name; | |||
name = _XKeysymToString(keysym); | |||
if (name == NULL) | |||
return "[unknown keysym]"; | |||
return name; | |||
} | |||
@@ -0,0 +1,32 @@ | |||
/* Copyright 2021 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_KEYSYMSTR_H__ | |||
#define __RFB_KEYSYMSTR_H__ | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
const char* KeySymName(unsigned keysym); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif |
@@ -28,6 +28,7 @@ | |||
#include <rfb/Encoder.h> | |||
#include <rfb/Exception.h> | |||
#include <rfb/KeyRemapper.h> | |||
#include <rfb/KeysymStr.h> | |||
#include <rfb/LogWriter.h> | |||
#include <rfb/Security.h> | |||
#include <rfb/ServerCore.h> | |||
@@ -89,8 +90,8 @@ VNCSConnectionST::~VNCSConnectionST() | |||
keycode = pressedKeys.begin()->first; | |||
pressedKeys.erase(pressedKeys.begin()); | |||
vlog.debug("Releasing key 0x%x / 0x%x on client disconnect", | |||
keysym, keycode); | |||
vlog.debug("Releasing key 0x%04x / XK_%s (0x%04x) on client disconnect", | |||
keycode, KeySymName(keysym), keysym); | |||
server->keyEvent(keysym, keycode, false); | |||
} | |||
@@ -514,9 +515,11 @@ void VNCSConnectionST::keyEvent(uint32_t keysym, uint32_t keycode, bool down) { | |||
if (!rfb::Server::acceptKeyEvents) return; | |||
if (down) | |||
vlog.debug("Key pressed: 0x%x / 0x%x", keysym, keycode); | |||
vlog.debug("Key pressed: 0x%04x / XK_%s (0x%04x)", | |||
keycode, KeySymName(keysym), keysym); | |||
else | |||
vlog.debug("Key released: 0x%x / 0x%x", keysym, keycode); | |||
vlog.debug("Key released: 0x%04x / XK_%s (0x%04x)", | |||
keycode, KeySymName(keysym), keysym); | |||
// Avoid lock keys if we don't know the server state | |||
if ((server->getLEDState() == ledUnknown) && |
@@ -58,6 +58,7 @@ | |||
#include <rfb/ComparingUpdateTracker.h> | |||
#include <rfb/Exception.h> | |||
#include <rfb/KeyRemapper.h> | |||
#include <rfb/KeysymStr.h> | |||
#include <rfb/LogWriter.h> | |||
#include <rfb/Security.h> | |||
#include <rfb/ServerCore.h> | |||
@@ -471,7 +472,8 @@ void VNCServerST::keyEvent(uint32_t keysym, uint32_t keycode, bool down) | |||
uint32_t newkey; | |||
newkey = keyRemapper->remapKey(keysym); | |||
if (newkey != keysym) { | |||
slog.debug("Key remapped to 0x%x", newkey); | |||
slog.debug("Key remapped to XK_%s (0x%x)", | |||
KeySymName(newkey), newkey); | |||
keysym = newkey; | |||
} | |||
} |
@@ -28,6 +28,9 @@ | |||
#include "vncExtInit.h" | |||
#include "RFBGlue.h" | |||
/* This is a C header, so safe to include */ | |||
#include <rfb/KeysymStr.h> | |||
#include "inputstr.h" | |||
#include "inpututils.h" | |||
#include "mi.h" | |||
@@ -404,7 +407,8 @@ static void vncKeysymKeyboardEvent(KeySym keysym, int down) | |||
* This can happen quite often as we ignore some | |||
* key presses. | |||
*/ | |||
LOG_DEBUG("Unexpected release of keysym 0x%x", keysym); | |||
LOG_DEBUG("Unexpected release of keysym XK_%s (0x%04x)", | |||
KeySymName(keysym), keysym); | |||
return; | |||
} | |||
@@ -466,12 +470,13 @@ static void vncKeysymKeyboardEvent(KeySym keysym, int down) | |||
if (keycode == 0) { | |||
keycode = vncAddKeysym(keysym, state); | |||
if (keycode == 0) { | |||
LOG_ERROR("Failure adding new keysym 0x%x", keysym); | |||
LOG_ERROR("Failure adding new keysym XK_%s (0x%x)", | |||
KeySymName(keysym), keysym); | |||
return; | |||
} | |||
LOG_INFO("Added keysym 0x%x to keycode %d", | |||
keysym, keycode); | |||
LOG_INFO("Added keysym XK_%s (0x%04x) to keycode %d", | |||
KeySymName(keysym), keysym, keycode); | |||
/* | |||
* The state given to addKeysym() is just a hint and | |||
@@ -480,7 +485,8 @@ static void vncKeysymKeyboardEvent(KeySym keysym, int down) | |||
*/ | |||
keycode = vncKeysymToKeycode(keysym, state, &new_state); | |||
if (keycode == 0) { | |||
LOG_ERROR("Newly added keysym 0x%x cannot be generated", keysym); | |||
LOG_ERROR("Newly added keysym XK_%s (0x%x) cannot be generated", | |||
KeySymName(keysym), keysym); | |||
return; | |||
} | |||
} | |||
@@ -501,7 +507,8 @@ static void vncKeysymKeyboardEvent(KeySym keysym, int down) | |||
KeyCode keycode2; | |||
unsigned new_state2; | |||
LOG_DEBUG("Finding alternative to keysym 0x%x to avoid fake shift for numpad", keysym); | |||
LOG_DEBUG("Finding alternative to keysym XK_%s (0x%x) to avoid fake shift for numpad", | |||
KeySymName(keysym), keysym); | |||
for (i = 0;i < sizeof(altKeysym)/sizeof(altKeysym[0]);i++) { | |||
KeySym altsym; | |||
@@ -610,7 +617,8 @@ static void vncKeysymKeyboardEvent(KeySym keysym, int down) | |||
if (i == keycode) | |||
continue; | |||
if (pressedKeys[i] == keysym) { | |||
LOG_ERROR("Keysym 0x%x generated by both keys %d and %d", keysym, i, keycode); | |||
LOG_ERROR("Keysym XK_%s (0x%04x) generated by both keys %d and %d", | |||
KeySymName(keysym), keysym, i, keycode); | |||
pressedKeys[i] = NoSymbol; | |||
} | |||
} |
@@ -28,6 +28,7 @@ | |||
#include <rfb/CMsgWriter.h> | |||
#include <rfb/LogWriter.h> | |||
#include <rfb/Exception.h> | |||
#include <rfb/KeysymStr.h> | |||
#include <rfb/ledStates.h> | |||
#include <rfb/util.h> | |||
@@ -867,12 +868,8 @@ void Viewport::handleKeyPress(int keyCode, uint32_t keySym) | |||
// and send the same on release. | |||
downKeySym[keyCode] = keySym; | |||
#if defined(WIN32) || defined(__APPLE__) | |||
vlog.debug("Key pressed: 0x%04x => 0x%04x", keyCode, keySym); | |||
#else | |||
vlog.debug("Key pressed: 0x%04x => XK_%s (0x%04x)", | |||
keyCode, XKeysymToString(keySym), keySym); | |||
#endif | |||
keyCode, KeySymName(keySym), keySym); | |||
try { | |||
// Fake keycode? | |||
@@ -902,12 +899,8 @@ void Viewport::handleKeyRelease(int keyCode) | |||
return; | |||
} | |||
#if defined(WIN32) || defined(__APPLE__) | |||
vlog.debug("Key released: 0x%04x => 0x%04x", keyCode, iter->second); | |||
#else | |||
vlog.debug("Key released: 0x%04x => XK_%s (0x%04x)", | |||
keyCode, XKeysymToString(iter->second), iter->second); | |||
#endif | |||
keyCode, KeySymName(iter->second), iter->second); | |||
try { | |||
if (keyCode > 0xff) |