diff --git a/.gitignore b/.gitignore index ad0ae435..213c1b29 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ module/*.mod.c module/.* module/Module.symvers module/modules.order +*.a +*.o +*.exe diff --git a/c-host/Makefile b/c-host/Makefile new file mode 100644 index 00000000..cc6797e7 --- /dev/null +++ b/c-host/Makefile @@ -0,0 +1,38 @@ +USE_DXGI ?= 1 + +CC=gcc.exe + +CFLAGS = -std=gnu99 -Wall -Werror +CFLAGS += -g -O0 +CFLAGS += -DCOBJMACROS +CFLAGS += -DINITGUID +CFLAGS += -I. +CFLAGS += -I../common + +OBJS = main.o + +# if windows +ifdef OS + LDFLAGS = -L./dll + OBJS += windebug.o + + ifeq ($(USE_DXGI), 1) + CFLAGS += -DUSE_DXGI + LIBS += -ld3d11 + LIBS += -ldxgi + DLLS += dll/libd3d11.a + OBJS += capture/dxgi.o + endif +endif + +all: $(OBJS) $(DLLS) + $(CC) $(CFLAGS) $(LDFLAGS) -o looking-glass-host.exe $(OBJS) $(LIBS) + +clean: + rm -v $(OBJS) $(DLLS) looking-glass-host.exe + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.a: %.def + dlltool --def $< --output-lib $@ diff --git a/c-host/README.md b/c-host/README.md new file mode 100644 index 00000000..c7c9e022 --- /dev/null +++ b/c-host/README.md @@ -0,0 +1,34 @@ +# What is this? + +This is an experimental rewrite of the host application in pure C using the MinGW toolchain. + +# Why make this? + +Several reasons: + +1. The client is written in C and I would like to unify the project's language +2. The host is currently hard to build using MinGW and is very Windows specific +3. The host is a jumbled mess of code from all the experimentation going on +4. I would eventually like to be able to port this to run on Linux guests + +# Why C and not C++ (or some other language) + +Beacuse I like C and for this project believe that C++ is overkill + +# When will it be ready? + +No idea + +# Will it replace the C++ host? + +Yes, but only when it is feature complete. + +# Why doesn't this use CMake? + +Because win-builds doesn't distribute it, so to make it easy for everyone to compile we do not require it. + +# How do I build it? + +Don't ask if you can't figure it out, this code is the very definition of experiemental and incomplete and should not be in use yet. + +_-Geoff_ diff --git a/c-host/capture/dxgi.c b/c-host/capture/dxgi.c new file mode 100644 index 00000000..e2dd38e8 --- /dev/null +++ b/c-host/capture/dxgi.c @@ -0,0 +1,465 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017-2019 Geoffrey McRae +https://looking-glass.hostfission.com + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "interface.h" +#include "debug.h" +#include "windebug.h" + +#include +#include +#include +#include + +#include "dxgi_extra.h" + +// locals +struct iface +{ + bool initialized; + IDXGIFactory1 * factory; + IDXGIAdapter1 * adapter; + IDXGIOutput * output; + ID3D11Device * device; + ID3D11DeviceContext * deviceContext; + D3D_FEATURE_LEVEL featureLevel; + IDXGIOutputDuplication * dup; + ID3D11Texture2D * texture; + bool hasFrame; + bool retryAcquire; + + unsigned int width; + unsigned int height; +}; + +static bool dpiDone = false; +static struct iface * this = NULL; + +// forwards + +static bool dxgi_deinit(); +static CaptureResult dxgi_releaseFrame(); + +// implementation + +static const char * dxgi_getName() +{ + return "DXGI"; +} + +static bool dxgi_create() +{ + assert(!this); + this = calloc(sizeof(struct iface), 1); + if (!this) + { + DEBUG_ERROR("failed to allocate iface struct"); + return false; + } + + return true; +} + +static bool dxgi_init() +{ + assert(this); + + // this is required for DXGI 1.5 support to function + if (!dpiDone) + { + DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); + #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4) + typedef BOOL (*User32_SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT value); + + HMODULE user32 = LoadLibraryA("user32.dll"); + User32_SetProcessDpiAwarenessContext fn; + fn = (User32_SetProcessDpiAwarenessContext)GetProcAddress(user32, "SetProcessDpiAwarenessContext"); + if (fn) + fn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + CloseHandle(user32); + dpiDone = true; + } + + HRESULT status; + IDXGIFactory1 * factory; + IDXGIAdapter1 * adapter; + IDXGIOutput * output; + DXGI_OUTPUT_DESC outputDesc; + + status = CreateDXGIFactory1(&IID_IDXGIFactory1, (void **)&factory); + if (FAILED(status)) + { + DEBUG_WINERROR("Failed to create DXGIFactory1", status); + goto fail; + } + + for(int i = 0; IDXGIFactory1_EnumAdapters1(factory, i, &adapter) != DXGI_ERROR_NOT_FOUND; ++i) + { + for(int n = 0; IDXGIAdapter1_EnumOutputs(adapter, n, &output) != DXGI_ERROR_NOT_FOUND; ++n) + { + IDXGIOutput_GetDesc(output, &outputDesc); + if (!outputDesc.AttachedToDesktop) + { + IDXGIOutput_Release(output); + output = NULL; + continue; + } + + break; + } + + if (output) + break; + + IDXGIAdapter1_Release(adapter); + adapter = NULL; + } + + if (!output) + { + DEBUG_ERROR("Failed to locate a valid output device"); + goto fail; + } + + static const D3D_FEATURE_LEVEL featureLevels[] = + { + D3D_FEATURE_LEVEL_12_1, + D3D_FEATURE_LEVEL_12_0, + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, + D3D_FEATURE_LEVEL_9_1 + }; + + IDXGIAdapter * tmp; + status = IDXGIAdapter1_QueryInterface(adapter, &IID_IDXGIAdapter, (void **)&tmp); + if (FAILED(status)) + { + DEBUG_ERROR("Failed to query IDXGIAdapter interface"); + goto fail_release; + } + + status = D3D11CreateDevice( + tmp, + D3D_DRIVER_TYPE_UNKNOWN, + NULL, + D3D11_CREATE_DEVICE_VIDEO_SUPPORT, + featureLevels, sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL), + D3D11_SDK_VERSION, + &this->device, + &this->featureLevel, + &this->deviceContext); + + IDXGIAdapter_Release(tmp); + + if (FAILED(status)) + { + DEBUG_WINERROR("Failed to create D3D11 device", status); + goto fail_release; + } + + DXGI_ADAPTER_DESC1 adapterDesc; + IDXGIAdapter1_GetDesc1(adapter, &adapterDesc); + this->width = outputDesc.DesktopCoordinates.right - outputDesc.DesktopCoordinates.left; + this->height = outputDesc.DesktopCoordinates.bottom - outputDesc.DesktopCoordinates.top; + + DEBUG_INFO("Device Descripion: %ls" , adapterDesc.Description); + DEBUG_INFO("Device Vendor ID : 0x%x" , adapterDesc.VendorId); + DEBUG_INFO("Device Device ID : 0x%x" , adapterDesc.DeviceId); + DEBUG_INFO("Device Video Mem : %u MB", (unsigned)(adapterDesc.DedicatedVideoMemory / 1048576)); + DEBUG_INFO("Device Sys Mem : %u MB", (unsigned)(adapterDesc.DedicatedSystemMemory / 1048576)); + DEBUG_INFO("Shared Sys Mem : %u MB", (unsigned)(adapterDesc.SharedSystemMemory / 1048576)); + DEBUG_INFO("Feature Level : 0x%x", this->featureLevel); + DEBUG_INFO("Capture Size : %u x %u", this->width, this->height); + + // bump up our priority + { + IDXGIDevice * dxgi; + status = ID3D11Device_QueryInterface(this->device, &IID_IDXGIDevice, (void **)&dxgi); + if (FAILED(status)) + { + DEBUG_WINERROR("failed to query DXGI interface from device", status); + goto fail_release_device; + } + + IDXGIDevice_SetGPUThreadPriority(dxgi, 7); + IDXGIDevice_Release(dxgi); + } + + IDXGIOutput5 * output5 = NULL; + status = IDXGIOutput_QueryInterface(output, &IID_IDXGIOutput5, (void **)&output5); + if (FAILED(status)) + { + DEBUG_WARN("IDXGIOutput5 is not available, please update windows for improved performance!"); + DEBUG_WARN("Falling back to IDXIGOutput1"); + + IDXGIOutput1 * output1 = NULL; + status = IDXGIOutput_QueryInterface(output, &IID_IDXGIOutput1, (void **)&output1); + if (FAILED(status)) + { + DEBUG_ERROR("Failed to query IDXGIOutput1 from the output"); + goto fail_release_device; + } + + // we try this twice in case we still get an error on re-initialization + for (int i = 0; i < 2; ++i) + { + status = IDXGIOutput1_DuplicateOutput(output1, (IUnknown *)this->device, &this->dup); + if (SUCCEEDED(status)) + break; + Sleep(200); + } + + if (FAILED(status)) + { + DEBUG_WINERROR("DuplicateOutput Failed", status); + IDXGIOutput1_Release(output1); + goto fail_release_device; + } + } + else + { + const DXGI_FORMAT supportedFormats[] = + { + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM + }; + + // we try this twice in case we still get an error on re-initialization + for (int i = 0; i < 2; ++i) + { + status = IDXGIOutput5_DuplicateOutput1( + output5, + (IUnknown *)this->device, + 0, + sizeof(supportedFormats) / sizeof(DXGI_FORMAT), + supportedFormats, + &this->dup); + + if (SUCCEEDED(status)) + break; + + Sleep(200); + } + + if (FAILED(status)) + { + DEBUG_WINERROR("DuplicateOutput1 Failed", status); + IDXGIOutput5_Release(output5); + goto fail_release_device; + } + } + + DXGI_OUTDUPL_DESC dupDesc; + IDXGIOutputDuplication_GetDesc(this->dup, &dupDesc); + DEBUG_INFO("Source Format : %s", GetDXGIFormatStr(dupDesc.ModeDesc.Format)); + + D3D11_TEXTURE2D_DESC texDesc; + memset(&texDesc, 0, sizeof(texDesc)); + texDesc.Width = this->width; + texDesc.Height = this->height; + texDesc.MipLevels = 1; + texDesc.ArraySize = 1; + texDesc.SampleDesc.Count = 1; + texDesc.SampleDesc.Quality = 0; + texDesc.Usage = D3D11_USAGE_STAGING; + texDesc.Format = dupDesc.ModeDesc.Format; + texDesc.BindFlags = 0; + texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + texDesc.MiscFlags = 0; + + status = ID3D11Device_CreateTexture2D(this->device, &texDesc, NULL, &this->texture); + if (FAILED(status)) + { + DEBUG_WINERROR("Failed to create texture", status); + goto fail_release_output; + } + + this->factory = factory; + this->adapter = adapter; + this->output = output; + this->initialized = true; + return true; + +fail_release_output: + IDXGIOutputDuplication_Release(this->dup); + this->dup = NULL; +fail_release_device: + ID3D11Device_Release(this->device); + this->device = NULL; +fail_release: + IDXGIOutput_Release (output ); + IDXGIAdapter1_Release(adapter); + IDXGIFactory1_Release(factory); +fail: + return false; +} + +static bool dxgi_deinit() +{ + assert(this); + + if (this->texture) + { + ID3D11Texture2D_Release(this->texture); + this->texture = NULL; + } + + if (this->dup) + { + dxgi_releaseFrame(); + IDXGIOutputDuplication_Release(this->dup); + this->dup = NULL; + } + + if (this->device) + { + ID3D11Device_Release(this->device); + this->device = NULL; + } + + if (this->output) + { + IDXGIOutput_Release(this->output); + this->output = NULL; + } + + if (this->adapter) + { + IDXGIAdapter1_Release(this->adapter); + this->adapter = NULL; + } + + if (this->factory) + { + IDXGIFactory1_Release(this->factory); + this->factory = NULL; + } + + this->initialized = false; + return true; +} + +static void dxgi_free() +{ + assert(this); + + if (this->initialized) + dxgi_deinit(); + + free(this); + this = NULL; +} + +static CaptureResult dxgi_capture() +{ + assert(this); + assert(this->initialized); + + CaptureResult result; + HRESULT status; + DXGI_OUTDUPL_FRAME_INFO frameInfo; + IDXGIResource * res; + + result = dxgi_releaseFrame(); + if (result != CAPTURE_RESULT_OK) + return result; + + status = IDXGIOutputDuplication_AcquireNextFrame(this->dup, 1000, &frameInfo, &res); + switch(status) + { + case S_OK: + this->hasFrame = true; + break; + + case DXGI_ERROR_WAIT_TIMEOUT: + return CAPTURE_RESULT_TIMEOUT; + + case WAIT_ABANDONED: + case DXGI_ERROR_ACCESS_LOST: + if (this->retryAcquire) + { + DEBUG_WINERROR("Unable to acquire next frame, giving up", status); + this->retryAcquire = false; + return CAPTURE_RESULT_ERROR; + } + + this->retryAcquire = true; + return CAPTURE_RESULT_REINIT; + + default: + DEBUG_WINERROR("AcquireNextFrame failed", status); + return CAPTURE_RESULT_ERROR; + } + + ID3D11Texture2D * src; + status = IDXGIResource_QueryInterface(res, &IID_ID3D11Texture2D, (void **)&src); + if (FAILED(status)) + { + DEBUG_WINERROR("Failed to get the texture from the dxgi resource", status); + return CAPTURE_RESULT_ERROR; + } + + ID3D11DeviceContext_CopyResource(this->deviceContext, + (ID3D11Resource *)this->texture, (ID3D11Resource *)src); + + return CAPTURE_RESULT_OK; +} + +static CaptureResult dxgi_releaseFrame() +{ + assert(this); + if (!this->hasFrame) + return CAPTURE_RESULT_OK; + + HRESULT status = IDXGIOutputDuplication_ReleaseFrame(this->dup); + switch(status) + { + case S_OK: + break; + + case DXGI_ERROR_INVALID_CALL: + DEBUG_WINERROR("Frame was already released", status); + return CAPTURE_RESULT_ERROR; + + case WAIT_ABANDONED: + case DXGI_ERROR_ACCESS_LOST: + return CAPTURE_RESULT_REINIT; + + default: + DEBUG_WINERROR("ReleaseFrame failed", status); + return CAPTURE_RESULT_ERROR; + } + + this->hasFrame = false; + return CAPTURE_RESULT_OK; +} + +struct CaptureInterface Capture_DXGI = +{ + .getName = dxgi_getName, + .create = dxgi_create, + .init = dxgi_init, + .deinit = dxgi_deinit, + .free = dxgi_free, + .capture = dxgi_capture +}; \ No newline at end of file diff --git a/c-host/capture/dxgi_extra.h b/c-host/capture/dxgi_extra.h new file mode 100644 index 00000000..6b69379f --- /dev/null +++ b/c-host/capture/dxgi_extra.h @@ -0,0 +1,635 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017-2019 Geoffrey McRae +https://looking-glass.hostfission.com + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include + +// missing declarations in dxgi.h +HRESULT __stdcall CreateDXGIFactory1(REFIID riid, void **factory); +#define D3D_FEATURE_LEVEL_12_0 0xc000 +#define D3D_FEATURE_LEVEL_12_1 0xc100 + +#define DXGI_ERROR_ACCESS_LOST _HRESULT_TYPEDEF_(0x887A0026L) +#define DXGI_ERROR_WAIT_TIMEOUT _HRESULT_TYPEDEF_(0x887A0027L) + +typedef struct DXGI_OUTDUPL_DESC { + DXGI_MODE_DESC ModeDesc; + DXGI_MODE_ROTATION Rotation; + BOOL DesktopImageInSystemMemory; +} +DXGI_OUTDUPL_DESC; + +typedef struct DXGI_OUTDUPL_POINTER_POSITION { + POINT Position; + BOOL Visible; +} +DXGI_OUTDUPL_POINTER_POSITION; + +typedef struct DXGI_OUTDUPL_FRAME_INFO { + LARGE_INTEGER LastPresentTime; + LARGE_INTEGER LastMouseUpdateTime; + UINT AccumulatedFrames; + BOOL RectsCoalesced; + BOOL ProtectedContentMaskedOut; + DXGI_OUTDUPL_POINTER_POSITION PointerPosition; + UINT TotalMetadataBufferSize; + UINT PointerShapeBufferSize; +} +DXGI_OUTDUPL_FRAME_INFO; + +typedef struct DXGI_OUTDUPL_MOVE_RECT { + POINT SourcePoint; + RECT DestinationRect; +} +DXGI_OUTDUPL_MOVE_RECT; + +typedef struct DXGI_OUTDUPL_POINTER_SHAPE_INFO { + UINT Type; + UINT Width; + UINT Height; + UINT Pitch; + POINT HotSpot; +} +DXGI_OUTDUPL_POINTER_SHAPE_INFO; + +DEFINE_GUID(IID_IDXGIOutputDuplication, 0x191cfac3, 0xa341, 0x470d, 0xb2,0x6e,0xa8,0x64,0xf4,0x28,0x31,0x9c); + +typedef interface IDXGIOutputDuplication IDXGIOutputDuplication; + +typedef struct IDXGIOutputDuplicationVtbl { + BEGIN_INTERFACE + + /*** IUnknown methods ***/ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IDXGIOutputDuplication* This, + REFIID riid, + void **ppvObject); + + ULONG (STDMETHODCALLTYPE *AddRef)( + IDXGIOutputDuplication* This); + + ULONG (STDMETHODCALLTYPE *Release)( + IDXGIOutputDuplication* This); + + /*** IDXGIObject methods ***/ + HRESULT (STDMETHODCALLTYPE *SetPrivateData)( + IDXGIOutputDuplication* This, + REFGUID guid, + UINT data_size, + const void *data); + + HRESULT (STDMETHODCALLTYPE *SetPrivateDataInterface)( + IDXGIOutputDuplication* This, + REFGUID guid, + const IUnknown *object); + + HRESULT (STDMETHODCALLTYPE *GetPrivateData)( + IDXGIOutputDuplication* This, + REFGUID guid, + UINT *data_size, + void *data); + + HRESULT (STDMETHODCALLTYPE *GetParent)( + IDXGIOutputDuplication* This, + REFIID riid, + void **parent); + + /*** IDXGIOutputDuplication methods ***/ + + void (STDMETHODCALLTYPE *GetDesc)( + IDXGIOutputDuplication* This, + DXGI_OUTDUPL_DESC *pDesc); + + HRESULT (STDMETHODCALLTYPE *AcquireNextFrame)( + IDXGIOutputDuplication* This, + UINT TimeoutInMilliseconds, + DXGI_OUTDUPL_FRAME_INFO *pFrameInfo, + IDXGIResource **ppDesktopResource); + + HRESULT (STDMETHODCALLTYPE *GetFrameDirtyRects)( + IDXGIOutputDuplication* This, + UINT DirtyRectsBufferSize, + RECT *pDirtyRectsBuffer, + UINT *pDirtyRectsBufferSizeRequired); + + HRESULT (STDMETHODCALLTYPE *GetFrameMoveRects)( + IDXGIOutputDuplication* This, + UINT MoveRectsBufferSize, + DXGI_OUTDUPL_MOVE_RECT *pMoveRectBuffer, + UINT *pMoveRectsBufferSizeRequired); + + HRESULT (STDMETHODCALLTYPE *GetFramePointerShape)( + IDXGIOutputDuplication* This, + UINT PointerShapeBufferSize, + void *pPointerShapeBuffer, + UINT *pPointerShapeBufferSizeRequired, + DXGI_OUTDUPL_POINTER_SHAPE_INFO *pPointerShapeInfo); + + HRESULT (STDMETHODCALLTYPE *MapDesktopSurface)( + IDXGIOutputDuplication* This, + DXGI_MAPPED_RECT *pLockedRect); + + HRESULT (STDMETHODCALLTYPE *UnMapDesktopSurface)( + IDXGIOutputDuplication* This); + + HRESULT (STDMETHODCALLTYPE *ReleaseFrame)( + IDXGIOutputDuplication* This); + + END_INTERFACE +} +IDXGIOutputDuplicationVtbl; + +interface IDXGIOutputDuplication { + CONST_VTBL IDXGIOutputDuplicationVtbl* lpVtbl; +}; + +#define IDXGIOutputDuplication_Release(This) (This)->lpVtbl->Release(This) +#define IDXGIOutputDuplication_GetDesc(This, pDesc) (This)->lpVtbl->GetDesc(This, pDesc) +#define IDXGIOutputDuplication_AcquireNextFrame(This, TimeoutInMilliseconds, pFrameInfo, ppDesktopResource) (This)->lpVtbl->AcquireNextFrame(This, TimeoutInMilliseconds, pFrameInfo, ppDesktopResource) +#define IDXGIOutputDuplication_GetFrameDirtyRects(This, DirtyRectsBufferSize, pDirectyRectsBuffer, pDirtyRectsBufferSizeRequired) (This)->lpVtbl->GetFrameDirtyRects(This, DirtyRectsBufferSize, pDirectyRectsBuffer, pDirtyRectsBufferSizeRequired) +#define IDXGIOutputDuplication_GetFrameMoveRects(This, MoveRectsBufferSize, pDirtyRectsBuffer, pDirtyRectsBufferSizeRequired) (This)->lpVtbl->GetFrameMoveRects(This, MoveRectsBufferSize, pDirtyRectsBuffer, pDirtyRectsBufferSizeRequired) +#define IDXGIOutputDuplication_GetFramePointerShape(This, PointerShapeBufferSize, pPointerShapeBuffer, pPointerShapeBufferSizeRequired, pPointerShapeInfo) (This)->lpVtbl->GetFramePointerShape(This, PointerShapeBufferSize, pPointerShapeBuffer, pPointerShapeBufferSizeRequired, pPointerShapeInfo) +#define IDXGIOutputDuplication_MapDesktopSurface(This, pLockedRect) (This)->lpVtbl->MapDesktopSurface(This, pLockedRect) +#define IDXGIOutputDuplication_UnMapDesktopSurface(This) (This)->lpVtbl->UnMapDesktopSurface(This) +#define IDXGIOutputDuplication_ReleaseFrame(This) (This)->lpVtbl->ReleaseFrame(This) + +typedef struct DXGI_MODE_DESC1 +{ + UINT Width; + UINT Height; + DXGI_RATIONAL RefreshRate; + DXGI_FORMAT Format; + DXGI_MODE_SCANLINE_ORDER ScanlineOrdering; + DXGI_MODE_SCALING Scaling; + BOOL Stereo; +} +DXGI_MODE_DESC1; + +typedef enum DXGI_COLOR_SPACE_TYPE { + DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 = 0, + DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709 = 1, + DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709 = 2, + DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020 = 3, + DXGI_COLOR_SPACE_RESERVED = 4, + DXGI_COLOR_SPACE_YCBCR_FULL_G22_NONE_P709_X601 = 5, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601 = 6, + DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P601 = 7, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709 = 8, + DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P709 = 9, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020 = 10, + DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020 = 11, + DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 = 12, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020 = 13, + DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020 = 14, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_TOPLEFT_P2020 = 15, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_TOPLEFT_P2020 = 16, + DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020 = 17, + DXGI_COLOR_SPACE_YCBCR_STUDIO_GHLG_TOPLEFT_P2020 = 18, + DXGI_COLOR_SPACE_YCBCR_FULL_GHLG_TOPLEFT_P2020 = 19, + DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P709 = 20, + DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P2020 = 21, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_LEFT_P709 = 22, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_LEFT_P2020 = 23, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_TOPLEFT_P2020 = 24, + DXGI_COLOR_SPACE_CUSTOM = 0xFFFFFFFF +} DXGI_COLOR_SPACE_TYPE; + +DEFINE_GUID(IID_IDXGIOutput1, 0x00cddea8, 0x939b, 0x4b83, 0xa3,0x40,0xa6,0x85,0x22,0x66,0x66,0xcc); + +typedef struct IDXGIOutput1 IDXGIOutput1; + +typedef struct IDXGIOutput1Vtbl { + BEGIN_INTERFACE + + /*** IUnknown methods ***/ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IDXGIOutput1* This, + REFIID riid, + void **ppvObject); + + ULONG (STDMETHODCALLTYPE *AddRef)( + IDXGIOutput1* This); + + ULONG (STDMETHODCALLTYPE *Release)( + IDXGIOutput1* This); + + /*** IDXGIObject methods ***/ + HRESULT (STDMETHODCALLTYPE *SetPrivateData)( + IDXGIOutput1* This, + REFGUID guid, + UINT data_size, + const void *data); + + HRESULT (STDMETHODCALLTYPE *SetPrivateDataInterface)( + IDXGIOutput1* This, + REFGUID guid, + const IUnknown *object); + + HRESULT (STDMETHODCALLTYPE *GetPrivateData)( + IDXGIOutput1* This, + REFGUID guid, + UINT *data_size, + void *data); + + HRESULT (STDMETHODCALLTYPE *GetParent)( + IDXGIOutput1* This, + REFIID riid, + void **parent); + + /*** IDXGIOutput methods ***/ + HRESULT (STDMETHODCALLTYPE *GetDesc)( + IDXGIOutput1* This, + DXGI_OUTPUT_DESC *desc); + + HRESULT (STDMETHODCALLTYPE *GetDisplayModeList)( + IDXGIOutput1* This, + DXGI_FORMAT format, + UINT flags, + UINT *mode_count, + DXGI_MODE_DESC *desc); + + HRESULT (STDMETHODCALLTYPE *FindClosestMatchingMode)( + IDXGIOutput1* This, + const DXGI_MODE_DESC *mode, + DXGI_MODE_DESC *closest_match, + IUnknown *device); + + HRESULT (STDMETHODCALLTYPE *WaitForVBlank)( + IDXGIOutput1* This); + + HRESULT (STDMETHODCALLTYPE *TakeOwnership)( + IDXGIOutput1* This, + IUnknown *device, + WINBOOL exclusive); + + void (STDMETHODCALLTYPE *ReleaseOwnership)( + IDXGIOutput1* This); + + HRESULT (STDMETHODCALLTYPE *GetGammaControlCapabilities)( + IDXGIOutput1* This, + DXGI_GAMMA_CONTROL_CAPABILITIES *gamma_caps); + + HRESULT (STDMETHODCALLTYPE *SetGammaControl)( + IDXGIOutput1* This, + const DXGI_GAMMA_CONTROL *gamma_control); + + HRESULT (STDMETHODCALLTYPE *GetGammaControl)( + IDXGIOutput1* This, + DXGI_GAMMA_CONTROL *gamma_control); + + HRESULT (STDMETHODCALLTYPE *SetDisplaySurface)( + IDXGIOutput1* This, + IDXGISurface *surface); + + HRESULT (STDMETHODCALLTYPE *GetDisplaySurfaceData)( + IDXGIOutput1* This, + IDXGISurface *surface); + + HRESULT (STDMETHODCALLTYPE *GetFrameStatistics)( + IDXGIOutput1* This, + DXGI_FRAME_STATISTICS *stats); + + /*** IDXGIOutput1 methods ***/ + + HRESULT (STDMETHODCALLTYPE *GetDisplayModeList1)( + IDXGIOutput1* This, + DXGI_FORMAT EnumFormat, + UINT Flags, + UINT *pNumModes, + DXGI_MODE_DESC1 *pDesc); + + HRESULT (STDMETHODCALLTYPE *FindClosestMatchingMode1)( + IDXGIOutput1* This, + const DXGI_MODE_DESC1 *pModeToMatch, + DXGI_MODE_DESC1 *pClosestMatch, + IUnknown *pConcernedDevice); + + HRESULT (STDMETHODCALLTYPE *GetDisplaySurfaceData1)( + IDXGIOutput1* This, + IDXGIResource *pDestination); + + HRESULT (STDMETHODCALLTYPE *DuplicateOutput)( + IDXGIOutput1* This, + IUnknown *pDevice, + IDXGIOutputDuplication **ppOutputDuplication); + + END_INTERFACE +} +IDXGIOutput1Vtbl; +interface IDXGIOutput1 { + CONST_VTBL IDXGIOutput1Vtbl* lpVtbl; +}; + +#define IDXGIOutput1_DuplicateOutput(This,pDevice,ppOutputDuplication) (This)->lpVtbl->DuplicateOutput(This,pDevice,ppOutputDuplication) +#define IDXGIOutput1_Release(This) (This)->lpVtbl->Release(This); + +DEFINE_GUID(IID_IDXGIOutput5, 0x80a07424, 0xab52, 0x42eb, 0x83,0x3c,0x0c,0x42,0xfd,0x28,0x2d,0x98); + +typedef struct IDXGIOutput5 IDXGIOutput5; + +typedef struct IDXGIOutput5Vtbl { + BEGIN_INTERFACE + + /*** IUnknown methods ***/ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IDXGIOutput5* This, + REFIID riid, + void **ppvObject); + + ULONG (STDMETHODCALLTYPE *AddRef)( + IDXGIOutput5* This); + + ULONG (STDMETHODCALLTYPE *Release)( + IDXGIOutput5* This); + + /*** IDXGIObject methods ***/ + HRESULT (STDMETHODCALLTYPE *SetPrivateData)( + IDXGIOutput5* This, + REFGUID guid, + UINT data_size, + const void *data); + + HRESULT (STDMETHODCALLTYPE *SetPrivateDataInterface)( + IDXGIOutput5* This, + REFGUID guid, + const IUnknown *object); + + HRESULT (STDMETHODCALLTYPE *GetPrivateData)( + IDXGIOutput5* This, + REFGUID guid, + UINT *data_size, + void *data); + + HRESULT (STDMETHODCALLTYPE *GetParent)( + IDXGIOutput5* This, + REFIID riid, + void **parent); + + /*** IDXGIOutput methods ***/ + HRESULT (STDMETHODCALLTYPE *GetDesc)( + IDXGIOutput5* This, + DXGI_OUTPUT_DESC *desc); + + HRESULT (STDMETHODCALLTYPE *GetDisplayModeList)( + IDXGIOutput5* This, + DXGI_FORMAT format, + UINT flags, + UINT *mode_count, + DXGI_MODE_DESC *desc); + + HRESULT (STDMETHODCALLTYPE *FindClosestMatchingMode)( + IDXGIOutput5* This, + const DXGI_MODE_DESC *mode, + DXGI_MODE_DESC *closest_match, + IUnknown *device); + + HRESULT (STDMETHODCALLTYPE *WaitForVBlank)( + IDXGIOutput5* This); + + HRESULT (STDMETHODCALLTYPE *TakeOwnership)( + IDXGIOutput5* This, + IUnknown *device, + WINBOOL exclusive); + + void (STDMETHODCALLTYPE *ReleaseOwnership)( + IDXGIOutput5* This); + + HRESULT (STDMETHODCALLTYPE *GetGammaControlCapabilities)( + IDXGIOutput5* This, + DXGI_GAMMA_CONTROL_CAPABILITIES *gamma_caps); + + HRESULT (STDMETHODCALLTYPE *SetGammaControl)( + IDXGIOutput5* This, + const DXGI_GAMMA_CONTROL *gamma_control); + + HRESULT (STDMETHODCALLTYPE *GetGammaControl)( + IDXGIOutput5* This, + DXGI_GAMMA_CONTROL *gamma_control); + + HRESULT (STDMETHODCALLTYPE *SetDisplaySurface)( + IDXGIOutput5* This, + IDXGISurface *surface); + + HRESULT (STDMETHODCALLTYPE *GetDisplaySurfaceData)( + IDXGIOutput5* This, + IDXGISurface *surface); + + HRESULT (STDMETHODCALLTYPE *GetFrameStatistics)( + IDXGIOutput5* This, + DXGI_FRAME_STATISTICS *stats); + + /*** IDXGIOutput1 methods ***/ + + HRESULT (STDMETHODCALLTYPE *GetDisplayModeList1)( + IDXGIOutput5* This, + DXGI_FORMAT EnumFormat, + UINT Flags, + UINT *pNumModes, + DXGI_MODE_DESC1 *pDesc); + + HRESULT (STDMETHODCALLTYPE *FindClosestMatchingMode1)( + IDXGIOutput5* This, + const DXGI_MODE_DESC1 *pModeToMatch, + DXGI_MODE_DESC1 *pClosestMatch, + IUnknown *pConcernedDevice); + + HRESULT (STDMETHODCALLTYPE *GetDisplaySurfaceData1)( + IDXGIOutput5* This, + IDXGIResource *pDestination); + + HRESULT (STDMETHODCALLTYPE *DuplicateOutput)( + IDXGIOutput5* This, + IUnknown *pDevice, + IDXGIOutputDuplication **ppOutputDuplication); + + /*** IDXGIOutput2 methods ***/ + + BOOL (STDMETHODCALLTYPE *SupportsOverlays)( + IDXGIOutput5* This); + + /*** IDXGIOutput3 methods ***/ + + HRESULT (STDMETHODCALLTYPE *CheckOverlaySupport)( + IDXGIOutput5* This, + DXGI_FORMAT EnumFormat, + IUnknown *pConcernedDevice, + UINT *pFlags); + + /*** IDXGIOutput4 methods ***/ + + HRESULT (STDMETHODCALLTYPE *CheckOverlayColorSpaceSupport)( + IDXGIOutput5* This, + DXGI_FORMAT Format, + DXGI_COLOR_SPACE_TYPE ColorSpace, + IUnknown *pConcernedDevice, + UINT *pFlags); + + /*** IDXGIOutput5 methods ***/ + + HRESULT (STDMETHODCALLTYPE *DuplicateOutput1)( + IDXGIOutput5* This, + IUnknown *pDevice, + UINT Flags, + UINT SupportedFormatsCount, + const DXGI_FORMAT *pSupportedFormats, + IDXGIOutputDuplication **ppOutputDuplication); + + END_INTERFACE +} +IDXGIOutput5Vtbl; +interface IDXGIOutput5 { + CONST_VTBL IDXGIOutput5Vtbl* lpVtbl; +}; + +#define IDXGIOutput5_DuplicateOutput1(This,pDevice,Flags,SupportedForamtsCount,pSupportedFormats,ppOutputDuplication) (This)->lpVtbl->DuplicateOutput1(This,pDevice,Flags,SupportedForamtsCount,pSupportedFormats,ppOutputDuplication) +#define IDXGIOutput5_Release(This) (This)->lpVtbl->Release(This); + + +static const char * DXGI_FORMAT_STR[] = { + "DXGI_FORMAT_UNKNOWN", + "DXGI_FORMAT_R32G32B32A32_TYPELESS", + "DXGI_FORMAT_R32G32B32A32_FLOAT", + "DXGI_FORMAT_R32G32B32A32_UINT", + "DXGI_FORMAT_R32G32B32A32_SINT", + "DXGI_FORMAT_R32G32B32_TYPELESS", + "DXGI_FORMAT_R32G32B32_FLOAT", + "DXGI_FORMAT_R32G32B32_UINT", + "DXGI_FORMAT_R32G32B32_SINT", + "DXGI_FORMAT_R16G16B16A16_TYPELESS", + "DXGI_FORMAT_R16G16B16A16_FLOAT", + "DXGI_FORMAT_R16G16B16A16_UNORM", + "DXGI_FORMAT_R16G16B16A16_UINT", + "DXGI_FORMAT_R16G16B16A16_SNORM", + "DXGI_FORMAT_R16G16B16A16_SINT", + "DXGI_FORMAT_R32G32_TYPELESS", + "DXGI_FORMAT_R32G32_FLOAT", + "DXGI_FORMAT_R32G32_UINT", + "DXGI_FORMAT_R32G32_SINT", + "DXGI_FORMAT_R32G8X24_TYPELESS", + "DXGI_FORMAT_D32_FLOAT_S8X24_UINT", + "DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS", + "DXGI_FORMAT_X32_TYPELESS_G8X24_UINT", + "DXGI_FORMAT_R10G10B10A2_TYPELESS", + "DXGI_FORMAT_R10G10B10A2_UNORM", + "DXGI_FORMAT_R10G10B10A2_UINT", + "DXGI_FORMAT_R11G11B10_FLOAT", + "DXGI_FORMAT_R8G8B8A8_TYPELESS", + "DXGI_FORMAT_R8G8B8A8_UNORM", + "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", + "DXGI_FORMAT_R8G8B8A8_UINT", + "DXGI_FORMAT_R8G8B8A8_SNORM", + "DXGI_FORMAT_R8G8B8A8_SINT", + "DXGI_FORMAT_R16G16_TYPELESS", + "DXGI_FORMAT_R16G16_FLOAT", + "DXGI_FORMAT_R16G16_UNORM", + "DXGI_FORMAT_R16G16_UINT", + "DXGI_FORMAT_R16G16_SNORM", + "DXGI_FORMAT_R16G16_SINT", + "DXGI_FORMAT_R32_TYPELESS", + "DXGI_FORMAT_D32_FLOAT", + "DXGI_FORMAT_R32_FLOAT", + "DXGI_FORMAT_R32_UINT", + "DXGI_FORMAT_R32_SINT", + "DXGI_FORMAT_R24G8_TYPELESS", + "DXGI_FORMAT_D24_UNORM_S8_UINT", + "DXGI_FORMAT_R24_UNORM_X8_TYPELESS", + "DXGI_FORMAT_X24_TYPELESS_G8_UINT", + "DXGI_FORMAT_R8G8_TYPELESS", + "DXGI_FORMAT_R8G8_UNORM", + "DXGI_FORMAT_R8G8_UINT", + "DXGI_FORMAT_R8G8_SNORM", + "DXGI_FORMAT_R8G8_SINT", + "DXGI_FORMAT_R16_TYPELESS", + "DXGI_FORMAT_R16_FLOAT", + "DXGI_FORMAT_D16_UNORM", + "DXGI_FORMAT_R16_UNORM", + "DXGI_FORMAT_R16_UINT", + "DXGI_FORMAT_R16_SNORM", + "DXGI_FORMAT_R16_SINT", + "DXGI_FORMAT_R8_TYPELESS", + "DXGI_FORMAT_R8_UNORM", + "DXGI_FORMAT_R8_UINT", + "DXGI_FORMAT_R8_SNORM", + "DXGI_FORMAT_R8_SINT", + "DXGI_FORMAT_A8_UNORM", + "DXGI_FORMAT_R1_UNORM", + "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", + "DXGI_FORMAT_R8G8_B8G8_UNORM", + "DXGI_FORMAT_G8R8_G8B8_UNORM", + "DXGI_FORMAT_BC1_TYPELESS", + "DXGI_FORMAT_BC1_UNORM", + "DXGI_FORMAT_BC1_UNORM_SRGB", + "DXGI_FORMAT_BC2_TYPELESS", + "DXGI_FORMAT_BC2_UNORM", + "DXGI_FORMAT_BC2_UNORM_SRGB", + "DXGI_FORMAT_BC3_TYPELESS", + "DXGI_FORMAT_BC3_UNORM", + "DXGI_FORMAT_BC3_UNORM_SRGB", + "DXGI_FORMAT_BC4_TYPELESS", + "DXGI_FORMAT_BC4_UNORM", + "DXGI_FORMAT_BC4_SNORM", + "DXGI_FORMAT_BC5_TYPELESS", + "DXGI_FORMAT_BC5_UNORM", + "DXGI_FORMAT_BC5_SNORM", + "DXGI_FORMAT_B5G6R5_UNORM", + "DXGI_FORMAT_B5G5R5A1_UNORM", + "DXGI_FORMAT_B8G8R8A8_UNORM", + "DXGI_FORMAT_B8G8R8X8_UNORM", + "DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM", + "DXGI_FORMAT_B8G8R8A8_TYPELESS", + "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB", + "DXGI_FORMAT_B8G8R8X8_TYPELESS", + "DXGI_FORMAT_B8G8R8X8_UNORM_SRGB", + "DXGI_FORMAT_BC6H_TYPELESS", + "DXGI_FORMAT_BC6H_UF16", + "DXGI_FORMAT_BC6H_SF16", + "DXGI_FORMAT_BC7_TYPELESS", + "DXGI_FORMAT_BC7_UNORM", + "DXGI_FORMAT_BC7_UNORM_SRGB", + "DXGI_FORMAT_AYUV", + "DXGI_FORMAT_Y410", + "DXGI_FORMAT_Y416", + "DXGI_FORMAT_NV12", + "DXGI_FORMAT_P010", + "DXGI_FORMAT_P016", + "DXGI_FORMAT_420_OPAQUE", + "DXGI_FORMAT_YUY2", + "DXGI_FORMAT_Y210", + "DXGI_FORMAT_Y216", + "DXGI_FORMAT_NV11", + "DXGI_FORMAT_AI44", + "DXGI_FORMAT_IA44", + "DXGI_FORMAT_P8", + "DXGI_FORMAT_A8P8", + "DXGI_FORMAT_B4G4R4A4_UNORM", + + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + "DXGI_FORMAT_P208", + "DXGI_FORMAT_V208", + "DXGI_FORMAT_V408" +}; + +static const char * GetDXGIFormatStr(DXGI_FORMAT format) +{ + if (format > sizeof(DXGI_FORMAT_STR) / sizeof(const char *)) + return DXGI_FORMAT_STR[0]; + return DXGI_FORMAT_STR[format]; +} \ No newline at end of file diff --git a/c-host/capture/interface.h b/c-host/capture/interface.h new file mode 100644 index 00000000..9dc6b11e --- /dev/null +++ b/c-host/capture/interface.h @@ -0,0 +1,42 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017-2019 Geoffrey McRae +https://looking-glass.hostfission.com + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#pragma once + +#include +#include + +typedef enum CaptureResult +{ + CAPTURE_RESULT_OK, + CAPTURE_RESULT_REINIT, + CAPTURE_RESULT_TIMEOUT, + CAPTURE_RESULT_ERROR +} +CaptureResult; + +struct CaptureInterface +{ + const char * (*getName)(); + bool (*create )(); + bool (*init )(); + bool (*deinit )(); + void (*free )(); + CaptureResult (*capture)(); +}; \ No newline at end of file diff --git a/c-host/capture/interfaces.h b/c-host/capture/interfaces.h new file mode 100644 index 00000000..1ff69f70 --- /dev/null +++ b/c-host/capture/interfaces.h @@ -0,0 +1,32 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017-2019 Geoffrey McRae +https://looking-glass.hostfission.com + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "interface.h" + +#if defined(USE_DXGI) +extern struct CaptureInterface Capture_DXGI; +#endif + +struct CaptureInterface * CaptureInterfaces[] = +{ +#if defined(USE_DXGI) + &Capture_DXGI, +#endif + NULL +}; \ No newline at end of file diff --git a/c-host/dll/libd3d11.def b/c-host/dll/libd3d11.def new file mode 100644 index 00000000..2bb27ba2 --- /dev/null +++ b/c-host/dll/libd3d11.def @@ -0,0 +1,44 @@ +LIBRARY "d3d11.dll" +EXPORTS +D3DKMTCloseAdapter +D3DKMTDestroyAllocation +D3DKMTDestroyContext +D3DKMTDestroyDevice +D3DKMTDestroySynchronizationObject +D3DKMTQueryAdapterInfo +D3DKMTSetDisplayPrivateDriverFormat +D3DKMTSignalSynchronizationObject +D3DKMTUnlock +D3DKMTWaitForSynchronizationObject +OpenAdapter10 +OpenAdapter10_2 +D3D11CoreCreateDevice +D3D11CoreCreateLayeredDevice +D3D11CoreGetLayeredDeviceSize +D3D11CoreRegisterLayers +D3D11CreateDevice +D3D11CreateDeviceAndSwapChain +D3DKMTCreateAllocation +D3DKMTCreateContext +D3DKMTCreateDevice +D3DKMTCreateSynchronizationObject +D3DKMTEscape +D3DKMTGetContextSchedulingPriority +D3DKMTGetDeviceState +D3DKMTGetDisplayModeList +D3DKMTGetMultisampleMethodList +D3DKMTGetRuntimeData +D3DKMTGetSharedPrimaryHandle +D3DKMTLock +D3DKMTOpenAdapterFromHdc +D3DKMTOpenResource +D3DKMTPresent +D3DKMTQueryAllocationResidency +D3DKMTQueryResourceInfo +D3DKMTRender +D3DKMTSetAllocationPriority +D3DKMTSetContextSchedulingPriority +D3DKMTSetDisplayMode +D3DKMTSetGammaRamp +D3DKMTSetVidPnSourceOwner +D3DKMTWaitForVerticalBlankEvent diff --git a/c-host/main.c b/c-host/main.c new file mode 100644 index 00000000..ec4c249b --- /dev/null +++ b/c-host/main.c @@ -0,0 +1,57 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017-2019 Geoffrey McRae +https://looking-glass.hostfission.com + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include "debug.h" +#include "capture/interfaces.h" + +int WINAPI WinMain(HINSTANCE hInstnace, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + struct CaptureInterface * iface = NULL; + for(int i = 0; CaptureInterfaces[i]; ++i) + { + iface = CaptureInterfaces[i]; + DEBUG_INFO("Trying : %s", iface->getName()); + if (!iface->create()) + continue; + + if (iface->init()) + break; + + iface->free(); + iface = NULL; + } + + if (!iface) + { + DEBUG_ERROR("Failed to find a supported capture interface"); + return -1; + } + + DEBUG_INFO("Using : %s", iface->getName()); + + iface->capture(); + iface->capture(); + iface->capture(); + + iface->deinit(); + iface->free(); + return 0; +} \ No newline at end of file diff --git a/c-host/windebug.c b/c-host/windebug.c new file mode 100644 index 00000000..fabe56cd --- /dev/null +++ b/c-host/windebug.c @@ -0,0 +1,42 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017-2019 Geoffrey McRae +https://looking-glass.hostfission.com + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "windebug.h" +#include + +void DebugWinError(const char * file, const unsigned int line, const char * function, const char * desc, HRESULT status) +{ + char *buffer; + FormatMessageA( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + status, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (char*)&buffer, + 1024, + NULL + ); + + for(size_t i = strlen(buffer) - 1; i > 0; --i) + if (buffer[i] == '\n' || buffer[i] == '\r') + buffer[i] = 0; + + fprintf(stderr, "[E] %20s:%-4u | %-30s | %s: 0x%08x (%s)\n", file, line, function, desc, (int)status, buffer); + LocalFree(buffer); +} \ No newline at end of file diff --git a/c-host/windebug.h b/c-host/windebug.h new file mode 100644 index 00000000..8057e604 --- /dev/null +++ b/c-host/windebug.h @@ -0,0 +1,27 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017-2019 Geoffrey McRae +https://looking-glass.hostfission.com + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#pragma once + +#include "debug.h" +#include + +void DebugWinError(const char * file, const unsigned int line, const char * function, const char * desc, HRESULT status); + +#define DEBUG_WINERROR(x, y) DebugWinError(STRIPPATH(__FILE__), __LINE__, __FUNCTION__, x, y) \ No newline at end of file