mirror of
https://github.com/kasmtech/KasmVNC.git
synced 2024-11-21 23:53:24 +01:00
Resolve KASM-2335 "Feature/ ime support"
This commit is contained in:
parent
0c020f2e79
commit
3f89e5c117
1
.gitignore
vendored
1
.gitignore
vendored
@ -21,3 +21,4 @@ debian/files
|
||||
debian/kasmvncserver.substvars
|
||||
debian/kasmvncserver/
|
||||
.pc
|
||||
.vscode/
|
||||
|
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -1,4 +1,4 @@
|
||||
[submodule "kasmweb"]
|
||||
path = kasmweb
|
||||
url = https://github.com/kasmtech/noVNC.git
|
||||
branch = master
|
||||
branch = feature/KASM-2335_IME_support_2
|
||||
|
@ -226,4 +226,4 @@ static void bandwidthPreset() {
|
||||
rfb::PresetParameter rfb::Server::preferBandwidth
|
||||
("PreferBandwidth",
|
||||
"Set various options for lower bandwidth use. The default is off, aka to prefer quality.",
|
||||
false, bandwidthPreset);
|
||||
false, bandwidthPreset);
|
@ -77,7 +77,6 @@ namespace rfb {
|
||||
static BoolParameter ignoreClientSettingsKasm;
|
||||
static BoolParameter selfBench;
|
||||
static PresetParameter preferBandwidth;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
2
kasmweb
2
kasmweb
@ -1 +1 @@
|
||||
Subproject commit df9c9d0d96acef17423c237fea9497850a6c1c17
|
||||
Subproject commit e2cc682243c55786e719436f214da0f0948f605a
|
@ -39,6 +39,7 @@
|
||||
#include "xkbsrv.h"
|
||||
#include "xkbstr.h"
|
||||
#include "xserver-properties.h"
|
||||
#include "stdbool.h"
|
||||
extern _X_EXPORT DevPrivateKey CoreDevicePrivateKey;
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/Xlib.h>
|
||||
@ -66,6 +67,8 @@ static const unsigned short *codeMap;
|
||||
static unsigned int codeMapLen;
|
||||
|
||||
static KeySym pressedKeys[256];
|
||||
static unsigned int needFree[256];
|
||||
static bool freeKeys;
|
||||
|
||||
static int vncPointerProc(DeviceIntPtr pDevice, int onoff);
|
||||
static void vncKeyboardBell(int percent, DeviceIntPtr device,
|
||||
@ -91,7 +94,7 @@ static void vncKeysymKeyboardEvent(KeySym keysym, int down);
|
||||
* Instead we call it from XserverDesktop at an appropriate
|
||||
* time.
|
||||
*/
|
||||
void vncInitInputDevice(void)
|
||||
void vncInitInputDevice(bool freeKeyMappings)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
@ -110,6 +113,8 @@ void vncInitInputDevice(void)
|
||||
codeMap = code_map_qnum_to_xorgkbd;
|
||||
codeMapLen = code_map_qnum_to_xorgkbd_len;
|
||||
#endif
|
||||
freeKeys = freeKeyMappings;
|
||||
memset(needFree, 0, sizeof(needFree));
|
||||
|
||||
for (i = 0;i < 256;i++)
|
||||
pressedKeys[i] = NoSymbol;
|
||||
@ -500,6 +505,7 @@ static void vncKeysymKeyboardEvent(KeySym keysym, int down)
|
||||
pressedKeys[i] = NoSymbol;
|
||||
pressKey(vncKeyboardDev, i, FALSE, "keycode");
|
||||
mieqProcessInputEvents();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -544,7 +550,7 @@ static void vncKeysymKeyboardEvent(KeySym keysym, int down)
|
||||
|
||||
/* No matches. Will have to add a new entry... */
|
||||
if (keycode == 0) {
|
||||
keycode = vncAddKeysym(keysym, state);
|
||||
keycode = vncAddKeysym(keysym, state, needFree, freeKeys);
|
||||
if (keycode == 0) {
|
||||
LOG_ERROR("Failure adding new keysym 0x%x", keysym);
|
||||
return;
|
||||
|
@ -25,12 +25,13 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <X11/X.h>
|
||||
#include "stdbool.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void vncInitInputDevice(void);
|
||||
void vncInitInputDevice(bool freeKeyMappings);
|
||||
|
||||
void vncPointerButtonAction(int buttonMask, const unsigned char skipclick,
|
||||
const unsigned char skiprelease);
|
||||
@ -57,7 +58,8 @@ KeyCode vncKeysymToKeycode(KeySym keysym, unsigned state, unsigned *new_state);
|
||||
|
||||
int vncIsAffectedByNumLock(KeyCode keycode);
|
||||
|
||||
KeyCode vncAddKeysym(KeySym keysym, unsigned state);
|
||||
KeyCode vncAddKeysym(KeySym keysym, unsigned state, unsigned int *needfree, bool freeKeys);
|
||||
void vncRemoveKeycode(unsigned keycode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -25,16 +25,19 @@
|
||||
#include "xorg-version.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#include "RFBGlue.h"
|
||||
#include "xkbsrv.h"
|
||||
#include "xkbstr.h"
|
||||
#include "eventstr.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "mi.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
#include "Input.h"
|
||||
|
||||
@ -50,7 +53,15 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define LOG_NAME "Input"
|
||||
|
||||
#define LOG_ERROR(...) vncLogError(LOG_NAME, __VA_ARGS__)
|
||||
#define LOG_STATUS(...) vncLogStatus(LOG_NAME, __VA_ARGS__)
|
||||
#define LOG_INFO(...) vncLogInfo(LOG_NAME, __VA_ARGS__)
|
||||
#define LOG_DEBUG(...) vncLogDebug(LOG_NAME, __VA_ARGS__)
|
||||
|
||||
extern DeviceIntPtr vncKeyboardDev;
|
||||
static unsigned int MAX_MAPPINGS = UINT_MAX - 1;
|
||||
|
||||
static void vncXkbProcessDeviceEvent(int screenNum,
|
||||
InternalEvent *event,
|
||||
@ -536,12 +547,16 @@ int vncIsAffectedByNumLock(KeyCode keycode)
|
||||
return 1;
|
||||
}
|
||||
|
||||
KeyCode vncAddKeysym(KeySym keysym, unsigned state)
|
||||
KeyCode vncAddKeysym(KeySym keysym, unsigned state, unsigned int *needFree, bool freeKeys)
|
||||
{
|
||||
DeviceIntPtr master;
|
||||
XkbDescPtr xkb;
|
||||
unsigned int key;
|
||||
|
||||
unsigned int key = 0;
|
||||
unsigned int i;
|
||||
unsigned int newest_k = 0;
|
||||
unsigned int oldest_k = 0;
|
||||
unsigned int freeCnt = 0;
|
||||
|
||||
XkbEventCauseRec cause;
|
||||
XkbChangesRec changes;
|
||||
|
||||
@ -551,14 +566,45 @@ KeyCode vncAddKeysym(KeySym keysym, unsigned state)
|
||||
|
||||
master = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT);
|
||||
xkb = master->key->xkbInfo->desc;
|
||||
for (key = xkb->max_key_code; key >= xkb->min_key_code; key--) {
|
||||
if (XkbKeyNumGroups(xkb, key) == 0)
|
||||
break;
|
||||
|
||||
//find the first free key to map
|
||||
for (i = xkb->max_key_code; i >= xkb->min_key_code; i--) {
|
||||
if (XkbKeyNumGroups(xkb, i) == 0 && *(needFree + i) != UINT_MAX) {
|
||||
if (++freeCnt == 1)
|
||||
key = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (key < xkb->min_key_code)
|
||||
return 0;
|
||||
|
||||
//find the oldest and newest keys that have been remapped
|
||||
for (i = 1;i < 256;i++) {
|
||||
//protect from uint rollover
|
||||
if (*(needFree + i) == MAX_MAPPINGS)
|
||||
*(needFree + i) = 1;
|
||||
if (*(needFree + i) > *(needFree + newest_k) && *(needFree + i) != UINT_MAX)
|
||||
newest_k = i;
|
||||
if (*(needFree + i) < *(needFree + oldest_k) && *(needFree +i) > 0)
|
||||
oldest_k = i;
|
||||
//mark as free to use
|
||||
if (*(needFree + i) == UINT_MAX)
|
||||
*(needFree + i) = 0;
|
||||
}
|
||||
*(needFree + key) = ++(*(needFree + newest_k));
|
||||
|
||||
//if running low on free keys, free the oldest key that was used
|
||||
if (freeCnt < 3 && *(needFree + oldest_k) > 0 && freeKeys) {
|
||||
vncRemoveKeycode(oldest_k);
|
||||
LOG_DEBUG("Removed mapping for keycode %d", oldest_k);
|
||||
//mark as free to use after one more cycle
|
||||
*(needFree + oldest_k) = UINT_MAX;
|
||||
} else if (freeCnt < 3 && freeKeys) {
|
||||
//this should only happen if the system had fewer than 3 free keys to begin with
|
||||
LOG_INFO("The system has fewer than 3 unmapped keys with no available keys to free.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&changes, 0, sizeof(changes));
|
||||
memset(&cause, 0, sizeof(cause));
|
||||
|
||||
@ -612,6 +658,40 @@ KeyCode vncAddKeysym(KeySym keysym, unsigned state)
|
||||
return key;
|
||||
}
|
||||
|
||||
void vncRemoveKeycode(unsigned keycode)
|
||||
{
|
||||
DeviceIntPtr master;
|
||||
XkbDescPtr xkb;
|
||||
|
||||
XkbEventCauseRec cause;
|
||||
XkbChangesRec changes;
|
||||
|
||||
master = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT);
|
||||
xkb = master->key->xkbInfo->desc;
|
||||
|
||||
memset(&changes, 0, sizeof(changes));
|
||||
memset(&cause, 0, sizeof(cause));
|
||||
|
||||
XkbSetCauseUnknown(&cause);
|
||||
|
||||
KeySym ks = NoSymbol;
|
||||
|
||||
KeySymsRec keysyms;
|
||||
keysyms.minKeyCode = keycode;
|
||||
keysyms.maxKeyCode = keycode;
|
||||
keysyms.mapWidth = 1;
|
||||
keysyms.map = &ks;
|
||||
|
||||
unsigned check = 0;
|
||||
XkbUpdateKeyTypesFromCore(master, &keysyms, keycode, 1, &changes);
|
||||
XkbUpdateActions(master, keycode, 1, &changes, &check, &cause);
|
||||
|
||||
if (check)
|
||||
XkbCheckSecondaryEffects(master->key->xkbInfo, 1, &changes, &cause);
|
||||
|
||||
XkbSendNotification(master, &changes, &cause);
|
||||
}
|
||||
|
||||
static void vncXkbProcessDeviceEvent(int screenNum,
|
||||
InternalEvent *event,
|
||||
DeviceIntPtr dev)
|
||||
|
@ -60,6 +60,10 @@ BoolParameter rawKeyboard("RawKeyboard",
|
||||
"Send keyboard events straight through and "
|
||||
"avoid mapping them to the current keyboard "
|
||||
"layout", false);
|
||||
BoolParameter freeKeyMappings("FreeKeyMappings",
|
||||
"Automatically free added keyboard mappings "
|
||||
"when there are not enough unused keys to "
|
||||
"map symbols to.", false);
|
||||
IntParameter queryConnectTimeout("QueryConnectTimeout",
|
||||
"Number of seconds to show the "
|
||||
"Accept Connection dialog before "
|
||||
@ -370,7 +374,7 @@ void XserverDesktop::blockHandler(int* timeout)
|
||||
// so we abuse the fact that this routine will be called first thing
|
||||
// once the dix is done initialising.
|
||||
// [1] Technically Xvnc has InitInput(), but libvnc.so has nothing.
|
||||
vncInitInputDevice();
|
||||
vncInitInputDevice(freeKeyMappings);
|
||||
|
||||
try {
|
||||
std::list<Socket*> sockets;
|
||||
|
Loading…
Reference in New Issue
Block a user