#include #include "d3d_device.h" #include "capture.h" #include "common.h" // Forward-declare the DwmGetDxSharedSurface lookup (defined in capture.cpp). // We re-check here so isAvailable() reflects true availability. static bool CheckDwmSharedSurfaceAvailable() { HMODULE hUser32 = GetModuleHandleW(L"user32.dll"); if (!hUser32) return false; return GetProcAddress(hUser32, "DwmGetDxSharedSurface") != nullptr; } // Check if DWM shared surface capture is available on this platform. // Requires: D3D11 device + DwmGetDxSharedSurface in user32.dll. Napi::Value IsAvailable(const Napi::CallbackInfo& info) { bool available = IsD3DAvailable() && CheckDwmSharedSurfaceAvailable(); return Napi::Boolean::New(info.Env(), available); } // captureWindow(hwnd: number) -> Promise // Dispatches CaptureWorker to perform DWM shared surface capture on a libuv worker thread. Napi::Value CaptureWindow(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); // Validate argument: expects one Number (the HWND) if (info.Length() < 1 || !info[0].IsNumber()) { auto deferred = Napi::Promise::Deferred::New(env); deferred.Reject(Napi::String::New(env, "captureWindow expects a numeric HWND argument")); return deferred.Promise(); } // Check D3D11 availability if (!IsD3DAvailable()) { auto deferred = Napi::Promise::Deferred::New(env); deferred.Reject(Napi::String::New(env, "D3D11 not available")); return deferred.Promise(); } // Extract HWND from JavaScript number HWND hwnd = reinterpret_cast(static_cast(info[0].As().Int64Value())); // Create and queue async worker auto* worker = new CaptureWorker(env, hwnd, GetD3DDevice(), GetD3DContext()); auto promise = worker->GetPromise(); worker->Queue(); return promise; } // Return current GDI object count for this process (for leak testing). Napi::Value GetGdiHandleCount(const Napi::CallbackInfo& info) { DWORD count = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS); return Napi::Number::New(info.Env(), static_cast(count)); } Napi::Object Init(Napi::Env env, Napi::Object exports) { // Initialize D3D11 device singleton at addon load (per D-17) InitializeD3D(); DWM_LOG("Addon loaded, D3D11 available: %s, DwmGetDxSharedSurface: %s", IsD3DAvailable() ? "yes" : "no", CheckDwmSharedSurfaceAvailable() ? "yes" : "no"); exports.Set("isAvailable", Napi::Function::New(env, IsAvailable)); exports.Set("captureWindow", Napi::Function::New(env, CaptureWindow)); exports.Set("getGdiHandleCount", Napi::Function::New(env, GetGdiHandleCount)); return exports; } NODE_API_MODULE(dwm_capture, Init)