mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-25 14:57:20 +00:00
parent
ca02e1aba9
commit
c7330167cf
130
host/src/app.c
130
host/src/app.c
@ -62,6 +62,14 @@ static const struct LGMPQueueConfig POINTER_QUEUE_CONFIG =
|
|||||||
|
|
||||||
#define MAX_POINTER_SIZE (sizeof(KVMFRCursor) + (128 * 128 * 4))
|
#define MAX_POINTER_SIZE (sizeof(KVMFRCursor) + (128 * 128 * 4))
|
||||||
|
|
||||||
|
enum AppState
|
||||||
|
{
|
||||||
|
APP_STATE_RUNNING,
|
||||||
|
APP_STATE_IDLE,
|
||||||
|
APP_STATE_RESTART,
|
||||||
|
APP_STATE_SHUTDOWN
|
||||||
|
};
|
||||||
|
|
||||||
struct app
|
struct app
|
||||||
{
|
{
|
||||||
PLGMPHost lgmp;
|
PLGMPHost lgmp;
|
||||||
@ -81,8 +89,7 @@ struct app
|
|||||||
|
|
||||||
CaptureInterface * iface;
|
CaptureInterface * iface;
|
||||||
|
|
||||||
bool running;
|
enum AppState state;
|
||||||
bool reinit;
|
|
||||||
LGTimer * lgmpTimer;
|
LGTimer * lgmpTimer;
|
||||||
LGThread * frameThread;
|
LGThread * frameThread;
|
||||||
};
|
};
|
||||||
@ -95,7 +102,7 @@ static bool lgmpTimer(void * opaque)
|
|||||||
if ((status = lgmpHostProcess(app.lgmp)) != LGMP_OK)
|
if ((status = lgmpHostProcess(app.lgmp)) != LGMP_OK)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("lgmpHostProcess Failed: %s", lgmpStatusString(status));
|
DEBUG_ERROR("lgmpHostProcess Failed: %s", lgmpStatusString(status));
|
||||||
app.running = false;
|
app.state = APP_STATE_SHUTDOWN;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +118,7 @@ static int frameThread(void * opaque)
|
|||||||
CaptureFrame frame = { 0 };
|
CaptureFrame frame = { 0 };
|
||||||
const long pageSize = sysinfo_getPageSize();
|
const long pageSize = sysinfo_getPageSize();
|
||||||
|
|
||||||
while(app.running)
|
while(app.state == APP_STATE_RUNNING)
|
||||||
{
|
{
|
||||||
//wait until there is room in the queue
|
//wait until there is room in the queue
|
||||||
if(lgmpHostQueuePending(app.frameQueue) == LGMP_Q_FRAME_LEN)
|
if(lgmpHostQueuePending(app.frameQueue) == LGMP_Q_FRAME_LEN)
|
||||||
@ -128,7 +135,7 @@ static int frameThread(void * opaque)
|
|||||||
|
|
||||||
case CAPTURE_RESULT_REINIT:
|
case CAPTURE_RESULT_REINIT:
|
||||||
{
|
{
|
||||||
app.reinit = true;
|
app.state = APP_STATE_RESTART;
|
||||||
DEBUG_INFO("Frame thread reinit");
|
DEBUG_INFO("Frame thread reinit");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -205,7 +212,7 @@ static int frameThread(void * opaque)
|
|||||||
|
|
||||||
bool startThreads()
|
bool startThreads()
|
||||||
{
|
{
|
||||||
app.running = true;
|
app.state = APP_STATE_RUNNING;
|
||||||
if (!lgCreateThread("FrameThread", frameThread, NULL, &app.frameThread))
|
if (!lgCreateThread("FrameThread", frameThread, NULL, &app.frameThread))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to create the frame thread");
|
DEBUG_ERROR("Failed to create the frame thread");
|
||||||
@ -219,8 +226,9 @@ bool stopThreads()
|
|||||||
{
|
{
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
app.running = false;
|
|
||||||
app.iface->stop();
|
app.iface->stop();
|
||||||
|
if (app.state != APP_STATE_SHUTDOWN)
|
||||||
|
app.state = APP_STATE_IDLE;
|
||||||
|
|
||||||
if (app.frameThread && !lgJoinThread(app.frameThread, NULL))
|
if (app.frameThread && !lgJoinThread(app.frameThread, NULL))
|
||||||
{
|
{
|
||||||
@ -234,7 +242,14 @@ bool stopThreads()
|
|||||||
|
|
||||||
static bool captureStart()
|
static bool captureStart()
|
||||||
{
|
{
|
||||||
DEBUG_INFO("Using : %s", app.iface->getName());
|
if (app.state == APP_STATE_IDLE)
|
||||||
|
{
|
||||||
|
if (!app.iface->init())
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Initialize the capture device");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const unsigned int maxFrameSize = app.iface->getMaxFrameSize();
|
const unsigned int maxFrameSize = app.iface->getMaxFrameSize();
|
||||||
if (maxFrameSize > app.maxFrameSize)
|
if (maxFrameSize > app.maxFrameSize)
|
||||||
@ -248,31 +263,33 @@ static bool captureStart()
|
|||||||
return startThreads();
|
return startThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool captureRestart()
|
static bool captureStop()
|
||||||
{
|
{
|
||||||
DEBUG_INFO("==== [ Capture Restart ] ====");
|
DEBUG_INFO("==== [ Capture Stop ] ====");
|
||||||
if (!stopThreads())
|
if (!stopThreads())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!app.iface->deinit() || !app.iface->init())
|
if (!app.iface->deinit())
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to reinitialize the capture device");
|
DEBUG_ERROR("Failed to deinitialize the capture device");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!captureStart())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool captureRestart()
|
||||||
|
{
|
||||||
|
return captureStop() && captureStart();
|
||||||
|
}
|
||||||
|
|
||||||
bool captureGetPointerBuffer(void ** data, uint32_t * size)
|
bool captureGetPointerBuffer(void ** data, uint32_t * size)
|
||||||
{
|
{
|
||||||
// spin until there is room
|
// spin until there is room
|
||||||
while(lgmpHostQueuePending(app.pointerQueue) == LGMP_Q_POINTER_LEN)
|
while(lgmpHostQueuePending(app.pointerQueue) == LGMP_Q_POINTER_LEN)
|
||||||
{
|
{
|
||||||
usleep(1);
|
usleep(1);
|
||||||
if (!app.running)
|
if (app.state == APP_STATE_RUNNING)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,6 +539,9 @@ int app_main(int argc, char * argv[])
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG_INFO("Using : %s", iface->getName());
|
||||||
|
|
||||||
|
app.state = APP_STATE_RUNNING;
|
||||||
app.iface = iface;
|
app.iface = iface;
|
||||||
|
|
||||||
LG_LOCK_INIT(app.pointerLock);
|
LG_LOCK_INIT(app.pointerLock);
|
||||||
@ -532,50 +552,66 @@ int app_main(int argc, char * argv[])
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!captureStart())
|
while(app.state != APP_STATE_SHUTDOWN)
|
||||||
{
|
{
|
||||||
exitcode = -1;
|
if(lgmpHostQueueHasSubs(app.pointerQueue) ||
|
||||||
goto exit;
|
lgmpHostQueueHasSubs(app.frameQueue))
|
||||||
}
|
|
||||||
|
|
||||||
while(app.running)
|
|
||||||
{
|
|
||||||
if (app.reinit && !captureRestart())
|
|
||||||
{
|
{
|
||||||
exitcode = -1;
|
if (!captureStart())
|
||||||
goto exit;
|
{
|
||||||
|
exitcode = -1;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
app.reinit = false;
|
else
|
||||||
|
|
||||||
if (lgmpHostQueueNewSubs(app.pointerQueue) > 0)
|
|
||||||
{
|
{
|
||||||
LG_LOCK(app.pointerLock);
|
usleep(100);
|
||||||
sendPointer(true);
|
continue;
|
||||||
LG_UNLOCK(app.pointerLock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(iface->capture())
|
while(app.state != APP_STATE_SHUTDOWN && (
|
||||||
|
lgmpHostQueueHasSubs(app.pointerQueue) ||
|
||||||
|
lgmpHostQueueHasSubs(app.frameQueue)))
|
||||||
{
|
{
|
||||||
case CAPTURE_RESULT_OK:
|
if (app.state == APP_STATE_RESTART)
|
||||||
break;
|
{
|
||||||
|
|
||||||
case CAPTURE_RESULT_TIMEOUT:
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case CAPTURE_RESULT_REINIT:
|
|
||||||
if (!captureRestart())
|
if (!captureRestart())
|
||||||
{
|
{
|
||||||
exitcode = -1;
|
exitcode = -1;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
app.reinit = false;
|
app.state = APP_STATE_RUNNING;
|
||||||
continue;
|
}
|
||||||
|
|
||||||
case CAPTURE_RESULT_ERROR:
|
if (lgmpHostQueueNewSubs(app.pointerQueue) > 0)
|
||||||
DEBUG_ERROR("Capture interface reported a fatal error");
|
{
|
||||||
exitcode = -1;
|
LG_LOCK(app.pointerLock);
|
||||||
goto finish;
|
sendPointer(true);
|
||||||
|
LG_UNLOCK(app.pointerLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(iface->capture())
|
||||||
|
{
|
||||||
|
case CAPTURE_RESULT_OK:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CAPTURE_RESULT_TIMEOUT:
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case CAPTURE_RESULT_REINIT:
|
||||||
|
app.state = APP_STATE_RESTART;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case CAPTURE_RESULT_ERROR:
|
||||||
|
DEBUG_ERROR("Capture interface reported a fatal error");
|
||||||
|
exitcode = -1;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (app.state != APP_STATE_SHUTDOWN)
|
||||||
|
DEBUG_INFO("No subscribers, going to sleep...");
|
||||||
|
captureStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
@ -602,5 +638,5 @@ fail:
|
|||||||
|
|
||||||
void app_quit()
|
void app_quit()
|
||||||
{
|
{
|
||||||
app.running = false;
|
app.state = APP_STATE_SHUTDOWN;
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 7d3b8a1d8b8a24f3812fb250b6e853f2c37ec483
|
Subproject commit 2a1477550cc122dcac8af7016ac5f15dec2e139a
|
Loading…
Reference in New Issue
Block a user