mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-25 23:07:18 +00:00
[host] added option parsing to application
This commit is contained in:
parent
71c6e5d317
commit
6eb40a1897
@ -18,11 +18,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef DEBUG
|
#define DEBUG_PRINT(type, fmt, ...) do {fprintf(stderr, type " %20s:%-5u | %-24s | " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);} while (0)
|
||||||
#define DEBUG_PRINT(type, fmt, ...) do {fprintf(stderr, type " %20s:%-5u | %-24s | " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);} while (0)
|
|
||||||
#else
|
|
||||||
#define DEBUG_PRINT(type, fmt, ...) do {} while(0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DEBUG_INFO(fmt, ...) DEBUG_PRINT("[I]", fmt, ##__VA_ARGS__)
|
#define DEBUG_INFO(fmt, ...) DEBUG_PRINT("[I]", fmt, ##__VA_ARGS__)
|
||||||
#define DEBUG_WARN(fmt, ...) DEBUG_PRINT("[W]", fmt, ##__VA_ARGS__)
|
#define DEBUG_WARN(fmt, ...) DEBUG_PRINT("[W]", fmt, ##__VA_ARGS__)
|
||||||
|
@ -22,6 +22,7 @@ using namespace Capture;
|
|||||||
#include "common\debug.h"
|
#include "common\debug.h"
|
||||||
|
|
||||||
DXGI::DXGI() :
|
DXGI::DXGI() :
|
||||||
|
m_options(NULL),
|
||||||
m_initialized(false),
|
m_initialized(false),
|
||||||
m_dxgiFactory(NULL),
|
m_dxgiFactory(NULL),
|
||||||
m_device(NULL),
|
m_device(NULL),
|
||||||
@ -37,11 +38,12 @@ DXGI::~DXGI()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DXGI::Initialize()
|
bool DXGI::Initialize(CaptureOptions * options)
|
||||||
{
|
{
|
||||||
if (m_initialized)
|
if (m_initialized)
|
||||||
DeInitialize();
|
DeInitialize();
|
||||||
|
|
||||||
|
m_options = options;
|
||||||
HRESULT status;
|
HRESULT status;
|
||||||
|
|
||||||
status = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void **)(&m_dxgiFactory));
|
status = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void **)(&m_dxgiFactory));
|
||||||
@ -208,7 +210,7 @@ bool DXGI::ReInitialize()
|
|||||||
*/
|
*/
|
||||||
Sleep(200);
|
Sleep(200);
|
||||||
|
|
||||||
return Initialize();
|
return Initialize(m_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameType DXGI::GetFrameType()
|
FrameType DXGI::GetFrameType()
|
||||||
|
@ -33,7 +33,10 @@ namespace Capture
|
|||||||
public:
|
public:
|
||||||
DXGI();
|
DXGI();
|
||||||
~DXGI();
|
~DXGI();
|
||||||
bool Initialize();
|
|
||||||
|
const char * GetName() { return "DXGI"; }
|
||||||
|
|
||||||
|
bool Initialize(CaptureOptions * options);
|
||||||
void DeInitialize();
|
void DeInitialize();
|
||||||
enum FrameType GetFrameType();
|
enum FrameType GetFrameType();
|
||||||
enum FrameComp GetFrameCompression();
|
enum FrameComp GetFrameCompression();
|
||||||
@ -41,6 +44,8 @@ namespace Capture
|
|||||||
bool GrabFrame(struct FrameInfo & frame);
|
bool GrabFrame(struct FrameInfo & frame);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
CaptureOptions * m_options;
|
||||||
|
|
||||||
bool ReInitialize();
|
bool ReInitialize();
|
||||||
|
|
||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
|
@ -31,6 +31,8 @@ using namespace Capture;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
NvFBC::NvFBC() :
|
NvFBC::NvFBC() :
|
||||||
|
m_options(NULL),
|
||||||
|
m_optNoCrop(false),
|
||||||
m_initialized(false),
|
m_initialized(false),
|
||||||
m_hDLL(NULL),
|
m_hDLL(NULL),
|
||||||
m_nvFBC(NULL)
|
m_nvFBC(NULL)
|
||||||
@ -41,11 +43,18 @@ NvFBC::~NvFBC()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NvFBC::Initialize()
|
bool NvFBC::Initialize(CaptureOptions * options)
|
||||||
{
|
{
|
||||||
if (m_initialized)
|
if (m_initialized)
|
||||||
DeInitialize();
|
DeInitialize();
|
||||||
|
|
||||||
|
m_options = options;
|
||||||
|
m_optNoCrop = false;
|
||||||
|
for (CaptureOptions::const_iterator it = options->begin(); it != options->end(); ++it)
|
||||||
|
{
|
||||||
|
if (_strcmpi(*it, "nocrop") == 0) { m_optNoCrop = true; continue; }
|
||||||
|
}
|
||||||
|
|
||||||
std::string nvfbc = Util::GetSystemRoot() + "\\" + NVFBC_LIBRARY_NAME;
|
std::string nvfbc = Util::GetSystemRoot() + "\\" + NVFBC_LIBRARY_NAME;
|
||||||
m_hDLL = LoadLibraryA(nvfbc.c_str());
|
m_hDLL = LoadLibraryA(nvfbc.c_str());
|
||||||
if (!m_hDLL)
|
if (!m_hDLL)
|
||||||
@ -221,15 +230,30 @@ bool NvFBC::GrabFrame(struct FrameInfo & frame)
|
|||||||
NVFBCRESULT status = m_nvFBC->NvFBCToSysGrabFrame(&m_grabFrameParams);
|
NVFBCRESULT status = m_nvFBC->NvFBCToSysGrabFrame(&m_grabFrameParams);
|
||||||
if (status == NVFBC_SUCCESS)
|
if (status == NVFBC_SUCCESS)
|
||||||
{
|
{
|
||||||
const unsigned int realHeight = min(m_grabInfo.dwHeight, desktop.bottom - desktop.top );
|
unsigned int dataWidth;
|
||||||
const unsigned int realWidth = min(m_grabInfo.dwWidth , desktop.right - desktop.left);
|
unsigned int dataOffset;
|
||||||
const unsigned int dataWidth = realWidth * 3;
|
|
||||||
const unsigned int dataOffset =
|
if (m_optNoCrop)
|
||||||
(((m_grabInfo.dwHeight - realHeight) >> 1) * m_grabInfo.dwBufferWidth +
|
{
|
||||||
((m_grabInfo.dwWidth - realWidth ) >> 1)) * 3;
|
dataWidth = m_grabInfo.dwWidth * 3;
|
||||||
|
dataOffset = 0;
|
||||||
|
|
||||||
|
frame.width = m_grabInfo.dwWidth;
|
||||||
|
frame.height = m_grabInfo.dwHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const unsigned int realHeight = min(m_grabInfo.dwHeight, (unsigned int)(desktop.bottom - desktop.top));
|
||||||
|
const unsigned int realWidth = min(m_grabInfo.dwWidth , (unsigned int)(desktop.right - desktop.left));
|
||||||
|
dataWidth = realWidth * 3;
|
||||||
|
dataOffset =
|
||||||
|
(((m_grabInfo.dwHeight - realHeight) >> 1) * m_grabInfo.dwBufferWidth +
|
||||||
|
((m_grabInfo.dwWidth - realWidth ) >> 1)) * 3;
|
||||||
|
|
||||||
|
frame.width = realWidth;
|
||||||
|
frame.height = realHeight;
|
||||||
|
}
|
||||||
|
|
||||||
frame.width = realWidth;
|
|
||||||
frame.height = realHeight;
|
|
||||||
frame.stride = frame.width;
|
frame.stride = frame.width;
|
||||||
frame.outSize = frame.width * frame.height * 3;
|
frame.outSize = frame.width * frame.height * 3;
|
||||||
|
|
||||||
@ -251,7 +275,7 @@ bool NvFBC::GrabFrame(struct FrameInfo & frame)
|
|||||||
{
|
{
|
||||||
DEBUG_WARN("Session was invalidated, attempting to restart");
|
DEBUG_WARN("Session was invalidated, attempting to restart");
|
||||||
DeInitialize();
|
DeInitialize();
|
||||||
if (!Initialize())
|
if (!Initialize(m_options))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to re-iniaialize");
|
DEBUG_ERROR("Failed to re-iniaialize");
|
||||||
return false;
|
return false;
|
||||||
|
@ -33,7 +33,9 @@ namespace Capture
|
|||||||
NvFBC();
|
NvFBC();
|
||||||
~NvFBC();
|
~NvFBC();
|
||||||
|
|
||||||
bool Initialize();
|
const char * GetName() { return "NvFBC"; }
|
||||||
|
|
||||||
|
bool Initialize(CaptureOptions * options);
|
||||||
void DeInitialize();
|
void DeInitialize();
|
||||||
enum FrameType GetFrameType();
|
enum FrameType GetFrameType();
|
||||||
enum FrameComp GetFrameCompression();
|
enum FrameComp GetFrameCompression();
|
||||||
@ -41,6 +43,9 @@ namespace Capture
|
|||||||
bool GrabFrame(struct FrameInfo & frame);
|
bool GrabFrame(struct FrameInfo & frame);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
CaptureOptions * m_options;
|
||||||
|
bool m_optNoCrop;
|
||||||
|
|
||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
HMODULE m_hDLL;
|
HMODULE m_hDLL;
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
|
|
||||||
#define W32_LEAN_AND_MEAN
|
#define W32_LEAN_AND_MEAN
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "common\debug.h"
|
#include "common\debug.h"
|
||||||
#include "ICapture.h"
|
#include "ICapture.h"
|
||||||
@ -29,29 +30,61 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
class CaptureFactory
|
class CaptureFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static ICapture * GetCaptureDevice()
|
typedef std::vector<ICapture *> DeviceList;
|
||||||
|
|
||||||
|
static DeviceList & GetDevices()
|
||||||
{
|
{
|
||||||
ICapture *dev;
|
static DeviceList devices;
|
||||||
|
if (!devices.empty())
|
||||||
|
return devices;
|
||||||
|
|
||||||
dev = new Capture::NvFBC();
|
devices.push_back(new Capture::NvFBC());
|
||||||
if (dev->Initialize())
|
devices.push_back(new Capture::DXGI ());
|
||||||
|
|
||||||
|
return devices;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ICapture * GetDevice(const char * name, CaptureOptions * options)
|
||||||
|
{
|
||||||
|
DeviceList devices = GetDevices();
|
||||||
|
for (DeviceList::const_iterator it = devices.begin(); it != devices.end(); ++it)
|
||||||
{
|
{
|
||||||
DEBUG_INFO("Using NvFBC");
|
ICapture * device = *it;
|
||||||
return dev;
|
if (_strcmpi(name, device->GetName()) != 0)
|
||||||
}
|
continue;
|
||||||
dev->DeInitialize();
|
|
||||||
delete dev;
|
|
||||||
|
|
||||||
dev = new Capture::DXGI();
|
if (device->Initialize(options))
|
||||||
if (dev->Initialize())
|
{
|
||||||
|
DEBUG_INFO("Using %s", device->GetName());
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
device->DeInitialize();
|
||||||
|
DEBUG_ERROR("Failed to initialize %s", device->GetName());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_ERROR("No such device: %s", name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ICapture * DetectDevice(CaptureOptions * options)
|
||||||
|
{
|
||||||
|
DeviceList devices = GetDevices();
|
||||||
|
for (DeviceList::const_iterator it = devices.begin(); it != devices.end(); ++it)
|
||||||
{
|
{
|
||||||
DEBUG_INFO("Using DXGI");
|
ICapture * device = *it;
|
||||||
return dev;
|
|
||||||
}
|
|
||||||
dev->DeInitialize();
|
|
||||||
delete dev;
|
|
||||||
|
|
||||||
DEBUG_ERROR("Failed to initialize a compatible capture device");
|
DEBUG_INFO("Trying %s", device->GetName());
|
||||||
|
if (device->Initialize(options))
|
||||||
|
{
|
||||||
|
DEBUG_INFO("Using %s", device->GetName());
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
device->DeInitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_ERROR("Failed to initialize a capture device");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -19,6 +19,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/KVMGFXHeader.h"
|
#include "common/KVMGFXHeader.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
struct FrameInfo
|
struct FrameInfo
|
||||||
{
|
{
|
||||||
@ -30,10 +31,14 @@ struct FrameInfo
|
|||||||
size_t outSize;
|
size_t outSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::vector<const char *> CaptureOptions;
|
||||||
|
|
||||||
__interface ICapture
|
__interface ICapture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool Initialize();
|
const char * GetName();
|
||||||
|
|
||||||
|
bool Initialize(CaptureOptions * options);
|
||||||
void DeInitialize();
|
void DeInitialize();
|
||||||
enum FrameType GetFrameType();
|
enum FrameType GetFrameType();
|
||||||
enum FrameComp GetFrameCompression();
|
enum FrameComp GetFrameCompression();
|
||||||
|
@ -40,19 +40,12 @@ Service::~Service()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Service::Initialize()
|
bool Service::Initialize(ICapture * captureDevice)
|
||||||
{
|
{
|
||||||
if (m_initialized)
|
if (m_initialized)
|
||||||
DeInitialize();
|
DeInitialize();
|
||||||
|
|
||||||
m_capture = CaptureFactory::GetCaptureDevice();
|
m_capture = captureDevice;
|
||||||
if (!m_capture)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Failed to initialize capture interface");
|
|
||||||
DeInitialize();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_ivshmem->Initialize())
|
if (!m_ivshmem->Initialize())
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("IVSHMEM failed to initalize");
|
DEBUG_ERROR("IVSHMEM failed to initalize");
|
||||||
|
@ -35,7 +35,7 @@ public:
|
|||||||
return m_instance;
|
return m_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Initialize();
|
bool Initialize(ICapture * captureDevice);
|
||||||
void DeInitialize();
|
void DeInitialize();
|
||||||
bool Process();
|
bool Process();
|
||||||
|
|
||||||
|
@ -160,6 +160,7 @@
|
|||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\vendor\getopt\getopt.c" />
|
||||||
<ClCompile Include="Capture\DXGI.cpp" />
|
<ClCompile Include="Capture\DXGI.cpp" />
|
||||||
<ClCompile Include="Capture\NvFBC.cpp" />
|
<ClCompile Include="Capture\NvFBC.cpp" />
|
||||||
<ClCompile Include="ivshmem.cpp" />
|
<ClCompile Include="ivshmem.cpp" />
|
||||||
|
@ -39,6 +39,9 @@
|
|||||||
<ClCompile Include="Capture\DXGI.cpp">
|
<ClCompile Include="Capture\DXGI.cpp">
|
||||||
<Filter>Source Files\Capture</Filter>
|
<Filter>Source Files\Capture</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\vendor\getopt\getopt.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="ivshmem.h">
|
<ClInclude Include="ivshmem.h">
|
||||||
|
262
host/main.cpp
262
host/main.cpp
@ -17,70 +17,244 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include "common\debug.h"
|
#include <Shlwapi.h>
|
||||||
|
|
||||||
|
#include "common\debug.h"
|
||||||
|
#include "vendor\getopt\getopt.h"
|
||||||
|
|
||||||
|
#include "CaptureFactory.h"
|
||||||
#include "Service.h"
|
#include "Service.h"
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#endif
|
|
||||||
|
int parseArgs(struct StartupArgs & args);
|
||||||
|
int run(struct StartupArgs & args);
|
||||||
|
|
||||||
|
void doHelp();
|
||||||
|
void doLicense();
|
||||||
|
|
||||||
|
bool consoleActive = false;
|
||||||
|
void setupConsole();
|
||||||
|
|
||||||
|
struct StartupArgs
|
||||||
|
{
|
||||||
|
bool foreground;
|
||||||
|
const char * captureDevice;
|
||||||
|
CaptureOptions captureOptions;
|
||||||
|
};
|
||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdParam, int iCmdShow)
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdParam, int iCmdShow)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
struct StartupArgs args;
|
||||||
|
ZeroMemory(&args, sizeof(struct StartupArgs));
|
||||||
|
int ret = parseArgs(args);
|
||||||
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
HANDLE _handle;
|
ret = run(args);
|
||||||
int _conout;
|
if (ret != 0)
|
||||||
FILE * fp;
|
{
|
||||||
|
if (!args.foreground)
|
||||||
AllocConsole();
|
{
|
||||||
|
setupConsole();
|
||||||
CONSOLE_SCREEN_BUFFER_INFO conInfo;
|
fprintf(stderr, "An error occurred, re-run in forground mode (-f) for more information\n");
|
||||||
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &conInfo);
|
}
|
||||||
conInfo.dwSize.Y = 500;
|
}
|
||||||
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), conInfo.dwSize);
|
|
||||||
|
|
||||||
_handle = GetStdHandle(STD_INPUT_HANDLE);
|
|
||||||
_conout = _open_osfhandle((intptr_t)_handle, _O_TEXT);
|
|
||||||
fp = _fdopen(_conout, "r");
|
|
||||||
freopen_s(&fp, "CONIN$", "r", stdin);
|
|
||||||
|
|
||||||
_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
_conout = _open_osfhandle((intptr_t)_handle, _O_TEXT);
|
|
||||||
fp = _fdopen(_conout, "w");
|
|
||||||
freopen_s(&fp, "CONOUT$", "w", stdout);
|
|
||||||
|
|
||||||
_handle = GetStdHandle(STD_ERROR_HANDLE);
|
|
||||||
_conout = _open_osfhandle((intptr_t)_handle, _O_TEXT);
|
|
||||||
fp = _fdopen(_conout, "w");
|
|
||||||
freopen_s(&fp, "CONOUT$", "w", stderr);
|
|
||||||
|
|
||||||
std::ios::sync_with_stdio();
|
|
||||||
std::wcout.clear();
|
|
||||||
std::cout.clear();
|
|
||||||
std::wcerr.clear();
|
|
||||||
std::cerr.clear();
|
|
||||||
std::wcin.clear();
|
|
||||||
std::cin.clear();
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
Service *svc = svc->Get();
|
if (consoleActive)
|
||||||
if (!svc->Initialize())
|
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to initialize service");
|
fprintf(stderr, "\nPress enter to terminate...");
|
||||||
|
fflush(stderr);
|
||||||
|
getc(stdin);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int run(struct StartupArgs & args)
|
||||||
|
{
|
||||||
|
if (args.foreground)
|
||||||
|
setupConsole();
|
||||||
|
|
||||||
|
ICapture * captureDevice;
|
||||||
|
if (args.captureDevice == NULL)
|
||||||
|
captureDevice = CaptureFactory::DetectDevice(&args.captureOptions);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
captureDevice = CaptureFactory::GetDevice(args.captureDevice, &args.captureOptions);
|
||||||
|
if (!captureDevice)
|
||||||
|
{
|
||||||
|
setupConsole();
|
||||||
|
fprintf(stderr, "Failed to configure requested capture device\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!captureDevice)
|
||||||
|
{
|
||||||
|
setupConsole();
|
||||||
|
fprintf(stderr, "Unable to configure a capture device\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Service *svc = svc->Get();
|
||||||
|
if (!svc->Initialize(captureDevice))
|
||||||
|
return -1;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
if (!svc->Process())
|
if (!svc->Process())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
svc->DeInitialize();
|
svc->DeInitialize();
|
||||||
#ifdef DEBUG
|
|
||||||
getc(stdin);
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int parseArgs(struct StartupArgs & args)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
while((c = getopt(__argc, __argv, "hc:o:fl")) != -1)
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '?':
|
||||||
|
case 'h':
|
||||||
|
doHelp();
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
{
|
||||||
|
const CaptureFactory::DeviceList deviceList = CaptureFactory::GetDevices();
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
if (strcmp(optarg, "?") != 0)
|
||||||
|
{
|
||||||
|
for (CaptureFactory::DeviceList::const_iterator it = deviceList.begin(); it != deviceList.end(); ++it)
|
||||||
|
{
|
||||||
|
if (_strcmpi(optarg, (*it)->GetName()) == 0)
|
||||||
|
{
|
||||||
|
args.captureDevice = (*it)->GetName();
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
setupConsole();
|
||||||
|
fprintf(stderr, "Invalid capture device: %s\n\n", optarg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
setupConsole();
|
||||||
|
fprintf(stderr, "Available Capture Devices:\n\n");
|
||||||
|
for (CaptureFactory::DeviceList::const_iterator it = deviceList.begin(); it != deviceList.end(); ++it)
|
||||||
|
fprintf(stderr, " %s\n", (*it)->GetName());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'o':
|
||||||
|
{
|
||||||
|
args.captureOptions.push_back(optarg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
args.foreground = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'l':
|
||||||
|
doLicense();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doHelp()
|
||||||
|
{
|
||||||
|
setupConsole();
|
||||||
|
const char *app = PathFindFileNameA(__argv[0]);
|
||||||
|
fprintf(stderr,
|
||||||
|
"Usage: %s [OPTION]...\n"
|
||||||
|
"Example: %s -c ?\n"
|
||||||
|
"\n"
|
||||||
|
" -h Print out this help\n"
|
||||||
|
" -c Specify the capture device to use or ? to list availble (device is probed if not specified)\n"
|
||||||
|
" -o Option to pass to the capture device, may be specified multiple times for extra options\n"
|
||||||
|
" -f Foreground mode\n"
|
||||||
|
" -l License information\n",
|
||||||
|
app,
|
||||||
|
app
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void doLicense()
|
||||||
|
{
|
||||||
|
setupConsole();
|
||||||
|
fprintf(stderr,
|
||||||
|
"KVMGFX Client - A KVM Client for VGA Passthrough\n"
|
||||||
|
"Copyright(C) 2017 Geoffrey McRae <geoff@hostfission.com>\n"
|
||||||
|
"\n"
|
||||||
|
"This program is free software; you can redistribute it and / or modify it under\n"
|
||||||
|
"the terms of the GNU General Public License as published by the Free Software\n"
|
||||||
|
"Foundation; either version 2 of the License, or (at your option) any later\n"
|
||||||
|
"version.\n"
|
||||||
|
"\n"
|
||||||
|
"This program is distributed in the hope that it will be useful, but WITHOUT ANY\n"
|
||||||
|
"WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A\n"
|
||||||
|
"PARTICULAR PURPOSE.See the GNU General Public License for more details.\n"
|
||||||
|
"\n"
|
||||||
|
"You should have received a copy of the GNU General Public License along with\n"
|
||||||
|
"this program; if not, write to the Free Software Foundation, Inc., 59 Temple\n"
|
||||||
|
"Place, Suite 330, Boston, MA 02111 - 1307 USA\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupConsole()
|
||||||
|
{
|
||||||
|
if (consoleActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
HANDLE _handle;
|
||||||
|
int _conout;
|
||||||
|
FILE * fp;
|
||||||
|
|
||||||
|
AllocConsole();
|
||||||
|
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO conInfo;
|
||||||
|
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &conInfo);
|
||||||
|
conInfo.dwSize.Y = 500;
|
||||||
|
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), conInfo.dwSize);
|
||||||
|
|
||||||
|
_handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
_conout = _open_osfhandle((intptr_t)_handle, _O_TEXT);
|
||||||
|
fp = _fdopen(_conout, "r");
|
||||||
|
freopen_s(&fp, "CONIN$", "r", stdin);
|
||||||
|
|
||||||
|
_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
_conout = _open_osfhandle((intptr_t)_handle, _O_TEXT);
|
||||||
|
fp = _fdopen(_conout, "w");
|
||||||
|
freopen_s(&fp, "CONOUT$", "w", stdout);
|
||||||
|
|
||||||
|
_handle = GetStdHandle(STD_ERROR_HANDLE);
|
||||||
|
_conout = _open_osfhandle((intptr_t)_handle, _O_TEXT);
|
||||||
|
fp = _fdopen(_conout, "w");
|
||||||
|
freopen_s(&fp, "CONOUT$", "w", stderr);
|
||||||
|
|
||||||
|
std::ios::sync_with_stdio();
|
||||||
|
std::wcout.clear();
|
||||||
|
std::cout.clear();
|
||||||
|
std::wcerr.clear();
|
||||||
|
std::cerr.clear();
|
||||||
|
std::wcin.clear();
|
||||||
|
std::cin.clear();
|
||||||
|
|
||||||
|
consoleActive = true;
|
||||||
|
}
|
1
vendor/getopt/README.txt
vendored
Normal file
1
vendor/getopt/README.txt
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
This source comes from: https://gist.github.com/superwills/5815344
|
106
vendor/getopt/getopt.c
vendored
Normal file
106
vendor/getopt/getopt.c
vendored
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#include "getopt.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1987, 1993, 1994
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int opterr = 1, /* if error message should be printed */
|
||||||
|
optind = 1, /* index into parent argv vector */
|
||||||
|
optopt, /* character checked for validity */
|
||||||
|
optreset; /* reset getopt */
|
||||||
|
char *optarg; /* argument associated with option */
|
||||||
|
|
||||||
|
#define BADCH (int)'?'
|
||||||
|
#define BADARG (int)':'
|
||||||
|
#define EMSG ""
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getopt --
|
||||||
|
* Parse argc/argv argument vector.
|
||||||
|
*/
|
||||||
|
int getopt(int nargc, char * const nargv[], const char *ostr)
|
||||||
|
{
|
||||||
|
static char *place = EMSG; /* option letter processing */
|
||||||
|
const char *oli; /* option letter list index */
|
||||||
|
|
||||||
|
if (optreset || !*place) { /* update scanning pointer */
|
||||||
|
optreset = 0;
|
||||||
|
if (optind >= nargc || *(place = nargv[optind]) != '-') {
|
||||||
|
place = EMSG;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (place[1] && *++place == '-') { /* found "--" */
|
||||||
|
++optind;
|
||||||
|
place = EMSG;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
} /* option letter okay? */
|
||||||
|
if ((optopt = (int)*place++) == (int)':' ||
|
||||||
|
!(oli = strchr(ostr, optopt))) {
|
||||||
|
/*
|
||||||
|
* if the user didn't specify '-' as an option,
|
||||||
|
* assume it means -1.
|
||||||
|
*/
|
||||||
|
if (optopt == (int)'-')
|
||||||
|
return (-1);
|
||||||
|
if (!*place)
|
||||||
|
++optind;
|
||||||
|
if (opterr && *ostr != ':')
|
||||||
|
(void)printf("illegal option -- %c\n", optopt);
|
||||||
|
return (BADCH);
|
||||||
|
}
|
||||||
|
if (*++oli != ':') { /* don't need argument */
|
||||||
|
optarg = NULL;
|
||||||
|
if (!*place)
|
||||||
|
++optind;
|
||||||
|
}
|
||||||
|
else { /* need an argument */
|
||||||
|
if (*place) /* no white space */
|
||||||
|
optarg = place;
|
||||||
|
else if (nargc <= ++optind) { /* no arg */
|
||||||
|
place = EMSG;
|
||||||
|
if (*ostr == ':')
|
||||||
|
return (BADARG);
|
||||||
|
if (opterr)
|
||||||
|
(void)printf("option requires an argument -- %c\n", optopt);
|
||||||
|
return (BADCH);
|
||||||
|
}
|
||||||
|
else /* white space */
|
||||||
|
optarg = nargv[optind];
|
||||||
|
place = EMSG;
|
||||||
|
++optind;
|
||||||
|
}
|
||||||
|
return (optopt); /* dump back option letter */
|
||||||
|
}
|
20
vendor/getopt/getopt.h
vendored
Normal file
20
vendor/getopt/getopt.h
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef GETOPT_H
|
||||||
|
#define GETOPT_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int opterr; /* if error message should be printed */
|
||||||
|
extern int optind; /* index into parent argv vector */
|
||||||
|
extern int optopt; /* character checked for validity */
|
||||||
|
extern int optreset; /* reset getopt */
|
||||||
|
extern char *optarg; /* argument associated with option */
|
||||||
|
|
||||||
|
int getopt(int nargc, char * const nargv[], const char *ostr);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user