mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-11-25 06:16:37 +01:00
Merge pull request #1569 from anoobs/vnc_improvements_v2
Add support for EXT_KEY_EVENT encoding in XenCenter VNC
This commit is contained in:
commit
30b83bc0b1
@ -294,7 +294,7 @@ namespace XenAdmin.ConsoleView
|
||||
internal Set<int> pressedScans = new Set<int>();
|
||||
private bool modifierKeyPressedAlone = false;
|
||||
|
||||
private void handleRDPKey(bool pressed, int scancode)
|
||||
private void handleRDPKey(bool pressed, int scancode, int keysym)
|
||||
{
|
||||
bool containsFocus = parent.ParentForm != null && parent.ParentForm.ContainsFocus;
|
||||
|
||||
|
@ -964,7 +964,7 @@ namespace XenAdmin.ConsoleView
|
||||
|
||||
foreach (int key in pressedScans)
|
||||
{
|
||||
this.vncStream.keyScanEvent(false, key);
|
||||
this.vncStream.keyScanEvent(false, key, -1, Helpers.InvernessOrGreater(this.SourceVM.Connection));
|
||||
}
|
||||
});
|
||||
|
||||
@ -1285,7 +1285,7 @@ namespace XenAdmin.ConsoleView
|
||||
}
|
||||
}
|
||||
|
||||
public void keyScan(bool pressed, int scanCode)
|
||||
public void keyScan(bool pressed, int scanCode, int keySym)
|
||||
{
|
||||
if (KeyHandler.handleExtras<int>(pressed, pressedScans, KeyHandler.ExtraScans, scanCode, KeyHandler.ModifierScans, ref modifierKeyPressedAlone))
|
||||
{
|
||||
@ -1293,21 +1293,26 @@ namespace XenAdmin.ConsoleView
|
||||
{
|
||||
// send key up anyway
|
||||
modifierKeyPressedAlone = false;
|
||||
keyScan_(pressed, scanCode);
|
||||
keyScan_(pressed, scanCode, keySym);
|
||||
return;
|
||||
}
|
||||
this.Focus();
|
||||
return;
|
||||
}
|
||||
|
||||
keyScan_(pressed, scanCode);
|
||||
keyScan_(pressed, scanCode, keySym);
|
||||
}
|
||||
|
||||
private void keyScan_(bool pressed, int scanCode)
|
||||
{
|
||||
keyScan_(pressed, scanCode, -1);
|
||||
}
|
||||
|
||||
private void keyScan_(bool pressed, int scanCode, int keySym)
|
||||
{
|
||||
DoIfConnected(delegate()
|
||||
{
|
||||
this.vncStream.keyScanEvent(pressed, scanCode);
|
||||
this.vncStream.keyScanEvent(pressed, scanCode, keySym, Helpers.InvernessOrGreater(this.SourceVM.Connection));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ namespace DotNetVnc
|
||||
private static LowLevelKeyboardProc _proc = HookCallback;
|
||||
private static IntPtr _hookID = IntPtr.Zero;
|
||||
|
||||
public delegate void KeyEvent(bool down, int scancode);
|
||||
public delegate void KeyEvent(bool down, int scancode, int keysym);
|
||||
private static KeyEvent keyEvent = null;
|
||||
|
||||
#pragma warning disable 0649
|
||||
@ -195,7 +195,8 @@ namespace DotNetVnc
|
||||
}
|
||||
}
|
||||
|
||||
private const int NUM_LOCK_SCAN = 197;
|
||||
private const int RIGHT_SHIFT_SCAN = 54;
|
||||
private const int NUM_LOCK_SCAN = 69;
|
||||
|
||||
private static int HookCallback(int nCode, int wParam, KBDLLHOOKSTRUCT* lParam)
|
||||
{
|
||||
@ -207,22 +208,40 @@ namespace DotNetVnc
|
||||
{
|
||||
KBDLLHOOKSTRUCT kbStruct = *lParam;
|
||||
|
||||
bool extended = (kbStruct.flags & FLAG_EXTENDED) == 0;
|
||||
bool extended = (kbStruct.flags & FLAG_EXTENDED) == FLAG_EXTENDED;
|
||||
bool down = (wParam == WM_KEYDOWN) || (wParam == WM_SYSKEYDOWN);
|
||||
int scanCode = kbStruct.scanCode;
|
||||
int keySym = KeyMap.translateKey((Keys)kbStruct.vkCode);
|
||||
|
||||
/* kbStruct.scanCode for NUM_LOCK and PAUSE are the same (69).
|
||||
* But NUM_LOCK is an extended key, where as PAUSE is not.
|
||||
* QEMU doesn't support PAUSE and expects NUM_LOCK scanCode
|
||||
* to be sent as 69
|
||||
*/
|
||||
|
||||
switch (scanCode)
|
||||
{
|
||||
case 54:
|
||||
break;
|
||||
/* Although RIGHT_SHIFT, NUMS_LOCK are extended keys,
|
||||
* scan code for these keys are not prefixed with 0xe0.
|
||||
*/
|
||||
case RIGHT_SHIFT_SCAN:
|
||||
case NUM_LOCK_SCAN:
|
||||
break;
|
||||
default:
|
||||
scanCode += (extended ? 0 : 128);
|
||||
/* 128 is added to scanCode to differentiate
|
||||
* an extended key. Scan code for all extended keys
|
||||
* needs to be prefixed with 0xe0, so adding 128
|
||||
* or ( | 0x80) will give a hint to qemu that this
|
||||
* scanCode is an extended one and qemu can then prefix
|
||||
* scanCode with 0xe0
|
||||
*/
|
||||
scanCode += (extended ? 128 : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (InterceptKeys.keyEvent != null)
|
||||
{
|
||||
InterceptKeys.keyEvent(down, scanCode);
|
||||
InterceptKeys.keyEvent(down, scanCode, keySym);
|
||||
}
|
||||
|
||||
if (bubble || scanCode == NUM_LOCK_SCAN)
|
||||
|
@ -54,12 +54,14 @@ namespace DotNetVnc
|
||||
private const int CURSOR_PSEUDO_ENCODING = -239;
|
||||
private const int DESKTOP_SIZE_PSEUDO_ENCODING = -223;
|
||||
private const int XENCENTER_ENCODING = -254;
|
||||
private const int QEMU_EXT_KEY_ENCODING = -258;
|
||||
|
||||
private const int SET_PIXEL_FORMAT = 0;
|
||||
private const int SET_ENCODINGS = 2;
|
||||
private const int FRAMEBUFFER_UPDATE_REQUEST = 3;
|
||||
private const int KEY_EVENT = 4;
|
||||
private const int KEY_SCAN_EVENT = 254;
|
||||
private const int QEMU_MSG = 255;
|
||||
private const int POINTER_EVENT = 5;
|
||||
private const int CLIENT_CUT_TEXT = 6;
|
||||
|
||||
@ -73,6 +75,8 @@ namespace DotNetVnc
|
||||
private const int BELL = 2;
|
||||
private const int SERVER_CUT_TEXT = 3;
|
||||
|
||||
private const int QEMU_EXT_KEY_EVENT = 0;
|
||||
|
||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Thread thread = null;
|
||||
@ -118,7 +122,8 @@ namespace DotNetVnc
|
||||
RAW_ENCODING,
|
||||
CURSOR_PSEUDO_ENCODING,
|
||||
DESKTOP_SIZE_PSEUDO_ENCODING,
|
||||
XENCENTER_ENCODING
|
||||
XENCENTER_ENCODING,
|
||||
QEMU_EXT_KEY_ENCODING
|
||||
};
|
||||
|
||||
private readonly IVNCGraphicsClient client;
|
||||
@ -134,6 +139,7 @@ namespace DotNetVnc
|
||||
private int height;
|
||||
|
||||
private bool incremental;
|
||||
private bool qemu_ext_key_encoding = false;
|
||||
|
||||
private PixelFormat pixelFormat;
|
||||
private PixelFormat pixelFormatCursor;
|
||||
@ -468,13 +474,36 @@ namespace DotNetVnc
|
||||
this.stream.writeInt32(key);
|
||||
}
|
||||
|
||||
public void keyScanEvent(bool down, int key)
|
||||
private void writeQemuExtKey(int command, bool down, int key, int sym)
|
||||
{
|
||||
this.stream.writeInt8(command);
|
||||
this.stream.writeInt8(QEMU_EXT_KEY_EVENT);
|
||||
this.stream.writePadding(1);
|
||||
this.stream.writeFlag(down);
|
||||
this.stream.writeInt32(sym);
|
||||
this.stream.writeInt32(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* use_qemu_ext_key_encoding: Dictates if we want to use QEMU_EXT_KEY encoding.
|
||||
*
|
||||
* XS6.2 doesn't properly support QEMU_EXT_KEY and XS6.5 supports QEMU_EXT_KEY encoding
|
||||
* only if XS65ESP1051 is applied, so restrict QEMU_EXT_KEY encoding to Inverness and above.
|
||||
*/
|
||||
public void keyScanEvent(bool down, int key, int sym, bool use_qemu_ext_key_encoding)
|
||||
{
|
||||
lock (this.writeLock)
|
||||
{
|
||||
try
|
||||
{
|
||||
writeKey(KEY_SCAN_EVENT, down, key);
|
||||
if (qemu_ext_key_encoding && use_qemu_ext_key_encoding)
|
||||
{
|
||||
writeQemuExtKey(QEMU_MSG, down, key, sym);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeKey(KEY_SCAN_EVENT, down, key);
|
||||
}
|
||||
this.stream.Flush();
|
||||
}
|
||||
catch (IOException e)
|
||||
@ -1274,6 +1303,10 @@ namespace DotNetVnc
|
||||
incremental = false;
|
||||
break;
|
||||
|
||||
case QEMU_EXT_KEY_ENCODING:
|
||||
qemu_ext_key_encoding = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new VNCException("unimplemented encoding: " + encoding);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user