1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-14 23:33:38 +00:00

Add Mouse Cursor Propagation Support to Windows KVM

This commit is contained in:
Bryan Roe
2019-09-19 16:38:19 -07:00
parent 6a84582764
commit c6042e0935
4 changed files with 184 additions and 5 deletions

View File

@@ -21,6 +21,27 @@ limitations under the License.
#include <stdio.h>
#include "input.h"
#include "microstack/ILibCrypto.h"
extern void ILibAppendStringToDiskEx(char *FileName, char *data, int dataLen);
int CUR_CURRENT = 0;
int CUR_APPSTARTING;
int CUR_ARROW;
int CUR_CROSS;
int CUR_HAND;
int CUR_HELP;
int CUR_IBEAM;
int CUR_NO;
int CUR_SIZEALL;
int CUR_SIZENESW;
int CUR_SIZENS;
int CUR_SIZENWSE;
int CUR_SIZEWE;
int CUR_UPARROW;
int CUR_WAIT;
/*
#if defined(WIN32) && !defined(_WIN32_WCE)
#define _CRTDBG_MAP_ALLOC
@@ -38,13 +59,72 @@ MOUSEEVENTF_MIDDLEUP 0x0040
MOUSEEVENTF_DOUBLECLK 0x0088
*/
void MouseAction(double absX, double absY, int button, short wheel)
int KVM_GetCursorHash(HCURSOR hc, char *buffer, size_t bufferLen)
{
int crc = 0;
BITMAP bm;
ICONINFO ii;
GetIconInfo(hc, &ii);
if (GetObject(ii.hbmMask, sizeof(bm), &bm) == sizeof(bm))
{
//printf("CX: %ul, CY:%ul, Color: %ul, Showing: %d\n", bm.bmWidth, bm.bmHeight, ii.hbmColor, info.flags);
HDC hdcScreen = GetDC(NULL);
HDC hdcMem = CreateCompatibleDC(hdcScreen);
HBITMAP hbmCanvas = CreateCompatibleBitmap(hdcScreen, bm.bmWidth, ii.hbmColor ? bm.bmHeight : (bm.bmHeight / 2));
HGDIOBJ hbmold = SelectObject(hdcMem, hbmCanvas);
BITMAPINFO bmpInfo;
char *tmpBuffer;
ZeroMemory(&bmpInfo, sizeof(bmpInfo));
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biCompression = BI_RGB;
DrawIconEx(hdcMem, 0, 0, hc, bm.bmWidth, ii.hbmColor ? bm.bmHeight : (bm.bmHeight / 2), 0, NULL, DI_NORMAL);
GetDIBits(hdcScreen, hbmCanvas, 0, 0, NULL, &bmpInfo, DIB_RGB_COLORS);
tmpBuffer = (char*)malloc(bmpInfo.bmiHeader.biSizeImage);
bmpInfo.bmiHeader.biCompression = BI_RGB;
GetDIBits(hdcScreen, hbmCanvas, 0, (UINT)(ii.hbmColor ? bm.bmHeight : (bm.bmHeight / 2)), tmpBuffer, &bmpInfo, DIB_RGB_COLORS);
crc = util_crc((unsigned char*)tmpBuffer, bmpInfo.bmiHeader.biSizeImage, 0);
SelectObject(hdcMem, hbmold);
ReleaseDC(NULL, hdcMem);
ReleaseDC(NULL, hdcScreen);
}
return(crc);
}
void KVM_InitMouseCursors()
{
CUR_ARROW = KVM_GetCursorHash(LoadCursorA(NULL, IDC_ARROW), NULL, 0);
CUR_APPSTARTING = KVM_GetCursorHash(LoadCursorA(NULL, IDC_APPSTARTING), NULL, 0);
CUR_CROSS = KVM_GetCursorHash(LoadCursorA(NULL, IDC_CROSS), NULL, 0);
CUR_HAND = KVM_GetCursorHash(LoadCursorA(NULL, IDC_HAND), NULL, 0);
CUR_HELP = KVM_GetCursorHash(LoadCursorA(NULL, IDC_HELP), NULL, 0);
CUR_IBEAM = KVM_GetCursorHash(LoadCursorA(NULL, IDC_IBEAM), NULL, 0);
CUR_NO = KVM_GetCursorHash(LoadCursorA(NULL, IDC_NO), NULL, 0);
CUR_SIZEALL = KVM_GetCursorHash(LoadCursorA(NULL, IDC_SIZEALL), NULL, 0);
CUR_SIZENESW = KVM_GetCursorHash(LoadCursorA(NULL, IDC_SIZENESW), NULL, 0);
CUR_SIZENS = KVM_GetCursorHash(LoadCursorA(NULL, IDC_SIZENS), NULL, 0);
CUR_SIZENWSE = KVM_GetCursorHash(LoadCursorA(NULL, IDC_SIZENWSE), NULL, 0);
CUR_SIZEWE = KVM_GetCursorHash(LoadCursorA(NULL, IDC_SIZEWE), NULL, 0);
CUR_UPARROW = KVM_GetCursorHash(LoadCursorA(NULL, IDC_UPARROW), NULL, 0);
CUR_WAIT = KVM_GetCursorHash(LoadCursorA(NULL, IDC_WAIT), NULL, 0);
}
KVM_MouseCursors MouseAction(double absX, double absY, int button, short wheel)
{
INPUT mouse;
KVM_MouseCursors ret = KVM_MouseCursor_NOCHANGE;
if (button == 0x88) {
if (button == 0x88)
{
// Double click indication, no nothing on windows.
return;
return(ret);
}
mouse.type = INPUT_MOUSE;
@@ -56,6 +136,73 @@ void MouseAction(double absX, double absY, int button, short wheel)
mouse.mi.time = 0;
mouse.mi.dwExtraInfo = 0;
SendInput(1, &mouse, sizeof(INPUT));
CURSORINFO info = { 0 };
info.cbSize = sizeof(info);
GetCursorInfo(&info);
int i = KVM_GetCursorHash(info.hCursor, NULL, 0);
if (i != CUR_CURRENT)
{
CUR_CURRENT = i;
if (CUR_CURRENT == CUR_APPSTARTING)
{
ret = KVM_MouseCursor_APPSTARTING;
}
else if (CUR_CURRENT == CUR_ARROW)
{
ret = KVM_MouseCursor_ARROW;
}
else if (CUR_CURRENT == CUR_CROSS)
{
ret = KVM_MouseCursor_CROSS;
}
else if (CUR_CURRENT == CUR_HAND)
{
ret = KVM_MouseCursor_HAND;
}
else if (CUR_CURRENT == CUR_HELP)
{
ret = KVM_MouseCursor_HELP;
}
else if (CUR_CURRENT == CUR_IBEAM)
{
ret = KVM_MouseCursor_IBEAM;
}
else if (CUR_CURRENT == CUR_NO)
{
ret = KVM_MouseCursor_NO;
}
else if (CUR_CURRENT == CUR_SIZEALL)
{
ret = KVM_MouseCursor_SIZEALL;
}
else if (CUR_CURRENT == CUR_SIZENESW)
{
ret = KVM_MouseCursor_SIZENESW;
}
else if (CUR_CURRENT == CUR_SIZENS)
{
ret = KVM_MouseCursor_SIZENS;
}
else if (CUR_CURRENT == CUR_SIZENWSE)
{
ret = KVM_MouseCursor_SIZENWSE;
}
else if (CUR_CURRENT == CUR_SIZEWE)
{
ret = KVM_MouseCursor_SIZEWE;
}
else if (CUR_CURRENT == CUR_UPARROW)
{
ret = KVM_MouseCursor_UPARROW;
}
else if (CUR_CURRENT == CUR_WAIT)
{
ret = KVM_MouseCursor_WAIT;
}
}
return(ret);
}

View File

@@ -16,7 +16,27 @@ limitations under the License.
#if defined(_LINKVM)
void MouseAction(double absX, double absY, int button, short wheel);
typedef enum KVM_MouseCursors
{
KVM_MouseCursor_NOCHANGE = -1,
KVM_MouseCursor_ARROW = 0,
KVM_MouseCursor_APPSTARTING = 1,
KVM_MouseCursor_CROSS = 2,
KVM_MouseCursor_HAND = 3,
KVM_MouseCursor_HELP = 4,
KVM_MouseCursor_IBEAM = 5,
KVM_MouseCursor_NO = 6,
KVM_MouseCursor_SIZEALL = 7,
KVM_MouseCursor_SIZENESW = 8,
KVM_MouseCursor_SIZENS = 9,
KVM_MouseCursor_SIZENWSE = 10,
KVM_MouseCursor_SIZEWE = 11,
KVM_MouseCursor_UPARROW = 12,
KVM_MouseCursor_WAIT = 13
}KVM_MouseCursors;
void KVM_InitMouseCursors();
KVM_MouseCursors MouseAction(double absX, double absY, int button, short wheel);
void KeyAction(unsigned char keycode, int up);
int TouchInit();
void TouchUnInit();

View File

@@ -490,6 +490,8 @@ int kvm_server_inputdata(char* block, int blocklen, ILibKVM_WriteHandler writeHa
{
double x, y;
short w = 0;
KVM_MouseCursors curcursor = KVM_MouseCursor_NOCHANGE;
if (size == 10 || size == 12)
{
// Get positions and scale correctly
@@ -506,7 +508,15 @@ int kvm_server_inputdata(char* block, int blocklen, ILibKVM_WriteHandler writeHa
// Perform the mouse movement
if (size == 12) w = ((short)ntohs(((short*)(block))[5]));
MouseAction((((double)x / (double)SCREEN_WIDTH)), (((double)y / (double)SCREEN_HEIGHT)), (int)(unsigned char)(block[5]), w);
curcursor = MouseAction((((double)x / (double)SCREEN_WIDTH)), (((double)y / (double)SCREEN_HEIGHT)), (int)(unsigned char)(block[5]), w);
if (curcursor != KVM_MouseCursor_NOCHANGE)
{
char buffer[8];
((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_KVM_MOUSE_CURSOR); // Write the type
((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)5); // Write the size
buffer[4] = (char)curcursor; // Cursor Type
writeHandler((char*)buffer, 5, reserved);
}
}
break;
}
@@ -786,6 +796,7 @@ DWORD WINAPI kvm_server_mainloop(LPVOID parm)
ILibKVM_WriteHandler writeHandler = (ILibKVM_WriteHandler)((void**)parm)[0];
void *reserved = ((void**)parm)[1];
KVM_InitMouseCursors();
#ifdef _WINSERVICE
if (!kvmConsoleMode)

View File

@@ -26,6 +26,7 @@ typedef enum RemoteManagementCommands
MNG_KVM_NOP = 0,
MNG_KVM_KEY = 1,
MNG_KVM_MOUSE = 2,
MNG_KVM_MOUSE_CURSOR = 88,
MNG_KVM_PICTURE = 3,
MNG_KVM_COPY = 4,
MNG_KVM_COMPRESSION = 5,