void VBoxSeamlessCheckWindows() { VBOX_ENUM_PARAM param; param.hdc = GetDC(HWND_DESKTOP); param.hrgn = 0; EnumWindows(VBoxEnumFunc, (LPARAM)¶m); if (param.hrgn) { DWORD cbSize; cbSize = GetRegionData(param.hrgn, 0, NULL); if (cbSize) { PVBOXDISPIFESCAPE lpEscapeData = (PVBOXDISPIFESCAPE)malloc(VBOXDISPIFESCAPE_SIZE(cbSize)); if (lpEscapeData) { lpEscapeData->escapeCode = VBOXESC_SETVISIBLEREGION; LPRGNDATA lpRgnData = VBOXDISPIFESCAPE_DATA(lpEscapeData, RGNDATA); memset(lpRgnData, 0, cbSize); cbSize = GetRegionData(param.hrgn, cbSize, lpRgnData); if (cbSize) { #ifdef DEBUG RECT *lpRect = (RECT *)&lpRgnData->Buffer[0]; Log(("VBoxTray: New visible region: \n")); for (DWORD i=0;i<lpRgnData->rdh.nCount;i++) { Log(("VBoxTray: visible rect (%d,%d)(%d,%d)\n", lpRect[i].left, lpRect[i].top, lpRect[i].right, lpRect[i].bottom)); } #endif LPRGNDATA lpCtxRgnData = VBOXDISPIFESCAPE_DATA(gCtx.lpEscapeData, RGNDATA); if ( !gCtx.lpEscapeData || (lpCtxRgnData->rdh.dwSize + lpCtxRgnData->rdh.nRgnSize != cbSize) || memcmp(lpCtxRgnData, lpRgnData, cbSize)) { /* send to display driver */ VBoxDispIfEscape(&gCtx.pEnv->dispIf, lpEscapeData, cbSize); if (gCtx.lpEscapeData) free(gCtx.lpEscapeData); gCtx.lpEscapeData = lpEscapeData; } else Log(("VBoxTray: Visible rectangles haven't changed; ignore\n")); } if (lpEscapeData != gCtx.lpEscapeData) free(lpEscapeData); } } DeleteObject(param.hrgn); } ReleaseDC(HWND_DESKTOP, param.hdc); }
static DWORD vboxDispIfEscapeXPDM(PCVBOXDISPIF pIf, PVBOXDISPIFESCAPE pEscape, int cbData) { HDC hdc = GetDC(HWND_DESKTOP); VOID *pvData = cbData ? VBOXDISPIFESCAPE_DATA(pEscape, VOID) : NULL; int iRet = ExtEscape(hdc, pEscape->escapeCode, cbData, (LPCSTR)pvData, 0, NULL); ReleaseDC(HWND_DESKTOP, hdc); if (iRet > 0) return VINF_SUCCESS; else if (iRet == 0) return ERROR_NOT_SUPPORTED; /* else */ return ERROR_GEN_FAILURE; }
void VBoxSeamlessCheckWindows(bool fForce) { PVBOXSEAMLESSCONTEXT pCtx = &g_Ctx; /** @todo r=andy Use instance data via service lookup (add void *pInstance). */ AssertPtr(pCtx); if (!VBoxDispIfSeamlesIsValid(&gVBoxDispIfSeamless)) return; VBOX_ENUM_PARAM param; param.hdc = GetDC(HWND_DESKTOP); param.hrgn = 0; EnumWindows(VBoxEnumFunc, (LPARAM)¶m); if (param.hrgn) { DWORD cbSize; cbSize = GetRegionData(param.hrgn, 0, NULL); if (cbSize) { PVBOXDISPIFESCAPE lpEscapeData = (PVBOXDISPIFESCAPE)malloc(VBOXDISPIFESCAPE_SIZE(cbSize)); if (lpEscapeData) { lpEscapeData->escapeCode = VBOXESC_SETVISIBLEREGION; LPRGNDATA lpRgnData = VBOXDISPIFESCAPE_DATA(lpEscapeData, RGNDATA); memset(lpRgnData, 0, cbSize); cbSize = GetRegionData(param.hrgn, cbSize, lpRgnData); if (cbSize) { #ifdef DEBUG RECT *lpRect = (RECT *)&lpRgnData->Buffer[0]; Log(("VBoxTray: New visible region: \n")); for (DWORD i=0;i<lpRgnData->rdh.nCount;i++) { Log(("VBoxTray: visible rect (%d,%d)(%d,%d)\n", lpRect[i].left, lpRect[i].top, lpRect[i].right, lpRect[i].bottom)); } #endif LPRGNDATA lpCtxRgnData = VBOXDISPIFESCAPE_DATA(pCtx->lpEscapeData, RGNDATA); if (fForce || !pCtx->lpEscapeData || (lpCtxRgnData->rdh.dwSize + lpCtxRgnData->rdh.nRgnSize != cbSize) || memcmp(lpCtxRgnData, lpRgnData, cbSize)) { /* send to display driver */ VBoxDispIfSeamlessSubmit(&gVBoxDispIfSeamless, lpEscapeData, cbSize); if (pCtx->lpEscapeData) free(pCtx->lpEscapeData); pCtx->lpEscapeData = lpEscapeData; } else Log(("VBoxTray: Visible rectangles haven't changed; ignore\n")); } if (lpEscapeData != pCtx->lpEscapeData) free(lpEscapeData); } } DeleteObject(param.hrgn); } ReleaseDC(HWND_DESKTOP, param.hdc); }