summaryrefslogtreecommitdiffstats
path: root/libvncserver/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvncserver/main.c')
-rw-r--r--libvncserver/main.c188
1 files changed, 151 insertions, 37 deletions
diff --git a/libvncserver/main.c b/libvncserver/main.c
index 9839c85..cb66976 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 <[email protected]>.
* LibVNCServer (C) 2001 Johannes E. Schindelin <[email protected]>
* Original OSXvnc (C) 2001 Dan McGuirk <[email protected]>.
* 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;
-#include <signal.h>
-#include <time.h>
+extern "C" {
+ /* from scale.c */
+ void rfbScaledScreenUpdate(rfbScreenInfoPtr screen, int x1, int y1, int x2, int y2);
+
+ /* 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;
@@ -445,6 +469,7 @@ clientOutput(void *data)
rfbClientPtr cl = (rfbClientPtr)data;
rfbBool haveUpdate;
sraRegion* updateRegion;
+ cl->onHold = FALSE;
while (1) {
haveUpdate = false;
@@ -453,7 +478,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 +534,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;
@@ -557,7 +587,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);
@@ -574,6 +608,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 wont die by restarting the server */
/* TODO: HTTP is not handled */
while (1) {
@@ -607,7 +650,12 @@ listenerRun(void *data)
void
rfbStartOnHoldClient(rfbClientPtr cl)
{
- pthread_create(&cl->client_thread, NULL, clientInput, (void *)cl);
+ mOnHoldClientHandlerThread = new TQEventLoopThread();
+ mOnHoldClientHandler = new OnHoldClientHandlerObject();
+ mOnHoldClientHandler->d = cl;
+ mOnHoldClientHandler->moveToThread(mOnHoldClientHandlerThread);
+ TQTimer::singleShot(0, mOnHoldClientHandler, SLOT(run()));
+ mOnHoldClientHandlerThread->start();
}
#else
@@ -702,7 +750,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);
@@ -810,7 +858,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);
@@ -919,6 +967,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;
@@ -1015,7 +1064,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);
@@ -1180,12 +1244,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;
@@ -1198,3 +1265,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" \ No newline at end of file