mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-25 14:57:20 +00:00
[client] update client to use the common ivshmem* methods
This commit is contained in:
parent
074af5d16c
commit
4345d94d68
@ -41,6 +41,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "common/stringutils.h"
|
#include "common/stringutils.h"
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
#include "common/event.h"
|
#include "common/event.h"
|
||||||
|
#include "common/ivshmem.h"
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "kb.h"
|
#include "kb.h"
|
||||||
#include "ll.h"
|
#include "ll.h"
|
||||||
@ -186,8 +188,8 @@ static int cursorThread(void * unused)
|
|||||||
while(state.running)
|
while(state.running)
|
||||||
{
|
{
|
||||||
// poll until we have cursor data
|
// poll until we have cursor data
|
||||||
if(!(state.shm->cursor.flags & KVMFR_CURSOR_FLAG_UPDATE) &&
|
if(!(state.kvmfr->cursor.flags & KVMFR_CURSOR_FLAG_UPDATE) &&
|
||||||
!(state.shm->cursor.flags & KVMFR_CURSOR_FLAG_POS))
|
!(state.kvmfr->cursor.flags & KVMFR_CURSOR_FLAG_POS))
|
||||||
{
|
{
|
||||||
if (!state.running)
|
if (!state.running)
|
||||||
return 0;
|
return 0;
|
||||||
@ -197,19 +199,19 @@ static int cursorThread(void * unused)
|
|||||||
|
|
||||||
// if the cursor was moved
|
// if the cursor was moved
|
||||||
bool moved = false;
|
bool moved = false;
|
||||||
if (state.shm->cursor.flags & KVMFR_CURSOR_FLAG_POS)
|
if (state.kvmfr->cursor.flags & KVMFR_CURSOR_FLAG_POS)
|
||||||
{
|
{
|
||||||
state.cursor.x = state.shm->cursor.x;
|
state.cursor.x = state.kvmfr->cursor.x;
|
||||||
state.cursor.y = state.shm->cursor.y;
|
state.cursor.y = state.kvmfr->cursor.y;
|
||||||
state.haveCursorPos = true;
|
state.haveCursorPos = true;
|
||||||
moved = true;
|
moved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if this was only a move event
|
// if this was only a move event
|
||||||
if (!(state.shm->cursor.flags & KVMFR_CURSOR_FLAG_UPDATE))
|
if (!(state.kvmfr->cursor.flags & KVMFR_CURSOR_FLAG_UPDATE))
|
||||||
{
|
{
|
||||||
// turn off the pos flag, trigger the event and continue
|
// turn off the pos flag, trigger the event and continue
|
||||||
__sync_and_and_fetch(&state.shm->cursor.flags, ~KVMFR_CURSOR_FLAG_POS);
|
__sync_and_and_fetch(&state.kvmfr->cursor.flags, ~KVMFR_CURSOR_FLAG_POS);
|
||||||
|
|
||||||
state.lgr->on_mouse_event
|
state.lgr->on_mouse_event
|
||||||
(
|
(
|
||||||
@ -223,7 +225,7 @@ static int cursorThread(void * unused)
|
|||||||
|
|
||||||
// we must take a copy of the header to prevent the contained arguments
|
// we must take a copy of the header to prevent the contained arguments
|
||||||
// from being abused to overflow buffers.
|
// from being abused to overflow buffers.
|
||||||
memcpy(&header, &state.shm->cursor, sizeof(struct KVMFRCursor));
|
memcpy(&header, &state.kvmfr->cursor, sizeof(struct KVMFRCursor));
|
||||||
|
|
||||||
if (header.flags & KVMFR_CURSOR_FLAG_SHAPE &&
|
if (header.flags & KVMFR_CURSOR_FLAG_SHAPE &&
|
||||||
header.version != version)
|
header.version != version)
|
||||||
@ -247,13 +249,13 @@ static int cursorThread(void * unused)
|
|||||||
|
|
||||||
// check the data position is sane
|
// check the data position is sane
|
||||||
const uint64_t dataSize = header.height * header.pitch;
|
const uint64_t dataSize = header.height * header.pitch;
|
||||||
if (header.dataPos + dataSize > state.shmSize)
|
if (header.dataPos + dataSize > state.shm.size)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("The guest sent an invalid mouse dataPos");
|
DEBUG_ERROR("The guest sent an invalid mouse dataPos");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t * data = (const uint8_t *)state.shm + header.dataPos;
|
const uint8_t * data = (const uint8_t *)state.kvmfr + header.dataPos;
|
||||||
if (!state.lgr->on_mouse_shape(
|
if (!state.lgr->on_mouse_shape(
|
||||||
state.lgrData,
|
state.lgrData,
|
||||||
cursorType,
|
cursorType,
|
||||||
@ -269,7 +271,7 @@ static int cursorThread(void * unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// now we have taken the mouse data, we can flag to the host we are ready
|
// now we have taken the mouse data, we can flag to the host we are ready
|
||||||
state.shm->cursor.flags = 0;
|
state.kvmfr->cursor.flags = 0;
|
||||||
|
|
||||||
bool showCursor = header.flags & KVMFR_CURSOR_FLAG_VISIBLE;
|
bool showCursor = header.flags & KVMFR_CURSOR_FLAG_VISIBLE;
|
||||||
if (showCursor != state.cursorVisible || moved)
|
if (showCursor != state.cursorVisible || moved)
|
||||||
@ -300,7 +302,7 @@ static int frameThread(void * unused)
|
|||||||
while(state.running)
|
while(state.running)
|
||||||
{
|
{
|
||||||
// poll until we have a new frame
|
// poll until we have a new frame
|
||||||
while(!(state.shm->frame.flags & KVMFR_FRAME_FLAG_UPDATE))
|
while(!(state.kvmfr->frame.flags & KVMFR_FRAME_FLAG_UPDATE))
|
||||||
{
|
{
|
||||||
if (!state.running)
|
if (!state.running)
|
||||||
break;
|
break;
|
||||||
@ -311,11 +313,11 @@ static int frameThread(void * unused)
|
|||||||
|
|
||||||
// we must take a copy of the header to prevent the contained
|
// we must take a copy of the header to prevent the contained
|
||||||
// arguments from being abused to overflow buffers.
|
// arguments from being abused to overflow buffers.
|
||||||
memcpy(&header, &state.shm->frame, sizeof(struct KVMFRFrame));
|
memcpy(&header, &state.kvmfr->frame, sizeof(struct KVMFRFrame));
|
||||||
|
|
||||||
// tell the host to continue as the host buffers up to one frame
|
// tell the host to continue as the host buffers up to one frame
|
||||||
// we can be sure the data for this frame wont be touched
|
// we can be sure the data for this frame wont be touched
|
||||||
__sync_and_and_fetch(&state.shm->frame.flags, ~KVMFR_FRAME_FLAG_UPDATE);
|
__sync_and_and_fetch(&state.kvmfr->frame.flags, ~KVMFR_FRAME_FLAG_UPDATE);
|
||||||
|
|
||||||
// sainty check of the frame format
|
// sainty check of the frame format
|
||||||
if (
|
if (
|
||||||
@ -324,7 +326,7 @@ static int frameThread(void * unused)
|
|||||||
header.height == 0 ||
|
header.height == 0 ||
|
||||||
header.pitch == 0 ||
|
header.pitch == 0 ||
|
||||||
header.dataPos == 0 ||
|
header.dataPos == 0 ||
|
||||||
header.dataPos > state.shmSize ||
|
header.dataPos > state.shm.size ||
|
||||||
header.pitch < header.width
|
header.pitch < header.width
|
||||||
){
|
){
|
||||||
DEBUG_WARN("Bad header");
|
DEBUG_WARN("Bad header");
|
||||||
@ -370,7 +372,7 @@ static int frameThread(void * unused)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// check the header's dataPos is sane
|
// check the header's dataPos is sane
|
||||||
if (header.dataPos + dataSize > state.shmSize)
|
if (header.dataPos + dataSize > state.shm.size)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("The guest sent an invalid dataPos");
|
DEBUG_ERROR("The guest sent an invalid dataPos");
|
||||||
break;
|
break;
|
||||||
@ -385,7 +387,7 @@ static int frameThread(void * unused)
|
|||||||
SDL_SetWindowSize(state.window, header.width, header.height);
|
SDL_SetWindowSize(state.window, header.width, header.height);
|
||||||
updatePositionInfo();
|
updatePositionInfo();
|
||||||
}
|
}
|
||||||
FrameBuffer frame = (FrameBuffer)((uint8_t *)state.shm + header.dataPos);
|
FrameBuffer frame = (FrameBuffer)((uint8_t *)state.kvmfr + header.dataPos);
|
||||||
|
|
||||||
if (!state.lgr->on_frame_event(state.lgrData, lgrFormat, frame))
|
if (!state.lgr->on_frame_event(state.lgrData, lgrFormat, frame))
|
||||||
{
|
{
|
||||||
@ -868,35 +870,6 @@ void int_handler(int signal)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void * map_memory()
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
if (stat(params.shmFile, &st) < 0)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Failed to stat the shared memory file: %s", params.shmFile);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.shmSize = params.shmSize ? params.shmSize : st.st_size;
|
|
||||||
state.shmFD = open(params.shmFile, O_RDWR, (mode_t)0600);
|
|
||||||
if (state.shmFD < 0)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Failed to open the shared memory file: %s", params.shmFile);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void * map = mmap(0, state.shmSize, PROT_READ | PROT_WRITE, MAP_SHARED, state.shmFD, 0);
|
|
||||||
if (map == MAP_FAILED)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Failed to map the shared memory file: %s", params.shmFile);
|
|
||||||
close(state.shmFD);
|
|
||||||
state.shmFD = 0;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool try_renderer(const int index, const LG_RendererParams lgrParams, Uint32 * sdlFlags)
|
static bool try_renderer(const int index, const LG_RendererParams lgrParams, Uint32 * sdlFlags)
|
||||||
{
|
{
|
||||||
const LG_Renderer *r = LG_Renderers[index];
|
const LG_Renderer *r = LG_Renderers[index];
|
||||||
@ -1062,13 +1035,14 @@ static int lg_run()
|
|||||||
signal(SIGTERM, int_handler);
|
signal(SIGTERM, int_handler);
|
||||||
|
|
||||||
// try map the shared memory
|
// try map the shared memory
|
||||||
state.shm = (struct KVMFRHeader *)map_memory();
|
if (!ivshmemOpen(&state.shm))
|
||||||
if (!state.shm)
|
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to map memory");
|
DEBUG_ERROR("Failed to map memory");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.kvmfr = (struct KVMFRHeader*)state.shm.mem;
|
||||||
|
|
||||||
// try to connect to the spice server
|
// try to connect to the spice server
|
||||||
if (params.useSpiceInput || params.useSpiceClipboard)
|
if (params.useSpiceInput || params.useSpiceClipboard)
|
||||||
{
|
{
|
||||||
@ -1272,9 +1246,9 @@ static int lg_run()
|
|||||||
// the host wakes up if it is waiting on an interrupt, the host will
|
// the host wakes up if it is waiting on an interrupt, the host will
|
||||||
// also send us the current mouse shape since we won't know it yet
|
// also send us the current mouse shape since we won't know it yet
|
||||||
DEBUG_INFO("Waiting for host to signal it's ready...");
|
DEBUG_INFO("Waiting for host to signal it's ready...");
|
||||||
__sync_or_and_fetch(&state.shm->flags, KVMFR_HEADER_FLAG_RESTART);
|
__sync_or_and_fetch(&state.kvmfr->flags, KVMFR_HEADER_FLAG_RESTART);
|
||||||
|
|
||||||
while(state.running && (state.shm->flags & KVMFR_HEADER_FLAG_RESTART))
|
while(state.running && (state.kvmfr->flags & KVMFR_HEADER_FLAG_RESTART))
|
||||||
SDL_WaitEventTimeout(NULL, 1000);
|
SDL_WaitEventTimeout(NULL, 1000);
|
||||||
|
|
||||||
if (!state.running)
|
if (!state.running)
|
||||||
@ -1283,15 +1257,15 @@ static int lg_run()
|
|||||||
DEBUG_INFO("Host ready, starting session");
|
DEBUG_INFO("Host ready, starting session");
|
||||||
|
|
||||||
// check the header's magic and version are valid
|
// check the header's magic and version are valid
|
||||||
if (memcmp(state.shm->magic, KVMFR_HEADER_MAGIC, sizeof(KVMFR_HEADER_MAGIC)) != 0)
|
if (memcmp(state.kvmfr->magic, KVMFR_HEADER_MAGIC, sizeof(KVMFR_HEADER_MAGIC)) != 0)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Invalid header magic, is the host running?");
|
DEBUG_ERROR("Invalid header magic, is the host running?");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.shm->version != KVMFR_HEADER_VERSION)
|
if (state.kvmfr->version != KVMFR_HEADER_VERSION)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("KVMFR version missmatch, expected %u but got %u", KVMFR_HEADER_VERSION, state.shm->version);
|
DEBUG_ERROR("KVMFR version missmatch, expected %u but got %u", KVMFR_HEADER_VERSION, state.kvmfr->version);
|
||||||
DEBUG_ERROR("This is not a bug, ensure you have the right version of looking-glass-host.exe on the guest");
|
DEBUG_ERROR("This is not a bug, ensure you have the right version of looking-glass-host.exe on the guest");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1315,7 +1289,7 @@ static int lg_run()
|
|||||||
|
|
||||||
if (closeAlert == NULL)
|
if (closeAlert == NULL)
|
||||||
{
|
{
|
||||||
if (state.shm->flags & KVMFR_HEADER_FLAG_PAUSED)
|
if (state.kvmfr->flags & KVMFR_HEADER_FLAG_PAUSED)
|
||||||
{
|
{
|
||||||
if (state.lgr && params.showAlerts)
|
if (state.lgr && params.showAlerts)
|
||||||
state.lgr->on_alert(
|
state.lgr->on_alert(
|
||||||
@ -1328,7 +1302,7 @@ static int lg_run()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!(state.shm->flags & KVMFR_HEADER_FLAG_PAUSED))
|
if (!(state.kvmfr->flags & KVMFR_HEADER_FLAG_PAUSED))
|
||||||
{
|
{
|
||||||
*closeAlert = true;
|
*closeAlert = true;
|
||||||
closeAlert = NULL;
|
closeAlert = NULL;
|
||||||
@ -1387,11 +1361,7 @@ static void lg_shutdown()
|
|||||||
if (cursor)
|
if (cursor)
|
||||||
SDL_FreeCursor(cursor);
|
SDL_FreeCursor(cursor);
|
||||||
|
|
||||||
if (state.shm)
|
ivshmemClose(&state.shm);
|
||||||
{
|
|
||||||
munmap(state.shm, state.shmSize);
|
|
||||||
close(state.shmFD);
|
|
||||||
}
|
|
||||||
|
|
||||||
release_key_binds();
|
release_key_binds();
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
@ -1406,6 +1376,7 @@ int main(int argc, char * argv[])
|
|||||||
DEBUG_WARN("Failed to install the crash handler");
|
DEBUG_WARN("Failed to install the crash handler");
|
||||||
|
|
||||||
config_init();
|
config_init();
|
||||||
|
ivshmemOptionsInit();
|
||||||
|
|
||||||
// early renderer setup for option registration
|
// early renderer setup for option registration
|
||||||
for(unsigned int i = 0; i < LG_RENDERER_COUNT; ++i)
|
for(unsigned int i = 0; i < LG_RENDERER_COUNT; ++i)
|
||||||
|
@ -23,6 +23,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "interface/app.h"
|
#include "interface/app.h"
|
||||||
#include "dynamic/renderers.h"
|
#include "dynamic/renderers.h"
|
||||||
#include "dynamic/clipboards.h"
|
#include "dynamic/clipboards.h"
|
||||||
|
#include "common/ivshmem.h"
|
||||||
|
|
||||||
#include "spice/spice.h"
|
#include "spice/spice.h"
|
||||||
|
|
||||||
@ -54,9 +55,9 @@ struct AppState
|
|||||||
struct ll * cbRequestList;
|
struct ll * cbRequestList;
|
||||||
|
|
||||||
SDL_Window * window;
|
SDL_Window * window;
|
||||||
int shmFD;
|
|
||||||
struct KVMFRHeader * shm;
|
struct IVSHMEM shm;
|
||||||
unsigned int shmSize;
|
struct KVMFRHeader * kvmfr;
|
||||||
|
|
||||||
uint64_t frameTime;
|
uint64_t frameTime;
|
||||||
uint64_t lastFrameTime;
|
uint64_t lastFrameTime;
|
||||||
|
@ -210,7 +210,7 @@ bool ivshmemOpen(struct IVSHMEM * dev)
|
|||||||
dev->opaque = info;
|
dev->opaque = info;
|
||||||
dev->size = devSize;
|
dev->size = devSize;
|
||||||
dev->mem = map;
|
dev->mem = map;
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ivshmemClose(struct IVSHMEM * dev)
|
void ivshmemClose(struct IVSHMEM * dev)
|
||||||
|
Loading…
Reference in New Issue
Block a user