summaryrefslogtreecommitdiffstats
path: root/libvncserver
diff options
context:
space:
mode:
Diffstat (limited to 'libvncserver')
-rw-r--r--libvncserver/main.c194
l---------libvncserver/main.cc1
-rw-r--r--libvncserver/main.h60
-rw-r--r--libvncserver/rfbserver.c11
4 files changed, 229 insertions, 37 deletions
diff --git a/libvncserver/main.c b/libvncserver/main.c
index dbda77d..4fbe036 100644
--- a/libvncserver/main.c
+++ b/libvncserver/main.c
@@ -2,6 +2,7 @@
* This file is called main.c, because it contains most of the new functions
* for use with LibVNCServer.
*
+ * Copyright (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>.
* LibVNCServer (C) 2001 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* Original OSXvnc (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc (C) 1999 AT&T Laboratories Cambridge.
@@ -10,33 +11,56 @@
* see GPL (latest version) for full details
*/
-#ifdef __STRICT_ANSI__
-#define _BSD_SOURCE
-#endif
-#include <rfb/rfb.h>
-#include <rfb/rfbregion.h>
-#include "private.h"
+extern "C" {
+ #ifdef __STRICT_ANSI__
+ #define _BSD_SOURCE
+ #endif
+ #include <rfb/rfb.h>
+ #include <rfb/rfbregion.h>
+ #include "private.h"
+
+ #include <stdarg.h>
+ #include <errno.h>
+
+ #ifndef false
+ #define false 0
+ #define true -1
+ #endif
+
+ #ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H
+ #include <sys/types.h>
+ #endif
+
+ #ifndef WIN32
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <unistd.h>
+ #endif
+
+ #include <signal.h>
+ #include <time.h>
+}
-#include <stdarg.h>
-#include <errno.h>
+#include <ntqobject.h>
+#include <ntqvariant.h>
+#include <ntqtimer.h>
+#include <ntqthread.h>
-#ifndef false
-#define false 0
-#define true -1
-#endif
+#include "main.h"
-#ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
+ControlPipeHandlerObject* mControlPipeHandler = NULL;
+TQEventLoopThread* mControlPipeHandlerThread = NULL;
-#ifndef WIN32
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <unistd.h>
-#endif
+OnHoldClientHandlerObject* mOnHoldClientHandler = NULL;
+TQEventLoopThread* mOnHoldClientHandlerThread = NULL;
+
+extern "C" {
+ /* from scale.c */
+ void rfbScaledScreenUpdate(rfbScreenInfoPtr screen, int x1, int y1, int x2, int y2);
-#include <signal.h>
-#include <time.h>
+ /* from rfbserver.c */
+ rfbClientIteratorPtr rfbGetClientIteratorWithClosed(rfbScreenInfoPtr rfbScreen);
+}
static int extMutex_initialized = 0;
static int logMutex_initialized = 0;
@@ -169,7 +193,7 @@ rfbBool rfbEnableExtension(rfbClientPtr cl, rfbProtocolExtension* extension,
if(extData->extension == extension)
return FALSE;
- extData = calloc(sizeof(rfbExtensionData),1);
+ extData = (rfbExtensionData*)calloc(sizeof(rfbExtensionData),1);
extData->extension = extension;
extData->data = data;
extData->next = cl->extensions;
@@ -453,7 +477,7 @@ clientOutput(void *data)
/* Client has disconnected. */
return NULL;
}
- if (cl->state != RFB_NORMAL || cl->onHold) {
+ if (cl->state != _rfbClientRec::RFB_NORMAL || cl->onHold) {
/* just sleep until things get normal */
usleep(cl->screen->deferUpdateTime * 1000);
continue;
@@ -509,8 +533,13 @@ static void *
clientInput(void *data)
{
rfbClientPtr cl = (rfbClientPtr)data;
- pthread_t output_thread;
- pthread_create(&output_thread, NULL, clientOutput, (void *)cl);
+ /* Start output thread */
+ TQEventLoopThread* clientOutputHandlerThread = new TQEventLoopThread();
+ ClientOutputHandlerObject* clientOutputHandler = new ClientOutputHandlerObject();
+ clientOutputHandler->d = cl;
+ clientOutputHandler->moveToThread(clientOutputHandlerThread);
+ TQTimer::singleShot(0, clientOutputHandler, SLOT(run()));
+ clientOutputHandlerThread->start();
while (1) {
fd_set rfds, wfds, efds;
@@ -565,7 +594,11 @@ clientInput(void *data)
LOCK(cl->updateMutex);
TSIGNAL(cl->updateCond);
UNLOCK(cl->updateMutex);
- IF_PTHREADS(pthread_join(output_thread, NULL));
+ clientOutputHandlerThread->wait();
+ delete clientOutputHandlerThread;
+ clientOutputHandlerThread = NULL;
+ delete clientOutputHandler;
+ clientOutputHandler = NULL;
rfbClientConnectionGone(cl);
@@ -582,6 +615,15 @@ listenerRun(void *data)
socklen_t len;
fd_set listen_fds; /* temp file descriptor list for select() */
+ if (screen->inetdSock != -1) {
+ cl = rfbNewClient(screen, screen->inetdSock);
+ if (cl && !cl->onHold)
+ rfbStartOnHoldClient(cl);
+ else if (screen->inetdDisconnectHook && !cl)
+ screen->inetdDisconnectHook();
+ return NULL;
+ }
+
/* TODO: this thread won't die by restarting the server */
/* TODO: HTTP is not handled */
while (1) {
@@ -612,7 +654,18 @@ listenerRun(void *data)
return(NULL);
}
-#endif
+void
+rfbStartOnHoldClient(rfbClientPtr cl)
+{
+ mOnHoldClientHandlerThread = new TQEventLoopThread();
+ mOnHoldClientHandler = new OnHoldClientHandlerObject();
+ mOnHoldClientHandler->d = cl;
+ mOnHoldClientHandler->moveToThread(mOnHoldClientHandlerThread);
+ TQTimer::singleShot(0, mOnHoldClientHandler, SLOT(run()));
+ mOnHoldClientHandlerThread->start();
+}
+
+#else
void
rfbStartOnHoldClient(rfbClientPtr cl)
@@ -624,6 +677,7 @@ rfbStartOnHoldClient(rfbClientPtr cl)
#endif
}
+#endif
void
rfbRefuseOnHoldClient(rfbClientPtr cl)
@@ -707,7 +761,7 @@ static rfbCursorPtr rfbDefaultGetCursorPtr(rfbClientPtr cl)
static rfbBool rfbDefaultPasswordCheck(rfbClientPtr cl,const char* response,int len)
{
int i;
- char *passwd=rfbDecryptPasswdFromFile(cl->screen->authPasswdData);
+ char *passwd=rfbDecryptPasswdFromFile((char*)cl->screen->authPasswdData);
if(!passwd) {
rfbErr("Couldn't read password file: %s\n",cl->screen->authPasswdData);
@@ -815,7 +869,7 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
int width,int height,int bitsPerSample,int samplesPerPixel,
int bytesPerPixel)
{
- rfbScreenInfoPtr screen=calloc(sizeof(rfbScreenInfo),1);
+ rfbScreenInfoPtr screen=(rfbScreenInfoPtr)calloc(sizeof(rfbScreenInfo),1);
if (! logMutex_initialized) {
INIT_MUTEX(logMutex);
@@ -924,6 +978,7 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
screen->setTranslateFunction = rfbSetTranslateFunction;
screen->newClientHook = rfbDefaultNewClientHook;
screen->displayHook = NULL;
+ screen->inetdDisconnectHook = NULL;
screen->displayFinishedHook = NULL;
screen->getKeyboardLedStateHook = NULL;
screen->xvpHook = NULL;
@@ -1020,7 +1075,22 @@ void rfbScreenCleanup(rfbScreenInfoPtr screen)
cl1=cl;
}
rfbReleaseClientIterator(i);
-
+
+ if (mOnHoldClientHandlerThread) {
+ mOnHoldClientHandlerThread->exit();
+ delete mOnHoldClientHandlerThread;
+ mOnHoldClientHandlerThread = NULL;
+ delete mOnHoldClientHandler;
+ mOnHoldClientHandler = NULL;
+ }
+ if (mControlPipeHandlerThread) {
+ mControlPipeHandlerThread->exit();
+ delete mControlPipeHandlerThread;
+ mControlPipeHandlerThread = NULL;
+ delete mControlPipeHandler;
+ mControlPipeHandler = NULL;
+ }
+
#define FREE_IF(x) if(screen->x) free(screen->x)
FREE_IF(colourMap.data.bytes);
FREE_IF(underCursorBuffer);
@@ -1185,12 +1255,15 @@ void rfbRunEventLoop(rfbScreenInfoPtr screen, long usec, rfbBool runInBackground
{
if(runInBackground) {
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
- pthread_t listener_thread;
-
- screen->backgroundLoop = TRUE;
-
- pthread_create(&listener_thread, NULL, listenerRun, screen);
- return;
+ screen->backgroundLoop = TRUE;
+
+ mControlPipeHandlerThread = new TQEventLoopThread();
+ mControlPipeHandler = new ControlPipeHandlerObject();
+ mControlPipeHandler->d = screen;
+ mControlPipeHandler->moveToThread(mControlPipeHandlerThread);
+ TQTimer::singleShot(0, mControlPipeHandler, SLOT(run()));
+ mControlPipeHandlerThread->start();
+ return;
#else
rfbErr("Can't run in background, because I don't have PThreads!\n");
return;
@@ -1203,3 +1276,50 @@ void rfbRunEventLoop(rfbScreenInfoPtr screen, long usec, rfbBool runInBackground
while(rfbIsActive(screen))
rfbProcessEvents(screen,usec);
}
+
+ControlPipeHandlerObject::ControlPipeHandlerObject() : TQObject() {
+ //
+}
+
+ControlPipeHandlerObject::~ControlPipeHandlerObject() {
+ //
+}
+
+void ControlPipeHandlerObject::run(void) {
+ listenerRun(d);
+
+ // Terminate thread
+ TQThread::exit();
+}
+
+OnHoldClientHandlerObject::OnHoldClientHandlerObject() : TQObject() {
+ //
+}
+
+OnHoldClientHandlerObject::~OnHoldClientHandlerObject() {
+ //
+}
+
+void OnHoldClientHandlerObject::run(void) {
+ clientInput(d);
+
+ // Terminate thread
+ TQThread::exit();
+}
+
+ClientOutputHandlerObject::ClientOutputHandlerObject() : TQObject() {
+ //
+}
+
+ClientOutputHandlerObject::~ClientOutputHandlerObject() {
+ //
+}
+
+void ClientOutputHandlerObject::run(void) {
+ clientOutput(d);
+
+ // Terminate thread
+ TQThread::exit();
+}
+
+#include "main.moc"
diff --git a/libvncserver/main.cc b/libvncserver/main.cc
new file mode 120000
index 0000000..8a03e94
--- /dev/null
+++ b/libvncserver/main.cc
@@ -0,0 +1 @@
+main.c \ No newline at end of file
diff --git a/libvncserver/main.h b/libvncserver/main.h
new file mode 100644
index 0000000..a02a476
--- /dev/null
+++ b/libvncserver/main.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>.
+ * LibVNCServer (C) 2001 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
+ * Original OSXvnc (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
+ * Original Xvnc (C) 1999 AT&T Laboratories Cambridge.
+ * All Rights Reserved.
+ *
+ * see GPL (latest version) for full details
+ */
+
+#ifndef _MAIN_H
+#define _MAIN_H
+
+class ControlPipeHandlerObject : public TQObject
+{
+ Q_OBJECT
+
+ public:
+ ControlPipeHandlerObject();
+ ~ControlPipeHandlerObject();
+
+ public slots:
+ void run();
+
+ public:
+ rfbScreenInfoPtr d;
+};
+
+class OnHoldClientHandlerObject : public TQObject
+{
+ Q_OBJECT
+
+ public:
+ OnHoldClientHandlerObject();
+ ~OnHoldClientHandlerObject();
+
+ public slots:
+ void run();
+
+ public:
+ rfbClientPtr d;
+};
+
+class ClientOutputHandlerObject : public TQObject
+{
+ Q_OBJECT
+
+ public:
+ ClientOutputHandlerObject();
+ ~ClientOutputHandlerObject();
+
+ public slots:
+ void run();
+
+ public:
+ rfbClientPtr d;
+};
+
+#endif // _MAIN_H
+
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
index bc9cc11..44723ef 100644
--- a/libvncserver/rfbserver.c
+++ b/libvncserver/rfbserver.c
@@ -3,6 +3,7 @@
*/
/*
+ * Copyright (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>.
* Copyright (C) 2011-2012 D. R. Commander
* Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin
* Copyright (C) 2002 RealVNC Ltd.
@@ -328,6 +329,7 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
cl->clientData = NULL;
cl->clientGoneHook = rfbDoNothingWithClient;
+ cl->negotiationFinishedHook = rfbDoNothingWithClient;
if(isUDP) {
rfbLog(" accepted UDP client\n");
@@ -432,6 +434,7 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
cl->enableCursorPosUpdates = FALSE;
cl->useRichCursorEncoding = FALSE;
cl->enableLastRectEncoding = FALSE;
+ cl->disableBackground = FALSE;
cl->enableKeyboardLedState = FALSE;
cl->enableSupportedMessages = FALSE;
cl->enableSupportedEncodings = FALSE;
@@ -2094,6 +2097,7 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
cl->enableCursorShapeUpdates = FALSE;
cl->enableCursorShapeUpdates = FALSE;
cl->enableLastRectEncoding = FALSE;
+ cl->disableBackground = FALSE;
cl->enableKeyboardLedState = FALSE;
cl->enableSupportedMessages = FALSE;
cl->enableSupportedEncodings = FALSE;
@@ -2182,6 +2186,11 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
cl->enableLastRectEncoding = TRUE;
}
break;
+ case rfbEncodingBackground:
+ rfbLog("Disabling background for client "
+ "%s\n", cl->host);
+ cl->disableBackground = TRUE;
+ break;
case rfbEncodingNewFBSize:
if (!cl->useNewFBSize) {
rfbLog("Enabling NewFBSize protocol extension for client "
@@ -2338,6 +2347,8 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
cl->enableCursorPosUpdates = FALSE;
}
+ cl->negotiationFinishedHook(cl);
+
return;
}