From c6042e0935ac9bfe37c1b3e6f3049c99a1dc2b72 Mon Sep 17 00:00:00 2001 From: Bryan Roe Date: Thu, 19 Sep 2019 16:38:19 -0700 Subject: [PATCH] Add Mouse Cursor Propagation Support to Windows KVM --- meshcore/KVM/Windows/input.c | 153 ++++++++++++++++++++++++++++++++++- meshcore/KVM/Windows/input.h | 22 ++++- meshcore/KVM/Windows/kvm.c | 13 ++- meshcore/meshdefines.h | 1 + 4 files changed, 184 insertions(+), 5 deletions(-) diff --git a/meshcore/KVM/Windows/input.c b/meshcore/KVM/Windows/input.c index 5416a28..cc6728b 100644 --- a/meshcore/KVM/Windows/input.c +++ b/meshcore/KVM/Windows/input.c @@ -21,6 +21,27 @@ limitations under the License. #include #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); } diff --git a/meshcore/KVM/Windows/input.h b/meshcore/KVM/Windows/input.h index 89f6131..4ea8cf9 100644 --- a/meshcore/KVM/Windows/input.h +++ b/meshcore/KVM/Windows/input.h @@ -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(); diff --git a/meshcore/KVM/Windows/kvm.c b/meshcore/KVM/Windows/kvm.c index e198980..6e90e20 100644 --- a/meshcore/KVM/Windows/kvm.c +++ b/meshcore/KVM/Windows/kvm.c @@ -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) diff --git a/meshcore/meshdefines.h b/meshcore/meshdefines.h index fa21451..0790b40 100644 --- a/meshcore/meshdefines.h +++ b/meshcore/meshdefines.h @@ -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,