diff --git a/common/include/common/KVMFR.h b/common/include/common/KVMFR.h index 3bf093b7..765480ef 100644 --- a/common/include/common/KVMFR.h +++ b/common/include/common/KVMFR.h @@ -38,6 +38,15 @@ typedef enum FrameType } FrameType; +typedef enum FrameRotation +{ + FRAME_ROT_0, + FRAME_ROT_90, + FRAME_ROT_180, + FRAME_ROT_270 +} +FrameRotation; + extern const char * FrameTypeStr[FRAME_TYPE_MAX]; enum @@ -57,7 +66,7 @@ typedef enum CursorType CursorType; #define KVMFR_MAGIC "KVMFR---" -#define KVMFR_VERSION 6 +#define KVMFR_VERSION 7 typedef struct KVMFR { @@ -80,13 +89,14 @@ KVMFRCursor; typedef struct KVMFRFrame { - uint32_t formatVer; // the frame format version number - FrameType type; // the frame data type - uint32_t width; // the width - uint32_t height; // the height - uint32_t stride; // the row stride (zero if compressed data) - uint32_t pitch; // the row pitch (stride in bytes or the compressed frame size) - uint32_t offset; // offset from the start of this header to the FrameBuffer header - uint32_t mouseScalePercent; // movement scale factor of the mouse (relates to DPI of display, 100 = no scale) + uint32_t formatVer; // the frame format version number + FrameType type; // the frame data type + uint32_t width; // the width + uint32_t height; // the height + FrameRotation rotation; // the frame rotation + uint32_t stride; // the row stride (zero if compressed data) + uint32_t pitch; // the row pitch (stride in bytes or the compressed frame size) + uint32_t offset; // offset from the start of this header to the FrameBuffer header + uint32_t mouseScalePercent; // movement scale factor of the mouse (relates to DPI of display, 100 = no scale) } KVMFRFrame; diff --git a/host/include/interface/capture.h b/host/include/interface/capture.h index 2f6d7162..c6c1294f 100644 --- a/host/include/interface/capture.h +++ b/host/include/interface/capture.h @@ -50,14 +50,24 @@ typedef enum CaptureFormat } CaptureFormat; +typedef enum CaptureRotation +{ + CAPTURE_ROT_0, + CAPTURE_ROT_90, + CAPTURE_ROT_180, + CAPTURE_ROT_270 +} +CaptureRotation; + typedef struct CaptureFrame { - unsigned int formatVer; - unsigned int width; - unsigned int height; - unsigned int pitch; - unsigned int stride; - CaptureFormat format; + unsigned int formatVer; + unsigned int width; + unsigned int height; + unsigned int pitch; + unsigned int stride; + CaptureFormat format; + CaptureRotation rotation; } CaptureFrame; diff --git a/host/platform/Linux/capture/XCB/src/xcb.c b/host/platform/Linux/capture/XCB/src/xcb.c index 63b7623d..438859d0 100644 --- a/host/platform/Linux/capture/XCB/src/xcb.c +++ b/host/platform/Linux/capture/XCB/src/xcb.c @@ -203,11 +203,12 @@ static CaptureResult xcb_waitFrame(CaptureFrame * frame) { lgWaitEvent(this->frameEvent, TIMEOUT_INFINITE); - frame->width = this->width; - frame->height = this->height; - frame->pitch = this->width * 4; - frame->stride = this->width; - frame->format = CAPTURE_FMT_BGRA; + frame->width = this->width; + frame->height = this->height; + frame->pitch = this->width * 4; + frame->stride = this->width; + frame->format = CAPTURE_FMT_BGRA; + frame->rotation = CAPTURE_ROT_0; return CAPTURE_RESULT_OK; } @@ -244,4 +245,4 @@ struct CaptureInterface Capture_XCB = .capture = xcb_capture, .waitFrame = xcb_waitFrame, .getFrame = xcb_getFrame -}; \ No newline at end of file +}; diff --git a/host/platform/Windows/capture/DXGI/src/dxgi.c b/host/platform/Windows/capture/DXGI/src/dxgi.c index 80e127cf..bb3cdd53 100644 --- a/host/platform/Windows/capture/DXGI/src/dxgi.c +++ b/host/platform/Windows/capture/DXGI/src/dxgi.c @@ -93,13 +93,14 @@ struct iface CapturePostPointerBuffer postPointerBufferFn; LGEvent * frameEvent; - unsigned int formatVer; - unsigned int width; - unsigned int height; - unsigned int pitch; - unsigned int stride; - CaptureFormat format; - unsigned int dpi; + unsigned int formatVer; + unsigned int width; + unsigned int height; + unsigned int pitch; + unsigned int stride; + CaptureFormat format; + CaptureRotation rotation; + unsigned int dpi; int lastPointerX, lastPointerY; bool lastPointerVisible; @@ -371,9 +372,46 @@ static bool dxgi_init(void) DXGI_ADAPTER_DESC1 adapterDesc; IDXGIAdapter1_GetDesc1(this->adapter, &adapterDesc); - this->width = outputDesc.DesktopCoordinates.right - outputDesc.DesktopCoordinates.left; - this->height = outputDesc.DesktopCoordinates.bottom - outputDesc.DesktopCoordinates.top; - this->dpi = monitor_dpi(outputDesc.Monitor); + + switch(outputDesc.Rotation) + { + case DXGI_MODE_ROTATION_ROTATE90: + case DXGI_MODE_ROTATION_ROTATE270: + this->width = outputDesc.DesktopCoordinates.bottom - + outputDesc.DesktopCoordinates.top; + this->height = outputDesc.DesktopCoordinates.right - + outputDesc.DesktopCoordinates.left; + break; + + default: + this->width = outputDesc.DesktopCoordinates.right - + outputDesc.DesktopCoordinates.left; + this->height = outputDesc.DesktopCoordinates.bottom - + outputDesc.DesktopCoordinates.top; + break; + } + + switch(outputDesc.Rotation) + { + case DXGI_MODE_ROTATION_ROTATE90: + this->rotation = CAPTURE_ROT_90; + break; + + case DXGI_MODE_ROTATION_ROTATE180: + this->rotation = CAPTURE_ROT_180; + break; + + case DXGI_MODE_ROTATION_ROTATE270: + this->rotation = CAPTURE_ROT_270; + + break; + + default: + this->rotation = CAPTURE_ROT_0; + break; + } + + this->dpi = monitor_dpi(outputDesc.Monitor); ++this->formatVer; DEBUG_INFO("Device Descripion: %ls" , adapterDesc.Description); @@ -928,6 +966,7 @@ static CaptureResult dxgi_waitFrame(CaptureFrame * frame) frame->pitch = this->pitch; frame->stride = this->stride; frame->format = this->format; + frame->rotation = this->rotation; atomic_fetch_sub_explicit(&this->texReady, 1, memory_order_release); return CAPTURE_RESULT_OK; diff --git a/host/platform/Windows/capture/NVFBC/src/nvfbc.c b/host/platform/Windows/capture/NVFBC/src/nvfbc.c index c8255e73..ffc5bfd1 100644 --- a/host/platform/Windows/capture/NVFBC/src/nvfbc.c +++ b/host/platform/Windows/capture/NVFBC/src/nvfbc.c @@ -312,6 +312,7 @@ static CaptureResult nvfbc_waitFrame(CaptureFrame * frame) frame->height = this->grabHeight; frame->pitch = this->grabStride * 4; frame->stride = this->grabStride; + frame->rotation = CAPTURE_ROT_0; #if 0 //NvFBC never sets bIsHDR so instead we check for any data in the alpha channel diff --git a/host/src/app.c b/host/src/app.c index 5486b4cc..74634c48 100644 --- a/host/src/app.c +++ b/host/src/app.c @@ -186,6 +186,18 @@ static int frameThread(void * opaque) continue; } + switch(frame.rotation) + { + case CAPTURE_ROT_0 : fi->rotation = FRAME_ROT_0 ; break; + case CAPTURE_ROT_90 : fi->rotation = FRAME_ROT_90 ; break; + case CAPTURE_ROT_180: fi->rotation = FRAME_ROT_180; break; + case CAPTURE_ROT_270: fi->rotation = FRAME_ROT_270; break; + default: + DEBUG_WARN("Unsupported frame rotation %d", frame.rotation); + fi->rotation = FRAME_ROT_0; + break; + } + fi->formatVer = frame.formatVer; fi->width = frame.width; fi->height = frame.height;