From 095539cd8c13a18b86f33eec817908cb10c2efbc Mon Sep 17 00:00:00 2001
From: dscho <dscho>
Date: Tue, 2 Oct 2001 02:44:03 +0000
Subject: support for server side colour maps, fix for non-pthread, support for
 3bpp

---
 Makefile              |  17 ++++--
 README                |   6 ++-
 TODO                  |   9 ++--
 example.c             |   2 +
 main.c                |  10 +++-
 rfb.h                 |  24 +++++++--
 rfbserver.c           |  29 +++++------
 sockets.c             |   5 +-
 tableinitcmtemplate.c |  38 +++++++-------
 translate.c           | 139 +++++++++++++++++++++++++++++++++++++++-----------
 10 files changed, 199 insertions(+), 80 deletions(-)

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 <time.h>
 
 #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 <stdio.h>
 #include <stdlib.h>
 #include "rfb.h"
-#include "region.h"
+#include "sraRegion.h"
 #include <unistd.h>
 #include <pwd.h>
 #include <sys/types.h>
@@ -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(i<cm->count) {
+	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 <stdio.h>
 #include <stdlib.h>
 #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)
-- 
cgit v1.2.3

