summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordscho <dscho>2001-10-04 11:58:57 +0000
committerdscho <dscho>2001-10-04 11:58:57 +0000
commitbd5fdd670ccae30a31d6b007c312b6d2a1a59cc0 (patch)
tree180753d573f8253e7667a763ef63e8c73e8ef57f
parent2a683877ecf21311cd05d4d509e3e2e4e43adae6 (diff)
downloadlibtdevnc-bd5fdd67.tar.gz
libtdevnc-bd5fdd67.zip
fixed 2 pthreads issues, added noXCursor option.
-rw-r--r--CHANGES10
-rw-r--r--TODO6
-rw-r--r--cursor.c26
-rw-r--r--main.c48
-rw-r--r--rfb.h27
-rw-r--r--rfbserver.c37
6 files changed, 81 insertions, 73 deletions
diff --git a/CHANGES b/CHANGES
index ccf5ee5..b15441c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,14 @@
0.2
+ added flag to optionally not send XCursor updates.
+ fixed java viewer on server side:
+ SendCursorUpdate would send data even before the client pixel format
+ was set.
+ fixed two pthread issues:
+ rfbSendFramebuffer was sent by a ProcessClientMessage function
+ (unprotected by updateMutex).
+ cursor coordinates were set without protection by cursorMutex
source is now equivalent to TridiaVNC 1.2.1
- pthreads now work (use the iterators!)
+ pthreads now work (use iterators!)
cursors are supported (rfbSetCursor automatically undraws cursor)
support for 3 bytes/pixel (slow!)
server side colourmap support
diff --git a/TODO b/TODO
index a78d83e..97dd04b 100644
--- a/TODO
+++ b/TODO
@@ -5,9 +5,6 @@ udp
documentation
perhaps the option (or just hint) not to mark very tiny regions as
modified, because that is inefficient for the encodings.
-optionally dont draw rich cursors as xcursors
-cursor smears on IRIX with pthreads, then has bus error. has to be a mutex
- problem in cursor routines.
later:
------
@@ -18,6 +15,9 @@ CORBA
done:
-----
+.optionally dont draw rich cursors as xcursors
+.cursor smears on IRIX with pthreads, then has bus error. has to be a mutex
+ problem in cursor routines.
.fix bug in http (java) client with big endian server: byte swapping is broken
(was a cursorshape which was sent too soon; java vncviewer assumes
a rich cursor shape to be always 1 byte per pixel, however, framebuffer
diff --git a/cursor.c b/cursor.c
index 42afd3f..6e678d5 100644
--- a/cursor.c
+++ b/cursor.c
@@ -337,10 +337,9 @@ void rfbUndrawCursor(rfbClientPtr cl)
rfbCursorPtr c=s->cursor;
int j,x1,x2,y1,y2,bpp=s->rfbServerFormat.bitsPerPixel/8,
rowstride=s->paddedWidthInBytes;
-
- LOCK(cl->screen->cursorMutex);
+ LOCK(s->cursorMutex);
if(!s->cursorIsDrawn) {
- UNLOCK(cl->screen->cursorMutex);
+ UNLOCK(s->cursorMutex);
return;
}
@@ -350,7 +349,7 @@ void rfbUndrawCursor(rfbClientPtr cl)
if(x1<0) x1=0;
if(x2>=s->width) x2=s->width-1;
x2-=x1; if(x2<=0) {
- UNLOCK(cl->screen->cursorMutex);
+ UNLOCK(s->cursorMutex);
return;
}
y1=s->cursorY-c->yhot;
@@ -358,9 +357,11 @@ void rfbUndrawCursor(rfbClientPtr cl)
if(y1<0) y1=0;
if(y2>=s->height) y2=s->height-1;
y2-=y1; if(y2<=0) {
- UNLOCK(cl->screen->cursorMutex);
+ UNLOCK(s->cursorMutex);
return;
}
+
+ /* get saved data */
for(j=0;j<y2;j++)
memcpy(s->frameBuffer+(y1+j)*rowstride+x1*bpp,
s->underCursorBuffer+j*x2*bpp,
@@ -368,7 +369,7 @@ void rfbUndrawCursor(rfbClientPtr cl)
rfbMarkRectAsModified(s,x1,y1,x1+x2,y1+y2);
s->cursorIsDrawn = FALSE;
- UNLOCK(cl->screen->cursorMutex);
+ UNLOCK(s->cursorMutex);
}
void rfbDrawCursor(rfbClientPtr cl)
@@ -379,10 +380,10 @@ void rfbDrawCursor(rfbClientPtr cl)
rowstride=s->paddedWidthInBytes,
bufSize,w;
if(!c) return;
- LOCK(cl->screen->cursorMutex);
+ LOCK(s->cursorMutex);
if(s->cursorIsDrawn) {
/* is already drawn */
- UNLOCK(cl->screen->cursorMutex);
+ UNLOCK(s->cursorMutex);
return;
}
bufSize=c->width*c->height*bpp;
@@ -400,7 +401,7 @@ void rfbDrawCursor(rfbClientPtr cl)
if(x1<0) { i1=-x1; x1=0; }
if(x2>=s->width) x2=s->width-1;
x2-=x1; if(x2<=0) {
- UNLOCK(cl->screen->cursorMutex);
+ UNLOCK(s->cursorMutex);
return; /* nothing to do */
}
y1=s->cursorY-c->yhot;
@@ -408,9 +409,11 @@ void rfbDrawCursor(rfbClientPtr cl)
if(y1<0) { j1=-y1; y1=0; }
if(y2>=s->height) y2=s->height-1;
y2-=y1; if(y2<=0) {
- UNLOCK(cl->screen->cursorMutex);
+ UNLOCK(s->cursorMutex);
return; /* nothing to do */
}
+
+ /* save data */
for(j=0;j<y2;j++)
memcpy(s->underCursorBuffer+j*x2*bpp,
s->frameBuffer+(y1+j)*rowstride+x1*bpp,
@@ -426,9 +429,10 @@ void rfbDrawCursor(rfbClientPtr cl)
memcpy(s->frameBuffer+(j+y1)*rowstride+(i+x1)*bpp,
c->richSource+(j+j1)*c->width*bpp+(i+i1)*bpp,bpp);
+
rfbMarkRectAsModified(s,x1,y1,x1+x2,y1+y2);
s->cursorIsDrawn = TRUE;
- UNLOCK(cl->screen->cursorMutex);
+ UNLOCK(s->cursorMutex);
}
/* for debugging */
diff --git a/main.c b/main.c
index 2b6cc25..e7c80fd 100644
--- a/main.c
+++ b/main.c
@@ -34,7 +34,7 @@
#include "sraRegion.h"
#ifdef HAVE_PTHREADS
-pthread_mutex_t logMutex;
+MUTEX(logMutex);
#endif
/*
@@ -48,7 +48,7 @@ rfbLog(char *format, ...)
char buf[256];
time_t log_clock;
- IF_PTHREADS(LOCK(logMutex));
+ LOCK(logMutex);
va_start(args, format);
time(&log_clock);
@@ -59,7 +59,7 @@ rfbLog(char *format, ...)
fflush(stderr);
va_end(args);
- IF_PTHREADS(UNLOCK(logMutex));
+ UNLOCK(logMutex);
}
void rfbLogPerror(char *str)
@@ -116,25 +116,28 @@ clientOutput(void *data)
while (1) {
haveUpdate = false;
- LOCK(cl->updateMutex);
while (!haveUpdate) {
if (cl->sock == -1) {
/* Client has disconnected. */
- UNLOCK(cl->updateMutex);
return NULL;
}
- updateRegion = sraRgnCreateRgn(cl->modifiedRegion);
- haveUpdate = sraRgnAnd(updateRegion,cl->requestedRegion);
- sraRgnDestroy(updateRegion);
+ LOCK(cl->updateMutex);
+ haveUpdate = FB_UPDATE_PENDING(cl);
+ if(!haveUpdate) {
+ updateRegion = sraRgnCreateRgn(cl->modifiedRegion);
+ haveUpdate = sraRgnAnd(updateRegion,cl->requestedRegion);
+ sraRgnDestroy(updateRegion);
+ }
+ UNLOCK(cl->updateMutex);
if (!haveUpdate) {
WAIT(cl->updateCond, cl->updateMutex);
+ UNLOCK(cl->updateMutex); /* we really needn't lock now. */
}
}
/* OK, now, to save bandwidth, wait a little while for more
updates to come along. */
- UNLOCK(cl->updateMutex);
usleep(rfbDeferUpdateTime * 1000);
/* Now, get the region we're going to update, and remove
@@ -143,12 +146,10 @@ clientOutput(void *data)
is updated, we'll be sure to do another update later. */
LOCK(cl->updateMutex);
updateRegion = sraRgnCreateRgn(cl->modifiedRegion);
- sraRgnAnd(updateRegion,cl->requestedRegion);
- sraRgnSubtract(cl->modifiedRegion,updateRegion);
+ UNLOCK(cl->updateMutex);
/* Now actually send the update. */
rfbSendFramebufferUpdate(cl, updateRegion);
- UNLOCK(cl->updateMutex);
sraRgnDestroy(updateRegion);
}
@@ -264,13 +265,14 @@ void
defaultPtrAddEvent(int buttonMask, int x, int y, rfbClientPtr cl)
{
if(x!=cl->screen->cursorX || y!=cl->screen->cursorY) {
- Bool cursorWasDrawn=cl->screen->cursorIsDrawn;
- if(cursorWasDrawn)
+ if(cl->screen->cursorIsDrawn)
rfbUndrawCursor(cl);
- cl->screen->cursorX = x;
- cl->screen->cursorY = y;
- if(cursorWasDrawn)
- rfbDrawCursor(cl);
+ LOCK(cl->screen->cursorMutex);
+ if(!cl->screen->cursorIsDrawn) {
+ cl->screen->cursorX = x;
+ cl->screen->cursorY = y;
+ }
+ UNLOCK(cl->screen->cursorMutex);
}
}
@@ -311,6 +313,8 @@ rfbScreenInfoPtr rfbGetScreen(int argc,char** argv,
rfbScreenInfoPtr rfbScreen=malloc(sizeof(rfbScreenInfo));
rfbPixelFormat* format=&rfbScreen->rfbServerFormat;
+ INIT_MUTEX(logMutex);
+
if(width&3)
fprintf(stderr,"WARNING: Width (%d) is not a multiple of 4. VncViewer has problems with that.\n",width);
@@ -387,7 +391,9 @@ rfbScreenInfoPtr rfbGetScreen(int argc,char** argv,
rfbScreen->dontSendFramebufferUpdate = FALSE;
rfbScreen->cursorX=rfbScreen->cursorY=rfbScreen->underCursorBufferLen=0;
rfbScreen->underCursorBuffer=NULL;
- //INIT_MUTEX(rfbScreen->cursorMutex);
+ rfbScreen->dontConvertRichCursorToXCursor = FALSE;
+ rfbScreen->cursor = &myCursor;
+ INIT_MUTEX(rfbScreen->cursorMutex);
/* proc's and hook's */
@@ -396,7 +402,6 @@ rfbScreenInfoPtr rfbGetScreen(int argc,char** argv,
rfbScreen->ptrAddEvent = defaultPtrAddEvent;
rfbScreen->setXCutText = defaultSetXCutText;
rfbScreen->getCursorPtr = defaultGetCursorPtr;
- rfbScreen->cursor = &myCursor;
rfbScreen->setTranslateFunction = rfbSetTranslateFunction;
rfbScreen->newClientHook = doNothingWithClient;
@@ -421,7 +426,6 @@ void rfbInitServer(rfbScreenInfoPtr rfbScreen)
{
rfbInitSockets(rfbScreen);
httpInitSockets(rfbScreen);
- INIT_MUTEX(logMutex);
}
void
@@ -448,8 +452,6 @@ rfbProcessEvents(rfbScreenInfoPtr rfbScreen,long usec)
void rfbRunEventLoop(rfbScreenInfoPtr rfbScreen, long usec, Bool runInBackground)
{
- rfbInitServer(rfbScreen);
-
if(runInBackground) {
#ifdef HAVE_PTHREADS
pthread_t listener_thread;
diff --git a/rfb.h b/rfb.h
index e67e683..18bb2fa 100644
--- a/rfb.h
+++ b/rfb.h
@@ -78,20 +78,20 @@ int max(int,int);
#ifdef HAVE_PTHREADS
#include <pthread.h>
#if 0
-#define LOCK(mutex) fprintf(stderr,"%s:%d LOCK(%s)\n",__FILE__,__LINE__,#mutex)
-#define UNLOCK(mutex) fprintf(stderr,"%s:%d UNLOCK(%s)\n",__FILE__,__LINE__,#mutex)
-#define MUTEX(mutex)
-#define INIT_MUTEX(mutex) fprintf(stderr,"%s:%d INIT_MUTEX(%s)\n",__FILE__,__LINE__,#mutex)
+#define LOCK(mutex) fprintf(stderr,"%s:%d LOCK(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex))
+#define UNLOCK(mutex) fprintf(stderr,"%s:%d UNLOCK(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex))
+#define MUTEX(mutex) int mutex
+#define INIT_MUTEX(mutex) fprintf(stderr,"%s:%d INIT_MUTEX(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex))
#define TINI_MUTEX(mutex) fprintf(stderr,"%s:%d TINI_MUTEX(%s)\n",__FILE__,__LINE__,#mutex)
#define SIGNAL(cond) fprintf(stderr,"%s:%d SIGNAL(%s)\n",__FILE__,__LINE__,#cond)
-#define WAIT(cond,mutex) fprintf(stderr,"%s:%d WAIT(%s,%s)\n",__FILE__,__LINE__,#cond,#mutex)
+#define WAIT(cond,mutex) /* fprintf(stderr,"%s:%d WAIT(%s,%s)\n",__FILE__,__LINE__,#cond,#mutex) */
#define COND(cond)
#define INIT_COND(cond) fprintf(stderr,"%s:%d INIT_COND(%s)\n",__FILE__,__LINE__,#cond)
#define TINI_COND(cond) fprintf(stderr,"%s:%d TINI_COND(%s)\n",__FILE__,__LINE__,#cond)
-#define IF_PTHREAD(x)
+#define IF_PTHREADS(x)
#else
-#define LOCK(mutex) pthread_mutex_lock(&(mutex))
-#define UNLOCK(mutex) pthread_mutex_unlock(&(mutex))
+#define LOCK(mutex) pthread_mutex_lock(&(mutex));
+#define UNLOCK(mutex) pthread_mutex_unlock(&(mutex));
#define MUTEX(mutex) pthread_mutex_t (mutex)
#define INIT_MUTEX(mutex) pthread_mutex_init(&(mutex),NULL)
#define TINI_MUTEX(mutex) pthread_mutex_destroy(&(mutex))
@@ -203,10 +203,6 @@ typedef struct
Bool dontSendFramebufferUpdate; /* TRUE while removing or drawing the
cursor */
- /* these variables are needed to save the area under the cursor */
- int cursorX, cursorY,underCursorBufferLen;
- char* underCursorBuffer;
-
/* additions by libvncserver */
rfbPixelFormat rfbServerFormat;
@@ -242,6 +238,11 @@ typedef struct
Bool rfbNeverShared;
Bool rfbDontDisconnect;
struct rfbClientRec* rfbClientHead;
+
+ /* cursor */
+ int cursorX, cursorY,underCursorBufferLen;
+ char* underCursorBuffer;
+ Bool dontConvertRichCursorToXCursor;
struct rfbCursor* cursor;
MUTEX(cursorMutex);
@@ -254,8 +255,6 @@ typedef struct
GetCursorProcPtr getCursorPtr;
SetTranslateFunctionProcPtr setTranslateFunction;
- /* the following members are hooks, i.e. they are called if set,
- but not overriding original functionality */
/* newClientHook is called just after a new client is created */
NewClientHookPtr newClientHook;
diff --git a/rfbserver.c b/rfbserver.c
index ef7eced..2695170 100644
--- a/rfbserver.c
+++ b/rfbserver.c
@@ -73,6 +73,7 @@ void
rfbClientListInit(rfbScreenInfoPtr rfbScreen)
{
rfbScreen->rfbClientHead = NULL;
+ INIT_MUTEX(rfbClientListMutex);
}
rfbClientIteratorPtr
@@ -657,10 +658,12 @@ rfbProcessClientNormalMessage(cl)
}
break;
case rfbEncodingXCursor:
- rfbLog("Enabling X-style cursor updates for client %s\n",
- cl->host);
- cl->enableCursorShapeUpdates = TRUE;
- cl->cursorWasChanged = TRUE;
+ if(!cl->screen->dontConvertRichCursorToXCursor) {
+ rfbLog("Enabling X-style cursor updates for client %s\n",
+ cl->host);
+ cl->enableCursorShapeUpdates = TRUE;
+ cl->cursorWasChanged = TRUE;
+ }
break;
case rfbEncodingRichCursor:
rfbLog("Enabling full-color cursor updates for client "
@@ -729,6 +732,7 @@ rfbProcessClientNormalMessage(cl)
if (!cl->format.trueColour) {
if (!rfbSetClientColourMap(cl, 0, 0)) {
sraRgnDestroy(tmpRegion);
+ UNLOCK(cl->updateMutex);
return;
}
}
@@ -740,10 +744,7 @@ rfbProcessClientNormalMessage(cl)
}
SIGNAL(cl->updateCond);
UNLOCK(cl->updateMutex);
-
- if(cl->sock>=0 && FB_UPDATE_PENDING(cl)) {
- rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
- }
+
sraRgnDestroy(tmpRegion);
return;
@@ -847,16 +848,12 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
sraRegionPtr updateRegion,updateCopyRegion;
int dx, dy;
Bool sendCursorShape = FALSE;
- Bool cursorWasDrawn = FALSE;
-
/*
* If this client understands cursor shape updates, cursor should be
* removed from the framebuffer. Otherwise, make sure it's put up.
*/
- cursorWasDrawn = cl->screen->cursorIsDrawn;
-
if (cl->enableCursorShapeUpdates) {
if (cl->screen->cursorIsDrawn) {
rfbUndrawCursor(cl);
@@ -869,7 +866,9 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
rfbDrawCursor(cl);
}
}
-
+
+ LOCK(cl->updateMutex);
+
/*
* The modifiedRegion may overlap the destination copyRegion. We remove
* any overlapping bits from the copyRegion (since they'd only be
@@ -889,6 +888,7 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
sraRgnOr(updateRegion,cl->copyRegion);
if(!sraRgnAnd(updateRegion,cl->requestedRegion) && !sendCursorShape) {
sraRgnDestroy(updateRegion);
+ UNLOCK(cl->updateMutex);
return TRUE;
}
@@ -927,12 +927,14 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
sraRgnOr(cl->modifiedRegion,cl->copyRegion);
sraRgnSubtract(cl->modifiedRegion,updateRegion);
sraRgnSubtract(cl->modifiedRegion,updateCopyRegion);
-
+
sraRgnMakeEmpty(cl->requestedRegion);
sraRgnMakeEmpty(cl->copyRegion);
cl->copyDX = 0;
cl->copyDY = 0;
+ UNLOCK(cl->updateMutex);
+
/*
* Now send the update.
*/
@@ -1066,13 +1068,6 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
return FALSE;
}
- if(cursorWasDrawn != cl->screen->cursorIsDrawn) {
- if(cursorWasDrawn)
- rfbDrawCursor(cl);
- else
- rfbUndrawCursor(cl);
- }
-
sraRgnDestroy(updateRegion);
return TRUE;
}