From 7c77677b3e2316e72807b4329fdba944771094dc Mon Sep 17 00:00:00 2001 From: Bryan Roe Date: Tue, 25 Feb 2020 15:24:00 -0800 Subject: [PATCH] 1. Updated Mouse Cursor Update to be event driven 2. Added support for remote mouse cursor rendering on Windows --- meshcore/KVM/Windows/input.c | 312 ++++++++++++++++++++++++---------- meshcore/KVM/Windows/input.h | 3 +- meshcore/KVM/Windows/kvm.c | 66 ++++--- meshcore/KVM/Windows/tile.cpp | 32 +++- meshcore/KVM/Windows/tile.h | 2 +- meshcore/agentcore.c | 5 +- meshcore/meshdefines.h | 1 + 7 files changed, 303 insertions(+), 118 deletions(-) diff --git a/meshcore/KVM/Windows/input.c b/meshcore/KVM/Windows/input.c index 9b917e3..324b983 100644 --- a/meshcore/KVM/Windows/input.c +++ b/meshcore/KVM/Windows/input.c @@ -22,8 +22,18 @@ limitations under the License. #include "input.h" #include "microstack/ILibCrypto.h" +#include "meshcore/meshdefines.h" extern void ILibAppendStringToDiskEx(char *FileName, char *data, int dataLen); +extern ILibQueue gPendingPackets; +extern int gRemoteMouseRenderDefault; +uint64_t gMouseInputTime = 0; + +HWINEVENTHOOK CUR_HOOK = NULL; +WNDCLASSEXA CUR_WNDCLASS; +HWND CUR_HWND = NULL; +HANDLE CUR_APCTHREAD = NULL; +HANDLE CUR_WORKTHREAD = NULL; int CUR_CURRENT = 0; int CUR_APPSTARTING; @@ -59,6 +69,68 @@ MOUSEEVENTF_MIDDLEUP 0x0040 MOUSEEVENTF_DOUBLECLK 0x0088 */ +int KVM_CursorHashToMSG(int hashcode) +{ + int ret = KVM_MouseCursor_ARROW; + if (hashcode == CUR_APPSTARTING) + { + ret = KVM_MouseCursor_APPSTARTING; + } + else if (hashcode == CUR_ARROW) + { + ret = KVM_MouseCursor_ARROW; + } + else if (hashcode == CUR_CROSS) + { + ret = KVM_MouseCursor_CROSS; + } + else if (hashcode == CUR_HAND) + { + ret = KVM_MouseCursor_HAND; + } + else if (hashcode == CUR_HELP) + { + ret = KVM_MouseCursor_HELP; + } + else if (hashcode == CUR_IBEAM) + { + ret = KVM_MouseCursor_IBEAM; + } + else if (hashcode == CUR_NO) + { + ret = KVM_MouseCursor_NO; + } + else if (hashcode == CUR_SIZEALL) + { + ret = KVM_MouseCursor_SIZEALL; + } + else if (hashcode == CUR_SIZENESW) + { + ret = KVM_MouseCursor_SIZENESW; + } + else if (hashcode == CUR_SIZENS) + { + ret = KVM_MouseCursor_SIZENS; + } + else if (hashcode == CUR_SIZENWSE) + { + ret = KVM_MouseCursor_SIZENWSE; + } + else if (hashcode == CUR_SIZEWE) + { + ret = KVM_MouseCursor_SIZEWE; + } + else if (hashcode == CUR_UPARROW) + { + ret = KVM_MouseCursor_UPARROW; + } + else if (hashcode == CUR_WAIT) + { + ret = KVM_MouseCursor_WAIT; + } + return(ret); +} + int KVM_GetCursorHash(HCURSOR hc, char *buffer, size_t bufferLen) { int crc = 0; @@ -71,33 +143,160 @@ int KVM_GetCursorHash(HCURSOR hc, char *buffer, size_t bufferLen) { //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; + if (hdcScreen != NULL) + { + HDC hdcMem = CreateCompatibleDC(hdcScreen); + HBITMAP hbmCanvas = CreateCompatibleBitmap(hdcScreen, bm.bmWidth, ii.hbmColor ? bm.bmHeight : (bm.bmHeight / 2)); + if (hdcMem != NULL && hbmCanvas != NULL) + { + HGDIOBJ hbmold = SelectObject(hdcMem, hbmCanvas); + BITMAPINFO bmpInfo; + char *tmpBuffer; - ZeroMemory(&bmpInfo, sizeof(bmpInfo)); - bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmpInfo.bmiHeader.biCompression = BI_RGB; + 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); - if ((tmpBuffer = (char*)malloc(bmpInfo.bmiHeader.biSizeImage)) == NULL) { ILIBCRITICALEXIT(254); } + 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); + if ((tmpBuffer = (char*)malloc(bmpInfo.bmiHeader.biSizeImage)) == NULL) { ILIBCRITICALEXIT(254); } - 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); + 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); - free(tmpBuffer); - SelectObject(hdcMem, hbmold); - ReleaseDC(NULL, hdcMem); - ReleaseDC(NULL, hdcScreen); + free(tmpBuffer); + SelectObject(hdcMem, hbmold); + } + if (hbmCanvas != NULL) { DeleteObject(hbmCanvas); } + if (hdcMem != NULL) { ReleaseDC(NULL, hdcMem); } + if (hdcScreen != NULL) { ReleaseDC(NULL, hdcScreen); } + } } return(crc); } +void __stdcall KVM_APCSink(ULONG_PTR user) +{ + ILibQueue_EnQueue(gPendingPackets, (char*)user); +} +void CALLBACK KVMWinEventProc( + HWINEVENTHOOK hook, + DWORD event, + HWND hwnd, + LONG idObject, + LONG idChild, + DWORD idEventThread, + DWORD time) +{ + char *buffer; + CURSORINFO info = { 0 }; + int i; + + if (hwnd == NULL && idObject == OBJID_CURSOR) + { + switch (event) + { + case EVENT_OBJECT_LOCATIONCHANGE: + if (gRemoteMouseRenderDefault != 0 || ((uint64_t)ILibGetUptime() - gMouseInputTime) > 500) + { + info.cbSize = sizeof(info); + GetCursorInfo(&info); + + buffer = (char*)ILibMemory_SmartAllocate(12); + ((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_KVM_MOUSE_MOVE); // Write the type + ((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)12); // Write the size + ((long*)buffer)[1] = info.ptScreenPos.x; + ((long*)buffer)[2] = info.ptScreenPos.y; + QueueUserAPC((PAPCFUNC)KVM_APCSink, CUR_APCTHREAD, (ULONG_PTR)buffer); + } + break; + case EVENT_OBJECT_NAMECHANGE: + case EVENT_OBJECT_HIDE: + // Mouse Cursor has changed + info.cbSize = sizeof(info); + GetCursorInfo(&info); + i = KVM_CursorHashToMSG(KVM_GetCursorHash(info.hCursor, NULL, 0)); + + buffer = (char*)ILibMemory_SmartAllocate(5); + ((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)i; // Cursor Type + QueueUserAPC((PAPCFUNC)KVM_APCSink, CUR_APCTHREAD, (ULONG_PTR)buffer); + break; + default: + //printf("Unknown: %ul\n", event); + break; + } + } +} + +void KVM_StopMessagePump() +{ + if (CUR_HWND != NULL) + { + PostMessageA(CUR_HWND, WM_QUIT, 0, 0); + WaitForSingleObject(CUR_WORKTHREAD, 5000); + } +} + +void KVM_UnInitMouseCursors() +{ + if (CUR_HOOK != NULL) + { + UnhookWinEvent(CUR_HOOK); + CUR_HOOK = NULL; + + KVM_StopMessagePump(); + } +} + +LRESULT CALLBACK KVMWindowProc( + _In_ HWND hwnd, + _In_ UINT uMsg, + _In_ WPARAM wParam, + _In_ LPARAM lParam +) +{ + if (uMsg == WM_CREATE) + { + CUR_HOOK = SetWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_NAMECHANGE, NULL, KVMWinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT); + } + return(DefWindowProcA(hwnd, uMsg, wParam, lParam)); +} + +void KVM_PumpMessage() +{ + MSG m; + while (GetMessageA(&m, CUR_HWND, 0, 0) > 0) + { + TranslateMessage(&m); + DispatchMessageA(&m); + } +} + +DWORD WINAPI KVM_InitMessagePumpEx(LPVOID parm) +{ + memset(&CUR_WNDCLASS, 0, sizeof(CUR_WNDCLASS)); + CUR_WNDCLASS.hInstance = GetModuleHandleA(NULL); + CUR_WNDCLASS.lpszClassName = "MainWWW2Class"; + CUR_WNDCLASS.cbSize = sizeof(CUR_WNDCLASS); + CUR_WNDCLASS.lpfnWndProc = KVMWindowProc; + + if (RegisterClassExA(&CUR_WNDCLASS) != 0) + { + CUR_HWND = CreateWindowExA(0x00000088, "MainWWW2Class", "TestTitle", 0x00800000, 0, 0, 100, 100, 0, 0, 0, 0); + KVM_PumpMessage(); + } + return(0); +} +void KVM_InitMessagePump() +{ + CUR_APCTHREAD = OpenThread(THREAD_ALL_ACCESS, FALSE, GetCurrentThreadId()); + CUR_WORKTHREAD = CreateThread(NULL, 0, KVM_InitMessagePumpEx, NULL, 0, 0); +} + void KVM_InitMouseCursors() { CUR_ARROW = KVM_GetCursorHash(LoadCursorA(NULL, IDC_ARROW), NULL, 0); @@ -113,18 +312,19 @@ void KVM_InitMouseCursors() 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); + CUR_WAIT = KVM_GetCursorHash(LoadCursorA(NULL, IDC_WAIT), NULL, 0); + + KVM_InitMessagePump(); } -KVM_MouseCursors MouseAction(double absX, double absY, int button, short wheel) +void MouseAction(double absX, double absY, int button, short wheel) { INPUT mouse; - KVM_MouseCursors ret = KVM_MouseCursor_NOCHANGE; if (button == 0x88) { // Double click indication, no nothing on windows. - return(ret); + return; } mouse.type = INPUT_MOUSE; @@ -135,74 +335,8 @@ KVM_MouseCursors MouseAction(double absX, double absY, int button, short wheel) if (wheel) mouse.mi.dwFlags |= MOUSEEVENTF_WHEEL; mouse.mi.time = 0; mouse.mi.dwExtraInfo = 0; + gMouseInputTime = (uint64_t)ILibGetUptime(); 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 4ea8cf9..4382bcd 100644 --- a/meshcore/KVM/Windows/input.h +++ b/meshcore/KVM/Windows/input.h @@ -36,7 +36,8 @@ typedef enum KVM_MouseCursors }KVM_MouseCursors; void KVM_InitMouseCursors(); -KVM_MouseCursors MouseAction(double absX, double absY, int button, short wheel); +void KVM_UnInitMouseCursors(); +void 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 e700664..3e4cc2e 100644 --- a/meshcore/KVM/Windows/kvm.c +++ b/meshcore/KVM/Windows/kvm.c @@ -38,6 +38,7 @@ limitations under the License. // #define KVMDEBUGENABLED 1 ILibProcessPipe_SpawnTypes gProcessSpawnType = ILibProcessPipe_SpawnTypes_USER; int gProcessTSID = -1; +extern int gRemoteMouseRenderDefault; #pragma pack(push, 1) typedef struct KVMDebugLog @@ -115,6 +116,8 @@ HANDLE hStdIn = INVALID_HANDLE_VALUE; int ThreadRunning = 0; int kvmConsoleMode = 0; +ILibQueue gPendingPackets = NULL; + ILibRemoteLogging gKVMRemoteLogging = NULL; #ifdef _WINSERVICE void kvm_slave_OnRawForwardLog(ILibRemoteLogging sender, ILibRemoteLogging_Modules module, ILibRemoteLogging_Flags flags, char *buffer, int bufferLen) @@ -509,15 +512,7 @@ int kvm_server_inputdata(char* block, int blocklen, ILibKVM_WriteHandler writeHa // Perform the mouse movement if (size == 12) w = ((short)ntohs(((short*)(block))[5])); - 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); - } + MouseAction((((double)x / (double)SCREEN_WIDTH)), (((double)y / (double)SCREEN_HEIGHT)), (int)(unsigned char)(block[5]), w); } break; } @@ -819,7 +814,10 @@ DWORD WINAPI kvm_server_mainloop_ex(LPVOID parm) int row, col; ILibKVM_WriteHandler writeHandler = (ILibKVM_WriteHandler)((void**)parm)[0]; void *reserved = ((void**)parm)[1]; - + char *tmoBuffer; + long mouseMove[3] = { 0,0,0 }; + + gPendingPackets = ILibQueue_Create(); KVM_InitMouseCursors(); #ifdef _WINSERVICE @@ -895,18 +893,6 @@ DWORD WINAPI kvm_server_mainloop_ex(LPVOID parm) // Loop and send only when a tile changes. while (!g_shutdown) { - /* - cur_timestamp = util_gettime(); - if (prev_timestamp != 0) - { - time_diff = (FRAME_RATE_TIMER - (cur_timestamp - prev_timestamp)); - if (time_diff < 20) { time_diff = 20; } - } - printf("%d\r\n", cur_timestamp); - Sleep(time_diff); - prev_timestamp = cur_timestamp; - */ - KVMDEBUG("kvm_server_mainloop / loop1", (int)GetCurrentThreadId()); // Reset all the flags to TILE_TODO @@ -918,8 +904,29 @@ DWORD WINAPI kvm_server_mainloop_ex(LPVOID parm) CheckDesktopSwitch(1, writeHandler, reserved); if (g_shutdown) break; + + // Enter Alertable State, so we can dispatch any packets if necessary. + // We are doing it here, in case we need to merge any data with the bitmaps + SleepEx(0, TRUE); + mouseMove[0] = 0; + while ((tmoBuffer = ILibQueue_DeQueue(gPendingPackets)) != NULL) + { + if (ntohs(((unsigned short*)tmoBuffer)[0]) == MNG_KVM_MOUSE_MOVE) + { + mouseMove[0] = 1; + mouseMove[1] = ((long*)tmoBuffer)[1] - VSCREEN_X; + mouseMove[2] = ((long*)tmoBuffer)[2] - VSCREEN_Y; + } + else + { + writeHandler(tmoBuffer, (int)ILibMemory_Size(tmoBuffer), reserved); + } + ILibMemory_Free(tmoBuffer); + } + + // Scan the desktop - if (get_desktop_buffer(&desktop, &desktopsize) == 1 || desktop == NULL) + if (get_desktop_buffer(&desktop, &desktopsize, mouseMove) == 1 || desktop == NULL) { #ifdef _WINSERVICE if (!kvmConsoleMode) @@ -930,7 +937,8 @@ DWORD WINAPI kvm_server_mainloop_ex(LPVOID parm) KVMDEBUG("get_desktop_buffer() failed, shutting down", (int)GetCurrentThreadId()); g_shutdown = 1; } - else { + else + { bmpInfo = get_bmp_info(TILE_WIDTH, TILE_HEIGHT); for (row = 0; row < TILE_HEIGHT_COUNT; row++) { for (col = 0; col < TILE_WIDTH_COUNT; col++) { @@ -983,7 +991,6 @@ DWORD WINAPI kvm_server_mainloop_ex(LPVOID parm) } KVMDEBUG("kvm_server_mainloop / end3", (int)GetCurrentThreadId()); - KVMDEBUG("kvm_server_mainloop / end2", (int)GetCurrentThreadId()); // if (kvmthread != NULL) { CloseHandle(kvmthread); kvmthread = NULL; } @@ -997,6 +1004,15 @@ DWORD WINAPI kvm_server_mainloop_ex(LPVOID parm) KVMDEBUG("kvm_server_mainloop / end", (int)GetCurrentThreadId()); + KVM_UnInitMouseCursors(); + + while ((tmoBuffer = ILibQueue_DeQueue(gPendingPackets)) != NULL) + { + ILibMemory_Free(tmoBuffer); + } + ILibQueue_Destroy(gPendingPackets); + + ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: Process Exiting..."); ThreadRunning = 0; diff --git a/meshcore/KVM/Windows/tile.cpp b/meshcore/KVM/Windows/tile.cpp index 5b198ef..821a64d 100644 --- a/meshcore/KVM/Windows/tile.cpp +++ b/meshcore/KVM/Windows/tile.cpp @@ -478,7 +478,7 @@ int get_tile_at(int x, int y, void** buffer, long long *bufferSize, void *deskto } // This function captures the entire desktop buffer to scan. -int get_desktop_buffer(void **buffer, long long *bufferSize) +int get_desktop_buffer(void **buffer, long long *bufferSize, long* mouseMove) { BITMAPINFO bmpInfo; @@ -502,6 +502,36 @@ int get_desktop_buffer(void **buffer, long long *bufferSize) KVMDEBUG("BitBlt() returned FALSE", 0); return 1; // If the copy fails, error out. } + if (mouseMove[0] != 0) + { + CURSORINFO info = { 0 }; + BITMAP bm; + ICONINFO ii; + info.cbSize = sizeof(info); + GetCursorInfo(&info); + GetIconInfo(info.hCursor, &ii); + if (GetObject(ii.hbmMask, sizeof(bm), &bm) == sizeof(bm)) + { + HDC hdcScreen = GetDC(NULL); + if (hdcScreen != NULL) + { + HDC hdcMem = CreateCompatibleDC(hdcScreen); + HBITMAP hbmCanvas = CreateCompatibleBitmap(hdcScreen, bm.bmWidth, ii.hbmColor ? bm.bmHeight : (bm.bmHeight / 2)); + if(hdcMem!=NULL && hbmCanvas != NULL) + { + HGDIOBJ hbmold = SelectObject(hdcMem, hbmCanvas); + + DrawIconEx(hdcMem, 0, 0, info.hCursor, bm.bmWidth, ii.hbmColor ? bm.bmHeight : (bm.bmHeight / 2), 0, NULL, DI_NORMAL); + BitBlt(hCaptureDC, mouseMove[1], mouseMove[2], bm.bmWidth, ii.hbmColor ? bm.bmHeight : (bm.bmHeight / 2), hdcMem, 0, 0, SRCPAINT); + + SelectObject(hdcMem, hbmold); + } + if (hbmCanvas != NULL) { DeleteObject(hbmCanvas); } + if (hdcMem != NULL) { ReleaseDC(NULL, hdcMem); } + if (hdcScreen != NULL) { ReleaseDC(NULL, hdcScreen); } + } + } + } } else { diff --git a/meshcore/KVM/Windows/tile.h b/meshcore/KVM/Windows/tile.h index fc1b975..790ede9 100644 --- a/meshcore/KVM/Windows/tile.h +++ b/meshcore/KVM/Windows/tile.h @@ -40,7 +40,7 @@ enum TILE_FLAGS_ENUM { short initialize_gdiplus(); void teardown_gdiplus(); int get_tile_at(int x, int y, void** buffer, long long *bufferSize, void *desktop, int row, int col); -int get_desktop_buffer(void **buffer, long long *bufferSize); +int get_desktop_buffer(void **buffer, long long *bufferSize, long*); BITMAPINFO get_bmp_info(int width, int height); void set_tile_compression(int type, int level); void switch_to_desktop_context(); diff --git a/meshcore/agentcore.c b/meshcore/agentcore.c index 3422894..85c5ff3 100644 --- a/meshcore/agentcore.c +++ b/meshcore/agentcore.c @@ -46,6 +46,8 @@ limitations under the License. #include #endif +int gRemoteMouseRenderDefault = 0; + #ifdef _LINKVM #ifdef WIN32 #include "KVM/Windows/kvm.h" @@ -100,7 +102,7 @@ int ILibDuktape_HECI_Debug = 0; #endif #endif - extern int ILibDuktape_ModSearch_ShowNames; +extern int ILibDuktape_ModSearch_ShowNames; char* MeshAgentHost_BatteryInfo_STRINGS[] = { "UNKNOWN", "HIGH_CHARGE", "LOW_CHARGE", "NO_BATTERY", "CRITICAL_CHARGE", "", "", "", "CHARGING" }; JS_ENGINE_CONTEXT MeshAgent_JavaCore_ContextGuid = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; @@ -3425,6 +3427,7 @@ void MeshServer_Connect(MeshAgentHostContainer *agent) if (agent->serverConnectionState != 0) return; util_random(sizeof(int), (char*)&timeout); + gRemoteMouseRenderDefault = ILibSimpleDataStore_Get(agent->masterDb, "remoteMouseRender", NULL, 0); agent->disableUpdate = ILibSimpleDataStore_Get(agent->masterDb, "disableUpdate", NULL, 0); agent->forceUpdate = ILibSimpleDataStore_Get(agent->masterDb, "forceUpdate", NULL, 0); agent->logUpdate = ILibSimpleDataStore_Get(agent->masterDb, "logUpdate", NULL, 0); diff --git a/meshcore/meshdefines.h b/meshcore/meshdefines.h index 0790b40..cf45cd8 100644 --- a/meshcore/meshdefines.h +++ b/meshcore/meshdefines.h @@ -27,6 +27,7 @@ typedef enum RemoteManagementCommands MNG_KVM_KEY = 1, MNG_KVM_MOUSE = 2, MNG_KVM_MOUSE_CURSOR = 88, + MNG_KVM_MOUSE_MOVE = 89, MNG_KVM_PICTURE = 3, MNG_KVM_COPY = 4, MNG_KVM_COMPRESSION = 5,