[c-host] added new pure C host project, see README.md

This commit is contained in:
Geoffrey McRae 2019-02-28 16:35:30 +11:00
parent 526c09b7ff
commit c99f4e31c5
11 changed files with 1419 additions and 0 deletions

3
.gitignore vendored
View File

@ -4,3 +4,6 @@ module/*.mod.c
module/.*
module/Module.symvers
module/modules.order
*.a
*.o
*.exe

38
c-host/Makefile Normal file
View File

@ -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 $@

34
c-host/README.md Normal file
View File

@ -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_

465
c-host/capture/dxgi.c Normal file
View File

@ -0,0 +1,465 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
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 <assert.h>
#include <dxgi.h>
#include <d3d11.h>
#include <d3dcommon.h>
#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
};

635
c-host/capture/dxgi_extra.h Normal file
View File

@ -0,0 +1,635 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
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 <dxgi.h>
#include <d3d11.h>
#include <d3dcommon.h>
// 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];
}

View File

@ -0,0 +1,42 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
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 <stdbool.h>
#include <stdint.h>
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)();
};

View File

@ -0,0 +1,32 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
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
};

44
c-host/dll/libd3d11.def Normal file
View File

@ -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

57
c-host/main.c Normal file
View File

@ -0,0 +1,57 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
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 <stdio.h>
#include <windows.h>
#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;
}

42
c-host/windebug.c Normal file
View File

@ -0,0 +1,42 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
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 <stdio.h>
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);
}

27
c-host/windebug.h Normal file
View File

@ -0,0 +1,27 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
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 <windows.h>
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)