/** * Looking Glass * Copyright © 2017-2026 The Looking Glass Authors * https://looking-glass.io * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., 59 * Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _H_LG_CLIENT_TRANSPORT_ #define _H_LG_CLIENT_TRANSPORT_ #include #include #include #include "common/framebuffer.h" #include "common/types.h" #define LG_TRANSPORT_MAX_DAMAGE_RECTS LG_MAX_FRAME_DAMAGE_RECTS typedef struct LG_Transport LG_Transport; typedef struct LG_RendererInterop LG_RendererInterop; typedef enum LG_TransportStatus { LG_TRANSPORT_OK, LG_TRANSPORT_TIMEOUT, LG_TRANSPORT_UNAVAILABLE, LG_TRANSPORT_INVALID_VERSION, LG_TRANSPORT_DISCONNECTED, LG_TRANSPORT_END, LG_TRANSPORT_ERROR, } LG_TransportStatus; typedef enum LG_TransportGuestOS { LG_TRANSPORT_OS_LINUX, LG_TRANSPORT_OS_BSD, LG_TRANSPORT_OS_OSX, LG_TRANSPORT_OS_WINDOWS, LG_TRANSPORT_OS_OTHER, } LG_TransportGuestOS; enum { LG_TRANSPORT_FEATURE_SET_CURSOR_POS = 0x1, LG_TRANSPORT_FEATURE_WINDOW_SIZE = 0x2, }; typedef uint32_t LG_TransportFeatureFlags; typedef struct LG_TransportSession { char version[32]; LG_TransportFeatureFlags features; bool uuidValid; uint8_t uuid[16]; LG_TransportGuestOS os; char osName[64]; char capture[32]; char cpuModel[256]; uint8_t cpus; uint8_t cores; uint8_t sockets; uint32_t remoteVersion; } LG_TransportSession; enum { LG_TRANSPORT_FRAME_BLOCK_SCREENSAVER = 0x1, LG_TRANSPORT_FRAME_REQUEST_ACTIVATION = 0x2, LG_TRANSPORT_FRAME_TRUNCATED = 0x4, }; typedef uint32_t LG_TransportFrameFlags; typedef struct LG_TransportFrameFormat { uint32_t version; FrameType type; uint32_t screenWidth; uint32_t screenHeight; uint32_t dataWidth; uint32_t dataHeight; uint32_t frameWidth; uint32_t frameHeight; FrameRotation rotation; uint32_t stride; uint32_t pitch; bool hdr; bool hdrPQ; bool hdrMetadata; uint16_t hdrDisplayPrimary[3][2]; uint16_t hdrWhitePoint[2]; uint32_t hdrMaxDisplayLuminance; uint32_t hdrMinDisplayLuminance; uint32_t hdrMaxContentLightLevel; uint32_t hdrMaxFrameAverageLightLevel; uint32_t sdrWhiteLevel; } LG_TransportFrameFormat; typedef struct LG_TransportFrame { uint64_t serial; uint64_t timestamp; LG_TransportFrameFlags flags; // Backend-owned immutable metadata, valid until releaseFrame. const LG_TransportFrameFormat * format; const FrameBuffer * framebuffer; int dmaFD; const FrameDamageRect * damageRects; uint32_t damageRectsCount; } LG_TransportFrame; enum { LG_TRANSPORT_POINTER_POSITION = 0x1, LG_TRANSPORT_POINTER_VISIBLE = 0x2, LG_TRANSPORT_POINTER_SHAPE = 0x4, LG_TRANSPORT_POINTER_COLOR_TRANSFORM = 0x8, LG_TRANSPORT_POINTER_VISIBLE_VALID = 0x10, }; typedef uint32_t LG_TransportPointerFlags; typedef struct LG_TransportPointer { LG_TransportPointerFlags flags; int16_t x; int16_t y; CursorType type; int8_t hx; int8_t hy; uint32_t width; uint32_t height; uint32_t pitch; uint32_t sdrWhiteLevel; const uint8_t * shape; const LGColorTransform * colorTransform; } LG_TransportPointer; typedef enum LG_TransportControlType { LG_TRANSPORT_CONTROL_SET_CURSOR_POS, LG_TRANSPORT_CONTROL_WINDOW_SIZE, } LG_TransportControlType; typedef struct LG_TransportControl { LG_TransportControlType type; union { struct { int32_t x, y; } cursorPos; struct { uint32_t width, height; } windowSize; }; } LG_TransportControl; typedef uint64_t LG_TransportControlToken; typedef struct LG_TransportOps { const char * name; void (*setup)(void); bool (*create)(LG_Transport ** transport); void (*destroy)(LG_Transport ** transport); LG_TransportStatus (*connect)(LG_Transport * transport, LG_TransportSession * session); void (*disconnect)(LG_Transport * transport); bool (*sessionValid)(LG_Transport * transport); bool (*supportsDMA)(LG_Transport * transport); bool (*attachRenderer)(LG_Transport * transport, const LG_RendererInterop * interop); void (*detachRenderer)(LG_Transport * transport); LG_TransportStatus (*nextFrame)(LG_Transport * transport, bool useDMA, LG_TransportFrame * frame); void (*releaseFrame)(LG_Transport * transport, LG_TransportFrame * frame); /* Called by the frame consumer as it exits. A backend may release transient * stream resources; nextFrame must reacquire them when the consumer restarts. */ void (*stopFrame)(LG_Transport * transport); LG_TransportStatus (*nextPointer)(LG_Transport * transport, LG_TransportPointer * pointer); void (*releasePointer)(LG_Transport * transport, LG_TransportPointer * pointer); /* Called by the pointer consumer as it exits. A backend may release transient * stream resources; nextPointer must reacquire them when the consumer restarts. */ void (*stopPointer)(LG_Transport * transport); LG_TransportStatus (*sendControl)(LG_Transport * transport, const LG_TransportControl * control, LG_TransportControlToken * token); LG_TransportStatus (*controlStatus)(LG_Transport * transport, LG_TransportControlToken token); } LG_TransportOps; void lgTransport_setup(void); bool lgTransport_isValid(const char * name); bool lgTransport_create(const char * name, LG_Transport ** transport, const LG_TransportOps ** ops); #endif