mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-11-17 07:28:44 +00:00
Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3784e9c06f | ||
|
|
24709ef186 | ||
|
|
db59e67ddb | ||
|
|
1815387bbb | ||
|
|
6595374a2c | ||
|
|
9d8f3a79b0 | ||
|
|
bf85358715 | ||
|
|
b77a34b8b6 | ||
|
|
287b983d27 | ||
|
|
7c5b2b5c1c | ||
|
|
758b7af754 | ||
|
|
b89a8fee04 | ||
|
|
2bb8b0227c | ||
|
|
ae4156d041 | ||
|
|
fe337cf510 | ||
|
|
7bfed41523 | ||
|
|
9bb66b7bd6 | ||
|
|
f7420317f1 | ||
|
|
c1379a45d2 | ||
|
|
9c03327701 | ||
|
|
0d8b2449cf | ||
|
|
d1bd5b3115 | ||
|
|
e03621a622 | ||
|
|
b93aca796c | ||
|
|
606da0ae47 | ||
|
|
d08fba9cf9 | ||
|
|
df13340439 | ||
|
|
b6c8136565 | ||
|
|
0948dda12f | ||
|
|
8ae9f8464b | ||
|
|
110aced7d1 | ||
|
|
3c61814c56 | ||
|
|
133001b545 | ||
|
|
106136afd6 | ||
|
|
c72afff055 | ||
|
|
d052239721 | ||
|
|
fdfa3006b4 | ||
|
|
a01d755ab5 | ||
|
|
9a9d84cd1f | ||
|
|
892a3970ff | ||
|
|
d6fee6bf0b | ||
|
|
7691093121 | ||
|
|
524183661d | ||
|
|
cd54cb179b | ||
|
|
973ad5e2b0 | ||
|
|
67bdf2ba97 |
11
.github/issue_template.md
vendored
Normal file
11
.github/issue_template.md
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
### Required information
|
||||
|
||||
Host CPU:
|
||||
Host GPU:
|
||||
Guest GPU:
|
||||
Host Kernel version:
|
||||
Host QEMU version:
|
||||
|
||||
Please describe what were you doing when the problem occured. If the Windows host application crashed please check for file named `looking-glass-host.dmp` and attach it to this bug report.
|
||||
|
||||
**Reports that do no include this information will be ignored and closed**
|
||||
@@ -30,6 +30,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
@@ -511,7 +512,8 @@ enum IVSHMEMWaitResult ivshmem_wait_irq(uint16_t vector, unsigned int timeout)
|
||||
if (FD_ISSET(fd, &fds))
|
||||
{
|
||||
uint64_t kick;
|
||||
read(fd, &kick, sizeof(kick));
|
||||
int unused = read(fd, &kick, sizeof(kick));
|
||||
(void)unused;
|
||||
return IVSHMEM_WAIT_RESULT_OK;
|
||||
}
|
||||
}
|
||||
@@ -543,4 +545,4 @@ bool ivshmem_kick_irq(uint16_t clientID, uint16_t vector)
|
||||
|
||||
DEBUG_ERROR("failed to send kick");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL_ttf.h>
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
||||
#define IS_LG_RENDERER_VALID(x) \
|
||||
((x)->get_name && \
|
||||
@@ -41,6 +41,7 @@ typedef struct LG_RendererParams
|
||||
TTF_Font * font;
|
||||
bool showFPS;
|
||||
bool resample;
|
||||
bool vsync;
|
||||
}
|
||||
LG_RendererParams;
|
||||
|
||||
|
||||
205
client/main.c
205
client/main.c
@@ -50,6 +50,7 @@ struct AppState
|
||||
SDL_Point srcSize;
|
||||
LG_RendererRect dstRect;
|
||||
SDL_Point cursor;
|
||||
bool cursorVisible;
|
||||
bool haveCursorPos;
|
||||
float scaleX, scaleY;
|
||||
|
||||
@@ -63,10 +64,12 @@ struct AppState
|
||||
|
||||
struct AppParams
|
||||
{
|
||||
bool vsync;
|
||||
bool autoResize;
|
||||
bool allowResize;
|
||||
bool keepAspect;
|
||||
bool borderless;
|
||||
bool fullscreen;
|
||||
bool center;
|
||||
int x, y;
|
||||
unsigned int w, h;
|
||||
@@ -83,10 +86,12 @@ struct AppParams
|
||||
struct AppState state;
|
||||
struct AppParams params =
|
||||
{
|
||||
.vsync = true,
|
||||
.autoResize = false,
|
||||
.allowResize = true,
|
||||
.keepAspect = true,
|
||||
.borderless = false,
|
||||
.fullscreen = false,
|
||||
.center = true,
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
@@ -134,8 +139,11 @@ inline void updatePositionInfo()
|
||||
state.dstRect.h = h;
|
||||
}
|
||||
|
||||
state.scaleX = (float)state.srcSize.y / (float)state.dstRect.h;
|
||||
state.scaleY = (float)state.srcSize.x / (float)state.dstRect.w;
|
||||
if (state.started)
|
||||
{
|
||||
state.scaleX = (float)state.srcSize.y / (float)state.dstRect.h;
|
||||
state.scaleY = (float)state.srcSize.x / (float)state.dstRect.w;
|
||||
}
|
||||
|
||||
if (state.lgr)
|
||||
state.lgr->on_resize(state.lgrData, w, h, state.dstRect);
|
||||
@@ -145,8 +153,16 @@ int renderThread(void * unused)
|
||||
{
|
||||
bool error = false;
|
||||
struct KVMFRHeader header;
|
||||
|
||||
LG_RendererCursor cursorType = LG_CURSOR_COLOR;
|
||||
struct KVMFRFrame cursor = {};
|
||||
size_t cursorDataSize = 0;
|
||||
uint8_t * cursorData = NULL;
|
||||
|
||||
volatile uint32_t * updateCount = &state.shm->updateCount;
|
||||
|
||||
memset(&header, 0, sizeof(struct KVMFRHeader));
|
||||
|
||||
while(state.running)
|
||||
{
|
||||
// poll until we have a new frame, or we time out
|
||||
@@ -169,25 +185,32 @@ int renderThread(void * unused)
|
||||
__sync_or_and_fetch(&state.shm->flags, KVMFR_HEADER_FLAG_READY);
|
||||
|
||||
// check the header's magic and version are valid
|
||||
if (
|
||||
memcmp(header.magic, KVMFR_HEADER_MAGIC, sizeof(KVMFR_HEADER_MAGIC)) != 0 ||
|
||||
header.version != KVMFR_HEADER_VERSION
|
||||
){
|
||||
if (memcmp(header.magic, KVMFR_HEADER_MAGIC, sizeof(KVMFR_HEADER_MAGIC)) != 0)
|
||||
{
|
||||
usleep(1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (header.version != KVMFR_HEADER_VERSION)
|
||||
{
|
||||
DEBUG_ERROR("KVMFR version missmatch, expected %u but got %u", KVMFR_HEADER_VERSION, header.version);
|
||||
DEBUG_ERROR("This is not a bug, ensure you have the right version of looking-glass-host.exe on the guest");
|
||||
break;
|
||||
}
|
||||
|
||||
// if we have a frame
|
||||
if (header.flags & KVMFR_HEADER_FLAG_FRAME)
|
||||
{
|
||||
// sainty check of the frame format
|
||||
if (
|
||||
header.frame.type >= FRAME_TYPE_MAX ||
|
||||
header.frame.width == 0 ||
|
||||
header.frame.height == 0 ||
|
||||
header.frame.stride == 0 ||
|
||||
header.frame.dataPos == 0 ||
|
||||
header.frame.dataPos > state.shmSize
|
||||
header.detail.frame.type >= FRAME_TYPE_MAX ||
|
||||
header.detail.frame.width == 0 ||
|
||||
header.detail.frame.height == 0 ||
|
||||
header.detail.frame.stride == 0 ||
|
||||
header.detail.frame.pitch == 0 ||
|
||||
header.detail.frame.dataPos == 0 ||
|
||||
header.detail.frame.dataPos > state.shmSize ||
|
||||
header.detail.frame.pitch < header.detail.frame.width
|
||||
){
|
||||
usleep(1000);
|
||||
continue;
|
||||
@@ -195,19 +218,18 @@ int renderThread(void * unused)
|
||||
|
||||
// setup the renderer format with the frame format details
|
||||
LG_RendererFormat lgrFormat;
|
||||
lgrFormat.width = header.frame.width;
|
||||
lgrFormat.height = header.frame.height;
|
||||
lgrFormat.stride = header.frame.stride;
|
||||
lgrFormat.width = header.detail.frame.width;
|
||||
lgrFormat.height = header.detail.frame.height;
|
||||
lgrFormat.stride = header.detail.frame.stride;
|
||||
lgrFormat.pitch = header.detail.frame.pitch;
|
||||
|
||||
switch(header.frame.type)
|
||||
switch(header.detail.frame.type)
|
||||
{
|
||||
case FRAME_TYPE_ARGB:
|
||||
lgrFormat.pitch = header.frame.stride * 4;
|
||||
lgrFormat.bpp = 32;
|
||||
break;
|
||||
|
||||
case FRAME_TYPE_RGB:
|
||||
lgrFormat.pitch = header.frame.stride * 3;
|
||||
lgrFormat.bpp = 24;
|
||||
break;
|
||||
|
||||
@@ -222,7 +244,7 @@ int renderThread(void * unused)
|
||||
|
||||
// check the header's dataPos is sane
|
||||
const size_t dataSize = lgrFormat.height * lgrFormat.pitch;
|
||||
if (header.frame.dataPos + dataSize > state.shmSize)
|
||||
if (header.detail.frame.dataPos + dataSize > state.shmSize)
|
||||
{
|
||||
DEBUG_ERROR("The guest sent an invalid dataPos");
|
||||
break;
|
||||
@@ -241,14 +263,49 @@ int renderThread(void * unused)
|
||||
break;
|
||||
}
|
||||
|
||||
state.srcSize.x = header.frame.width;
|
||||
state.srcSize.y = header.frame.height;
|
||||
state.srcSize.x = header.detail.frame.width;
|
||||
state.srcSize.y = header.detail.frame.height;
|
||||
if (params.autoResize)
|
||||
SDL_SetWindowSize(state.window, header.frame.width, header.frame.height);
|
||||
SDL_SetWindowSize(state.window, header.detail.frame.width, header.detail.frame.height);
|
||||
|
||||
state.started = true;
|
||||
updatePositionInfo();
|
||||
|
||||
// if we have saved shape info, send it now
|
||||
if (cursorData)
|
||||
{
|
||||
if (!state.lgr->on_mouse_shape(
|
||||
state.lgrData,
|
||||
cursorType,
|
||||
cursor.width,
|
||||
cursor.height,
|
||||
cursor.pitch,
|
||||
cursorData
|
||||
))
|
||||
{
|
||||
DEBUG_ERROR("Failed to update mouse shape");
|
||||
break;
|
||||
}
|
||||
|
||||
free(cursorData);
|
||||
cursorData = NULL;
|
||||
cursorDataSize = 0;
|
||||
}
|
||||
|
||||
// if we have a cursor position, send it now
|
||||
if (state.haveCursorPos)
|
||||
{
|
||||
state.lgr->on_mouse_event
|
||||
(
|
||||
state.lgrData,
|
||||
state.cursorVisible,
|
||||
state.cursor.x,
|
||||
state.cursor.y
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const uint8_t * data = (const uint8_t *)state.shm + header.frame.dataPos;
|
||||
const uint8_t * data = (const uint8_t *)state.shm + header.detail.frame.dataPos;
|
||||
if (!state.lgr->on_frame_event(state.lgrData, data))
|
||||
{
|
||||
DEBUG_ERROR("Failed to render the frame");
|
||||
@@ -259,36 +316,64 @@ int renderThread(void * unused)
|
||||
// if we have cursor data
|
||||
if (header.flags & KVMFR_HEADER_FLAG_CURSOR)
|
||||
{
|
||||
if (header.cursor.flags & KVMFR_CURSOR_FLAG_POS)
|
||||
if (header.detail.cursor.flags & KVMFR_CURSOR_FLAG_POS)
|
||||
{
|
||||
state.cursor.x = header.cursor.x;
|
||||
state.cursor.y = header.cursor.y;
|
||||
state.cursor.x = header.detail.cursor.x;
|
||||
state.cursor.y = header.detail.cursor.y;
|
||||
state.cursorVisible = header.detail.cursor.flags & KVMFR_CURSOR_FLAG_VISIBLE;
|
||||
state.haveCursorPos = true;
|
||||
}
|
||||
|
||||
if (header.cursor.flags & KVMFR_CURSOR_FLAG_SHAPE)
|
||||
if (header.detail.cursor.flags & KVMFR_CURSOR_FLAG_SHAPE)
|
||||
{
|
||||
LG_RendererCursor c = LG_CURSOR_COLOR;
|
||||
switch(header.cursor.type)
|
||||
{
|
||||
case CURSOR_TYPE_COLOR : c = LG_CURSOR_COLOR ; break;
|
||||
case CURSOR_TYPE_MONOCHROME : c = LG_CURSOR_MONOCHROME ; break;
|
||||
case CURSOR_TYPE_MASKED_COLOR: c = LG_CURSOR_MASKED_COLOR; break;
|
||||
default:
|
||||
DEBUG_ERROR("Invalid cursor type");
|
||||
break;
|
||||
}
|
||||
|
||||
if (state.lgr)
|
||||
{
|
||||
bool bad = false;
|
||||
switch(header.detail.cursor.type)
|
||||
{
|
||||
case CURSOR_TYPE_COLOR : cursorType = LG_CURSOR_COLOR ; break;
|
||||
case CURSOR_TYPE_MONOCHROME : cursorType = LG_CURSOR_MONOCHROME ; break;
|
||||
case CURSOR_TYPE_MASKED_COLOR: cursorType = LG_CURSOR_MASKED_COLOR; break;
|
||||
default:
|
||||
DEBUG_ERROR("Invalid cursor type");
|
||||
bad = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bad)
|
||||
break;
|
||||
|
||||
// check the data position is sane
|
||||
const uint64_t dataSize = header.detail.frame.height * header.detail.frame.pitch;
|
||||
if (header.detail.frame.dataPos + dataSize > state.shmSize)
|
||||
{
|
||||
DEBUG_ERROR("The guest sent an invalid mouse dataPos");
|
||||
break;
|
||||
}
|
||||
|
||||
const uint8_t * data = (const uint8_t *)state.shm + header.detail.frame.dataPos;
|
||||
if (!state.started)
|
||||
{
|
||||
// save off the cursor data so we can tell the renderer when it's ready
|
||||
if (cursorDataSize < dataSize)
|
||||
{
|
||||
if (cursorData) free(cursorData);
|
||||
cursorData = (uint8_t *)malloc(dataSize);
|
||||
cursorDataSize = dataSize;
|
||||
}
|
||||
memcpy(&cursor, &header.detail.frame, sizeof(struct KVMFRFrame));
|
||||
memcpy(cursorData, data, dataSize);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!state.lgr->on_mouse_shape(
|
||||
state.lgrData,
|
||||
c,
|
||||
header.cursor.w,
|
||||
header.cursor.h,
|
||||
header.cursor.pitch,
|
||||
header.cursor.shape
|
||||
))
|
||||
cursorType,
|
||||
header.detail.frame.width,
|
||||
header.detail.frame.height,
|
||||
header.detail.frame.pitch,
|
||||
data)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to update mouse shape");
|
||||
break;
|
||||
@@ -296,21 +381,24 @@ int renderThread(void * unused)
|
||||
}
|
||||
}
|
||||
|
||||
if (state.lgr)
|
||||
if (state.lgr && state.started)
|
||||
{
|
||||
state.lgr->on_mouse_event(
|
||||
state.lgrData,
|
||||
(header.cursor.flags & KVMFR_CURSOR_FLAG_VISIBLE) != 0,
|
||||
state.cursorVisible,
|
||||
state.cursor.x,
|
||||
state.cursor.y
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (state.lgr)
|
||||
if (state.started && state.lgr)
|
||||
state.lgr->render(state.lgrData);
|
||||
}
|
||||
|
||||
if (cursorData)
|
||||
free(cursorData);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -613,6 +701,7 @@ int run()
|
||||
lgrParams.font = state.font;
|
||||
lgrParams.resample = params.useMipmap;
|
||||
lgrParams.showFPS = params.showFPS;
|
||||
lgrParams.vsync = params.vsync;
|
||||
Uint32 sdlFlags;
|
||||
|
||||
// probe for a a suitable renderer
|
||||
@@ -651,12 +740,18 @@ int run()
|
||||
params.h,
|
||||
(
|
||||
SDL_WINDOW_SHOWN |
|
||||
(params.fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0) |
|
||||
(params.allowResize ? SDL_WINDOW_RESIZABLE : 0) |
|
||||
(params.borderless ? SDL_WINDOW_BORDERLESS : 0) |
|
||||
sdlFlags
|
||||
)
|
||||
);
|
||||
|
||||
if (params.fullscreen)
|
||||
{
|
||||
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
|
||||
}
|
||||
|
||||
// set the compositor hint to bypass for low latency
|
||||
SDL_SysWMinfo wminfo;
|
||||
SDL_VERSION(&wminfo.version);
|
||||
@@ -724,8 +819,7 @@ int run()
|
||||
DEBUG_ERROR("Failed to map memory");
|
||||
break;
|
||||
}
|
||||
state.shmSize = ivshmem_get_map_size();
|
||||
state.shm->hostID = ivshmem_get_id();
|
||||
state.shmSize = ivshmem_get_map_size();
|
||||
|
||||
if (params.useSpice)
|
||||
{
|
||||
@@ -822,13 +916,14 @@ void doHelp(char * app)
|
||||
" -M Don't hide the host cursor\n"
|
||||
"\n"
|
||||
" -m Disable mipmapping\n"
|
||||
" -v Disable VSync\n"
|
||||
" -v Disable VSYNC\n"
|
||||
" -k Enable FPS display\n"
|
||||
"\n"
|
||||
" -a Auto resize the window to the guest\n"
|
||||
" -n Don't allow the window to be manually resized\n"
|
||||
" -r Don't maintain the aspect ratio\n"
|
||||
" -d Borderless mode\n"
|
||||
" -F Borderless fullscreen mode\n"
|
||||
" -x XPOS Initial window X position [current: %s]\n"
|
||||
" -y YPOS Initial window Y position [current: %s]\n"
|
||||
" -w WIDTH Initial window width [current: %u]\n"
|
||||
@@ -875,7 +970,7 @@ void doLicense()
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
int c;
|
||||
while((c = getopt(argc, argv, "hf:sc:p:jMmkanrdx:y:w:b:l")) != -1)
|
||||
while((c = getopt(argc, argv, "hf:sc:p:jMmvkanrdFx:y:w:b:l")) != -1)
|
||||
switch(c)
|
||||
{
|
||||
case '?':
|
||||
@@ -912,6 +1007,10 @@ int main(int argc, char * argv[])
|
||||
params.useMipmap = false;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
params.vsync = false;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
params.showFPS = true;
|
||||
break;
|
||||
@@ -932,6 +1031,10 @@ int main(int argc, char * argv[])
|
||||
params.borderless = true;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
params.fullscreen = true;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
params.center = false;
|
||||
params.x = atoi(optarg);
|
||||
|
||||
@@ -47,6 +47,7 @@ struct LGR_OpenGL
|
||||
{
|
||||
LG_RendererParams params;
|
||||
bool configured;
|
||||
SDL_Window * sdlWindow;
|
||||
SDL_GLContext glContext;
|
||||
bool doneInfo;
|
||||
|
||||
@@ -68,7 +69,6 @@ struct LGR_OpenGL
|
||||
int fpsList;
|
||||
int mouseList;
|
||||
LG_RendererRect destRect;
|
||||
bool mipmap;
|
||||
|
||||
bool hasTextures;
|
||||
GLuint textures[TEXTURE_COUNT];
|
||||
@@ -81,6 +81,7 @@ struct LGR_OpenGL
|
||||
SDL_Rect fpsRect;
|
||||
|
||||
bool mouseUpdate;
|
||||
bool newShape;
|
||||
uint64_t lastMouseDraw;
|
||||
LG_RendererCursor mouseType;
|
||||
bool mouseVisible;
|
||||
@@ -131,7 +132,7 @@ bool lgr_opengl_initialize(void ** opaque, const LG_RendererParams params, Uint3
|
||||
}
|
||||
|
||||
*sdlFlags = SDL_WINDOW_OPENGL;
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -147,6 +148,7 @@ bool lgr_opengl_configure(void * opaque, SDL_Window *window, const LG_RendererFo
|
||||
return false;
|
||||
}
|
||||
|
||||
this->sdlWindow = window;
|
||||
this->glContext = SDL_GL_CreateContext(window);
|
||||
if (!this->glContext)
|
||||
{
|
||||
@@ -168,7 +170,7 @@ bool lgr_opengl_configure(void * opaque, SDL_Window *window, const LG_RendererFo
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_GL_SetSwapInterval(0);
|
||||
SDL_GL_SetSwapInterval(this->params.vsync ? 1 : 0);
|
||||
|
||||
// check if the GPU supports GL_ARB_buffer_storage first
|
||||
// there is no advantage to this renderer if it is not present.
|
||||
@@ -362,7 +364,7 @@ void lgr_opengl_on_resize(void * opaque, const int width, const int height, cons
|
||||
if (!this || !this->configured)
|
||||
return;
|
||||
|
||||
this->window.x = width;
|
||||
this->window.x = width;
|
||||
this->window.y = height;
|
||||
memcpy(&this->destRect, &destRect, sizeof(LG_RendererRect));
|
||||
|
||||
@@ -391,7 +393,7 @@ bool lgr_opengl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor, co
|
||||
width ,
|
||||
height ,
|
||||
0 ,
|
||||
GL_RGBA,
|
||||
GL_BGRA, // windows cursors are in BGRA format
|
||||
GL_UNSIGNED_BYTE,
|
||||
data
|
||||
);
|
||||
@@ -491,6 +493,7 @@ bool lgr_opengl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor, co
|
||||
}
|
||||
|
||||
this->mouseUpdate = true;
|
||||
this->newShape = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -630,15 +633,17 @@ bool lgr_opengl_on_frame_event(void * opaque, const uint8_t * data)
|
||||
(this->format.width > this->destRect.w) ||
|
||||
(this->format.height > this->destRect.h));
|
||||
|
||||
if (this->mipmap != mipmap)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
|
||||
this->mipmap = mipmap;
|
||||
}
|
||||
|
||||
if (mipmap)
|
||||
{
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
@@ -700,15 +705,27 @@ bool lgr_opengl_render(void * opaque)
|
||||
if (!this->mouseUpdate)
|
||||
return true;
|
||||
|
||||
// don't update the mouse too fast
|
||||
const uint64_t delta = nanotime() - this->lastMouseDraw;
|
||||
if (delta < 1e7)
|
||||
return true;
|
||||
}
|
||||
if (!this->newShape)
|
||||
{
|
||||
// don't update the mouse too fast
|
||||
const uint64_t delta = nanotime() - this->lastMouseDraw;
|
||||
if (delta < 5e6)
|
||||
return true;
|
||||
}
|
||||
this->newShape = false;
|
||||
|
||||
// wait for vsync
|
||||
unsigned int count;
|
||||
glXWaitVideoSyncSGI(1, 0, &count);
|
||||
glDrawBuffer(GL_FRONT);
|
||||
glCallList(this->texList + this->texIndex);
|
||||
lgr_opengl_draw_mouse(this);
|
||||
if (this->fpsTexture)
|
||||
glCallList(this->fpsList);
|
||||
glDrawBuffer(GL_BACK);
|
||||
glFlush();
|
||||
|
||||
this->mouseUpdate = false;
|
||||
this->lastMouseDraw = nanotime();
|
||||
return true;
|
||||
}
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
@@ -718,7 +735,15 @@ bool lgr_opengl_render(void * opaque)
|
||||
lgr_opengl_draw_mouse(this);
|
||||
if (this->fpsTexture)
|
||||
glCallList(this->fpsList);
|
||||
glFlush();
|
||||
|
||||
unsigned int before, after;
|
||||
glXGetVideoSyncSGI(&before);
|
||||
SDL_GL_SwapWindow(this->sdlWindow);
|
||||
|
||||
// wait for the swap to happen to ensure we dont buffer frames
|
||||
glXGetVideoSyncSGI(&after);
|
||||
if (before == after)
|
||||
glXWaitVideoSyncSGI(1, 0, &before);
|
||||
|
||||
++this->frameCount;
|
||||
const uint64_t t = nanotime();
|
||||
|
||||
@@ -21,8 +21,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include <stdint.h>
|
||||
|
||||
#define KVMFR_HEADER_MAGIC "[[KVMFR]]"
|
||||
#define KVMFR_HEADER_VERSION 2
|
||||
#define KVMFR_CURSOR_BUFFER (32*32*4)
|
||||
#define KVMFR_HEADER_VERSION 4
|
||||
|
||||
typedef enum FrameType
|
||||
{
|
||||
@@ -50,9 +49,6 @@ typedef struct KVMFRCursor
|
||||
uint8_t flags; // KVMFR_CURSOR_FLAGS
|
||||
int16_t x, y; // cursor x & y position
|
||||
CursorType type; // shape buffer data type
|
||||
uint8_t w, h; // shape width and height
|
||||
uint8_t pitch; // shape row length in bytes
|
||||
uint8_t shape[KVMFR_CURSOR_BUFFER];
|
||||
}
|
||||
KVMFRCursor;
|
||||
|
||||
@@ -61,7 +57,8 @@ typedef struct KVMFRFrame
|
||||
FrameType type; // the frame data type
|
||||
uint32_t width; // the width
|
||||
uint32_t height; // the height
|
||||
uint32_t stride; // the row stride
|
||||
uint32_t stride; // the row stride (zero if cursor data)
|
||||
uint32_t pitch; // the row pitch (stride in bytes)
|
||||
uint64_t dataPos; // offset to the frame
|
||||
}
|
||||
KVMFRFrame;
|
||||
@@ -71,16 +68,19 @@ KVMFRFrame;
|
||||
#define KVMFR_HEADER_FLAG_RESTART 4 // restart signal from client
|
||||
#define KVMFR_HEADER_FLAG_READY 8 // ready signal from client
|
||||
|
||||
typedef struct KVMFRDetail
|
||||
{
|
||||
KVMFRFrame frame; // the frame information
|
||||
KVMFRCursor cursor; // the cursor information
|
||||
}
|
||||
KVMFRDetail;
|
||||
|
||||
typedef struct KVMFRHeader
|
||||
{
|
||||
char magic[sizeof(KVMFR_HEADER_MAGIC)];
|
||||
uint32_t version; // version of this structure
|
||||
uint16_t hostID; // the host ivshmem client id
|
||||
uint16_t guestID; // the guest ivshmem client id
|
||||
uint32_t updateCount; // updated each change
|
||||
uint8_t flags; // KVMFR_HEADER_FLAGS
|
||||
|
||||
KVMFRFrame frame; // the frame information
|
||||
KVMFRCursor cursor; // the cursor information
|
||||
KVMFRDetail detail; // details
|
||||
}
|
||||
KVMFRHeader;
|
||||
KVMFRHeader;
|
||||
|
||||
BIN
contrib/redhat/qemu-ivshmem-sock.pp
Normal file
BIN
contrib/redhat/qemu-ivshmem-sock.pp
Normal file
Binary file not shown.
@@ -17,20 +17,21 @@ 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 "Capture/DXGI.h"
|
||||
using namespace Capture;
|
||||
|
||||
#include "common\debug.h"
|
||||
#include "common\memcpySSE.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/memcpySSE.h"
|
||||
|
||||
DXGI::DXGI() :
|
||||
m_options(NULL),
|
||||
m_initialized(false),
|
||||
m_dxgiFactory(NULL),
|
||||
m_device(NULL),
|
||||
m_deviceContext(NULL),
|
||||
m_dup(NULL),
|
||||
m_texture(NULL),
|
||||
m_dxgiFactory(),
|
||||
m_device(),
|
||||
m_deviceContext(),
|
||||
m_dup(),
|
||||
m_texture(),
|
||||
m_surface(),
|
||||
m_pointer(NULL)
|
||||
{
|
||||
}
|
||||
@@ -51,15 +52,15 @@ bool DXGI::Initialize(CaptureOptions * options)
|
||||
status = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void **)(&m_dxgiFactory));
|
||||
if (FAILED(status))
|
||||
{
|
||||
DEBUG_ERROR("Failed to create DXGIFactory: %08x", status);
|
||||
DEBUG_ERROR("Failed to create DXGIFactory: %08x", (int)status);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool done = false;
|
||||
CComPtr<IDXGIAdapter1> adapter;
|
||||
IDXGIAdapter1Ptr adapter;
|
||||
for (int i = 0; m_dxgiFactory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND; i++)
|
||||
{
|
||||
CComPtr<IDXGIOutput> output;
|
||||
IDXGIOutputPtr output;
|
||||
for (int i = 0; adapter->EnumOutputs(i, &output) != DXGI_ERROR_NOT_FOUND; i++)
|
||||
{
|
||||
DXGI_OUTPUT_DESC outputDesc;
|
||||
@@ -150,7 +151,7 @@ bool DXGI::Initialize(CaptureOptions * options)
|
||||
|
||||
if (FAILED(status))
|
||||
{
|
||||
DEBUG_ERROR("DuplicateOutput Failed: %08x", status);
|
||||
DEBUG_ERROR("DuplicateOutput Failed: %08x", (int)status);
|
||||
DeInitialize();
|
||||
return false;
|
||||
}
|
||||
@@ -172,7 +173,7 @@ bool DXGI::Initialize(CaptureOptions * options)
|
||||
status = m_device->CreateTexture2D(&texDesc, NULL, &m_texture);
|
||||
if (FAILED(status))
|
||||
{
|
||||
DEBUG_ERROR("Failed to create texture: %08x", status);
|
||||
DEBUG_ERROR("Failed to create texture: %08x", (int)status);
|
||||
DeInitialize();
|
||||
return false;
|
||||
}
|
||||
@@ -190,6 +191,15 @@ void DXGI::DeInitialize()
|
||||
m_pointerBufSize = 0;
|
||||
}
|
||||
|
||||
if (m_surfaceMapped)
|
||||
{
|
||||
m_surface->Unmap();
|
||||
m_surfaceMapped = false;
|
||||
}
|
||||
|
||||
if (m_surface)
|
||||
m_surface.Release();
|
||||
|
||||
if (m_texture)
|
||||
m_texture.Release();
|
||||
|
||||
@@ -233,7 +243,7 @@ GrabStatus DXGI::GrabFrame(FrameInfo & frame)
|
||||
return GRAB_STATUS_ERROR;
|
||||
|
||||
DXGI_OUTDUPL_FRAME_INFO frameInfo;
|
||||
CComPtr<IDXGIResource> res;
|
||||
IDXGIResourcePtr res;
|
||||
|
||||
HRESULT status;
|
||||
bool cursorUpdate = false;
|
||||
@@ -241,7 +251,23 @@ GrabStatus DXGI::GrabFrame(FrameInfo & frame)
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
status = m_dup->AcquireNextFrame(INFINITE, &frameInfo, &res);
|
||||
status = m_dup->AcquireNextFrame(1000, &frameInfo, &res);
|
||||
if (status == DXGI_ERROR_WAIT_TIMEOUT)
|
||||
{
|
||||
if (!m_surfaceMapped)
|
||||
break;
|
||||
|
||||
// send the last frame again if we timeout to prevent the client stalling on restart
|
||||
frame.width = m_desc.Width;
|
||||
frame.height = m_desc.Height;
|
||||
frame.pitch = m_rect.Pitch;
|
||||
frame.stride = m_rect.Pitch / 4;
|
||||
|
||||
unsigned int size = m_height * m_rect.Pitch;
|
||||
memcpySSE(frame.buffer, m_rect.pBits, size < frame.bufferSize ? size : frame.bufferSize);
|
||||
return GRAB_STATUS_OK;
|
||||
}
|
||||
|
||||
if (!SUCCEEDED(status))
|
||||
break;
|
||||
|
||||
@@ -266,7 +292,7 @@ GrabStatus DXGI::GrabFrame(FrameInfo & frame)
|
||||
m_lastMouseVis = frameInfo.PointerPosition.Visible;
|
||||
}
|
||||
|
||||
frame.cursor.visible = m_lastMouseVis;
|
||||
frame.cursor.visible = m_lastMouseVis == TRUE;
|
||||
}
|
||||
|
||||
// if the pointer shape has changed
|
||||
@@ -286,7 +312,7 @@ GrabStatus DXGI::GrabFrame(FrameInfo & frame)
|
||||
if (!SUCCEEDED(status))
|
||||
{
|
||||
m_dup->ReleaseFrame();
|
||||
DEBUG_ERROR("Failed to get the new pointer shape: %08x", status);
|
||||
DEBUG_ERROR("Failed to get the new pointer shape: %08x", (int)status);
|
||||
return GRAB_STATUS_ERROR;
|
||||
}
|
||||
|
||||
@@ -321,36 +347,38 @@ GrabStatus DXGI::GrabFrame(FrameInfo & frame)
|
||||
if (SUCCEEDED(status))
|
||||
break;
|
||||
|
||||
HDESK desktop = NULL;
|
||||
switch (status)
|
||||
{
|
||||
case DXGI_ERROR_ACCESS_LOST: // desktop switch, mode change or switch DWM on or off
|
||||
return GRAB_STATUS_REINIT;
|
||||
// desktop switch, mode change, switch DWM on or off or Secure Desktop
|
||||
case DXGI_ERROR_ACCESS_LOST:
|
||||
// see if we can open the desktop, if so request a reinit
|
||||
// if not the secure desktop is active so just wait for it
|
||||
// instead of aborting out
|
||||
desktop = OpenInputDesktop(0, TRUE, GENERIC_READ);
|
||||
if (desktop)
|
||||
{
|
||||
// open suceeded, not on the secure desktop, return to reinit
|
||||
CloseDesktop(desktop);
|
||||
return GRAB_STATUS_REINIT;
|
||||
}
|
||||
// fall through
|
||||
|
||||
case WAIT_ABANDONED: // this can happen also during desktop switches, not documented by MS though
|
||||
{
|
||||
// see if we can open the desktop, if not the secure desktop
|
||||
// is active so just wait for it instead of aborting out
|
||||
HDESK desktop = NULL;
|
||||
while(!desktop)
|
||||
// this can happen during desktop switches also, not documented by MS though
|
||||
case WAIT_ABANDONED:
|
||||
do
|
||||
{
|
||||
desktop = OpenInputDesktop(0, TRUE, GENERIC_READ);
|
||||
if (desktop)
|
||||
break;
|
||||
Sleep(100);
|
||||
}
|
||||
} while (!desktop);
|
||||
CloseDesktop(desktop);
|
||||
|
||||
if (!ReInitialize())
|
||||
{
|
||||
DEBUG_ERROR("Failed to ReInitialize after lost access to desktop");
|
||||
return GRAB_STATUS_ERROR;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return GRAB_STATUS_REINIT;
|
||||
|
||||
default:
|
||||
// unknown failure
|
||||
DEBUG_INFO("AcquireNextFrame failed: %08x", status);
|
||||
DEBUG_INFO("AcquireNextFrame failed: %08x", (int)status);
|
||||
return GRAB_STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -363,7 +391,7 @@ GrabStatus DXGI::GrabFrame(FrameInfo & frame)
|
||||
return GRAB_STATUS_ERROR;
|
||||
}
|
||||
|
||||
CComQIPtr<ID3D11Texture2D> src = res;
|
||||
ID3D11Texture2DPtr src(res);
|
||||
if (!src)
|
||||
{
|
||||
m_dup->ReleaseFrame();
|
||||
@@ -371,8 +399,7 @@ GrabStatus DXGI::GrabFrame(FrameInfo & frame)
|
||||
return GRAB_STATUS_ERROR;
|
||||
}
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
src->GetDesc(&desc);
|
||||
src->GetDesc(&m_desc);
|
||||
|
||||
m_deviceContext->CopyResource(m_texture, src);
|
||||
|
||||
@@ -380,37 +407,43 @@ GrabStatus DXGI::GrabFrame(FrameInfo & frame)
|
||||
res.Release();
|
||||
src.Release();
|
||||
|
||||
CComQIPtr<IDXGISurface1> surface = m_texture;
|
||||
if (!surface)
|
||||
if (m_surfaceMapped)
|
||||
{
|
||||
status = m_surface->Unmap();
|
||||
if (FAILED(status))
|
||||
{
|
||||
DEBUG_ERROR("Failed to unmap surface: %08x", (int)status);
|
||||
return GRAB_STATUS_ERROR;
|
||||
}
|
||||
m_surfaceMapped = false;
|
||||
m_surface.Release();
|
||||
}
|
||||
|
||||
m_surface = m_texture;
|
||||
if (!m_surface)
|
||||
{
|
||||
DEBUG_ERROR("Failed to get IDXGISurface1");
|
||||
return GRAB_STATUS_ERROR;
|
||||
}
|
||||
|
||||
DXGI_MAPPED_RECT rect;
|
||||
status = surface->Map(&rect, DXGI_MAP_READ);
|
||||
status = m_surface->Map(&m_rect, DXGI_MAP_READ);
|
||||
if (FAILED(status))
|
||||
{
|
||||
DEBUG_ERROR("Failed to map surface: %08x", status);
|
||||
DEBUG_ERROR("Failed to map surface: %08x", (int)status);
|
||||
return GRAB_STATUS_ERROR;
|
||||
}
|
||||
m_surfaceMapped = true;
|
||||
|
||||
m_width = desc.Width;
|
||||
m_height = desc.Height;
|
||||
m_width = m_desc.Width;
|
||||
m_height = m_desc.Height;
|
||||
|
||||
frame.width = desc.Width;
|
||||
frame.height = desc.Height;
|
||||
frame.stride = rect.Pitch / 4;
|
||||
|
||||
memcpySSE(frame.buffer, rect.pBits, min(frame.bufferSize, m_height * rect.Pitch));
|
||||
frame.width = m_desc.Width;
|
||||
frame.height = m_desc.Height;
|
||||
frame.pitch = m_rect.Pitch;
|
||||
frame.stride = m_rect.Pitch / 4;
|
||||
|
||||
status = surface->Unmap();
|
||||
|
||||
if (FAILED(status))
|
||||
{
|
||||
DEBUG_ERROR("Failed to unmap surface: %08x", status);
|
||||
return GRAB_STATUS_ERROR;
|
||||
}
|
||||
unsigned int size = m_height * m_rect.Pitch;
|
||||
memcpySSE(frame.buffer, m_rect.pBits, size < frame.bufferSize ? size : frame.bufferSize);
|
||||
|
||||
return GRAB_STATUS_OK;
|
||||
}
|
||||
@@ -25,7 +25,19 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include <windows.h>
|
||||
#include <dxgi1_2.h>
|
||||
#include <d3d11.h>
|
||||
#include <atlbase.h>
|
||||
#include <stdio.h>
|
||||
#include <comdef.h>
|
||||
|
||||
_COM_SMARTPTR_TYPEDEF(IDXGIFactory1 , __uuidof(IDXGIFactory1 ));
|
||||
_COM_SMARTPTR_TYPEDEF(ID3D11Device , __uuidof(ID3D11Device ));
|
||||
_COM_SMARTPTR_TYPEDEF(ID3D11DeviceContext , __uuidof(ID3D11DeviceContext ));
|
||||
_COM_SMARTPTR_TYPEDEF(IDXGIOutput1 , __uuidof(IDXGIOutput1 ));
|
||||
_COM_SMARTPTR_TYPEDEF(IDXGIOutput , __uuidof(IDXGIOutput ));
|
||||
_COM_SMARTPTR_TYPEDEF(IDXGIAdapter1 , __uuidof(IDXGIAdapter1 ));
|
||||
_COM_SMARTPTR_TYPEDEF(IDXGIOutputDuplication, __uuidof(IDXGIOutputDuplication));
|
||||
_COM_SMARTPTR_TYPEDEF(ID3D11Texture2D , __uuidof(ID3D11Texture2D ));
|
||||
_COM_SMARTPTR_TYPEDEF(IDXGIResource , __uuidof(IDXGIResource ));
|
||||
_COM_SMARTPTR_TYPEDEF(IDXGISurface1 , __uuidof(IDXGISurface1 ));
|
||||
|
||||
namespace Capture
|
||||
{
|
||||
@@ -51,7 +63,6 @@ namespace Capture
|
||||
}
|
||||
|
||||
enum FrameType GetFrameType();
|
||||
enum FrameComp GetFrameCompression();
|
||||
size_t GetMaxFrameSize();
|
||||
enum GrabStatus GrabFrame(struct FrameInfo & frame);
|
||||
|
||||
@@ -62,13 +73,17 @@ namespace Capture
|
||||
unsigned int m_width;
|
||||
unsigned int m_height;
|
||||
|
||||
CComPtr<IDXGIFactory1> m_dxgiFactory;
|
||||
CComPtr<ID3D11Device> m_device;
|
||||
IDXGIFactory1Ptr m_dxgiFactory;
|
||||
ID3D11DevicePtr m_device;
|
||||
D3D_FEATURE_LEVEL m_featureLevel;
|
||||
CComPtr<ID3D11DeviceContext> m_deviceContext;
|
||||
CComQIPtr<IDXGIOutput1> m_output;
|
||||
CComPtr<IDXGIOutputDuplication> m_dup;
|
||||
CComPtr<ID3D11Texture2D> m_texture;
|
||||
ID3D11DeviceContextPtr m_deviceContext;
|
||||
IDXGIOutput1Ptr m_output;
|
||||
IDXGIOutputDuplicationPtr m_dup;
|
||||
ID3D11Texture2DPtr m_texture;
|
||||
IDXGISurface1Ptr m_surface;
|
||||
D3D11_TEXTURE2D_DESC m_desc;
|
||||
DXGI_MAPPED_RECT m_rect;
|
||||
bool m_surfaceMapped;
|
||||
BYTE * m_pointer;
|
||||
UINT m_pointerBufSize;
|
||||
UINT m_pointerSize;
|
||||
|
||||
@@ -17,13 +17,15 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#if CONFIG_CAPTURE_NVFBC
|
||||
|
||||
#include "NvFBC.h"
|
||||
using namespace Capture;
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "common\debug.h"
|
||||
#include "common\memcpySSE.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/memcpySSE.h"
|
||||
#include "Util.h"
|
||||
|
||||
#ifdef _WIN64
|
||||
@@ -287,6 +289,7 @@ enum GrabStatus NvFBC::GrabFrame(struct FrameInfo & frame)
|
||||
}
|
||||
|
||||
frame.stride = frame.width;
|
||||
frame.pitch = dataWidth;
|
||||
uint8_t *src = (uint8_t *)m_frameBuffer + dataOffset;
|
||||
uint8_t *dst = (uint8_t *)frame.buffer;
|
||||
for(unsigned int y = 0; y < frame.height; ++y, dst += dataWidth, src += m_grabInfo.dwBufferWidth * 4)
|
||||
@@ -311,3 +314,5 @@ enum GrabStatus NvFBC::GrabFrame(struct FrameInfo & frame)
|
||||
DEBUG_ERROR("Failed to grab frame");
|
||||
return GRAB_STATUS_ERROR;
|
||||
}
|
||||
|
||||
#endif// CONFIG_CAPTURE_NVFBC
|
||||
|
||||
@@ -17,14 +17,16 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#if CONFIG_CAPTURE_NVFBC
|
||||
|
||||
#pragma once
|
||||
#include "ICapture.h"
|
||||
|
||||
#define W32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <NvFBC\nvFBC.h>
|
||||
#include <NvFBC\nvFBCToSys.h>
|
||||
#include <NvFBC/nvFBC.h>
|
||||
#include <NvFBC/nvFBCToSys.h>
|
||||
|
||||
namespace Capture
|
||||
{
|
||||
@@ -44,7 +46,6 @@ namespace Capture
|
||||
return Initialize(m_options);
|
||||
}
|
||||
enum FrameType GetFrameType();
|
||||
enum FrameComp GetFrameCompression();
|
||||
size_t GetMaxFrameSize();
|
||||
enum GrabStatus GrabFrame(struct FrameInfo & frame);
|
||||
|
||||
@@ -68,4 +69,6 @@ namespace Capture
|
||||
NvFBCFrameGrabInfo m_grabInfo;
|
||||
NVFBC_TOSYS_GRAB_FRAME_PARAMS m_grabFrameParams;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#endif //CONFIG_CAPTURE_NVFBC
|
||||
|
||||
@@ -20,13 +20,15 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#pragma once
|
||||
|
||||
#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 "Capture\NvFBC.h"
|
||||
#include "Capture\DXGI.h"
|
||||
#if CONFIG_CAPTURE_NVFBC
|
||||
#include "Capture/NvFBC.h"
|
||||
#endif
|
||||
#include "Capture/DXGI.h"
|
||||
|
||||
class CaptureFactory
|
||||
{
|
||||
@@ -39,7 +41,9 @@ public:
|
||||
if (!devices.empty())
|
||||
return devices;
|
||||
|
||||
#if CONFIG_CAPTURE_NVFBC
|
||||
devices.push_back(new Capture::NvFBC());
|
||||
#endif
|
||||
devices.push_back(new Capture::DXGI ());
|
||||
|
||||
return devices;
|
||||
|
||||
@@ -18,8 +18,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <DbgHelp.h>
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
class CrashHandler
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
#include "common/KVMFR.h"
|
||||
#include <vector>
|
||||
#include <windows.h>
|
||||
|
||||
struct CursorInfo
|
||||
{
|
||||
@@ -41,6 +42,7 @@ struct FrameInfo
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int stride;
|
||||
unsigned int pitch;
|
||||
void * buffer;
|
||||
size_t bufferSize;
|
||||
|
||||
@@ -57,15 +59,15 @@ enum GrabStatus
|
||||
|
||||
typedef std::vector<const char *> CaptureOptions;
|
||||
|
||||
__interface ICapture
|
||||
class ICapture
|
||||
{
|
||||
public:
|
||||
const char * GetName();
|
||||
|
||||
bool Initialize(CaptureOptions * options);
|
||||
void DeInitialize();
|
||||
bool ReInitialize();
|
||||
enum FrameType GetFrameType();
|
||||
size_t GetMaxFrameSize();
|
||||
enum GrabStatus GrabFrame(struct FrameInfo & frame);
|
||||
};
|
||||
virtual const char * GetName() = 0;
|
||||
|
||||
virtual bool Initialize(CaptureOptions * options) = 0;
|
||||
virtual void DeInitialize() = 0;
|
||||
virtual bool ReInitialize() = 0;
|
||||
virtual enum FrameType GetFrameType() = 0;
|
||||
virtual size_t GetMaxFrameSize() = 0;
|
||||
virtual enum GrabStatus GrabFrame(struct FrameInfo & frame) = 0;
|
||||
};
|
||||
|
||||
@@ -17,12 +17,12 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ivshmem.h"
|
||||
#include "IVSHMEM.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <SetupAPI.h>
|
||||
#include "vendor\kvm-guest-drivers-windows\ivshmem\Public.h"
|
||||
#include "common\debug.h"
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
#include "vendor/kvm-guest-drivers-windows/ivshmem/Public.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
IVSHMEM * IVSHMEM::m_instance = NULL;
|
||||
|
||||
@@ -112,7 +112,7 @@ void IVSHMEM::DeInitialize()
|
||||
if (m_gotMemory)
|
||||
{
|
||||
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_RELEASE_MMAP, NULL, 0, NULL, 0, NULL, NULL))
|
||||
DEBUG_ERROR("DeviceIoControl failed: %d", GetLastError());
|
||||
DEBUG_ERROR("DeviceIoControl failed: %d", (int)GetLastError());
|
||||
m_memory = NULL;
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ UINT64 IVSHMEM::GetSize()
|
||||
IVSHMEM_SIZE size;
|
||||
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_SIZE, NULL, 0, &size, sizeof(IVSHMEM_SIZE), NULL, NULL))
|
||||
{
|
||||
DEBUG_ERROR("DeviceIoControl Failed: %d", GetLastError());
|
||||
DEBUG_ERROR("DeviceIoControl Failed: %d", (int)GetLastError());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ UINT16 IVSHMEM::GetPeerID()
|
||||
IVSHMEM_PEERID peerID;
|
||||
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_SIZE, NULL, 0, &peerID, sizeof(IVSHMEM_PEERID), NULL, NULL))
|
||||
{
|
||||
DEBUG_ERROR("DeviceIoControl Failed: %d", GetLastError());
|
||||
DEBUG_ERROR("DeviceIoControl Failed: %d", (int)GetLastError());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ void * IVSHMEM::GetMemory()
|
||||
ZeroMemory(&map, sizeof(IVSHMEM_MMAP));
|
||||
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_MMAP, NULL, 0, &map, sizeof(IVSHMEM_MMAP), NULL, NULL))
|
||||
{
|
||||
DEBUG_ERROR("DeviceIoControl Failed: %d", GetLastError());
|
||||
DEBUG_ERROR("DeviceIoControl Failed: %d", (int)GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ HANDLE IVSHMEM::CreateVectorEvent(UINT16 vector)
|
||||
HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (event == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DEBUG_ERROR("CreateEvent Failed: %d", GetLastError());
|
||||
DEBUG_ERROR("CreateEvent Failed: %d", (int)GetLastError());
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
@@ -230,7 +230,7 @@ HANDLE IVSHMEM::CreateVectorEvent(UINT16 vector)
|
||||
|
||||
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REGISTER_EVENT, &msg, sizeof(IVSHMEM_EVENT), NULL, 0, NULL, NULL))
|
||||
{
|
||||
DEBUG_ERROR("DeviceIoControl Failed: %d", GetLastError());
|
||||
DEBUG_ERROR("DeviceIoControl Failed: %d", (int)GetLastError());
|
||||
CloseHandle(event);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
@@ -249,7 +249,7 @@ bool IVSHMEM::RingDoorbell(UINT16 peerID, UINT16 door)
|
||||
|
||||
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_RING_DOORBELL, &msg, sizeof(IVSHMEM_RING), NULL, 0, NULL, NULL))
|
||||
{
|
||||
DEBUG_ERROR("DeviceIoControl Failed: %d", GetLastError());
|
||||
DEBUG_ERROR("DeviceIoControl Failed: %d", (int)GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#pragma once
|
||||
|
||||
#define W32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <windows.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
class IVSHMEM
|
||||
|
||||
@@ -9,24 +9,44 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sync-test", "sync-test\sync
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug - NvFBC|x64 = Debug - NvFBC|x64
|
||||
Debug - NvFBC|x86 = Debug - NvFBC|x86
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release - NvFBC|x64 = Release - NvFBC|x64
|
||||
Release - NvFBC|x86 = Release - NvFBC|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Debug - NvFBC|x64.ActiveCfg = Debug - NvFBC|x64
|
||||
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Debug - NvFBC|x64.Build.0 = Debug - NvFBC|x64
|
||||
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Debug - NvFBC|x86.ActiveCfg = Debug - NvFBC|Win32
|
||||
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Debug - NvFBC|x86.Build.0 = Debug - NvFBC|Win32
|
||||
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Debug|x64.Build.0 = Debug|x64
|
||||
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Debug|x86.Build.0 = Debug|Win32
|
||||
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Release - NvFBC|x64.ActiveCfg = Release - NvFBC|x64
|
||||
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Release - NvFBC|x64.Build.0 = Release - NvFBC|x64
|
||||
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Release - NvFBC|x86.ActiveCfg = Release - NvFBC|Win32
|
||||
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Release - NvFBC|x86.Build.0 = Release - NvFBC|Win32
|
||||
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Release|x64.ActiveCfg = Release|x64
|
||||
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Release|x64.Build.0 = Release|x64
|
||||
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Release|x86.ActiveCfg = Release|Win32
|
||||
{D439DE3E-32FB-4599-8B5D-C92674D400D4}.Release|x86.Build.0 = Release|Win32
|
||||
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Debug - NvFBC|x64.ActiveCfg = Debug - NvFBC|x64
|
||||
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Debug - NvFBC|x64.Build.0 = Debug - NvFBC|x64
|
||||
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Debug - NvFBC|x86.ActiveCfg = Debug - NvFBC|Win32
|
||||
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Debug - NvFBC|x86.Build.0 = Debug - NvFBC|Win32
|
||||
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Debug|x64.Build.0 = Debug|x64
|
||||
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Debug|x86.Build.0 = Debug|Win32
|
||||
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Release - NvFBC|x64.ActiveCfg = Release - NvFBC|x64
|
||||
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Release - NvFBC|x64.Build.0 = Release - NvFBC|x64
|
||||
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Release - NvFBC|x86.ActiveCfg = Release - NvFBC|Win32
|
||||
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Release - NvFBC|x86.Build.0 = Release - NvFBC|Win32
|
||||
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Release|x64.ActiveCfg = Release|x64
|
||||
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Release|x64.Build.0 = Release|x64
|
||||
{6CC4DA30-6FBD-4ACA-9BA6-2DE731032800}.Release|x86.ActiveCfg = Release|Win32
|
||||
|
||||
49
host/Makefile
Normal file
49
host/Makefile
Normal file
@@ -0,0 +1,49 @@
|
||||
BINARY = looking-glass-host.exe
|
||||
CFLAGS = -g -O3 -march=native -Wall -Werror -I./ -I../common # -DDEBUG
|
||||
LDFLAGS = -lshlwapi -ldxgi -ld3d11 -lsetupapi -luuid
|
||||
|
||||
CFLAGS += -ffast-math
|
||||
CFLAGS += -fdata-sections -ffunction-sections
|
||||
CFLAGS += -I../ -I.
|
||||
LDFLAGS += -Wl,--gc-sections -mwindows
|
||||
|
||||
PREFIX ?= x86_64-w64-mingw32-
|
||||
STRIP = $(PREFIX)strip
|
||||
CC = $(PREFIX)cc
|
||||
CXX = $(PREFIX)c++
|
||||
LD = $(CXX)
|
||||
|
||||
BUILD ?= .build
|
||||
BIN ?= bin
|
||||
|
||||
#CFLAGS += -DCONFIG_CAPTURE_NVFBC=1
|
||||
|
||||
CFLAGS += -DBUILD_VERSION='"$(shell git describe --always --long --dirty --abbrev=10 --tags)"'
|
||||
|
||||
OBJS = main.o \
|
||||
CrashHandler.o \
|
||||
IVSHMEM.o \
|
||||
Service.o \
|
||||
Capture/DXGI.o
|
||||
|
||||
BUILD_OBJS = $(foreach obj,$(OBJS),$(BUILD)/$(obj))
|
||||
|
||||
all: $(BIN)/$(BINARY)
|
||||
|
||||
$(BUILD)/%.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) -c $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BUILD)/%.o: %.cpp
|
||||
@mkdir -p $(dir $@)
|
||||
$(CXX) -c $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BIN)/$(BINARY): $(BUILD_OBJS)
|
||||
@mkdir -p $(dir $@)
|
||||
$(LD) -o $@ $^ $(LDFLAGS)
|
||||
$(STRIP) -s $@
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD) $(BIN)
|
||||
|
||||
.PHONY: clean
|
||||
245
host/Service.cpp
245
host/Service.cpp
@@ -20,11 +20,19 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "Service.h"
|
||||
#include "IVSHMEM.h"
|
||||
|
||||
#include "common\debug.h"
|
||||
#include "common\KVMFR.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/KVMFR.h"
|
||||
|
||||
#include "CaptureFactory.h"
|
||||
|
||||
#if __MINGW32__
|
||||
#define INTERLOCKED_AND8 __sync_and_and_fetch
|
||||
#define INTERLOCKED_OR8 __sync_or_and_fetch
|
||||
#else
|
||||
#define INTERLOCKED_OR8 InterlockedOr8
|
||||
#define INTERLOCKED_AND8 InterlockedAnd8
|
||||
#endif
|
||||
|
||||
Service * Service::m_instance = NULL;
|
||||
|
||||
Service::Service() :
|
||||
@@ -32,9 +40,13 @@ Service::Service() :
|
||||
m_memory(NULL),
|
||||
m_timer(NULL),
|
||||
m_capture(NULL),
|
||||
m_header(NULL),
|
||||
m_frameIndex(0)
|
||||
m_shmHeader(NULL),
|
||||
m_frameIndex(0),
|
||||
m_cursorDataSize(0),
|
||||
m_cursorData(NULL),
|
||||
m_shapePending(false)
|
||||
{
|
||||
m_consoleSessionID = WTSGetActiveConsoleSessionId();
|
||||
m_ivshmem = IVSHMEM::Get();
|
||||
}
|
||||
|
||||
@@ -81,15 +93,13 @@ bool Service::Initialize(ICapture * captureDevice)
|
||||
}
|
||||
|
||||
// update everything except for the hostID
|
||||
memcpy(m_header->magic, KVMFR_HEADER_MAGIC, sizeof(KVMFR_HEADER_MAGIC));
|
||||
m_header->version = KVMFR_HEADER_VERSION;
|
||||
m_header->guestID = m_ivshmem->GetPeerID();
|
||||
m_header->updateCount = 0;
|
||||
memcpy(m_shmHeader->magic, KVMFR_HEADER_MAGIC, sizeof(KVMFR_HEADER_MAGIC));
|
||||
m_shmHeader->version = KVMFR_HEADER_VERSION;
|
||||
m_shmHeader->updateCount = 0;
|
||||
|
||||
// clear but retain the restart flag if it was set by the client
|
||||
InterlockedAnd8((char *)&m_header->flags, KVMFR_HEADER_FLAG_RESTART);
|
||||
ZeroMemory(&m_header->frame , sizeof(KVMFRFrame ));
|
||||
ZeroMemory(&m_header->cursor, sizeof(KVMFRCursor));
|
||||
INTERLOCKED_AND8((char *)&m_shmHeader->flags, KVMFR_HEADER_FLAG_RESTART);
|
||||
ZeroMemory(&m_shmHeader->detail, sizeof(KVMFRDetail));
|
||||
|
||||
m_initialized = true;
|
||||
return true;
|
||||
@@ -97,7 +107,7 @@ bool Service::Initialize(ICapture * captureDevice)
|
||||
|
||||
bool Service::InitPointers()
|
||||
{
|
||||
m_header = reinterpret_cast<KVMFRHeader *>(m_memory);
|
||||
m_shmHeader = reinterpret_cast<KVMFRHeader *>(m_memory);
|
||||
m_frame[0] = (uint8_t *)(((uintptr_t)m_memory + sizeof(KVMFRHeader *) + 0x7F) & ~0x7F);
|
||||
m_frameSize = ((m_ivshmem->GetSize() - (m_frame[0] - m_memory)) & ~0x7F) >> 1;
|
||||
m_frame[1] = m_frame[0] + m_frameSize;
|
||||
@@ -122,7 +132,16 @@ void Service::DeInitialize()
|
||||
m_timer = NULL;
|
||||
}
|
||||
|
||||
m_header = NULL;
|
||||
m_shapePending = false;
|
||||
|
||||
if (m_cursorData)
|
||||
{
|
||||
delete[] m_cursorData;
|
||||
m_cursorDataSize = 0;
|
||||
m_cursorData = NULL;
|
||||
}
|
||||
|
||||
m_shmHeader = NULL;
|
||||
m_frame[0] = NULL;
|
||||
m_frame[1] = NULL;
|
||||
m_dataOffset[0] = 0;
|
||||
@@ -151,7 +170,7 @@ bool Service::Process()
|
||||
frame.buffer = m_frame[m_frameIndex];
|
||||
frame.bufferSize = m_frameSize;
|
||||
|
||||
volatile uint8_t *flags = &m_header->flags;
|
||||
volatile uint8_t *flags = &m_shmHeader->flags;
|
||||
|
||||
// wait for the host to notify that is it is ready to proceed
|
||||
while (true)
|
||||
@@ -161,7 +180,8 @@ bool Service::Process()
|
||||
// check if the client has flagged a restart
|
||||
if (f & KVMFR_HEADER_FLAG_RESTART)
|
||||
{
|
||||
InterlockedAnd8((volatile char *)flags, ~(KVMFR_HEADER_FLAG_RESTART));
|
||||
m_shmHeader->updateCount = 0;
|
||||
INTERLOCKED_AND8((volatile char *)flags, ~(KVMFR_HEADER_FLAG_RESTART));
|
||||
restart = true;
|
||||
break;
|
||||
}
|
||||
@@ -169,7 +189,7 @@ bool Service::Process()
|
||||
// check if the client has flagged it's ready
|
||||
if (f & KVMFR_HEADER_FLAG_READY)
|
||||
{
|
||||
InterlockedAnd8((volatile char *)flags, ~(KVMFR_HEADER_FLAG_READY));
|
||||
INTERLOCKED_AND8((volatile char *)flags, ~(KVMFR_HEADER_FLAG_READY));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -186,37 +206,50 @@ bool Service::Process()
|
||||
|
||||
bool ok = false;
|
||||
bool cursorOnly = false;
|
||||
for(int i = 0; i < 2; ++i)
|
||||
if (m_shapePending)
|
||||
{
|
||||
// capture a frame of data
|
||||
switch (m_capture->GrabFrame(frame))
|
||||
{
|
||||
case GRAB_STATUS_OK:
|
||||
ok = true;
|
||||
break;
|
||||
|
||||
case GRAB_STATUS_CURSOR:
|
||||
ok = true;
|
||||
cursorOnly = true;
|
||||
break;
|
||||
|
||||
case GRAB_STATUS_ERROR:
|
||||
DEBUG_ERROR("Capture failed");
|
||||
return false;
|
||||
|
||||
case GRAB_STATUS_REINIT:
|
||||
DEBUG_INFO("ReInitialize Requested");
|
||||
if (!m_capture->ReInitialize() || !InitPointers())
|
||||
{
|
||||
DEBUG_ERROR("ReInitialize Failed");
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ok)
|
||||
break;
|
||||
ok = true;
|
||||
cursorOnly = true;
|
||||
}
|
||||
else
|
||||
for(int i = 0; i < 2; ++i)
|
||||
{
|
||||
// capture a frame of data
|
||||
switch (m_capture->GrabFrame(frame))
|
||||
{
|
||||
case GRAB_STATUS_OK:
|
||||
ok = true;
|
||||
break;
|
||||
|
||||
case GRAB_STATUS_CURSOR:
|
||||
ok = true;
|
||||
cursorOnly = true;
|
||||
break;
|
||||
|
||||
case GRAB_STATUS_ERROR:
|
||||
DEBUG_ERROR("Capture failed");
|
||||
return false;
|
||||
|
||||
case GRAB_STATUS_REINIT:
|
||||
DEBUG_INFO("ReInitialize Requested");
|
||||
if(WTSGetActiveConsoleSessionId() != m_consoleSessionID)
|
||||
{
|
||||
DEBUG_INFO("User switch detected, waiting to regain control");
|
||||
while (WTSGetActiveConsoleSessionId() != m_consoleSessionID)
|
||||
Sleep(100);
|
||||
}
|
||||
|
||||
if (!m_capture->ReInitialize() || !InitPointers())
|
||||
{
|
||||
DEBUG_ERROR("ReInitialize Failed");
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ok)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
@@ -225,76 +258,106 @@ bool Service::Process()
|
||||
}
|
||||
|
||||
uint8_t updateFlags = 0;
|
||||
m_header->cursor.flags = 0;
|
||||
m_detail.cursor.flags = 0;
|
||||
|
||||
if (!cursorOnly)
|
||||
{
|
||||
// signal a frame update
|
||||
updateFlags |= KVMFR_HEADER_FLAG_FRAME;
|
||||
m_header->frame.type = m_capture->GetFrameType();
|
||||
m_header->frame.width = frame.width;
|
||||
m_header->frame.height = frame.height;
|
||||
m_header->frame.stride = frame.stride;
|
||||
m_header->frame.dataPos = m_dataOffset[m_frameIndex];
|
||||
m_detail.frame.type = m_capture->GetFrameType();
|
||||
m_detail.frame.width = frame.width;
|
||||
m_detail.frame.height = frame.height;
|
||||
m_detail.frame.stride = frame.stride;
|
||||
m_detail.frame.pitch = frame.pitch;
|
||||
m_detail.frame.dataPos = m_dataOffset[m_frameIndex];
|
||||
if (++m_frameIndex == 2)
|
||||
m_frameIndex = 0;
|
||||
}
|
||||
|
||||
if (frame.cursor.hasPos)
|
||||
if (frame.cursor.hasPos || (m_cursor.hasPos && restart))
|
||||
{
|
||||
// remember the last state for client restart
|
||||
if (frame.cursor.hasPos)
|
||||
{
|
||||
m_cursor.hasPos = true;
|
||||
m_cursor.visible = frame.cursor.visible;
|
||||
m_cursor.x = frame.cursor.x;
|
||||
m_cursor.y = frame.cursor.y;
|
||||
}
|
||||
|
||||
// tell the host where the cursor is
|
||||
updateFlags |= KVMFR_HEADER_FLAG_CURSOR;
|
||||
m_header->cursor.flags |= KVMFR_CURSOR_FLAG_POS;
|
||||
if (frame.cursor.visible)
|
||||
m_header->cursor.flags |= KVMFR_CURSOR_FLAG_VISIBLE;
|
||||
m_header->cursor.x = frame.cursor.x;
|
||||
m_header->cursor.y = frame.cursor.y;
|
||||
|
||||
// update our local copy for client restarts
|
||||
m_cursor.flags = m_header->cursor.flags;
|
||||
m_cursor.x = frame.cursor.x;
|
||||
m_cursor.y = frame.cursor.y;
|
||||
m_detail.cursor.flags |= KVMFR_CURSOR_FLAG_POS;
|
||||
if (m_cursor.visible)
|
||||
m_detail.cursor.flags |= KVMFR_CURSOR_FLAG_VISIBLE;
|
||||
m_detail.cursor.x = m_cursor.x;
|
||||
m_detail.cursor.y = m_cursor.y;
|
||||
}
|
||||
|
||||
if (frame.cursor.hasShape)
|
||||
if (frame.cursor.hasShape || m_shapePending || (m_cursor.hasShape && restart))
|
||||
{
|
||||
// give the host the new cursor shape
|
||||
updateFlags |= KVMFR_HEADER_FLAG_CURSOR;
|
||||
m_header->cursor.flags |= KVMFR_CURSOR_FLAG_SHAPE;
|
||||
m_header->cursor.type = frame.cursor.type;
|
||||
m_header->cursor.w = frame.cursor.w;
|
||||
m_header->cursor.h = frame.cursor.h;
|
||||
m_header->cursor.pitch = frame.cursor.pitch;
|
||||
if (frame.cursor.dataSize > KVMFR_CURSOR_BUFFER)
|
||||
if (!m_shapePending && !restart)
|
||||
{
|
||||
DEBUG_ERROR("Cursor shape size exceeds buffer size");
|
||||
return false;
|
||||
if (frame.cursor.dataSize > m_frameSize)
|
||||
{
|
||||
DEBUG_ERROR("Cursor size exceeds frame size! This should never happen unless your shared memory is WAY too small");
|
||||
return false;
|
||||
}
|
||||
|
||||
// take a copy of the shape information for client restarts or pending shape changes
|
||||
m_cursor.hasShape = frame.cursor.hasShape;
|
||||
m_cursor.type = frame.cursor.type;
|
||||
m_cursor.w = frame.cursor.w;
|
||||
m_cursor.h = frame.cursor.h;
|
||||
m_cursor.pitch = frame.cursor.pitch;
|
||||
m_cursor.dataSize = frame.cursor.dataSize;
|
||||
memcpy(&m_cursor, &frame.cursor, sizeof(CursorInfo));
|
||||
if (m_cursorDataSize < frame.cursor.dataSize)
|
||||
{
|
||||
delete[] m_cursorData;
|
||||
m_cursorData = new uint8_t[frame.cursor.dataSize];
|
||||
m_cursorDataSize = frame.cursor.dataSize;
|
||||
}
|
||||
|
||||
memcpy(m_cursorData, frame.cursor.shape, frame.cursor.dataSize);
|
||||
}
|
||||
memcpy(m_header->cursor.shape, frame.cursor.shape, frame.cursor.dataSize);
|
||||
|
||||
// take a copy of the information for client restarts
|
||||
uint8_t f = m_cursor.flags;
|
||||
memcpy(&m_cursor, &m_header->cursor, sizeof(KVMFRCursor));
|
||||
m_cursor.flags = f | m_header->cursor.flags;
|
||||
m_haveShape = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we already have a shape and the client restarted send it to them
|
||||
if (restart && m_haveShape)
|
||||
// we can't send a frame with the cursor shape as we need the buffer location
|
||||
// flag it to send on the next packet
|
||||
if (updateFlags & KVMFR_HEADER_FLAG_FRAME)
|
||||
m_shapePending = true;
|
||||
else
|
||||
{
|
||||
updateFlags |= KVMFR_HEADER_FLAG_CURSOR;
|
||||
m_cursor.flags |= KVMFR_CURSOR_FLAG_SHAPE;
|
||||
memcpy(&m_header->cursor, &m_cursor, sizeof(KVMFRCursor));
|
||||
// give the host the new cursor shape
|
||||
updateFlags |= KVMFR_HEADER_FLAG_CURSOR;
|
||||
m_detail.cursor.flags |= KVMFR_CURSOR_FLAG_SHAPE;
|
||||
if (m_cursor.visible)
|
||||
m_detail.cursor.flags |= KVMFR_CURSOR_FLAG_VISIBLE;
|
||||
|
||||
// shapes are sent as frame data
|
||||
m_detail.cursor.type = m_cursor.type;
|
||||
m_detail.frame.width = m_cursor.w;
|
||||
m_detail.frame.height = m_cursor.h;
|
||||
m_detail.frame.stride = 0;
|
||||
m_detail.frame.pitch = m_cursor.pitch;
|
||||
m_detail.frame.dataPos = m_dataOffset[m_frameIndex];
|
||||
memcpy(m_frame[m_frameIndex], m_cursorData, m_cursor.dataSize);
|
||||
m_shapePending = false;
|
||||
|
||||
if (++m_frameIndex == 2)
|
||||
m_frameIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// update the flags
|
||||
InterlockedAnd8((volatile char *)flags, KVMFR_HEADER_FLAG_RESTART);
|
||||
InterlockedOr8 ((volatile char *)flags, updateFlags);
|
||||
INTERLOCKED_AND8((volatile char *)flags, KVMFR_HEADER_FLAG_RESTART);
|
||||
INTERLOCKED_OR8 ((volatile char *)flags, updateFlags);
|
||||
|
||||
// increment the update count to resume the host
|
||||
++m_header->updateCount;
|
||||
// update the shared details only
|
||||
memcpy(&m_shmHeader->detail, &m_detail, sizeof(KVMFRDetail));
|
||||
|
||||
// increment the update count so the guest stops waiting
|
||||
++m_shmHeader->updateCount;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -20,7 +20,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#pragma once
|
||||
|
||||
#define W32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <windows.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "IVSHMEM.h"
|
||||
@@ -49,17 +49,21 @@ private:
|
||||
~Service();
|
||||
|
||||
bool m_initialized;
|
||||
DWORD m_consoleSessionID;
|
||||
uint8_t * m_memory;
|
||||
IVSHMEM * m_ivshmem;
|
||||
HANDLE m_timer;
|
||||
ICapture * m_capture;
|
||||
|
||||
KVMFRHeader * m_header;
|
||||
KVMFRDetail m_detail;
|
||||
KVMFRHeader * m_shmHeader;
|
||||
uint8_t * m_frame[2];
|
||||
size_t m_frameSize;
|
||||
uint64_t m_dataOffset[2];
|
||||
int m_frameIndex;
|
||||
|
||||
KVMFRCursor m_cursor;
|
||||
bool m_haveShape;
|
||||
CursorInfo m_cursor;
|
||||
size_t m_cursorDataSize;
|
||||
uint8_t * m_cursorData;
|
||||
bool m_shapePending;
|
||||
};
|
||||
@@ -1,10 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug - NvFBC|Win32">
|
||||
<Configuration>Debug - NvFBC</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug - NvFBC|x64">
|
||||
<Configuration>Debug - NvFBC</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release - NvFBC|Win32">
|
||||
<Configuration>Release - NvFBC</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release - NvFBC|x64">
|
||||
<Configuration>Release - NvFBC</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
@@ -31,6 +47,11 @@
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|Win32'" Label="Configuration">
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
@@ -38,11 +59,23 @@
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'" Label="Configuration">
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
@@ -50,6 +83,13 @@
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
@@ -58,32 +98,60 @@
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);;C:\Program Files %28x86%29\NVIDIA Corporation\NVIDIA Capture SDK\inc</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);;C:\Program Files %28x86%29\NVIDIA Corporation\NVIDIA Capture SDK\inc</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);;C:\Program Files %28x86%29\NVIDIA Corporation\NVIDIA Capture SDK\inc</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);;C:\Program Files %28x86%29\NVIDIA Corporation\NVIDIA Capture SDK\inc</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);;C:\Program Files %28x86%29\NVIDIA Corporation\NVIDIA Capture SDK\inc</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);;C:\Program Files %28x86%29\NVIDIA Corporation\NVIDIA Capture SDK\inc</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);;C:\Program Files %28x86%29\NVIDIA Corporation\NVIDIA Capture SDK\inc</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);;C:\Program Files %28x86%29\NVIDIA Corporation\NVIDIA Capture SDK\inc</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
@@ -97,7 +165,27 @@
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;setupapi.lib;d3d11.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>CONFIG_CAPTURE_NVFBC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\;.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Manifest>
|
||||
@@ -117,7 +205,27 @@
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;setupapi.lib;d3d11.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>CONFIG_CAPTURE_NVFBC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\;.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Manifest>
|
||||
@@ -141,7 +249,31 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;setupapi.lib;d3d11.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>CONFIG_CAPTURE_NVFBC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\;.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Manifest>
|
||||
@@ -165,7 +297,31 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;setupapi.lib;d3d11.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>CONFIG_CAPTURE_NVFBC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\;.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;shlwapi.lib;dxgi.lib;d3d11.lib;setupapi.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Manifest>
|
||||
|
||||
@@ -17,11 +17,11 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <Windows.h>
|
||||
#include <Shlwapi.h>
|
||||
#include <windows.h>
|
||||
#include <shlwapi.h>
|
||||
|
||||
#include "common\debug.h"
|
||||
#include "vendor\getopt\getopt.h"
|
||||
#include "common/debug.h"
|
||||
#include "vendor/getopt/getopt.h"
|
||||
|
||||
#include "CrashHandler.h"
|
||||
#include "CaptureFactory.h"
|
||||
|
||||
@@ -1,10 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug - NvFBC|Win32">
|
||||
<Configuration>Debug - NvFBC</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug - NvFBC|x64">
|
||||
<Configuration>Debug - NvFBC</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release - NvFBC|Win32">
|
||||
<Configuration>Release - NvFBC</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release - NvFBC|x64">
|
||||
<Configuration>Release - NvFBC</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
@@ -31,6 +47,12 @@
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
@@ -38,12 +60,25 @@
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
@@ -51,6 +86,13 @@
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
@@ -59,28 +101,52 @@
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
@@ -95,6 +161,20 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
@@ -109,6 +189,20 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - NvFBC|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
@@ -127,6 +221,24 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
@@ -145,6 +257,24 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - NvFBC|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c" />
|
||||
</ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user