diff --git a/Makefile b/Makefile index 8554699..5fed831 100644 --- a/Makefile +++ b/Makefile @@ -2,11 +2,15 @@ INCLUDES=-I. VNCSERVERLIB=-L. -lvncserver -L/usr/local/lib -lz -ljpeg # Uncomment these two lines to enable use of PThreads -PTHREADDEF = -DHAVE_PTHREADS -PTHREADLIB = -lpthread +#PTHREADDEF = -DHAVE_PTHREADS +#PTHREADLIB = -lpthread + +# Comment the following line to disable the use of 3 Bytes/Pixel. +# The code for 3 Bytes/Pixel is not very efficient! +FLAG24 = -DALLOW24BPP #CC=cc -CFLAGS=-g -Wall $(PTHREADDEF) $(INCLUDES) +CFLAGS=-g -Wall $(PTHREADDEF) $(FLAG24) $(INCLUDES) #CFLAGS=-O2 -Wall RANLIB=ranlib @@ -34,6 +38,8 @@ install_OSX: OSXvnc-server .c.o: $(CC) $(CFLAGS) -c $< +$(OBJS): Makefile rfb.h + libvncserver.a: $(OBJS) $(AR) cru $@ $(OBJS) $(RANLIB) $@ @@ -62,6 +68,11 @@ blooptest: blooptest.o libvncserver.a blooptest.o: example.c $(CC) $(CFLAGS) -DBACKGROUND_LOOP_TEST -c -o blooptest.o example.c +pnmshow24: pnmshow24.o libvncserver.a + $(CC) -o pnmshow24 pnmshow24.o $(LIBS) + +pnmshow24.o: Makefile + clean: rm -f $(OBJS) *~ core "#"* *.bak *.orig storepasswd.o \ mac.o example.o pnmshow.o sratest.o $(OBJS) diff --git a/README b/README index c99e48c..654a97a 100644 --- a/README +++ b/README @@ -48,8 +48,10 @@ To make a server, you just have to initialise a server structure using the function rfbDefaultScreenInit, like rfbScreenInfoPtr rfbScreen = rfbGetScreen(argc,argv,width,height,8,3,bpp); -where byte per pixel is 1, 2 or 4. This is so because of speed considerations -(you can use native data types of that width). +where byte per pixel should be 1, 2 or 4. If performance doesn't matter, +you may try bpp=3 (internally one cannot use native data types in this +case; if you want to use this, look at pnmshow24). + You then can set hooks and io functions (see below) or other options (see below). diff --git a/TODO b/TODO index 20147c8..57fade5 100644 --- a/TODO +++ b/TODO @@ -19,15 +19,18 @@ cursor "smears" sometimes when not using cursor encoding (seems to be gone now; haven't debugged properly, though) udp autoconf? at least Sun Solaris compilation -rfbCloseClient, rfbConnect, ConnectToTcpAddr +rfbConnect, ConnectToTcpAddr CORBA -translate.c: warning about non 8-bit colourmaps -set colourmap documentation done: ----- +.translate.c: warning about non 8-bit colourmaps + 16-bit colourmaps are 192k -> no use without fast net. +.rfbCloseClient +.set colourmap +.support 3 bytes per pixel .cursors .cutpaste .httpd diff --git a/example.c b/example.c index cc021e4..da01d7a 100644 --- a/example.c +++ b/example.c @@ -315,6 +315,8 @@ int main(int argc,char** argv) /* this is the blocking event loop, i.e. it never returns */ /* 40000 are the microseconds, i.e. 0.04 seconds */ rfbRunEventLoop(rfbScreen,40000,FALSE); +#elif !defined(HAVE_PTHREADS) +#error "I need pthreads for that." #endif /* this is the non-blocking event loop; a background thread is started */ diff --git a/main.c b/main.c index d33b7a0..b709bb7 100644 --- a/main.c +++ b/main.c @@ -31,7 +31,7 @@ #include #include "rfb.h" -#include "region.h" +#include "sraRegion.h" #ifdef HAVE_PTHREADS pthread_mutex_t logMutex; @@ -75,10 +75,14 @@ void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion) iterator=rfbGetClientIterator(rfbScreen); while((cl=rfbClientIteratorNext(iterator))) { +#ifdef HAVE_PTHREADS pthread_mutex_lock(&cl->updateMutex); +#endif sraRgnOr(cl->modifiedRegion,modRegion); +#ifdef HAVE_PTHREADS pthread_cond_signal(&cl->updateCond); pthread_mutex_unlock(&cl->updateMutex); +#endif } rfbReleaseClientIterator(iterator); @@ -353,7 +357,9 @@ rfbScreenInfoPtr rfbGetScreen(int argc,char** argv, format->depth = rfbScreen->depth; format->bigEndian = rfbEndianTest?FALSE:TRUE; format->trueColour = TRUE; - rfbScreen->colourMap = NULL; + rfbScreen->colourMap.count = 0; + rfbScreen->colourMap.is16 = 0; + rfbScreen->colourMap.data.bytes = NULL; if(bytesPerPixel == 8) { format->redMax = 7; diff --git a/rfb.h b/rfb.h index 0cdf6e4..54f5bde 100644 --- a/rfb.h +++ b/rfb.h @@ -98,6 +98,15 @@ typedef struct rfbCursor* (*GetCursorProcPtr) (struct rfbClientRec* pScreen); typedef Bool (*SetTranslateFunctionProcPtr)(struct rfbClientRec* cl); typedef void (*NewClientHookPtr)(struct rfbClientRec* cl); +typedef struct { + int count; + Bool is16; /* is the data format short? */ + union { + CARD8* bytes; + CARD16* shorts; + } data; /* there have to be count*3 entries */ +} rfbColourMap; + /* * Per-screen (framebuffer) structure. There is only one of these, since we * don't allow the X server to have multiple screens. @@ -184,7 +193,7 @@ typedef struct ScreenRec screen; */ rfbPixelFormat rfbServerFormat; - CARD16* colourMap; /* set this if rfbServerFormat.trueColour==FALSE */ + rfbColourMap colourMap; /* set this if rfbServerFormat.trueColour==FALSE */ char* desktopName; char rfbThisHost[255]; int rfbPort; @@ -453,6 +462,9 @@ typedef struct rfbClientRec { #define Swap16(s) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) +#define Swap24(l) ((((l) & 0xff) << 16) | (((l) >> 16) & 0xff) | \ + (((l) & 0x00ff00))) + #define Swap32(l) (((l) >> 24) | \ (((l) & 0x00ff0000) >> 8) | \ (((l) & 0x0000ff00) << 8) | \ @@ -462,7 +474,7 @@ typedef struct rfbClientRec { static const int rfbEndianTest = (_BYTE_ORDER == _LITTLE_ENDIAN); #define Swap16IfLE(s) (rfbEndianTest ? Swap16(s) : (s)) - +#define Swap24IfLE(l) (rfbEndianTest ? Swap24(l) : (l)) #define Swap32IfLE(l) (rfbEndianTest ? Swap32(l) : (l)) /* main.c */ @@ -511,6 +523,7 @@ extern Bool rfbSendUpdateBuf(rfbClientPtr cl); extern void rfbSendServerCutText(rfbScreenInfoPtr rfbScreen,char *str, int len); extern Bool rfbSendCopyRegion(rfbClientPtr cl,sraRegionPtr reg,int dx,int dy); extern Bool rfbSendLastRectMarker(rfbClientPtr cl); +extern Bool rfbSendSetColourMapEntries(rfbClientPtr cl, int firstColour, int nColours); void rfbGotXCutText(rfbScreenInfoPtr rfbScreen, char *str, int len); @@ -524,7 +537,8 @@ extern void rfbTranslateNone(char *table, rfbPixelFormat *in, int bytesBetweenInputLines, int width, int height); extern Bool rfbSetTranslateFunction(rfbClientPtr cl); - +extern Bool rfbSetClientColourMap(rfbClientPtr cl, int firstColour, int nColours); +extern void rfbSetClientColourMaps(rfbScreenInfoPtr rfbScreen, int firstColour, int nColours); /* httpd.c */ @@ -595,8 +609,8 @@ typedef struct rfbCursor { unsigned char *source; /* points to bits */ unsigned char *mask; /* points to bits */ unsigned short width, height, xhot, yhot; /* metrics */ - unsigned short foreRed, foreGreen, foreBlue; /* device-independent color */ - unsigned short backRed, backGreen, backBlue; /* device-independent color */ + unsigned short foreRed, foreGreen, foreBlue; /* device-independent colour */ + unsigned short backRed, backGreen, backBlue; /* device-independent colour */ unsigned char *richSource; /* source bytes for a rich cursor */ #ifdef HAVE_PTHREADS pthread_mutex_t mutex; diff --git a/rfbserver.c b/rfbserver.c index 471a25e..c1bf69d 100644 --- a/rfbserver.c +++ b/rfbserver.c @@ -26,7 +26,7 @@ #include #include #include "rfb.h" -#include "region.h" +#include "sraRegion.h" #include #include #include @@ -699,7 +699,6 @@ rfbProcessClientNormalMessage(cl) #endif sraRgnOr(cl->requestedRegion,tmpRegion); -#ifdef NOT_YET if (!cl->readyForSetColourMapEntries) { /* client hasn't sent a SetPixelFormat so is using server's */ cl->readyForSetColourMapEntries = TRUE; @@ -710,7 +709,6 @@ rfbProcessClientNormalMessage(cl) } } } -#endif if (!msg.fur.incremental) { sraRgnOr(cl->modifiedRegion,tmpRegion); @@ -1221,7 +1219,6 @@ rfbSendUpdateBuf(cl) return TRUE; } -#ifdef NOT_YET /* * rfbSendSetColourMapEntries sends a SetColourMapEntries message to the * client, using values from the currently installed colormap. @@ -1236,7 +1233,8 @@ rfbSendSetColourMapEntries(cl, firstColour, nColours) char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2]; rfbSetColourMapEntriesMsg *scme = (rfbSetColourMapEntriesMsg *)buf; CARD16 *rgb = (CARD16 *)(&buf[sz_rfbSetColourMapEntriesMsg]); - EntryPtr pent; + rfbColourMap* cm = &cl->screen->colourMap; + int i, len; scme->type = rfbSetColourMapEntries; @@ -1246,30 +1244,29 @@ rfbSendSetColourMapEntries(cl, firstColour, nColours) len = sz_rfbSetColourMapEntriesMsg; - pent = (EntryPtr)&rfbInstalledColormap->red[firstColour]; for (i = 0; i < nColours; i++) { - if (pent->fShared) { - rgb[i*3] = Swap16IfLE(pent->co.shco.red->color); - rgb[i*3+1] = Swap16IfLE(pent->co.shco.green->color); - rgb[i*3+2] = Swap16IfLE(pent->co.shco.blue->color); + if(icount) { + if(cm->is16) { + rgb[i*3] = Swap16IfLE(cm->data.shorts[i*3]); + rgb[i*3+1] = Swap16IfLE(cm->data.shorts[i*3+1]); + rgb[i*3+2] = Swap16IfLE(cm->data.shorts[i*3+2]); } else { - rgb[i*3] = Swap16IfLE(pent->co.local.red); - rgb[i*3+1] = Swap16IfLE(pent->co.local.green); - rgb[i*3+2] = Swap16IfLE(pent->co.local.blue); + rgb[i*3] = Swap16IfLE(cm->data.bytes[i*3]); + rgb[i*3+1] = Swap16IfLE(cm->data.bytes[i*3+1]); + rgb[i*3+2] = Swap16IfLE(cm->data.bytes[i*3+2]); } - pent++; + } } len += nColours * 3 * 2; - if (WriteExact(cl->sock, buf, len) < 0) { + if (WriteExact(cl, buf, len) < 0) { rfbLogPerror("rfbSendSetColourMapEntries: write"); rfbCloseClient(cl); return FALSE; } return TRUE; } -#endif /* * rfbSendBell sends a Bell message to all the clients. diff --git a/sockets.c b/sockets.c index 145236b..da5d99f 100644 --- a/sockets.c +++ b/sockets.c @@ -276,14 +276,17 @@ void rfbCloseClient(cl) rfbClientPtr cl; { +#ifdef HAVE_PTHREADS pthread_mutex_lock(&cl->updateMutex); +#endif FD_CLR(cl->sock,&(cl->screen->allFds)); close(cl->sock); cl->sock = -1; +#ifdef HAVE_PTHREADS pthread_cond_signal(&cl->updateCond); //pthread_mutex_lock(&cl->updateMutex); - //rfbClientConnectionGone(cl); pthread_mutex_unlock(&cl->updateMutex); +#endif } diff --git a/tableinitcmtemplate.c b/tableinitcmtemplate.c index 13de763..b8144ea 100644 --- a/tableinitcmtemplate.c +++ b/tableinitcmtemplate.c @@ -43,39 +43,39 @@ CONCAT2E(rfbInitColourMapSingleTable,OUT) static void -rfbInitColourMapSingleTableOUT (char **table, rfbPixelFormat *in, - rfbPixelFormat *out) +rfbInitColourMapSingleTableOUT(char **table, rfbPixelFormat *in, + rfbPixelFormat *out,rfbColourMap* colourMap) { - int i, r, g, b; + CARD32 i, r, g, b; OUT_T *t; - EntryPtr pent; int nEntries = 1 << in->bitsPerPixel; + int shift = colourMap->is16?16:8; if (*table) free(*table); *table = (char *)malloc(nEntries * sizeof(OUT_T)); t = (OUT_T *)*table; - pent = (EntryPtr)&rfbInstalledColormap->red[0]; - for (i = 0; i < nEntries; i++) { - if (pent->fShared) { - r = pent->co.shco.red->color; - g = pent->co.shco.green->color; - b = pent->co.shco.blue->color; - } else { - r = pent->co.local.red; - g = pent->co.local.green; - b = pent->co.local.blue; - } - t[i] = ((((r * out->redMax + 32767) / 65535) << out->redShift) | - (((g * out->greenMax + 32767) / 65535) << out->greenShift) | - (((b * out->blueMax + 32767) / 65535) << out->blueShift)); + r = g = b = 0; + if(i < colourMap->count) { + if(colourMap->is16) { + r = colourMap->data.shorts[3*i+0]; + g = colourMap->data.shorts[3*i+1]; + b = colourMap->data.shorts[3*i+2]; + } else { + r = colourMap->data.bytes[3*i+0]; + g = colourMap->data.bytes[3*i+1]; + b = colourMap->data.bytes[3*i+2]; + } + } + t[i] = ((((r * (1 + out->redMax)) >> shift) << out->redShift) | + (((g * (1 + out->greenMax)) >> shift) << out->greenShift) | + (((b * (1 + out->blueMax)) >> shift) << out->blueShift)); #if (OUT != 8) if (out->bigEndian != in->bigEndian) { t[i] = SwapOUT(t[i]); } #endif - pent++; } } diff --git a/translate.c b/translate.c index 5745bf2..59128a5 100644 --- a/translate.c +++ b/translate.c @@ -26,6 +26,7 @@ #include #include #include "rfb.h" +#include "sraRegion.h" static void PrintPixelFormat(rfbPixelFormat *pf); static Bool rfbSetClientColourMapBGR233(); @@ -63,6 +64,7 @@ static const rfbPixelFormat BGR233Format = { #define CONCAT4E(a,b,c,d) CONCAT4(a,b,c,d) #define OUT 8 +#include "tableinitcmtemplate.c" #include "tableinittctemplate.c" #define IN 8 #include "tabletranstemplate.c" @@ -76,6 +78,7 @@ static const rfbPixelFormat BGR233Format = { #undef OUT #define OUT 16 +#include "tableinitcmtemplate.c" #include "tableinittctemplate.c" #define IN 8 #include "tabletranstemplate.c" @@ -89,6 +92,7 @@ static const rfbPixelFormat BGR233Format = { #undef OUT #define OUT 32 +#include "tableinitcmtemplate.c" #include "tableinittctemplate.c" #define IN 8 #include "tabletranstemplate.c" @@ -101,42 +105,110 @@ static const rfbPixelFormat BGR233Format = { #undef IN #undef OUT +#ifdef ALLOW24BPP +#define COUNT_OFFSETS 4 +#define BPP2OFFSET(bpp) ((bpp)/8-1) +#include "tableinit24.c" +#define BPP 8 +#include "tabletrans24template.c" +#undef BPP +#define BPP 16 +#include "tabletrans24template.c" +#undef BPP +#define BPP 24 +#include "tabletrans24template.c" +#undef BPP +#define BPP 32 +#include "tabletrans24template.c" +#undef BPP +#else +#define COUNT_OFFSETS 3 +#define BPP2OFFSET(bpp) ((int)(bpp)/16) +#endif + +typedef void (*rfbInitCMTableFnType)(char **table, rfbPixelFormat *in, + rfbPixelFormat *out,rfbColourMap* cm); typedef void (*rfbInitTableFnType)(char **table, rfbPixelFormat *in, rfbPixelFormat *out); -rfbInitTableFnType rfbInitTrueColourSingleTableFns[3] = { +rfbInitCMTableFnType rfbInitColourMapSingleTableFns[COUNT_OFFSETS] = { + rfbInitColourMapSingleTable8, + rfbInitColourMapSingleTable16, +#ifdef ALLOW24BPP + rfbInitColourMapSingleTable24, +#endif + rfbInitColourMapSingleTable32 +}; + +rfbInitTableFnType rfbInitTrueColourSingleTableFns[COUNT_OFFSETS] = { rfbInitTrueColourSingleTable8, rfbInitTrueColourSingleTable16, +#ifdef ALLOW24BPP + rfbInitTrueColourSingleTable24, +#endif rfbInitTrueColourSingleTable32 }; -rfbInitTableFnType rfbInitTrueColourRGBTablesFns[3] = { +rfbInitTableFnType rfbInitTrueColourRGBTablesFns[COUNT_OFFSETS] = { rfbInitTrueColourRGBTables8, rfbInitTrueColourRGBTables16, +#ifdef ALLOW24BPP + rfbInitTrueColourRGBTables24, +#endif rfbInitTrueColourRGBTables32 }; -rfbTranslateFnType rfbTranslateWithSingleTableFns[3][3] = { +rfbTranslateFnType rfbTranslateWithSingleTableFns[COUNT_OFFSETS][COUNT_OFFSETS] = { { rfbTranslateWithSingleTable8to8, rfbTranslateWithSingleTable8to16, +#ifdef ALLOW24BPP + rfbTranslateWithSingleTable8to24, +#endif rfbTranslateWithSingleTable8to32 }, { rfbTranslateWithSingleTable16to8, rfbTranslateWithSingleTable16to16, +#ifdef ALLOW24BPP + rfbTranslateWithSingleTable16to24, +#endif rfbTranslateWithSingleTable16to32 }, +#ifdef ALLOW24BPP + { rfbTranslateWithSingleTable24to8, + rfbTranslateWithSingleTable24to16, + rfbTranslateWithSingleTable24to24, + rfbTranslateWithSingleTable24to32 }, +#endif { rfbTranslateWithSingleTable32to8, rfbTranslateWithSingleTable32to16, +#ifdef ALLOW24BPP + rfbTranslateWithSingleTable32to24, +#endif rfbTranslateWithSingleTable32to32 } }; -rfbTranslateFnType rfbTranslateWithRGBTablesFns[3][3] = { +rfbTranslateFnType rfbTranslateWithRGBTablesFns[COUNT_OFFSETS][COUNT_OFFSETS] = { { rfbTranslateWithRGBTables8to8, rfbTranslateWithRGBTables8to16, +#ifdef ALLOW24BPP + rfbTranslateWithRGBTables8to24, +#endif rfbTranslateWithRGBTables8to32 }, { rfbTranslateWithRGBTables16to8, rfbTranslateWithRGBTables16to16, +#ifdef ALLOW24BPP + rfbTranslateWithRGBTables16to24, +#endif rfbTranslateWithRGBTables16to32 }, +#ifdef ALLOW24BPP + { rfbTranslateWithRGBTables24to8, + rfbTranslateWithRGBTables24to16, + rfbTranslateWithRGBTables24to24, + rfbTranslateWithRGBTables24to32 }, +#endif { rfbTranslateWithRGBTables32to8, rfbTranslateWithRGBTables32to16, +#ifdef ALLOW24BPP + rfbTranslateWithRGBTables32to24, +#endif rfbTranslateWithRGBTables32to32 } }; @@ -179,6 +251,9 @@ rfbSetTranslateFunction(cl) if ((cl->screen->rfbServerFormat.bitsPerPixel != 8) && (cl->screen->rfbServerFormat.bitsPerPixel != 16) && +#ifdef ALLOW24BPP + (cl->screen->rfbServerFormat.bitsPerPixel != 24) && +#endif (cl->screen->rfbServerFormat.bitsPerPixel != 32)) { rfbLog("%s: server bits per pixel not 8, 16 or 32\n", @@ -189,6 +264,9 @@ rfbSetTranslateFunction(cl) if ((cl->format.bitsPerPixel != 8) && (cl->format.bitsPerPixel != 16) && +#ifdef ALLOW24BPP + (cl->format.bitsPerPixel != 24) && +#endif (cl->format.bitsPerPixel != 32)) { rfbLog("%s: client bits per pixel not 8, 16 or 32\n", @@ -235,28 +313,34 @@ rfbSetTranslateFunction(cl) } if ((cl->screen->rfbServerFormat.bitsPerPixel < 16) || - (!rfbEconomicTranslate && (cl->screen->rfbServerFormat.bitsPerPixel == 16))) { + ((!cl->screen->rfbServerFormat.trueColour || !rfbEconomicTranslate) && + (cl->screen->rfbServerFormat.bitsPerPixel == 16))) { /* we can use a single lookup table for <= 16 bpp */ cl->translateFn = rfbTranslateWithSingleTableFns - [cl->screen->rfbServerFormat.bitsPerPixel / 16] - [cl->format.bitsPerPixel / 16]; - - (*rfbInitTrueColourSingleTableFns - [cl->format.bitsPerPixel / 16]) (&cl->translateLookupTable, - &(cl->screen->rfbServerFormat), &cl->format); + [BPP2OFFSET(cl->screen->rfbServerFormat.bitsPerPixel)] + [BPP2OFFSET(cl->format.bitsPerPixel)]; + + if(cl->screen->rfbServerFormat.trueColour) + (*rfbInitTrueColourSingleTableFns + [BPP2OFFSET(cl->format.bitsPerPixel)]) (&cl->translateLookupTable, + &(cl->screen->rfbServerFormat), &cl->format); + else + (*rfbInitColourMapSingleTableFns + [BPP2OFFSET(cl->format.bitsPerPixel)]) (&cl->translateLookupTable, + &(cl->screen->rfbServerFormat), &cl->format,&cl->screen->colourMap); } else { /* otherwise we use three separate tables for red, green and blue */ cl->translateFn = rfbTranslateWithRGBTablesFns - [cl->screen->rfbServerFormat.bitsPerPixel / 16] - [cl->format.bitsPerPixel / 16]; + [BPP2OFFSET(cl->screen->rfbServerFormat.bitsPerPixel)] + [BPP2OFFSET(cl->format.bitsPerPixel)]; (*rfbInitTrueColourRGBTablesFns - [cl->format.bitsPerPixel / 16]) (&cl->translateLookupTable, + [BPP2OFFSET(cl->format.bitsPerPixel)]) (&cl->translateLookupTable, &(cl->screen->rfbServerFormat), &cl->format); } @@ -280,13 +364,13 @@ rfbSetClientColourMapBGR233(cl) int i, len; int r, g, b; - if (cl->format.bitsPerPixel != 8) { + if (cl->format.bitsPerPixel != 8 ) { rfbLog("%s: client not 8 bits per pixel\n", "rfbSetClientColourMapBGR233"); rfbCloseClient(cl); return FALSE; } - + scme->type = rfbSetColourMapEntries; scme->firstColour = Swap16IfLE(0); @@ -316,7 +400,9 @@ rfbSetClientColourMapBGR233(cl) return TRUE; } -#ifdef NOT_YET +/* this function is not called very often, so it needn't be + efficient. */ + /* * rfbSetClientColourMap is called to set the client's colour map. If the * client is a true colour client, we simply update our own translation table @@ -329,26 +415,22 @@ rfbSetClientColourMap(cl, firstColour, nColours) int firstColour; int nColours; { - EntryPtr pent; - int i, r, g, b; - BoxRec box; - - if (nColours == 0) { - nColours = rfbInstalledColormap->pVisual->ColormapEntries; + if (cl->screen->rfbServerFormat.trueColour || !cl->readyForSetColourMapEntries) { + return TRUE; } - if (rfbServerFormat.trueColour || !cl->readyForSetColourMapEntries) { - return TRUE; + if (nColours == 0) { + nColours = cl->screen->colourMap.count; } if (cl->format.trueColour) { (*rfbInitColourMapSingleTableFns - [cl->format.bitsPerPixel / 16]) (&cl->translateLookupTable, - &rfbServerFormat, &cl->format); + [BPP2OFFSET(cl->format.bitsPerPixel)]) (&cl->translateLookupTable, + &cl->screen->rfbServerFormat, &cl->format,&cl->screen->colourMap); sraRgnDestroy(cl->modifiedRegion); cl->modifiedRegion = - sraRgnCreateRect(0,0,rfbScreen.width,rfbScreen.height); + sraRgnCreateRect(0,0,cl->screen->width,cl->screen->height); return TRUE; } @@ -374,7 +456,6 @@ rfbSetClientColourMaps(rfbScreen, firstColour, nColours) rfbSetClientColourMap(cl, firstColour, nColours); } } -#endif static void PrintPixelFormat(pf)