Dynamically load libvnc at runtime
This commit is contained in:
parent
1c4e4abbab
commit
640dfdd4a0
|
@ -684,7 +684,7 @@ if(NOT ZM_NO_LIBVNC)
|
||||||
find_library(LIBVNC_LIBRARIES vncclient)
|
find_library(LIBVNC_LIBRARIES vncclient)
|
||||||
if(LIBVNC_LIBRARIES)
|
if(LIBVNC_LIBRARIES)
|
||||||
set(HAVE_LIBVNC 1)
|
set(HAVE_LIBVNC 1)
|
||||||
list(APPEND ZM_BIN_LIBS "${LIBVNC_LIBRARIES}")
|
# list(APPEND ZM_BIN_LIBS "${LIBVNC_LIBRARIES}")
|
||||||
find_path(LIBVNC_INCLUDE_DIR "rfb/rfb.h")
|
find_path(LIBVNC_INCLUDE_DIR "rfb/rfb.h")
|
||||||
if(LIBVNC_INCLUDE_DIR)
|
if(LIBVNC_INCLUDE_DIR)
|
||||||
include_directories("${LIBVNC_INCLUDE_DIR}")
|
include_directories("${LIBVNC_INCLUDE_DIR}")
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <dlfcn.h>
|
||||||
#include "zm.h"
|
#include "zm.h"
|
||||||
#include "zm_signal.h"
|
#include "zm_signal.h"
|
||||||
#include "zm_libvnc_camera.h"
|
#include "zm_libvnc_camera.h"
|
||||||
|
@ -8,14 +9,41 @@
|
||||||
static int TAG_0;
|
static int TAG_0;
|
||||||
static int TAG_1;
|
static int TAG_1;
|
||||||
static int TAG_2;
|
static int TAG_2;
|
||||||
|
static void *libvnc_lib = nullptr;
|
||||||
|
static void *(*rfbClientGetClientData_f)(rfbClient*, void*) = nullptr;
|
||||||
|
static rfbClient *(*rfbGetClient_f)(int, int, int) = nullptr;
|
||||||
|
static void (*rfbClientSetClientData_f)(rfbClient*, void*, void*) = nullptr;
|
||||||
|
static rfbBool (*rfbInitClient_f)(rfbClient*, int*, char**) = nullptr;
|
||||||
|
static void (*rfbClientCleanup_f)(rfbClient*) = nullptr;
|
||||||
|
static int (*WaitForMessage_f)(rfbClient*, unsigned int) = nullptr;
|
||||||
|
static rfbBool (*HandleRFBServerMessage_f)(rfbClient*) = nullptr;
|
||||||
|
|
||||||
|
void bind_libvnc_symbols() {
|
||||||
|
if(libvnc_lib != nullptr) // Safe-check
|
||||||
|
return;
|
||||||
|
|
||||||
|
libvnc_lib = dlopen("libvncclient.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||||
|
if(!libvnc_lib){
|
||||||
|
Error("Error loading libvlc: %s", dlerror());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(void**) (&rfbClientGetClientData_f) = dlsym(libvnc_lib, "rfbClientGetClientData");
|
||||||
|
*(void**) (&rfbGetClient_f) = dlsym(libvnc_lib, "rfbGetClient");
|
||||||
|
*(void**) (&rfbClientSetClientData_f) = dlsym(libvnc_lib, "rfbClientSetClientData");
|
||||||
|
*(void**) (&rfbInitClient_f) = dlsym(libvnc_lib, "rfbInitClient");
|
||||||
|
*(void**) (&rfbClientCleanup_f) = dlsym(libvnc_lib, "rfbClientCleanup");
|
||||||
|
*(void**) (&WaitForMessage_f) = dlsym(libvnc_lib, "WaitForMessage");
|
||||||
|
*(void**) (&HandleRFBServerMessage_f) = dlsym(libvnc_lib, "HandleRFBServerMessage");
|
||||||
|
}
|
||||||
|
|
||||||
static void GotFrameBufferUpdateCallback(rfbClient *rfb, int x, int y, int w, int h){
|
static void GotFrameBufferUpdateCallback(rfbClient *rfb, int x, int y, int w, int h){
|
||||||
VncPrivateData *data = (VncPrivateData *)rfbClientGetClientData(rfb, &TAG_0);
|
VncPrivateData *data = (VncPrivateData *)(*rfbClientGetClientData_f)(rfb, &TAG_0);
|
||||||
data->buffer = rfb->frameBuffer;
|
data->buffer = rfb->frameBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* GetPasswordCallback(rfbClient* cl){
|
static char* GetPasswordCallback(rfbClient* cl){
|
||||||
return strdup((const char *)rfbClientGetClientData(cl, &TAG_1));
|
return strdup((const char *)(*rfbClientGetClientData_f)(cl, &TAG_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static rfbCredential* GetCredentialsCallback(rfbClient* cl, int credentialType){
|
static rfbCredential* GetCredentialsCallback(rfbClient* cl, int credentialType){
|
||||||
|
@ -25,8 +53,8 @@ static rfbCredential* GetCredentialsCallback(rfbClient* cl, int credentialType){
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
c->userCredential.password = strdup((const char *)rfbClientGetClientData(cl, &TAG_1));
|
c->userCredential.password = strdup((const char *)(*rfbClientGetClientData_f)(cl, &TAG_1));
|
||||||
c->userCredential.username = strdup((const char *)rfbClientGetClientData(cl, &TAG_2));
|
c->userCredential.username = strdup((const char *)(*rfbClientGetClientData_f)(cl, &TAG_2));
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,11 +122,12 @@ VncCamera::~VncCamera() {
|
||||||
|
|
||||||
void VncCamera::Initialise() {
|
void VncCamera::Initialise() {
|
||||||
Debug(2, "Initializing Client");
|
Debug(2, "Initializing Client");
|
||||||
mRfb = rfbGetClient(8, 3, 4);
|
bind_libvnc_symbols();
|
||||||
|
mRfb = (*rfbGetClient_f)(8, 3, 4);
|
||||||
|
|
||||||
rfbClientSetClientData(mRfb, &TAG_0, &mVncData);
|
(*rfbClientSetClientData_f)(mRfb, &TAG_0, &mVncData);
|
||||||
rfbClientSetClientData(mRfb, &TAG_1, (void *)mPass.c_str());
|
(*rfbClientSetClientData_f)(mRfb, &TAG_1, (void *)mPass.c_str());
|
||||||
rfbClientSetClientData(mRfb, &TAG_2, (void *)mUser.c_str());
|
(*rfbClientSetClientData_f)(mRfb, &TAG_2, (void *)mUser.c_str());
|
||||||
|
|
||||||
mRfb->GotFrameBufferUpdate = GotFrameBufferUpdateCallback;
|
mRfb->GotFrameBufferUpdate = GotFrameBufferUpdateCallback;
|
||||||
mRfb->GetPassword = GetPasswordCallback;
|
mRfb->GetPassword = GetPasswordCallback;
|
||||||
|
@ -107,14 +136,14 @@ void VncCamera::Initialise() {
|
||||||
mRfb->programName = "Zoneminder VNC Monitor";
|
mRfb->programName = "Zoneminder VNC Monitor";
|
||||||
mRfb->serverHost = strdup(mHost.c_str());
|
mRfb->serverHost = strdup(mHost.c_str());
|
||||||
mRfb->serverPort = atoi(mPort.c_str());
|
mRfb->serverPort = atoi(mPort.c_str());
|
||||||
rfbInitClient(mRfb, 0, nullptr);
|
(*rfbInitClient_f)(mRfb, 0, nullptr);
|
||||||
scale.init();
|
scale.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VncCamera::Terminate() {
|
void VncCamera::Terminate() {
|
||||||
if(mRfb->frameBuffer)
|
if(mRfb->frameBuffer)
|
||||||
free(mRfb->frameBuffer);
|
free(mRfb->frameBuffer);
|
||||||
rfbClientCleanup(mRfb);
|
(*rfbClientCleanup_f)(mRfb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,8 +154,8 @@ int VncCamera::PrimeCapture() {
|
||||||
|
|
||||||
int VncCamera::PreCapture() {
|
int VncCamera::PreCapture() {
|
||||||
Debug(2, "PreCapture");
|
Debug(2, "PreCapture");
|
||||||
WaitForMessage(mRfb, 500);
|
(*WaitForMessage_f)(mRfb, 500);
|
||||||
rfbBool res = HandleRFBServerMessage(mRfb);
|
rfbBool res = (*HandleRFBServerMessage_f)(mRfb);
|
||||||
return res == TRUE ? 1 : -1 ;
|
return res == TRUE ? 1 : -1 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue