Merge branch 'pixeltest' of https://github.com/CendioOssman/tigervnc
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bdb1824..ce0a00a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -378,18 +378,10 @@
   set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)
 endif()
 check_function_exists(inet_aton HAVE_INET_ATON)
-check_function_exists(inet_ntop HAVE_INET_NTOP)
 check_function_exists(getaddrinfo HAVE_GETADDRINFO)
-check_type_size(socklen_t SOCKLEN_T)
 set(CMAKE_EXTRA_INCLUDE_FILES) 
 set(CMAKE_REQUIRED_LIBRARIES)
 
-# Check for the newer standard string functions
-check_function_exists(snprintf HAVE_SNPRINTF)
-check_function_exists(strcasecmp HAVE_STRCASECMP)
-check_function_exists(strncasecmp HAVE_STRNCASECMP)
-check_function_exists(vsnprintf HAVE_VSNPRINTF)
-
 # Generate config.h and make sure the source finds it
 configure_file(config.h.in config.h)
 add_definitions(-DHAVE_CONFIG_H)
diff --git a/common/network/TcpSocket.cxx b/common/network/TcpSocket.cxx
index e494a11..d9e9376 100644
--- a/common/network/TcpSocket.cxx
+++ b/common/network/TcpSocket.cxx
@@ -43,7 +43,6 @@
 
 #include <stdlib.h>
 #include <network/TcpSocket.h>
-#include <os/net.h>
 #include <rfb/util.h>
 #include <rfb/LogWriter.h>
 
diff --git a/common/os/CMakeLists.txt b/common/os/CMakeLists.txt
index 39d5c10..fd3794d 100644
--- a/common/os/CMakeLists.txt
+++ b/common/os/CMakeLists.txt
@@ -1,8 +1,6 @@
 include_directories(${CMAKE_SOURCE_DIR}/common)
 
 add_library(os STATIC
-  print.c
-  net.c
   w32tiger.c
   os.cxx
   tls.cxx)
diff --git a/common/os/net.c b/common/os/net.c
deleted file mode 100644
index 7bad36c..0000000
--- a/common/os/net.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Copyright (C) 2008 TightVNC Team.  All Rights Reserved.
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#else
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#endif
-
-#include <os/net.h>
-
-
-#ifndef HAVE_INET_NTOP
-const char *tight_inet_ntop(int af, const void *src, char *dst,
-			    socklen_t size) {
-	char *tempstr;
-
-	/* Catch bugs - we should not use IPv6 if we don't have inet_ntop */
-	if (af != AF_INET)
-		abort();
-
-	/* inet_ntoa never fails */
-	tempstr = inet_ntoa(*(struct in_addr *)(src));
-	memcpy(dst, tempstr, strlen(tempstr) + 1);
-
-	return dst;
-}
-#endif
diff --git a/common/os/net.h b/common/os/net.h
deleted file mode 100644
index bd8b21c..0000000
--- a/common/os/net.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright (C) 2008 TightVNC Team.  All Rights Reserved.
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-#ifndef OS_NET_H
-#define OS_NET_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef HAVE_SOCKLEN_T
-typedef int socklen_t;
-#endif
-
-/* IPv6 support on server side - we have to have all those functions */
-#if defined(HAVE_INET_NTOP)
-#define HAVE_IPV6
-#endif
-
-/* IPv4-only stub implementation */
-#ifndef HAVE_INET_NTOP
-const char *tight_inet_ntop(int af, const void *src,
-			    char *dst, socklen_t size);
-#define inet_ntop tight_inet_ntop
-#endif
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif /* OS_NET_H */
diff --git a/common/os/print.c b/common/os/print.c
deleted file mode 100644
index 4be2203..0000000
--- a/common/os/print.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Copyright (C) 2008 TightVNC Team.  All Rights Reserved.
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <os/print.h>
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef HAVE_VSNPRINTF
-size_t internal_memcpy(char *dest, const char *src, size_t destsize,
-		       size_t srcsize) {
-	size_t copied;
-
-	copied = ((destsize) < (srcsize)) ? (destsize) : (srcsize);
-	memcpy(dest, src, copied);
-
-	return copied;
-}
-
-int tight_vsnprintf(char *str, size_t n, const char *format, va_list ap) {
-	int written = 0;
-	int tmpint, len;
-	char buf[64]; /* Is it enough? */
-	char *tmpstr;
-
-	if (format == NULL || n < 1)
-		return 0;
-
-	while (*format != '\0' && written < n - 1) {
-		if (*format != '%') {
-			if (written < n) {
-				str[written++] = *format++;
-				continue;
-			} else
-				break;
-		}
-
-		format++;
-		switch (*format) {
-			case '\0':
-				str[written++] = '%';
-				continue;
-			case 'd':
-				tmpint = va_arg(ap, int);
-				sprintf(buf, "%d", tmpint);
-				len = strlen(buf);
-				written += internal_memcpy (&str[written], buf,
-							    len, n - written);
-				break;
-			case 's':
-				tmpstr = va_arg(ap, char *);
-				len = strlen(tmpstr);
-				written += internal_memcpy (&str[written],
-							    tmpstr, len,
-							    n - written);
-				break;
-			/* Catch unimplemented stuff */
-			default:
-				fprintf(stderr, "Unimplemented format: %c\n",
-					*format);
-				abort();
-		}
-		format++;
-	}
-
-	str[written] = '\0';
-
-	return written;
-}
-#endif /* HAVE_VSNPRINTF */
-
-#ifndef HAVE_SNPRINTF
-int tight_snprintf(char *str, size_t n, const char *format, ...) {
-	va_list ap;
-	int written;
-
-	va_start(ap, format);
-	written = vsnprintf(str, n, format, ap);
-	va_end(ap);
-
-	return written;
-}
-#endif /* HAVE_SNPRINTF */
-
diff --git a/common/os/print.h b/common/os/print.h
deleted file mode 100644
index 442dd64..0000000
--- a/common/os/print.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Copyright (C) 2008 TightVNC Team.  All Rights Reserved.
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-#ifndef OS_PRINT_H
-#define OS_PRINT_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef HAVE_VSNPRINTF
-/* NOTE:
- *
- * This is only very limited implementation for our internal purposes. It
- * doesn't conform to C99/POSIX
- * - limited conversion specifiers
- * - returns written number of characters instead of number what would be
- *   written
- */
-int tight_vsnprintf(char *str, size_t n, const char *format, va_list ap);
-#define vsnprintf tight_vsnprintf
-#endif
-
-#ifndef HAVE_SNPRINTF
-/* Inherits tight_vsnprintf limitations if vsnprintf is not present */
-int tight_snprintf(char *str, size_t n, const char *format, ...);
-#define snprintf tight_snprintf
-#endif
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif /* OS_PRINT_H */
diff --git a/common/os/w32tiger.h b/common/os/w32tiger.h
index 5e0c5de..d09994f 100644
--- a/common/os/w32tiger.h
+++ b/common/os/w32tiger.h
@@ -28,6 +28,11 @@
 #include <wininet.h>
 
 
+/* Windows has different names for these */
+#define strcasecmp _stricmp
+#define strncasecmp _strnicmp
+
+
 /* MSLLHOOKSTRUCT structure*/
 #ifndef LLMHF_INJECTED
 #define LLMHF_INJECTED          0x00000001
diff --git a/common/rdr/Exception.cxx b/common/rdr/Exception.cxx
index fd40582..d70cd9f 100644
--- a/common/rdr/Exception.cxx
+++ b/common/rdr/Exception.cxx
@@ -22,6 +22,9 @@
 #include <config.h>
 #endif
 
+#include <stdio.h>
+#include <stdarg.h>
+
 #include <rdr/Exception.h>
 #include <rdr/TLSException.h>
 #ifdef _WIN32
@@ -30,8 +33,6 @@
 #include <windows.h>
 #endif
 
-#include <os/print.h>
-
 #include <string.h>
 
 #ifdef HAVE_GNUTLS
diff --git a/common/rdr/ZlibOutStream.cxx b/common/rdr/ZlibOutStream.cxx
index 260bd1a..9d9f8ba 100644
--- a/common/rdr/ZlibOutStream.cxx
+++ b/common/rdr/ZlibOutStream.cxx
@@ -17,9 +17,10 @@
  * USA.
  */
 
+#include <stdio.h>
+
 #include <rdr/ZlibOutStream.h>
 #include <rdr/Exception.h>
-#include <os/print.h>
 
 #include <zlib.h>
 
diff --git a/common/rdr/msvcwarning.h b/common/rdr/msvcwarning.h
deleted file mode 100644
index bea8d3f..0000000
--- a/common/rdr/msvcwarning.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-// Trim out extraneous cruft from windows.h includes
-#define WIN32_LEAN_AND_MEAN
-
-// Force all Windows NT-specific APIs to be visible
-#define _WIN32_WINNT 0xffff
-
-#pragma warning( disable : 4800 ) // forcing bool 'true' or 'false'
-#pragma warning( disable : 4786 ) // truncating debug information to 255 chars
\ No newline at end of file
diff --git a/common/rfb/CMakeLists.txt b/common/rfb/CMakeLists.txt
index c2df95a..9f5b59e 100644
--- a/common/rfb/CMakeLists.txt
+++ b/common/rfb/CMakeLists.txt
@@ -52,7 +52,6 @@
   SSecurityStack.cxx
   SSecurityVncAuth.cxx
   SSecurityVeNCrypt.cxx
-  ScaledPixelBuffer.cxx
   ScaleFilters.cxx
   Timer.cxx
   TightDecoder.cxx
diff --git a/common/rfb/CMsgHandler.h b/common/rfb/CMsgHandler.h
index d69d4f2..d7ffd65 100644
--- a/common/rfb/CMsgHandler.h
+++ b/common/rfb/CMsgHandler.h
@@ -71,8 +71,8 @@
     virtual void imageRect(const Rect& r, void* pixels) = 0;
     virtual void copyRect(const Rect& r, int srcX, int srcY) = 0;
 
-    virtual rdr::U8* getRawPixelsRW(const Rect& r, int* stride) = 0;
-    virtual void releaseRawPixels(const Rect& r) = 0;
+    virtual rdr::U8* getRawBufferRW(const Rect& r, int* stride) = 0;
+    virtual void releaseRawBuffer(const Rect& r) = 0;
 
     virtual const PixelFormat &getPreferredPF(void) = 0;
 
diff --git a/common/rfb/CMsgWriter.cxx b/common/rfb/CMsgWriter.cxx
index ddc25ff..9ee7a02 100644
--- a/common/rfb/CMsgWriter.cxx
+++ b/common/rfb/CMsgWriter.cxx
@@ -18,6 +18,7 @@
 #include <stdio.h>
 #include <rdr/OutStream.h>
 #include <rfb/msgTypes.h>
+#include <rfb/encodings.h>
 #include <rfb/PixelFormat.h>
 #include <rfb/Rect.h>
 #include <rfb/ConnParams.h>
@@ -113,9 +114,9 @@
     }
   }
 
-  if (cp->customCompressLevel && cp->compressLevel >= 0 && cp->compressLevel <= 9)
+  if (cp->compressLevel >= 0 && cp->compressLevel <= 9)
       encodings[nEncodings++] = pseudoEncodingCompressLevel0 + cp->compressLevel;
-  if (!cp->noJpeg && cp->qualityLevel >= 0 && cp->qualityLevel <= 9)
+  if (cp->qualityLevel >= 0 && cp->qualityLevel <= 9)
       encodings[nEncodings++] = pseudoEncodingQualityLevel0 + cp->qualityLevel;
 
   writeSetEncodings(nEncodings, encodings);
diff --git a/common/rfb/CSecurityTLS.cxx b/common/rfb/CSecurityTLS.cxx
index 59fd506..a8abeeb 100644
--- a/common/rfb/CSecurityTLS.cxx
+++ b/common/rfb/CSecurityTLS.cxx
@@ -42,7 +42,6 @@
 #include <rdr/TLSInStream.h>
 #include <rdr/TLSOutStream.h>
 #include <os/os.h>
-#include <os/print.h>
 #include <os/tls.h>
 
 #include <gnutls/x509.h>
diff --git a/common/rfb/ComparingUpdateTracker.cxx b/common/rfb/ComparingUpdateTracker.cxx
index 1c2bd38..8d4311a 100644
--- a/common/rfb/ComparingUpdateTracker.cxx
+++ b/common/rfb/ComparingUpdateTracker.cxx
@@ -53,7 +53,7 @@
     for (int y=0; y<fb->height(); y+=BLOCK_SIZE) {
       Rect pos(0, y, fb->width(), __rfbmin(fb->height(), y+BLOCK_SIZE));
       int srcStride;
-      const rdr::U8* srcData = fb->getPixelsR(pos, &srcStride);
+      const rdr::U8* srcData = fb->getBuffer(pos, &srcStride);
       oldFb.imageRect(pos, srcData, srcStride);
     }
 
@@ -106,7 +106,7 @@
 
   int bytesPerPixel = fb->getPF().bpp/8;
   int oldStride;
-  rdr::U8* oldData = oldFb.getPixelsRW(r, &oldStride);
+  rdr::U8* oldData = oldFb.getBufferRW(r, &oldStride);
   int oldStrideBytes = oldStride * bytesPerPixel;
 
   std::vector<Rect> changedBlocks;
@@ -116,7 +116,7 @@
     // Get a strip of the source buffer
     Rect pos(r.tl.x, blockTop, r.br.x, __rfbmin(r.br.y, blockTop+BLOCK_SIZE));
     int fbStride;
-    const rdr::U8* newBlockPtr = fb->getPixelsR(pos, &fbStride);
+    const rdr::U8* newBlockPtr = fb->getBuffer(pos, &fbStride);
     int newStrideBytes = fbStride * bytesPerPixel;
 
     rdr::U8* oldBlockPtr = oldData;
diff --git a/common/rfb/Configuration.cxx b/common/rfb/Configuration.cxx
index 414b18f..d700522 100644
--- a/common/rfb/Configuration.cxx
+++ b/common/rfb/Configuration.cxx
@@ -22,10 +22,6 @@
 #include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
-#ifdef WIN32
-#define strcasecmp _stricmp
-#define strncasecmp _strnicmp
-#endif
 
 #include <rfb/util.h>
 #include <rfb/Configuration.h>
diff --git a/common/rfb/ConnParams.cxx b/common/rfb/ConnParams.cxx
index ed74752..6fd6668 100644
--- a/common/rfb/ConnParams.cxx
+++ b/common/rfb/ConnParams.cxx
@@ -1,5 +1,6 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
  * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
+ * Copyright 2014 Pierre Ossman for Cendio AB
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -35,10 +36,8 @@
     supportsDesktopRename(false), supportsLastRect(false),
     supportsSetDesktopSize(false), supportsFence(false),
     supportsContinuousUpdates(false),
-    customCompressLevel(false), compressLevel(2),
-    noJpeg(false), qualityLevel(-1), fineQualityLevel(-1),
-    subsampling(SUBSAMP_UNDEFINED),
-    name_(0), nEncodings_(0), encodings_(0),
+    compressLevel(2), qualityLevel(-1), fineQualityLevel(-1),
+    subsampling(subsampleUndefined), name_(0),
     currentEncoding_(encodingRaw), verStrPos(0)
 {
   setName("");
@@ -47,7 +46,6 @@
 ConnParams::~ConnParams()
 {
   delete [] name_;
-  delete [] encodings_;
 }
 
 bool ConnParams::readVersion(rdr::InStream* is, bool* done)
@@ -90,69 +88,80 @@
 
 void ConnParams::setEncodings(int nEncodings, const rdr::S32* encodings)
 {
-  if (nEncodings > nEncodings_) {
-    delete [] encodings_;
-    encodings_ = new rdr::S32[nEncodings];
-  }
-  nEncodings_ = nEncodings;
   useCopyRect = false;
   supportsLocalCursor = false;
   supportsDesktopResize = false;
   supportsExtendedDesktopSize = false;
   supportsLocalXCursor = false;
   supportsLastRect = false;
-  customCompressLevel = false;
   compressLevel = -1;
-  noJpeg = true;
   qualityLevel = -1;
   fineQualityLevel = -1;
-  subsampling = SUBSAMP_UNDEFINED;
+  subsampling = subsampleUndefined;
   currentEncoding_ = encodingRaw;
 
   for (int i = nEncodings-1; i >= 0; i--) {
-    encodings_[i] = encodings[i];
-
-    if (encodings[i] == encodingCopyRect)
+    switch (encodings[i]) {
+    case encodingCopyRect:
       useCopyRect = true;
-    else if (encodings[i] == pseudoEncodingCursor)
+      break;
+    case pseudoEncodingCursor:
       supportsLocalCursor = true;
-    else if (encodings[i] == pseudoEncodingXCursor)
+      break;
+    case pseudoEncodingXCursor:
       supportsLocalXCursor = true;
-    else if (encodings[i] == pseudoEncodingDesktopSize)
+      break;
+    case pseudoEncodingDesktopSize:
       supportsDesktopResize = true;
-    else if (encodings[i] == pseudoEncodingExtendedDesktopSize)
+      break;
+    case pseudoEncodingExtendedDesktopSize:
       supportsExtendedDesktopSize = true;
-    else if (encodings[i] == pseudoEncodingDesktopName)
+      break;
+    case pseudoEncodingDesktopName:
       supportsDesktopRename = true;
-    else if (encodings[i] == pseudoEncodingLastRect)
+      break;
+    case pseudoEncodingLastRect:
       supportsLastRect = true;
-    else if (encodings[i] == pseudoEncodingFence)
+      break;
+    case pseudoEncodingFence:
       supportsFence = true;
-    else if (encodings[i] == pseudoEncodingContinuousUpdates)
+      break;
+    case pseudoEncodingContinuousUpdates:
       supportsContinuousUpdates = true;
-    else if (encodings[i] >= pseudoEncodingCompressLevel0 &&
-	     encodings[i] <= pseudoEncodingCompressLevel9) {
-      customCompressLevel = true;
-      compressLevel = encodings[i] - pseudoEncodingCompressLevel0;
-    } else if (encodings[i] >= pseudoEncodingQualityLevel0 &&
-	       encodings[i] <= pseudoEncodingQualityLevel9) {
-      noJpeg = false;
-      qualityLevel = encodings[i] - pseudoEncodingQualityLevel0;
-    } else if (Encoder::supported(encodings[i]))
-      currentEncoding_ = encodings[i];
-  }
-
-  // If the TurboVNC fine quality/subsampling encodings exist, let them
-  // override the coarse TightVNC quality level
-  for (int i = nEncodings-1; i >= 0; i--) {
-    if (encodings[i] >= pseudoEncodingFineQualityLevel0 + 1 &&
-        encodings[i] <= pseudoEncodingFineQualityLevel100) {
-      noJpeg = false;
-      fineQualityLevel = encodings[i] - pseudoEncodingFineQualityLevel0;
-    } else if (encodings[i] >= pseudoEncodingSubsamp1X &&
-               encodings[i] <= pseudoEncodingSubsampGray) {
-      noJpeg = false;
-      subsampling = (JPEG_SUBSAMP)(encodings[i] - pseudoEncodingSubsamp1X);
+      break;
+    case pseudoEncodingSubsamp1X:
+      subsampling = subsampleNone;
+      break;
+    case pseudoEncodingSubsampGray:
+      subsampling = subsampleGray;
+      break;
+    case pseudoEncodingSubsamp2X:
+      subsampling = subsample2X;
+      break;
+    case pseudoEncodingSubsamp4X:
+      subsampling = subsample4X;
+      break;
+    case pseudoEncodingSubsamp8X:
+      subsampling = subsample8X;
+      break;
+    case pseudoEncodingSubsamp16X:
+      subsampling = subsample16X;
+      break;
     }
+
+    if (encodings[i] >= pseudoEncodingCompressLevel0 &&
+        encodings[i] <= pseudoEncodingCompressLevel9)
+      compressLevel = encodings[i] - pseudoEncodingCompressLevel0;
+
+    if (encodings[i] >= pseudoEncodingQualityLevel0 &&
+        encodings[i] <= pseudoEncodingQualityLevel9)
+      qualityLevel = encodings[i] - pseudoEncodingQualityLevel0;
+
+    if (encodings[i] >= pseudoEncodingFineQualityLevel0 &&
+        encodings[i] <= pseudoEncodingFineQualityLevel100)
+      fineQualityLevel = encodings[i] - pseudoEncodingFineQualityLevel0;
+
+    if (Encoder::supported(encodings[i]))
+      currentEncoding_ = encodings[i];
   }
 }
diff --git a/common/rfb/ConnParams.h b/common/rfb/ConnParams.h
index fa0fe02..43267ff 100644
--- a/common/rfb/ConnParams.h
+++ b/common/rfb/ConnParams.h
@@ -1,4 +1,5 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * Copyright 2014 Pierre Ossman for Cendio AB
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,12 +26,19 @@
 #include <rdr/types.h>
 #include <rfb/PixelFormat.h>
 #include <rfb/ScreenSet.h>
-#include <rfb/JpegCompressor.h>
 
 namespace rdr { class InStream; }
 
 namespace rfb {
 
+  const int subsampleUndefined = -1;
+  const int subsampleNone = 0;
+  const int subsampleGray = 1;
+  const int subsample2X = 2;
+  const int subsample4X = 3;
+  const int subsample8X = 4;
+  const int subsample16X = 5;
+
   class ConnParams {
   public:
     ConnParams();
@@ -67,9 +75,9 @@
     void setName(const char* name);
 
     rdr::S32 currentEncoding() { return currentEncoding_; }
-    int nEncodings() { return nEncodings_; }
-    const rdr::S32* encodings() { return encodings_; }
+
     void setEncodings(int nEncodings, const rdr::S32* encodings);
+
     bool useCopyRect;
 
     bool supportsLocalCursor;
@@ -83,19 +91,15 @@
     bool supportsFence;
     bool supportsContinuousUpdates;
 
-    bool customCompressLevel;
     int compressLevel;
-    bool noJpeg;
     int qualityLevel;
     int fineQualityLevel;
-    JPEG_SUBSAMP subsampling;
+    int subsampling;
 
   private:
 
     PixelFormat pf_;
     char* name_;
-    int nEncodings_;
-    rdr::S32* encodings_;
     int currentEncoding_;
     char verStr[13];
     int verStrPos;
diff --git a/common/rfb/Decoder.cxx b/common/rfb/Decoder.cxx
index 193b61c..e201821 100644
--- a/common/rfb/Decoder.cxx
+++ b/common/rfb/Decoder.cxx
@@ -1,4 +1,5 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * Copyright 2014 Pierre Ossman for Cendio AB
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,7 +17,7 @@
  * USA.
  */
 #include <stdio.h>
-#include <rfb/Exception.h>
+#include <rfb/encodings.h>
 #include <rfb/Decoder.h>
 #include <rfb/RawDecoder.h>
 #include <rfb/RREDecoder.h>
@@ -30,41 +31,34 @@
 {
 }
 
-DecoderCreateFnType Decoder::createFns[encodingMax+1] = { 0 };
-
 bool Decoder::supported(int encoding)
 {
-  return encoding >= 0 && encoding <= encodingMax && createFns[encoding];
+  switch (encoding) {
+  case encodingRaw:
+  case encodingRRE:
+  case encodingHextile:
+  case encodingZRLE:
+  case encodingTight:
+    return true;
+  default:
+    return false;
+  }
 }
 
 Decoder* Decoder::createDecoder(int encoding, CMsgReader* reader)
 {
-  if (supported(encoding))
-    return (*createFns[encoding])(reader);
-  return 0;
-}
-
-void Decoder::registerDecoder(int encoding,
-                              DecoderCreateFnType createFn)
-{
-  if (encoding > encodingMax)
-    throw Exception("Decoder::registerDecoder: encoding out of range");
-
-  if (createFns[encoding])
-    fprintf(stderr,"Replacing existing decoder for encoding %s (%d)\n",
-            encodingName(encoding), encoding);
-  createFns[encoding] = createFn;
-}
-
-int DecoderInit::count = 0;
-
-DecoderInit::DecoderInit()
-{
-  if (count++ != 0) return;
-
-  Decoder::registerDecoder(encodingRaw, RawDecoder::create);
-  Decoder::registerDecoder(encodingRRE, RREDecoder::create);
-  Decoder::registerDecoder(encodingHextile, HextileDecoder::create);
-  Decoder::registerDecoder(encodingZRLE, ZRLEDecoder::create);
-  Decoder::registerDecoder(encodingTight, TightDecoder::create);
+  switch (encoding) {
+  case encodingRaw:
+    return new RawDecoder(reader);
+  case encodingRRE:
+    return new RREDecoder(reader);
+  case encodingHextile:
+    return new HextileDecoder(reader);
+  case encodingZRLE:
+    return new ZRLEDecoder(reader);
+  case encodingTight:
+    return new TightDecoder(reader);
+  default:
+    return NULL;
+  }
 }
diff --git a/common/rfb/Decoder.h b/common/rfb/Decoder.h
index 50aee82..025d63f 100644
--- a/common/rfb/Decoder.h
+++ b/common/rfb/Decoder.h
@@ -1,4 +1,5 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * Copyright 2014 Pierre Ossman for Cendio AB
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,13 +20,10 @@
 #define __RFB_DECODER_H__
 
 #include <rfb/Rect.h>
-#include <rfb/encodings.h>
 
 namespace rfb {
   class CMsgReader;
   class CMsgHandler;
-  class Decoder;
-  typedef Decoder* (*DecoderCreateFnType)(CMsgReader*);
 
   class Decoder {
   public:
@@ -34,19 +32,7 @@
 
     static bool supported(int encoding);
     static Decoder* createDecoder(int encoding, CMsgReader* reader);
-    static void registerDecoder(int encoding,
-                                DecoderCreateFnType createFn);
-  private:
-    static DecoderCreateFnType createFns[encodingMax+1];
   };
-
-  class DecoderInit {
-    static int count;
-  public:
-    DecoderInit();
-  };
-
-  static DecoderInit decoderInitObj;
 }
 
 #endif
diff --git a/common/rfb/Encoder.cxx b/common/rfb/Encoder.cxx
index 5de7543..1733c8e 100644
--- a/common/rfb/Encoder.cxx
+++ b/common/rfb/Encoder.cxx
@@ -1,4 +1,5 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * Copyright 2014 Pierre Ossman for Cendio AB
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,6 +17,7 @@
  * USA.
  */
 #include <stdio.h>
+#include <rfb/encodings.h>
 #include <rfb/Exception.h>
 #include <rfb/Encoder.h>
 #include <rfb/RawEncoder.h>
@@ -30,48 +32,34 @@
 {
 }
 
-EncoderCreateFnType Encoder::createFns[encodingMax+1] = { 0 };
-
 bool Encoder::supported(int encoding)
 {
-  return encoding >= 0 && encoding <= encodingMax && createFns[encoding];
+  switch (encoding) {
+  case encodingRaw:
+  case encodingRRE:
+  case encodingHextile:
+  case encodingZRLE:
+  case encodingTight:
+    return true;
+  default:
+    return false;
+  }
 }
 
 Encoder* Encoder::createEncoder(int encoding, SMsgWriter* writer)
 {
-  if (supported(encoding))
-    return (*createFns[encoding])(writer);
-  return 0;
-}
-
-void Encoder::registerEncoder(int encoding,
-                              EncoderCreateFnType createFn)
-{
-  if (encoding > encodingMax)
-    throw Exception("Encoder::registerEncoder: encoding out of range");
-
-  if (createFns[encoding])
-    fprintf(stderr,"Replacing existing encoder for encoding %s (%d)\n",
-            encodingName(encoding), encoding);
-  createFns[encoding] = createFn;
-}
-
-void Encoder::unregisterEncoder(int encoding)
-{
-  if (encoding > encodingMax)
-    throw Exception("Encoder::unregisterEncoder: encoding out of range");
-  createFns[encoding] = 0;
-}
-
-int EncoderInit::count = 0;
-
-EncoderInit::EncoderInit()
-{
-  if (count++ != 0) return;
-
-  Encoder::registerEncoder(encodingRaw, RawEncoder::create);
-  Encoder::registerEncoder(encodingRRE, RREEncoder::create);
-  Encoder::registerEncoder(encodingHextile, HextileEncoder::create);
-  Encoder::registerEncoder(encodingZRLE, ZRLEEncoder::create);
-  Encoder::registerEncoder(encodingTight, TightEncoder::create);
+  switch (encoding) {
+  case encodingRaw:
+    return new RawEncoder(writer);
+  case encodingRRE:
+    return new RREEncoder(writer);
+  case encodingHextile:
+    return new HextileEncoder(writer);
+  case encodingZRLE:
+    return new ZRLEEncoder(writer);
+  case encodingTight:
+    return new TightEncoder(writer);
+  default:
+    return NULL;
+  }
 }
diff --git a/common/rfb/Encoder.h b/common/rfb/Encoder.h
index da2c5c0..26d5796 100644
--- a/common/rfb/Encoder.h
+++ b/common/rfb/Encoder.h
@@ -1,5 +1,6 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
  * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
+ * Copyright 2014 Pierre Ossman for Cendio AB
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,15 +21,11 @@
 #define __RFB_ENCODER_H__
 
 #include <rfb/Rect.h>
-#include <rfb/encodings.h>
 #include <rfb/TransImageGetter.h>
-#include <rfb/JpegCompressor.h>
 
 namespace rfb {
   class SMsgWriter;
-  class Encoder;
-  class ImageGetter;
-  typedef Encoder* (*EncoderCreateFnType)(SMsgWriter*);
+  class TransImageGetter;
 
   class Encoder {
   public:
@@ -36,7 +33,7 @@
 
     virtual void setCompressLevel(int level) {};
     virtual void setQualityLevel(int level) {};
-    virtual void setFineQualityLevel(int quality, JPEG_SUBSAMP subsampling) {};
+    virtual void setFineQualityLevel(int quality, int subsampling) {};
     virtual int getNumRects(const Rect &r) { return 1; }
 
     // writeRect() tries to write the given rectangle.  If it is unable to
@@ -47,20 +44,7 @@
 
     static bool supported(int encoding);
     static Encoder* createEncoder(int encoding, SMsgWriter* writer);
-    static void registerEncoder(int encoding,
-                                EncoderCreateFnType createFn);
-    static void unregisterEncoder(int encoding);
-  private:
-    static EncoderCreateFnType createFns[encodingMax+1];
   };
-
-  class EncoderInit {
-    static int count;
-  public:
-    EncoderInit();
-  };
-
-  static EncoderInit encoderInitObj;
 }
 
 #endif
diff --git a/common/rfb/HTTPServer.cxx b/common/rfb/HTTPServer.cxx
index 94f0609..f50722a 100644
--- a/common/rfb/HTTPServer.cxx
+++ b/common/rfb/HTTPServer.cxx
@@ -21,10 +21,6 @@
 #include <rfb/util.h>
 #include <rdr/MemOutStream.h>
 
-#ifdef WIN32
-#define strcasecmp _stricmp
-#endif
-
 
 using namespace rfb;
 using namespace rdr;
diff --git a/common/rfb/HextileDecoder.cxx b/common/rfb/HextileDecoder.cxx
index e817c73..ae61267 100644
--- a/common/rfb/HextileDecoder.cxx
+++ b/common/rfb/HextileDecoder.cxx
@@ -34,11 +34,6 @@
 #include <rfb/hextileDecode.h>
 #undef BPP
 
-Decoder* HextileDecoder::create(CMsgReader* reader)
-{
-  return new HextileDecoder(reader);
-}
-
 HextileDecoder::HextileDecoder(CMsgReader* reader_) : reader(reader_)
 {
 }
diff --git a/common/rfb/HextileDecoder.h b/common/rfb/HextileDecoder.h
index e7dd3d5..95a7f8a 100644
--- a/common/rfb/HextileDecoder.h
+++ b/common/rfb/HextileDecoder.h
@@ -24,11 +24,10 @@
 
   class HextileDecoder : public Decoder {
   public:
-    static Decoder* create(CMsgReader* reader);
-    virtual void readRect(const Rect& r, CMsgHandler* handler);
-    virtual ~HextileDecoder();
-  private:
     HextileDecoder(CMsgReader* reader);
+    virtual ~HextileDecoder();
+    virtual void readRect(const Rect& r, CMsgHandler* handler);
+  private:
     CMsgReader* reader;
   };
 }
diff --git a/common/rfb/HextileEncoder.cxx b/common/rfb/HextileEncoder.cxx
index 73f1f57..0907bab 100644
--- a/common/rfb/HextileEncoder.cxx
+++ b/common/rfb/HextileEncoder.cxx
@@ -16,7 +16,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
  * USA.
  */
-#include <rfb/ImageGetter.h>
+#include <rfb/TransImageGetter.h>
 #include <rfb/encodings.h>
 #include <rfb/SMsgWriter.h>
 #include <rfb/HextileEncoder.h>
@@ -45,11 +45,6 @@
 #include <rfb/hextileEncodeBetter.h>
 #undef BPP
 
-Encoder* HextileEncoder::create(SMsgWriter* writer)
-{
-  return new HextileEncoder(writer);
-}
-
 HextileEncoder::HextileEncoder(SMsgWriter* writer_) : writer(writer_)
 {
 }
diff --git a/common/rfb/HextileEncoder.h b/common/rfb/HextileEncoder.h
index 6b89643..0c475a8 100644
--- a/common/rfb/HextileEncoder.h
+++ b/common/rfb/HextileEncoder.h
@@ -24,11 +24,10 @@
 
   class HextileEncoder : public Encoder {
   public:
-    static Encoder* create(SMsgWriter* writer);
-    virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual);
-    virtual ~HextileEncoder();
-  private:
     HextileEncoder(SMsgWriter* writer);
+    virtual ~HextileEncoder();
+    virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual);
+  private:
     SMsgWriter* writer;
   };
 }
diff --git a/common/rfb/JpegCompressor.cxx b/common/rfb/JpegCompressor.cxx
index b3c5f7c..c19af34 100644
--- a/common/rfb/JpegCompressor.cxx
+++ b/common/rfb/JpegCompressor.cxx
@@ -1,5 +1,6 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
  * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
+ * Copyright 2014 Pierre Ossman for Cendio AB
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,7 +22,7 @@
 #include <rdr/Exception.h>
 #include <rfb/Rect.h>
 #include <rfb/PixelFormat.h>
-#include <os/print.h>
+#include <rfb/ConnParams.h>
 
 #include <stdio.h>
 extern "C" {
@@ -32,6 +33,15 @@
 using namespace rfb;
 
 //
+// Special formats that libjpeg can have optimised code paths for
+//
+
+static const PixelFormat pfRGBX(32, 24, false, true, 255, 255, 255, 0, 8, 16);
+static const PixelFormat pfBGRX(32, 24, false, true, 255, 255, 255, 16, 8, 0);
+static const PixelFormat pfXRGB(32, 24, false, true, 255, 255, 255, 8, 16, 24);
+static const PixelFormat pfXBGR(32, 24, false, true, 255, 255, 255, 24, 16, 8);
+
+//
 // Error manager implmentation for the JPEG library
 //
 
@@ -141,8 +151,8 @@
   delete cinfo;
 }
 
-void JpegCompressor::compress(const rdr::U8 *buf, int pitch, const Rect& r,
-  const PixelFormat& pf, int quality, JPEG_SUBSAMP subsamp)
+void JpegCompressor::compress(const rdr::U8 *buf, int stride, const Rect& r,
+  const PixelFormat& pf, int quality, int subsamp)
 {
   int w = r.width();
   int h = r.height();
@@ -165,62 +175,58 @@
   pixelsize = 3;
 
 #ifdef JCS_EXTENSIONS
-  // Try to have libjpeg read directly from our native format
-  if(pf.is888()) {
-    int redShift, greenShift, blueShift;
+  // Try to have libjpeg output directly to our native format
+  // libjpeg can only handle some "standard" formats
+  if (pfRGBX.equal(pf))
+    cinfo->in_color_space = JCS_EXT_RGBX;
+  else if (pfBGRX.equal(pf))
+    cinfo->in_color_space = JCS_EXT_BGRX;
+  else if (pfXRGB.equal(pf))
+    cinfo->in_color_space = JCS_EXT_XRGB;
+  else if (pfXBGR.equal(pf))
+    cinfo->in_color_space = JCS_EXT_XBGR;
 
-    if(pf.bigEndian) {
-      redShift = 24 - pf.redShift;
-      greenShift = 24 - pf.greenShift;
-      blueShift = 24 - pf.blueShift;
-    } else {
-      redShift = pf.redShift;
-      greenShift = pf.greenShift;
-      blueShift = pf.blueShift;
-    }
-
-    if(redShift == 0 && greenShift == 8 && blueShift == 16)
-      cinfo->in_color_space = JCS_EXT_RGBX;
-    if(redShift == 16 && greenShift == 8 && blueShift == 0)
-      cinfo->in_color_space = JCS_EXT_BGRX;
-    if(redShift == 24 && greenShift == 16 && blueShift == 8)
-      cinfo->in_color_space = JCS_EXT_XBGR;
-    if(redShift == 8 && greenShift == 16 && blueShift == 24)
-      cinfo->in_color_space = JCS_EXT_XRGB;
-
-    if (cinfo->in_color_space != JCS_RGB) {
-      srcBuf = (rdr::U8 *)buf;
-      pixelsize = 4;
-    }
+  if (cinfo->in_color_space != JCS_RGB) {
+    srcBuf = (rdr::U8 *)buf;
+    pixelsize = 4;
   }
 #endif
 
-  if (pitch == 0) pitch = w * pf.bpp / 8;
+  if (stride == 0)
+    stride = w;
 
   if (cinfo->in_color_space == JCS_RGB) {
     srcBuf = new rdr::U8[w * h * pixelsize];
     srcBufIsTemp = true;
-    pf.rgbFromBuffer(srcBuf, (const rdr::U8 *)buf, w, pitch, h);
-    pitch = w * pixelsize;
+    pf.rgbFromBuffer(srcBuf, (const rdr::U8 *)buf, w, stride, h);
+    stride = w;
   }
 
   cinfo->input_components = pixelsize;
 
   jpeg_set_defaults(cinfo);
-  jpeg_set_quality(cinfo, quality, TRUE);
-  if(quality >= 96) cinfo->dct_method = JDCT_ISLOW;
-  else cinfo->dct_method = JDCT_FASTEST;
+
+  if (quality >= 1 && quality <= 100) {
+    jpeg_set_quality(cinfo, quality, TRUE);
+    if (quality >= 96)
+      cinfo->dct_method = JDCT_ISLOW;
+    else
+      cinfo->dct_method = JDCT_FASTEST;
+  }
 
   switch (subsamp) {
-  case SUBSAMP_420:
+  case subsample16X:
+  case subsample8X:
+    // FIXME (fall through)
+  case subsample4X:
     cinfo->comp_info[0].h_samp_factor = 2;
     cinfo->comp_info[0].v_samp_factor = 2;
     break;
-  case SUBSAMP_422:
+  case subsample2X:
     cinfo->comp_info[0].h_samp_factor = 2;
     cinfo->comp_info[0].v_samp_factor = 1;
     break;
-  case SUBSAMP_GRAY:
+  case subsampleGray:
     jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
   default:
     cinfo->comp_info[0].h_samp_factor = 1;
@@ -229,7 +235,7 @@
 
   rowPointer = new JSAMPROW[h];
   for (int dy = 0; dy < h; dy++)
-    rowPointer[dy] = (JSAMPROW)(&srcBuf[dy * pitch]);
+    rowPointer[dy] = (JSAMPROW)(&srcBuf[dy * stride * pixelsize]);
 
   jpeg_start_compress(cinfo, TRUE);
   while (cinfo->next_scanline < cinfo->image_height)
diff --git a/common/rfb/JpegCompressor.h b/common/rfb/JpegCompressor.h
index d50e587..8fbb7a9 100644
--- a/common/rfb/JpegCompressor.h
+++ b/common/rfb/JpegCompressor.h
@@ -36,14 +36,6 @@
 
 namespace rfb {
 
-  enum JPEG_SUBSAMP {
-    SUBSAMP_UNDEFINED = -1,
-    SUBSAMP_NONE = 0,
-    SUBSAMP_420,
-    SUBSAMP_422,
-    SUBSAMP_GRAY
-  };
-
   class JpegCompressor : public rdr::MemOutStream {
 
   public:
@@ -51,8 +43,7 @@
     JpegCompressor(int bufferLen = 128*1024);
     virtual ~JpegCompressor();
 
-    void compress(const rdr::U8 *, int, const Rect&, const PixelFormat&, int,
-      JPEG_SUBSAMP);
+    void compress(const rdr::U8 *, int, const Rect&, const PixelFormat&, int, int);
 
     void writeBytes(const void*, int);
 
diff --git a/common/rfb/JpegDecompressor.cxx b/common/rfb/JpegDecompressor.cxx
index 503c030..ca1ad22 100644
--- a/common/rfb/JpegDecompressor.cxx
+++ b/common/rfb/JpegDecompressor.cxx
@@ -1,6 +1,7 @@
 /* Copyright (C) 2000-2003 Constantin Kaplinsky.  All Rights Reserved.
  * Copyright (C) 2004-2005 Cendio AB. All rights reserved.
  * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
+ * Copyright 2014 Pierre Ossman for Cendio AB
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,7 +23,6 @@
 #include <rdr/Exception.h>
 #include <rfb/Rect.h>
 #include <rfb/PixelFormat.h>
-#include <os/print.h>
 
 #include <stdio.h>
 extern "C" {
@@ -33,6 +33,14 @@
 
 using namespace rfb;
 
+//
+// Special formats that libjpeg can have optimised code paths for
+//
+
+static const PixelFormat pfRGBX(32, 24, false, true, 255, 255, 255, 0, 8, 16);
+static const PixelFormat pfBGRX(32, 24, false, true, 255, 255, 255, 16, 8, 0);
+static const PixelFormat pfXRGB(32, 24, false, true, 255, 255, 255, 8, 16, 24);
+static const PixelFormat pfXBGR(32, 24, false, true, 255, 255, 255, 24, 16, 8);
 
 //
 // Error manager implmentation for the JPEG library
@@ -139,12 +147,12 @@
 }
 
 void JpegDecompressor::decompress(const rdr::U8 *jpegBuf, int jpegBufLen,
-  rdr::U8 *buf, int pitch, const Rect& r, const PixelFormat& pf)
+  rdr::U8 *buf, int stride, const Rect& r, const PixelFormat& pf)
 {
   int w = r.width();
   int h = r.height();
   int pixelsize;
-  int dstBufPitch;
+  int dstBufStride;
   rdr::U8 *dstBuf = NULL;
   bool dstBufIsTemp = false;
   JSAMPROW *rowPointer = NULL;
@@ -163,50 +171,37 @@
   jpeg_read_header(dinfo, TRUE);
   dinfo->out_color_space = JCS_RGB;
   pixelsize = 3;
-  if (pitch == 0) pitch = w * pf.bpp / 8;
-  dstBufPitch = pitch;
+  if (stride == 0)
+    stride = w;
+  dstBufStride = stride;
 
 #ifdef JCS_EXTENSIONS
   // Try to have libjpeg output directly to our native format
-  if (pf.is888()) {
-    int redShift, greenShift, blueShift;
+  // libjpeg can only handle some "standard" formats
+  if (pfRGBX.equal(pf))
+    dinfo->out_color_space = JCS_EXT_RGBX;
+  else if (pfBGRX.equal(pf))
+    dinfo->out_color_space = JCS_EXT_BGRX;
+  else if (pfXRGB.equal(pf))
+    dinfo->out_color_space = JCS_EXT_XRGB;
+  else if (pfXBGR.equal(pf))
+    dinfo->out_color_space = JCS_EXT_XBGR;
 
-    if(pf.bigEndian) {
-      redShift = 24 - pf.redShift;
-      greenShift = 24 - pf.greenShift;
-      blueShift = 24 - pf.blueShift;
-    } else {
-      redShift = pf.redShift;
-      greenShift = pf.greenShift;
-      blueShift = pf.blueShift;
-    }
-
-    // libjpeg can only handle some "standard" formats
-    if(redShift == 0 && greenShift == 8 && blueShift == 16)
-      dinfo->out_color_space = JCS_EXT_RGBX;
-    if(redShift == 16 && greenShift == 8 && blueShift == 0)
-      dinfo->out_color_space = JCS_EXT_BGRX;
-    if(redShift == 24 && greenShift == 16 && blueShift == 8)
-      dinfo->out_color_space = JCS_EXT_XBGR;
-    if(redShift == 8 && greenShift == 16 && blueShift == 24)
-      dinfo->out_color_space = JCS_EXT_XRGB;
-
-    if (dinfo->out_color_space != JCS_RGB) {
-      dstBuf = (rdr::U8 *)buf;
-      pixelsize = 4;
-    }
+  if (dinfo->out_color_space != JCS_RGB) {
+    dstBuf = (rdr::U8 *)buf;
+    pixelsize = 4;
   }
 #endif
 
   if (dinfo->out_color_space == JCS_RGB) {
     dstBuf = new rdr::U8[w * h * pixelsize];
     dstBufIsTemp = true;
-    dstBufPitch = w * pixelsize;
+    dstBufStride = w;
   }
 
   rowPointer = new JSAMPROW[h];
   for (int dy = 0; dy < h; dy++)
-    rowPointer[dy] = (JSAMPROW)(&dstBuf[dy * dstBufPitch]);
+    rowPointer[dy] = (JSAMPROW)(&dstBuf[dy * dstBufStride * pixelsize]);
 
   jpeg_start_decompress(dinfo);
 
@@ -225,7 +220,7 @@
   }
 
   if (dinfo->out_color_space == JCS_RGB)
-    pf.bufferFromRGB((rdr::U8*)buf, dstBuf, w, pitch, h);
+    pf.bufferFromRGB((rdr::U8*)buf, dstBuf, w, stride, h);
 
   jpeg_finish_decompress(dinfo);
 
diff --git a/common/rfb/LogWriter.cxx b/common/rfb/LogWriter.cxx
index c6461d1..37a9d1c 100644
--- a/common/rfb/LogWriter.cxx
+++ b/common/rfb/LogWriter.cxx
@@ -19,9 +19,6 @@
 // -=- LogWriter.cxx - client-side logging interface
 
 #include <string.h>
-#ifdef WIN32
-#define strcasecmp _stricmp
-#endif
 
 #include <rfb/LogWriter.h>
 #include <rfb/Configuration.h>
diff --git a/common/rfb/Logger.cxx b/common/rfb/Logger.cxx
index 451cee2..3daf248 100644
--- a/common/rfb/Logger.cxx
+++ b/common/rfb/Logger.cxx
@@ -21,11 +21,7 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
-#ifdef WIN32
-#define strcasecmp _stricmp
-#endif
 
-#include <os/print.h>
 #include <rfb/Logger.h>
 #include <rfb/LogWriter.h>
 #include <rfb/util.h>
diff --git a/common/rfb/PixelBuffer.cxx b/common/rfb/PixelBuffer.cxx
index 60957a2..9d151b9 100644
--- a/common/rfb/PixelBuffer.cxx
+++ b/common/rfb/PixelBuffer.cxx
@@ -48,7 +48,7 @@
 void
 PixelBuffer::getImage(void* imageBuf, const Rect& r, int outStride) {
   int inStride;
-  const U8* data = getPixelsR(r, &inStride);
+  const U8* data = getBuffer(r, &inStride);
   // We assume that the specified rectangle is pre-clipped to the buffer
   int bytesPerPixel = format.bpp/8;
   int inBytesPerRow = inStride * bytesPerPixel;
@@ -64,19 +64,6 @@
   }
 }
 
-/* ***
-Pixel PixelBuffer::getPixel(const Point& p) {
-  int stride;
-  Rect r = Rect(p.x, p.y, p.x+1, p.y+1);
-  switch(format.bpp) {
-  case 8: return *((rdr::U8*)getDataAt(r, &stride));
-  case 16: return *((rdr::U16*)getDataAt(r, &stride));
-  case 32: return *((rdr::U32*)getDataAt(r, &stride));
-  default: return 0;
-  };
-}
-*/
-
 
 static void fillRect8(U8 *buf, int stride, const Rect& r, Pixel pix)
 {
@@ -167,7 +154,7 @@
 
 int FullFramePixelBuffer::getStride() const { return width(); }
 
-rdr::U8* FullFramePixelBuffer::getPixelsRW(const Rect& r, int* stride)
+rdr::U8* FullFramePixelBuffer::getBufferRW(const Rect& r, int* stride)
 {
   *stride = getStride();
   return &data[(r.tl.x + (r.tl.y * *stride)) * format.bpp/8];
@@ -176,14 +163,14 @@
 
 void FullFramePixelBuffer::fillRect(const Rect& r, Pixel pix) {
   int stride;
-  U8 *buf = getPixelsRW(r, &stride);
+  U8 *buf = getBufferRW(r, &stride);
   fillRectFn(buf, stride, r, pix);
 }
 
 void FullFramePixelBuffer::imageRect(const Rect& r, const void* pixels, int srcStride) {
   int bytesPerPixel = getPF().bpp/8;
   int destStride;
-  U8* dest = getPixelsRW(r, &destStride);
+  U8* dest = getBufferRW(r, &destStride);
   int bytesPerDestRow = bytesPerPixel * destStride;
   if (!srcStride) srcStride = r.width();
   int bytesPerSrcRow = bytesPerPixel * srcStride;
@@ -201,7 +188,7 @@
   Rect cr = getRect().intersect(r);
   if (cr.is_empty()) return;
   int stride;
-  U8* data = getPixelsRW(cr, &stride);
+  U8* data = getBufferRW(cr, &stride);
   U8* mask = (U8*) mask_;
   int w = cr.width();
   int h = cr.height();
@@ -239,7 +226,7 @@
   Rect cr = getRect().intersect(r);
   if (cr.is_empty()) return;
   int stride;
-  U8* data = getPixelsRW(cr, &stride);
+  U8* data = getBufferRW(cr, &stride);
   U8* mask = (U8*) mask_;
   int w = cr.width();
   int h = cr.height();
@@ -299,7 +286,7 @@
   if (srect.is_empty())
     return;
 
-  data = getPixelsRW(getRect(), &stride);
+  data = getBufferRW(getRect(), &stride);
   bytesPerPixel = getPF().bpp/8;
   bytesPerRow = stride * bytesPerPixel;
   bytesPerMemCpy = drect.width() * bytesPerPixel;
diff --git a/common/rfb/PixelBuffer.h b/common/rfb/PixelBuffer.h
index e870622..5c4f966 100644
--- a/common/rfb/PixelBuffer.h
+++ b/common/rfb/PixelBuffer.h
@@ -70,18 +70,14 @@
     // Get a pointer into the buffer
     //   The pointer is to the top-left pixel of the specified Rect.
     //   The buffer stride (in pixels) is returned.
-    virtual const rdr::U8* getPixelsR(const Rect& r, int* stride) = 0;
-    virtual rdr::U8* getPixelsRW(const Rect& r, int* stride) = 0;
+    virtual const rdr::U8* getBuffer(const Rect& r, int* stride) = 0;
+    virtual rdr::U8* getBufferRW(const Rect& r, int* stride) = 0;
 
     // Get pixel data for a given part of the buffer
     //   Data is copied into the supplied buffer, with the specified
     //   stride.
     virtual void getImage(void* imageBuf, const Rect& r, int stride=0);
 
-    // Get the data at (x,y) as a Pixel.
-    //   VERY INEFFICIENT!!!
-    // *** Pixel getPixel(const Point& p);
-
     ///////////////////////////////////////////////
     // Framebuffer update methods
     //
@@ -115,10 +111,10 @@
     virtual int getStride() const;
 
     // Get a pointer to specified pixel data
-    rdr::U8* getPixelsRW(const Rect& r, int* stride);
-    virtual const rdr::U8* getPixelsR(const Rect& r, int* stride) {
-      return getPixelsRW(r, stride);
+    virtual const rdr::U8* getBuffer(const Rect& r, int* stride) {
+      return getBufferRW(r, stride);
     }
+    virtual rdr::U8* getBufferRW(const Rect& r, int* stride);
 
     ///////////////////////////////////////////////
     // Basic rendering operations
diff --git a/common/rfb/PixelFormat.cxx b/common/rfb/PixelFormat.cxx
index a2e9496..b11f883 100644
--- a/common/rfb/PixelFormat.cxx
+++ b/common/rfb/PixelFormat.cxx
@@ -1,6 +1,6 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * Copyright 2009 Pierre Ossman for Cendio AB
  * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
+ * Copyright 2009-2014 Pierre Ossman for Cendio AB
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
 #include <string.h>
 #include <rdr/InStream.h>
 #include <rdr/OutStream.h>
+#include <rfb/Exception.h>
 #include <rfb/PixelFormat.h>
 #include <rfb/util.h>
 
@@ -37,11 +38,7 @@
     redMax(rm), greenMax(gm), blueMax(bm),
     redShift(rs), greenShift(gs), blueShift(bs)
 {
-  assert((bpp == 8) || (bpp == 16) || (bpp == 32));
-  assert(depth <= bpp);
-  assert((redMax & (redMax + 1)) == 0);
-  assert((greenMax & (greenMax + 1)) == 0);
-  assert((blueMax & (blueMax + 1)) == 0);
+  assert(isSane());
 
   updateState();
 }
@@ -82,6 +79,9 @@
   blueShift = is->readU8();
   is->skip(3);
 
+  if (!isSane())
+    throw Exception("invalid pixel format");
+
   updateState();
 }
 
@@ -132,160 +132,58 @@
 }
 
 
-Pixel PixelFormat::pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 blue,
-                                ColourMap* cm) const
-{
-  if (trueColour) {
-    rdr::U32 r = ((rdr::U32)red   * redMax   + 32767) / 65535;
-    rdr::U32 g = ((rdr::U32)green * greenMax + 32767) / 65535;
-    rdr::U32 b = ((rdr::U32)blue  * blueMax  + 32767) / 65535;
-
-    return (r << redShift) | (g << greenShift) | (b << blueShift);
-  } else if (cm) {
-    // Try to find the closest pixel by Cartesian distance
-    int colours = 1 << depth;
-    int diff = 256 * 256 * 4;
-    int col = 0;
-    for (int i=0; i<colours; i++) {
-      int r, g, b;
-      cm->lookup(i, &r, &g, &b);
-      int rd = (r-red) >> 8;
-      int gd = (g-green) >> 8;
-      int bd = (b-blue) >> 8;
-      int d = rd*rd + gd*gd + bd*bd;
-      if (d < diff) {
-        col = i;
-        diff = d;
-      }
-    }
-    return col;
-  }
-  // XXX just return 0 for colour map?
-  return 0;
-}
-
-
-Pixel PixelFormat::pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue,
-                                ColourMap* cm) const
-{
-  if (trueColour) {
-    rdr::U32 r = ((rdr::U32)red   * redMax   + 127) / 255;
-    rdr::U32 g = ((rdr::U32)green * greenMax + 127) / 255;
-    rdr::U32 b = ((rdr::U32)blue  * blueMax  + 127) / 255;
-
-    return (r << redShift) | (g << greenShift) | (b << blueShift);
-  }
-
-  return pixelFromRGB((rdr::U16)(red << 8), (rdr::U16)(green << 8),
-      (rdr::U16)(blue << 8), cm);
-}
-
-
 void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src,
                                 int pixels, ColourMap* cm) const
 {
+  bufferFromRGB(dst, src, pixels, pixels, 1, cm);
+}
+
+void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src,
+                                int w, int stride, int h, ColourMap* cm) const
+{
   if (is888()) {
     // Optimised common case
-    rdr::U8 *r, *g, *b;
+    rdr::U8 *r, *g, *b, *x;
 
     if (bigEndian) {
       r = dst + (24 - redShift)/8;
       g = dst + (24 - greenShift)/8;
       b = dst + (24 - blueShift)/8;
+      x = dst + (24 - (48 - redShift - greenShift - blueShift))/8;
     } else {
       r = dst + redShift/8;
       g = dst + greenShift/8;
       b = dst + blueShift/8;
+      x = dst + (48 - redShift - greenShift - blueShift)/8;
     }
 
-    while (pixels--) {
-      *r = *(src++);
-      *g = *(src++);
-      *b = *(src++);
-      r += 4;
-      g += 4;
-      b += 4;
-    }
-  } else {
-    // Generic code
-    Pixel p;
-    rdr::U8 r, g, b;
-
-    while (pixels--) {
-      r = *(src++);
-      g = *(src++);
-      b = *(src++);
-
-      p = pixelFromRGB(r, g, b, cm);
-
-      bufferFromPixel(dst, p);
-      dst += bpp/8;
-    }
-  }
-}
-
-#define trueColorBufferFromRGB(BPP) {  \
-  rdr::U8 r, g, b;  \
-  int dstPad = pitch - w * BPP / 8;  \
-  while (h > 0) {  \
-    rdr::U8 *dstEndOfRow = (rdr::U8 *)dst + w * BPP / 8;  \
-    while (dst < dstEndOfRow) {  \
-      r = *(src++);  \
-      g = *(src++);  \
-      b = *(src++);  \
-      *(rdr::U##BPP *)dst = (((r * redMax + 127) / 255) << redShift)  \
-                          | (((g * greenMax + 127) / 255) << greenShift)  \
-                          | (((b * blueMax + 127) / 255) << blueShift);  \
-      dst += BPP / 8;  \
-    }  \
-    dst += dstPad;  \
-    h--;  \
-  }  \
-}
-
-void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src,
-                                int w, int pitch, int h, ColourMap* cm) const
-{
-  if (is888()) {
-    // Optimised common case
-    int rindex, gindex, bindex;
-
-    if (bigEndian) {
-      rindex = (24 - redShift)/8;
-      gindex = (24 - greenShift)/8;
-      bindex = (24 - blueShift)/8;
-    } else {
-      rindex = redShift/8;
-      gindex = greenShift/8;
-      bindex = blueShift/8;
-    }
-
-    int dstPad = pitch - w * 4;
-    while (h > 0) {
-      rdr::U8 *dstEndOfRow = (rdr::U8 *)dst + w * 4;
-      while (dst < dstEndOfRow) {
-        dst[rindex] = *(src++);
-        dst[gindex] = *(src++);
-        dst[bindex] = *(src++);
-        dst += 4;
+    int dstPad = (stride - w) * 4;
+    while (h--) {
+      int w_ = w;
+      while (w_--) {
+        *r = *(src++);
+        *g = *(src++);
+        *b = *(src++);
+        *x = 0;
+        r += 4;
+        g += 4;
+        b += 4;
+        x += 4;
       }
-      dst += dstPad;
-      h--;
+      r += dstPad;
+      g += dstPad;
+      b += dstPad;
+      x += dstPad;
     }
-  } else if (!cm && bpp == 16) {
-    trueColorBufferFromRGB(16);
-  } else if (!cm && bpp == 8) {
-    trueColorBufferFromRGB(8);
   } else {
     // Generic code
-    Pixel p;
-    rdr::U8 r, g, b;
-    int pixelSize = bpp/8;
+    int dstPad = (stride - w) * 4;
+    while (h--) {
+      int w_ = w;
+      while (w_--) {
+        Pixel p;
+        rdr::U8 r, g, b;
 
-    int dstPad = pitch - w * pixelSize;
-    while (h > 0) {
-      rdr::U8 *dstEndOfRow = (rdr::U8 *)dst + w * pixelSize;
-      while (dst < dstEndOfRow) {
         r = *(src++);
         g = *(src++);
         b = *(src++);
@@ -293,10 +191,9 @@
         p = pixelFromRGB(r, g, b, cm);
 
         bufferFromPixel(dst, p);
-        dst += pixelSize;
+        dst += bpp/8;
       }
       dst += dstPad;
-      h--;
     }
   }
 }
@@ -314,24 +211,14 @@
 }
 
 
-void PixelFormat::rgbFromBuffer(rdr::U16* dst, const rdr::U8* src, int pixels, ColourMap* cm) const
+void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels, ColourMap* cm) const
 {
-  Pixel p;
-  rdr::U16 r, g, b;
-
-  while (pixels--) {
-    p = pixelFromBuffer(src);
-    src += bpp/8;
-
-    rgbFromPixel(p, cm, &r, &g, &b);
-    *(dst++) = r;
-    *(dst++) = g;
-    *(dst++) = b;
-  }
+  rgbFromBuffer(dst, src, pixels, pixels, 1, cm);
 }
 
 
-void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels, ColourMap* cm) const
+void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src,
+                                int w, int stride, int h, ColourMap* cm) const
 {
   if (is888()) {
     // Optimised common case
@@ -347,81 +234,40 @@
       b = src + blueShift/8;
     }
 
-    while (pixels--) {
-      *(dst++) = *r;
-      *(dst++) = *g;
-      *(dst++) = *b;
-      r += 4;
-      g += 4;
-      b += 4;
-    }
-  } else {
-    // Generic code
-    Pixel p;
-    rdr::U8 r, g, b;
-
-    while (pixels--) {
-      p = pixelFromBuffer(src);
-      src += bpp/8;
-
-      rgbFromPixel(p, cm, &r, &g, &b);
-      *(dst++) = r;
-      *(dst++) = g;
-      *(dst++) = b;
-    }
-  }
-}
-
-
-void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src,
-                                int w, int pitch, int h, ColourMap* cm) const
-{
-  if (is888()) {
-    // Optimised common case
-    int rindex, gindex, bindex;
-
-    if (bigEndian) {
-      rindex = (24 - redShift)/8;
-      gindex = (24 - greenShift)/8;
-      bindex = (24 - blueShift)/8;
-    } else {
-      rindex = redShift/8;
-      gindex = greenShift/8;
-      bindex = blueShift/8;
-    }
-
-    int srcPad = pitch - w * 4;
-    while (h > 0) {
-      rdr::U8 *srcEndOfRow = (rdr::U8 *)src + w * 4;
-      while (src < srcEndOfRow) {
-        *(dst++) = src[rindex];
-        *(dst++) = src[gindex];
-        *(dst++) = src[bindex];
-        src += 4;
+    int srcPad = (stride - w) * 4;
+    while (h--) {
+      int w_ = w;
+      while (w_--) {
+        *(dst++) = *r;
+        *(dst++) = *g;
+        *(dst++) = *b;
+        r += 4;
+        g += 4;
+        b += 4;
       }
-      src += srcPad;
-      h--;      
+      r += srcPad;
+      g += srcPad;
+      b += srcPad;
     }
   } else {
     // Generic code
-    Pixel p;
-    rdr::U8 r, g, b;
-    int pixelSize = bpp/8;
+    int srcPad = (stride - w) * bpp/8;
+    while (h--) {
+      int w_ = w;
+      while (w_--) {
+        Pixel p;
+        rdr::U8 r, g, b;
 
-    int srcPad = pitch - w * pixelSize;
-    while (h > 0) {
-      rdr::U8 *srcEndOfRow = (rdr::U8 *)src + w * pixelSize;
-      while (src < srcEndOfRow) {
         p = pixelFromBuffer(src);
 
         rgbFromPixel(p, cm, &r, &g, &b);
+
         *(dst++) = r;
         *(dst++) = g;
         *(dst++) = b;
-        src += pixelSize;
+        src += bpp/8;
       }
       src += srcPad;
-      h--;
     }
   }
 }
@@ -531,6 +377,8 @@
     return false;
   }
 
+  assert(isSane());
+
   updateState();
 
   return true;
@@ -565,19 +413,72 @@
 
 void PixelFormat::updateState(void)
 {
-  int redBits, greenBits, blueBits;
   int endianTest = 1;
 
   redBits = bits(redMax);
   greenBits = bits(greenMax);
   blueBits = bits(blueMax);
 
-  redConvShift = 16 - redBits;
-  greenConvShift = 16 - greenBits;
-  blueConvShift = 16 - blueBits;
+  maxBits = redBits;
+  if (greenBits > maxBits)
+    maxBits = greenBits;
+  if (blueBits > maxBits)
+    maxBits = blueBits;
+
+  minBits = redBits;
+  if (greenBits < minBits)
+    minBits = greenBits;
+  if (blueBits < minBits)
+    minBits = blueBits;
 
   if (((*(char*)&endianTest) == 0) != bigEndian)
     endianMismatch = true;
   else
     endianMismatch = false;
 }
+
+bool PixelFormat::isSane(void)
+{
+  int totalBits;
+
+  if ((bpp != 8) && (bpp != 16) && (bpp != 32))
+    return false;
+  if (depth > bpp)
+    return false;
+
+  if (!trueColour && (depth != 8))
+    return false;
+
+  if (trueColour) {
+    if ((redMax & (redMax + 1)) != 0)
+      return false;
+    if ((greenMax & (greenMax + 1)) != 0)
+      return false;
+    if ((blueMax & (blueMax + 1)) != 0)
+      return false;
+
+    /*
+     * We don't allow individual channels > 8 bits in order to keep our
+     * conversions simple.
+     */
+    if (redMax >= (1 << 8))
+      return false;
+    if (greenMax >= (1 << 8))
+      return false;
+    if (blueMax >= (1 << 8))
+      return false;
+
+    totalBits = bits(redMax) + bits(greenMax) + bits(blueMax);
+    if (totalBits > bpp)
+      return false;
+
+    if (((redMax << redShift) & (greenMax << greenShift)) != 0)
+      return false;
+    if (((redMax << redShift) & (blueMax << blueShift)) != 0)
+      return false;
+    if (((greenMax << greenShift) & (blueMax << blueShift)) != 0)
+      return false;
+  }
+
+  return true;
+}
diff --git a/common/rfb/PixelFormat.h b/common/rfb/PixelFormat.h
index 88e80f4..a8408dd 100644
--- a/common/rfb/PixelFormat.h
+++ b/common/rfb/PixelFormat.h
@@ -1,5 +1,6 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
  * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
+ * Copyright 2009-2014 Pierre Ossman for Cendio AB
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,7 +19,16 @@
  */
 //
 // PixelFormat - structure to represent a pixel format.  Also has useful
-// methods for reading & writing to streams, etc.
+// methods for reading & writing to streams, etc. Conversion to and from
+// other formats are also handled by this class. We have three different
+// representations that we refer to:
+//
+// a) Pixels - Unsigned native integers in the format specified by this
+//             PixelFormat object.
+// b) Buffer - Same thing as pixels, but in the appropriate byte stream
+//             format. This involves endian conversion and padding.
+// c) RGB - A byte stream of 8 bit red, green and blue elements, in that
+//          order.
 //
 
 #ifndef __RFB_PIXELFORMAT_H__
@@ -49,20 +59,19 @@
     inline Pixel pixelFromBuffer(const rdr::U8* buffer) const;
     inline void bufferFromPixel(rdr::U8* buffer, Pixel pixel) const;
 
-    Pixel pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 blue, ColourMap* cm=0) const;
-    Pixel pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue, ColourMap* cm=0) const;
+    inline Pixel pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 blue, ColourMap* cm=0) const;
+    inline Pixel pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue, ColourMap* cm=0) const;
 
     void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int pixels, ColourMap* cm=0) const;
-    void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int w, int pitch,
+    void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int w, int stride,
                        int h, ColourMap* cm=0) const;
 
     void rgbFromPixel(Pixel pix, ColourMap* cm, Colour* rgb) const;
     inline void rgbFromPixel(Pixel pix, ColourMap* cm, rdr::U16 *r, rdr::U16 *g, rdr::U16 *b) const;
     inline void rgbFromPixel(Pixel pix, ColourMap* cm, rdr::U8 *r, rdr::U8 *g, rdr::U8 *b) const;
 
-    void rgbFromBuffer(rdr::U16* dst, const rdr::U8* src, int pixels, ColourMap* cm=0) const;
     void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels, ColourMap* cm=0) const;
-    void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int w, int pitch,
+    void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int w, int stride,
                        int h, ColourMap* cm=0) const;
 
     void print(char* str, int len) const;
@@ -70,6 +79,7 @@
 
   protected:
     void updateState(void);
+    bool isSane(void);
 
   public:
     int bpp;
@@ -87,9 +97,9 @@
     int blueShift;
 
   protected:
-    int redConvShift;
-    int greenConvShift;
-    int blueConvShift;
+    /* Pre-computed values to keep algorithms simple */
+    int redBits, greenBits, blueBits;
+    int maxBits, minBits;
     bool endianMismatch;
   };
 }
diff --git a/common/rfb/PixelFormat.inl b/common/rfb/PixelFormat.inl
index 90d8e6d..547fae5 100644
--- a/common/rfb/PixelFormat.inl
+++ b/common/rfb/PixelFormat.inl
@@ -1,4 +1,4 @@
-/* Copyright 2009 Pierre Ossman for Cendio AB
+/* Copyright 2009-2014 Pierre Ossman for Cendio AB
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -75,13 +75,83 @@
 }
 
 
+inline Pixel PixelFormat::pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 blue, ColourMap* cm) const
+{
+  if (trueColour) {
+    Pixel p;
+
+    /* We don't need to mask since we shift out unwanted bits */
+    p = ((Pixel)red >> (16 - redBits)) << redShift;
+    p |= ((Pixel)green >> (16 - greenBits)) << greenShift;
+    p |= ((Pixel)blue >> (16 - blueBits)) << blueShift;
+  } else if (cm) {
+    // Try to find the closest pixel by Cartesian distance
+    int colours = 1 << depth;
+    int diff = 256 * 256 * 4;
+    int col = 0;
+    for (int i=0; i<colours; i++) {
+      int r, g, b;
+      cm->lookup(i, &r, &g, &b);
+      int rd = (r-red) >> 8;
+      int gd = (g-green) >> 8;
+      int bd = (b-blue) >> 8;
+      int d = rd*rd + gd*gd + bd*bd;
+      if (d < diff) {
+        col = i;
+        diff = d;
+      }
+    }
+    return col;
+  } else {
+    // XXX just return 0 for colour map?
+    return 0;
+  }
+}
+
+
+inline Pixel PixelFormat::pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue, ColourMap* cm) const
+{
+  if (trueColour) {
+    Pixel p;
+
+    p = ((Pixel)red >> (8 - redBits)) << redShift;
+    p |= ((Pixel)green >> (8 - greenBits)) << greenShift;
+    p |= ((Pixel)blue >> (8 - blueBits)) << blueShift;
+
+    return p;
+  } else {
+    return pixelFromRGB((rdr::U16)(red << 8 | red),
+                        (rdr::U16)(green << 8 | green),
+                        (rdr::U16)(blue << 8 | blue), cm);
+  }
+}
+
+
 inline void PixelFormat::rgbFromPixel(Pixel p, ColourMap* cm, rdr::U16 *r, rdr::U16 *g, rdr::U16 *b) const
 {
   if (trueColour) {
-    /* We don't need to mask since we shift out unwanted bits */
-    *r = (p >> redShift) << redConvShift;
-    *g = (p >> greenShift) << greenConvShift;
-    *b = (p >> blueShift) << blueConvShift;
+    int mb, rb, gb, bb;
+
+    /* Bit replication is much cheaper than multiplication and division */
+
+    mb = minBits;
+    rb = redBits;
+    gb = greenBits;
+    bb = blueBits;
+
+    *r = (p >> redShift) << (16 - rb);
+    *g = (p >> greenShift) << (16 - gb);
+    *b = (p >> blueShift) << (16 - bb);
+
+    while (mb < 16) {
+      *r = *r | (*r >> rb);
+      *g = *g | (*g >> gb);
+      *b = *b | (*b >> bb);
+      mb <<= 1;
+      rb <<= 1;
+      gb <<= 1;
+      bb <<= 1;
+    }
   } else if (cm) {
     int ir, ig, ib;
     cm->lookup(p, &ir, &ig, &ib);
@@ -100,9 +170,28 @@
 inline void PixelFormat::rgbFromPixel(Pixel p, ColourMap* cm, rdr::U8 *r, rdr::U8 *g, rdr::U8 *b) const
 {
   if (trueColour) {
-    *r = (p >> redShift) << (redConvShift - 8);
-    *g = (p >> greenShift) << (greenConvShift - 8);
-    *b = (p >> blueShift) << (blueConvShift - 8);
+    int mb, rb, gb, bb;
+
+    /* Bit replication is much cheaper than multiplication and division */
+
+    mb = minBits;
+    rb = redBits;
+    gb = greenBits;
+    bb = blueBits;
+
+    *r = (p >> redShift) << (8 - rb);
+    *g = (p >> greenShift) << (8 - gb);
+    *b = (p >> blueShift) << (8 - bb);
+
+    while (mb < 8) {
+      *r = *r | (*r >> rb);
+      *g = *g | (*g >> gb);
+      *b = *b | (*b >> bb);
+      mb <<= 1;
+      rb <<= 1;
+      gb <<= 1;
+      bb <<= 1;
+    }
   } else {
     rdr::U16 r2, g2, b2;
 
diff --git a/common/rfb/RREDecoder.cxx b/common/rfb/RREDecoder.cxx
index da56ee7..b81a4a8 100644
--- a/common/rfb/RREDecoder.cxx
+++ b/common/rfb/RREDecoder.cxx
@@ -34,11 +34,6 @@
 #include <rfb/rreDecode.h>
 #undef BPP
 
-Decoder* RREDecoder::create(CMsgReader* reader)
-{
-  return new RREDecoder(reader);
-}
-
 RREDecoder::RREDecoder(CMsgReader* reader_) : reader(reader_)
 {
 }
diff --git a/common/rfb/RREDecoder.h b/common/rfb/RREDecoder.h
index 2309f75..98abf98 100644
--- a/common/rfb/RREDecoder.h
+++ b/common/rfb/RREDecoder.h
@@ -24,11 +24,10 @@
 
   class RREDecoder : public Decoder {
   public:
-    static Decoder* create(CMsgReader* reader);
-    virtual void readRect(const Rect& r, CMsgHandler* handler);
-    virtual ~RREDecoder();
-  private:
     RREDecoder(CMsgReader* reader);
+    virtual ~RREDecoder();
+    virtual void readRect(const Rect& r, CMsgHandler* handler);
+  private:
     CMsgReader* reader;
   };
 }
diff --git a/common/rfb/RREEncoder.cxx b/common/rfb/RREEncoder.cxx
index 1b86986..36d4695 100644
--- a/common/rfb/RREEncoder.cxx
+++ b/common/rfb/RREEncoder.cxx
@@ -16,7 +16,7 @@
  * USA.
  */
 #include <rdr/OutStream.h>
-#include <rfb/ImageGetter.h>
+#include <rfb/TransImageGetter.h>
 #include <rfb/encodings.h>
 #include <rfb/SMsgWriter.h>
 #include <rfb/RREEncoder.h>
@@ -33,11 +33,6 @@
 #include <rfb/rreEncode.h>
 #undef BPP
 
-Encoder* RREEncoder::create(SMsgWriter* writer)
-{
-  return new RREEncoder(writer);
-}
-
 RREEncoder::RREEncoder(SMsgWriter* writer_) : writer(writer_)
 {
 }
diff --git a/common/rfb/RREEncoder.h b/common/rfb/RREEncoder.h
index 6178d57..f7d576e 100644
--- a/common/rfb/RREEncoder.h
+++ b/common/rfb/RREEncoder.h
@@ -25,11 +25,10 @@
 
   class RREEncoder : public Encoder {
   public:
-    static Encoder* create(SMsgWriter* writer);
-    virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual);
-    virtual ~RREEncoder();
-  private:
     RREEncoder(SMsgWriter* writer);
+    virtual ~RREEncoder();
+    virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual);
+  private:
     SMsgWriter* writer;
     rdr::MemOutStream mos;
   };
diff --git a/common/rfb/RawDecoder.cxx b/common/rfb/RawDecoder.cxx
index 57cb37b..5fd3b7c 100644
--- a/common/rfb/RawDecoder.cxx
+++ b/common/rfb/RawDecoder.cxx
@@ -22,11 +22,6 @@
 
 using namespace rfb;
 
-Decoder* RawDecoder::create(CMsgReader* reader)
-{
-  return new RawDecoder(reader);
-}
-
 RawDecoder::RawDecoder(CMsgReader* reader_) : reader(reader_)
 {
 }
diff --git a/common/rfb/RawDecoder.h b/common/rfb/RawDecoder.h
index 9fdbb22..e09cca2 100644
--- a/common/rfb/RawDecoder.h
+++ b/common/rfb/RawDecoder.h
@@ -24,11 +24,10 @@
 
   class RawDecoder : public Decoder {
   public:
-    static Decoder* create(CMsgReader* reader);
-    virtual void readRect(const Rect& r, CMsgHandler* handler);
-    virtual ~RawDecoder();
-  private:
     RawDecoder(CMsgReader* reader);
+    virtual ~RawDecoder();
+    virtual void readRect(const Rect& r, CMsgHandler* handler);
+  private:
     CMsgReader* reader;
   };
 }
diff --git a/common/rfb/RawEncoder.cxx b/common/rfb/RawEncoder.cxx
index 5612cb8..4b8de6b 100644
--- a/common/rfb/RawEncoder.cxx
+++ b/common/rfb/RawEncoder.cxx
@@ -16,18 +16,13 @@
  * USA.
  */
 #include <rdr/OutStream.h>
-#include <rfb/ImageGetter.h>
+#include <rfb/TransImageGetter.h>
 #include <rfb/encodings.h>
 #include <rfb/SMsgWriter.h>
 #include <rfb/RawEncoder.h>
 
 using namespace rfb;
 
-Encoder* RawEncoder::create(SMsgWriter* writer)
-{
-  return new RawEncoder(writer);
-}
-
 RawEncoder::RawEncoder(SMsgWriter* writer_) : writer(writer_)
 {
 }
diff --git a/common/rfb/RawEncoder.h b/common/rfb/RawEncoder.h
index 34dba0b..22d45db 100644
--- a/common/rfb/RawEncoder.h
+++ b/common/rfb/RawEncoder.h
@@ -24,11 +24,10 @@
 
   class RawEncoder : public Encoder {
   public:
-    static Encoder* create(SMsgWriter* writer);
-    virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual);
-    virtual ~RawEncoder();
-  private:
     RawEncoder(SMsgWriter* writer);
+    virtual ~RawEncoder();
+    virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual);
+  private:
     SMsgWriter* writer;
   };
 }
diff --git a/common/rfb/SMsgWriter.cxx b/common/rfb/SMsgWriter.cxx
index f47f3ee..509ffbf 100644
--- a/common/rfb/SMsgWriter.cxx
+++ b/common/rfb/SMsgWriter.cxx
@@ -122,18 +122,6 @@
   return false;
 }
 
-// FIXME: This functions is not used because it incorrectly computes
-//        the number of rectangles if the Tight encoder is used.
-/*
-void SMsgWriter::writeFramebufferUpdate(const UpdateInfo& ui, ImageGetter* ig,
-                                        Region* updatedRegion)
-{
-  writeFramebufferUpdateStart(ui.numRects());
-  writeRects(ui, ig, updatedRegion);
-  writeFramebufferUpdateEnd();
-}
-*/
-
 bool SMsgWriter::needNoDataUpdate()
 {
   return false;
diff --git a/common/rfb/SMsgWriter.h b/common/rfb/SMsgWriter.h
index 3933b38..edf2944 100644
--- a/common/rfb/SMsgWriter.h
+++ b/common/rfb/SMsgWriter.h
@@ -109,18 +109,6 @@
     // order to flush out pseudo-rectangles to the client.
     virtual bool needFakeUpdate();
 
-    // writeFramebufferUpdate() writes a framebuffer update using the given
-    // UpdateInfo and ImageGetter.  On a V3 writer this may have
-    // pseudo-rectangles for setDesktopSize and setCursor added to it, and so
-    // may invoke writeSetCursorCallback().
-    //
-    // FIXME: This function is not used because it incorrectly computes
-    //        the number of rectangles if the Tight encoder is used.
-    /*
-    virtual void writeFramebufferUpdate(const UpdateInfo& ui, ImageGetter* ig,
-                                        Region* updatedRegion);
-    */
-
     // needNoDataUpdate() returns true when an update without any
     // framebuffer changes need to be sent (using writeNoDataUpdate()).
     // Commonly this is an update that modifies the size of the framebuffer
diff --git a/common/rfb/ScaleFilters.cxx b/common/rfb/ScaleFilters.cxx
index 07f3db8..3e414d9 100644
--- a/common/rfb/ScaleFilters.cxx
+++ b/common/rfb/ScaleFilters.cxx
@@ -23,10 +23,6 @@
 #include <rfb/Rect.h>
 #include <rfb/ScaleFilters.h>
 
-#ifdef _WIN32
-#define strcasecmp _stricmp
-#endif
-
 using namespace rfb;
 
 //
diff --git a/common/rfb/ScaledPixelBuffer.cxx b/common/rfb/ScaledPixelBuffer.cxx
deleted file mode 100644
index dc6096d..0000000
--- a/common/rfb/ScaledPixelBuffer.cxx
+++ /dev/null
@@ -1,225 +0,0 @@
-/* Copyright (C) 2005 TightVNC Team.  All Rights Reserved.
- *    
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-// -=- ScaledPixelBuffer.cxx
-
-#include <rfb/Exception.h>
-#include <rfb/ScaledPixelBuffer.h>
-
-#include <math.h>
-#include <memory.h>
-#include <stdlib.h>
-
-using namespace rdr;
-using namespace rfb;
-
-ScaledPixelBuffer::ScaledPixelBuffer(U8 **src_data_, int src_width_,
-                                     int src_height_, int scale_, PixelFormat pf_)
-  : scale(scale_), scale_ratio_x(1), scale_ratio_y(1), scaleFilterID(scaleFilterBilinear),
-    xWeightTabs(0), yWeightTabs(0), raccum(0), gaccum(0), baccum(0), scaled_data(0) {
-
-  setSourceBuffer(src_data_, src_width_, src_height_);
-  setPF(pf_);
-}
-
-ScaledPixelBuffer::ScaledPixelBuffer() 
-  : src_width(0), src_height(0), scaled_width(0), scaled_height(0), scale(100), 
-    scale_ratio_x(1), scale_ratio_y(1), scaleFilterID(scaleFilterBilinear),
-    xWeightTabs(0), yWeightTabs(0), raccum(0), gaccum(0), baccum(0),
-    src_data(0), scaled_data(0) {
-  memset(&pf, 0, sizeof(pf));
-}
-
-ScaledPixelBuffer::~ScaledPixelBuffer() {
-  freeWeightTabs();
-  if (raccum) delete [] raccum;
-  if (gaccum) delete [] gaccum;
-  if (baccum) delete [] baccum;
-}
-
-void ScaledPixelBuffer::freeWeightTabs() {
-  if (xWeightTabs) {
-    for (int i = 0; i < scaled_width; i++) delete [] xWeightTabs[i].weight;
-    delete [] xWeightTabs;
-    xWeightTabs = 0;
-  }
-  if (yWeightTabs) {
-    for (int i = 0; i < scaled_height; i++) delete [] yWeightTabs[i].weight;
-    delete [] yWeightTabs;
-    yWeightTabs = 0;
-  }
-}
-
-void ScaledPixelBuffer::recreateRowAccum() {
-  if (raccum) delete [] raccum;
-  if (gaccum) delete [] gaccum;
-  if (baccum) delete [] baccum;
-  raccum = new int[src_width];
-  gaccum = new int[src_width];
-  baccum = new int[src_width];
-}
-
-void ScaledPixelBuffer::setSourceBuffer(U8 **src_data_, int w, int h) {
-  if (w > 0 && h > 0 && src_data_ != NULL) {
-    freeWeightTabs();
-    src_data = src_data_;
-    src_width  = w;
-    src_height = h;
-    recreateRowAccum();
-    calculateScaledBufferSize();
-    scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, &xWeightTabs);
-    scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, &yWeightTabs);
-  }
-}
-
-void ScaledPixelBuffer::setPF(const PixelFormat &pf_) {
-  ///if (pf_.depth != 24) throw rfb::UnsupportedPixelFormatException();
-  pf = pf_;
-}
-
-void ScaledPixelBuffer::setScale(int scale_) {
-  if (scale != scale_ && scale_ > 0) {
-    scale = scale_;
-    freeWeightTabs();
-    calculateScaledBufferSize();
-    scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, &xWeightTabs);
-    scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, &yWeightTabs);
-  }
-}
-
-void ScaledPixelBuffer::setScaleFilter(unsigned int scaleFilterID_) {
-  if (scaleFilterID == scaleFilterID_ || scaleFilterID_ > scaleFilterMaxNumber) return;
-
-  scaleFilterID = scaleFilterID_;
-  
-  if (src_width && src_height && scaled_width && scaled_height) {
-    freeWeightTabs();
-    scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, &xWeightTabs);
-    scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, &yWeightTabs);
-    if (scale != 100 && pf.depth > 0 && scaled_data) scaleRect(Rect(0, 0, src_width, src_height));
-  }
-}
-
-inline U32 ScaledPixelBuffer::getSourcePixel(int x, int y) {
-  int bytes_per_pixel = pf.bpp / 8;
-  U8 *ptr = &(*src_data)[(x + y*src_width)*bytes_per_pixel];
-  if (bytes_per_pixel == 1) {
-    return *ptr;
-  } else if (bytes_per_pixel == 2) {
-    int b0 = *ptr++; int b1 = *ptr;
-    return b1 << 8 | b0;
-  } else if (bytes_per_pixel == 4) {
-    int b0 = *ptr++; int b1 = *ptr++;
-    int b2 = *ptr++; int b3 = *ptr;
-    return b3 << 24 | b2 << 16 | b1 << 8 | b0;
-  } else {
-    return 0;
-  }
-}
-
-void ScaledPixelBuffer::scaleRect(const Rect& rect) {
-  Rect changed_rect;
-  U8 *ptr, *ptrs, *px, *pxs;
-  U16 r, g, b;
-  int red, green, blue;
-  short *xweight, *yweight, weight;
-
-  // Calculate the changed pixel rect in the scaled image
-  changed_rect = calculateScaleBoundary(rect);
-
-  int bytesPerSrcPixel = pf.bpp / 8;
-  int bytesPerSrcRow = src_width * bytesPerSrcPixel;
-  int bytesPerScaledRow = scaled_width * 4;
-
-  int bytesPerAccumRow = src_width * sizeof(int);
-
-  ptrs = &(*scaled_data)[(changed_rect.tl.x + changed_rect.tl.y*scaled_width) * 4];
-  for (int y = changed_rect.tl.y; y < changed_rect.br.y; y++) {
-    ptr = ptrs;
-    yweight = yWeightTabs[y].weight;
-
-    // Clear the color accumulators
-    memset(raccum, 0, bytesPerAccumRow);
-    memset(gaccum, 0, bytesPerAccumRow);
-    memset(baccum, 0, bytesPerAccumRow);
-
-    // Make the convolution the source image with scale filter weights
-    // by y axis and save results to the color accumulators.
-    pxs = &(*src_data)[(xWeightTabs[changed_rect.tl.x].i0 + yWeightTabs[y].i0*src_width) * bytesPerSrcPixel];
-    for (int ys = yWeightTabs[y].i0; ys < yWeightTabs[y].i1; ys++) {
-      px = pxs;
-      for (int xs = xWeightTabs[changed_rect.tl.x].i0; xs < xWeightTabs[changed_rect.br.x-1].i1; xs++) {
-        pf.rgbFromPixel(*((U32*)px), NULL, &r, &g, &b);
-        weight = *yweight;
-        raccum[xs] += (int)(weight) * r;
-        gaccum[xs] += (int)(weight) * g;
-        baccum[xs] += (int)(weight) * b;
-        px += bytesPerSrcPixel;
-      }
-      yweight++;
-      pxs += bytesPerSrcRow;
-    }
-
-    // Make the convolution the color accumulators with scale filter weights
-    // by x axis and save results to the scaled image.
-    for (int x = changed_rect.tl.x; x < changed_rect.br.x; x++) {
-      // Init the sum of colors with (1 << (shift-1)) for rounding.
-      red = green = blue = 1 << (FINALSHIFT-1);
-      xweight = xWeightTabs[x].weight;
-      for (int xs = xWeightTabs[x].i0; xs < xWeightTabs[x].i1; xs++) {
-        weight = *xweight;
-        red   += (int)(weight) * (raccum[xs] >> BITS_OF_CHANEL);
-        green += (int)(weight) * (gaccum[xs] >> BITS_OF_CHANEL);
-        blue  += (int)(weight) * (baccum[xs] >> BITS_OF_CHANEL);
-        xweight++;
-      }
-      *ptr++ = U8(blue  >> FINALSHIFT);
-      *ptr++ = U8(green >> FINALSHIFT);
-      *ptr++ = U8(red   >> FINALSHIFT);
-      ptr++;
-    }
-    ptrs += bytesPerScaledRow;
-  }
-}
-
-Rect ScaledPixelBuffer::calculateScaleBoundary(const Rect& r) {
-  int x_start, y_start, x_end, y_end;
-  double translate_x = 0.5*scale_ratio_x - 0.5;
-  double translate_y = 0.5*scale_ratio_y - 0.5;
-  double sourceXScale  = __rfbmax(1.0, 1.0/scale_ratio_x);
-  double sourceYScale  = __rfbmax(1.0, 1.0/scale_ratio_y);
-  double sourceXRadius = __rfbmax(0.5, sourceXScale*scaleFilters[scaleFilterID].radius);
-  double sourceYRadius = __rfbmax(0.5, sourceYScale*scaleFilters[scaleFilterID].radius);
-  x_start = (int)ceil(scale_ratio_x*(r.tl.x-sourceXRadius) + translate_x + SCALE_ERROR);
-  y_start = (int)ceil(scale_ratio_y*(r.tl.y-sourceYRadius) + translate_y + SCALE_ERROR);
-  x_end   = (int)floor(scale_ratio_x*((r.br.x-1)+sourceXRadius) + translate_x - SCALE_ERROR) + 1;
-  y_end   = (int)floor(scale_ratio_y*((r.br.y-1)+sourceXRadius) + translate_y - SCALE_ERROR) + 1;
-  if (x_start < 0) x_start = 0;
-  if (y_start < 0) y_start = 0;
-  if (x_end > scaled_width) x_end = scaled_width;
-  if (y_end > scaled_height) y_end = scaled_height;
-  return Rect(x_start, y_start, x_end, y_end);
-}
-
-void ScaledPixelBuffer::calculateScaledBufferSize() {
-  double scale_ratio = (double)scale / 100;
-  scaled_width  = (int)ceil(src_width  * scale_ratio);
-  scaled_height = (int)ceil(src_height * scale_ratio);
-  scale_ratio_x = (double)scaled_width / src_width;
-  scale_ratio_y = (double)scaled_height / src_height;
-}
diff --git a/common/rfb/ScaledPixelBuffer.h b/common/rfb/ScaledPixelBuffer.h
deleted file mode 100644
index 453ab78..0000000
--- a/common/rfb/ScaledPixelBuffer.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Copyright (C) 2005 TightVNC Team.  All Rights Reserved.
- *    
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-// -=- ScaledPixelBuffer.h
-//
-// The ScaledPixelBuffer class allows to scale the image data 
-// from the source buffer to destination buffer using bilinear 
-// interpolation.
-
-#ifndef __RFB_SCALEDPIXELBUFFER_H__
-#define __RFB_SCALEDPIXELBUFFER_H__
-
-#include <rdr/types.h>
-#include <rdr/Exception.h>
-#include <rfb/Rect.h>
-#include <rfb/PixelFormat.h>
-#include <rfb/ScaleFilters.h>
-
-using namespace rdr;
-
-namespace rfb {
-
-  struct UnsupportedPixelFormatException : public Exception {
-    UnsupportedPixelFormatException(const char* s="Now supported only true colour pixel data in the scaling mode.")
-      : Exception(s) {}
-  };
-
-  class ScaledPixelBuffer {
-  public:
-    ScaledPixelBuffer(U8 **data, int width, int height, int scale, PixelFormat pf);
-    ScaledPixelBuffer();
-    virtual ~ScaledPixelBuffer();
-
-    // Get width, height, number of pixels and scale
-    int width()  const { return scaled_width; }
-    int height() const { return scaled_height; }
-    int getSrcWidth()  const { return src_width; }
-    int getSrcHeight() const { return src_height; }
-    int area() const { return scaled_width * scaled_height; }
-    int getScale() const { return scale; }
-    double getScaleRatioX() const { return scale_ratio_x; }
-    double getScaleRatioY() const { return scale_ratio_y; }
-
-    // Pixel manipulation routines
-    inline U32 getSourcePixel(int x, int y);
-
-    // Get rectangle encompassing this buffer
-    //   Top-left of rectangle is either at (0,0), or the specified point.
-    Rect getRect() const { return Rect(0, 0, scaled_width, scaled_height); }
-    Rect getRect(const Point& pos) const {
-      return Rect(pos, pos.translate(Point(scaled_width, scaled_height)));
-    }
-
-    // Set the new source buffer and its parameters
-    void setSourceBuffer(U8 **src_data, int w, int h);
-
-    void setScaledBuffer(U8 **scaled_data_) {
-      scaled_data = scaled_data_;
-    };
-
-    // Set the new pixel format
-    void setPF(const PixelFormat &pf);
-
-    // Set the new scale, in percent
-    virtual void setScale(int scale);
-
-    // Set/get the scale method
-    virtual void setScaleFilter(unsigned int scaleFilterID);
-    unsigned int getScaleFilterID() const { return scaleFilterID; }
-
-    // Scale rect from the source image buffer to the destination buffer
-    // using the current interpolation method
-    virtual void scaleRect(const Rect& r);
-
-    // Calculate the scaled image rectangle which depend on the source 
-    // image rectangle.
-    Rect calculateScaleBoundary(const Rect& r);
-
-  protected:
-
-    // Calculate the scaled buffer size depending on the source buffer
-    // parameters (width, height, pixel format)
-    virtual void calculateScaledBufferSize();
-
-    // Free the weight tabs for x and y 
-    virtual void freeWeightTabs();
-
-    // Recreates the row accumulators.
-    virtual void recreateRowAccum();
-
-
-    int src_width;
-    int src_height;
-    int scaled_width;
-    int scaled_height;
-    int scale;
-    double scale_ratio_x;
-    double scale_ratio_y;
-    PixelFormat pf;
-    unsigned int scaleFilterID;
-    ScaleFilters scaleFilters;
-    SFilterWeightTab *xWeightTabs;
-    SFilterWeightTab *yWeightTabs;
-    int *raccum;
-    int *gaccum;
-    int *baccum;
-    U8 **src_data;
-    U8 **scaled_data;
-  };
-
-};
-
-#endif
diff --git a/common/rfb/Security.cxx b/common/rfb/Security.cxx
index 238f335..62ea50e 100644
--- a/common/rfb/Security.cxx
+++ b/common/rfb/Security.cxx
@@ -24,9 +24,6 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
-#ifdef _WIN32
-#define strcasecmp _stricmp
-#endif
 #include <rfb/CSecurityNone.h>
 #include <rfb/CSecurityStack.h>
 #include <rfb/CSecurityVeNCrypt.h>
diff --git a/common/rfb/TightDecoder.cxx b/common/rfb/TightDecoder.cxx
index b3d174a..d4ee877 100644
--- a/common/rfb/TightDecoder.cxx
+++ b/common/rfb/TightDecoder.cxx
@@ -37,11 +37,6 @@
 #include <rfb/tightDecode.h>
 #undef BPP
 
-Decoder* TightDecoder::create(CMsgReader* reader)
-{
-  return new TightDecoder(reader);
-}
-
 TightDecoder::TightDecoder(CMsgReader* reader_) : reader(reader_)
 {
 }
diff --git a/common/rfb/TightDecoder.h b/common/rfb/TightDecoder.h
index 5cdf873..8200d2b 100644
--- a/common/rfb/TightDecoder.h
+++ b/common/rfb/TightDecoder.h
@@ -28,9 +28,9 @@
   class TightDecoder : public Decoder {
 
   public:
-    static Decoder* create(CMsgReader* reader);
-    virtual void readRect(const Rect& r, CMsgHandler* handler);
+    TightDecoder(CMsgReader* reader);
     virtual ~TightDecoder();
+    virtual void readRect(const Rect& r, CMsgHandler* handler);
 
   private:
     void tightDecode8(const Rect& r);
@@ -54,8 +54,6 @@
     void directFillRect16(const Rect& r, Pixel pix);
     void directFillRect32(const Rect& r, Pixel pix);
 
-    TightDecoder(CMsgReader* reader);
-
     CMsgReader* reader;
     CMsgHandler* handler;
     rdr::InStream* is;
diff --git a/common/rfb/TightEncoder.cxx b/common/rfb/TightEncoder.cxx
index 9be4581..733365e 100644
--- a/common/rfb/TightEncoder.cxx
+++ b/common/rfb/TightEncoder.cxx
@@ -17,6 +17,7 @@
  * USA.
  */
 #include <rdr/OutStream.h>
+#include <rfb/TransImageGetter.h>
 #include <rfb/encodings.h>
 #include <rfb/ConnParams.h>
 #include <rfb/SMsgWriter.h>
@@ -63,16 +64,16 @@
 // 0 = JPEG quality 15,  4:2:0 subsampling (ratio ~= 100:1)
 
 const TIGHT_CONF TightEncoder::conf[10] = {
-  { 65536, 2048,   6, 0, 0, 0,   4, 24, 15, SUBSAMP_420 }, // 0
-  { 65536, 2048,   6, 1, 1, 1,   8, 24, 29, SUBSAMP_420 }, // 1
-  { 65536, 2048,   8, 3, 3, 2,  24, 96, 41, SUBSAMP_420 }, // 2
-  { 65536, 2048,  12, 5, 5, 2,  32, 96, 42, SUBSAMP_422 }, // 3
-  { 65536, 2048,  12, 6, 7, 3,  32, 96, 62, SUBSAMP_422 }, // 4
-  { 65536, 2048,  12, 7, 8, 4,  32, 96, 77, SUBSAMP_422 }, // 5
-  { 65536, 2048,  16, 7, 8, 5,  32, 96, 79, SUBSAMP_NONE }, // 6
-  { 65536, 2048,  16, 8, 9, 6,  64, 96, 86, SUBSAMP_NONE }, // 7
-  { 65536, 2048,  24, 9, 9, 7,  64, 96, 92, SUBSAMP_NONE }, // 8
-  { 65536, 2048,  32, 9, 9, 9,  96, 96,100, SUBSAMP_NONE }  // 9
+  { 65536, 2048,   6, 0, 0, 0,   4, 24, 15, subsample4X }, // 0
+  { 65536, 2048,   6, 1, 1, 1,   8, 24, 29, subsample4X }, // 1
+  { 65536, 2048,   8, 3, 3, 2,  24, 96, 41, subsample4X }, // 2
+  { 65536, 2048,  12, 5, 5, 2,  32, 96, 42, subsample2X }, // 3
+  { 65536, 2048,  12, 6, 7, 3,  32, 96, 62, subsample2X }, // 4
+  { 65536, 2048,  12, 7, 8, 4,  32, 96, 77, subsample2X }, // 5
+  { 65536, 2048,  16, 7, 8, 5,  32, 96, 79, subsampleNone }, // 6
+  { 65536, 2048,  16, 8, 9, 6,  64, 96, 86, subsampleNone }, // 7
+  { 65536, 2048,  24, 9, 9, 7,  64, 96, 92, subsampleNone }, // 8
+  { 65536, 2048,  32, 9, 9, 9,  96, 96,100, subsampleNone }  // 9
 };
 
 const int TightEncoder::defaultCompressLevel = 2;
@@ -91,11 +92,6 @@
 #include <rfb/tightEncode.h>
 #undef BPP
 
-Encoder* TightEncoder::create(SMsgWriter* writer)
-{
-  return new TightEncoder(writer);
-} 
-
 TightEncoder::TightEncoder(SMsgWriter* writer_) : writer(writer_)
 {
   setCompressLevel(defaultCompressLevel);
@@ -122,18 +118,14 @@
     jpegSubsampling = conf[level].jpegSubsampling;
   } else {
     jpegQuality = -1;
-    jpegSubsampling = SUBSAMP_UNDEFINED;
+    jpegSubsampling = subsampleUndefined;
   }
 }
 
-void TightEncoder::setFineQualityLevel(int quality, JPEG_SUBSAMP subsampling)
+void TightEncoder::setFineQualityLevel(int quality, int subsampling)
 {
-  if (quality >= 1 && quality <= 100) {
-    jpegQuality = quality;
-  }
-  if (subsampling >= SUBSAMP_NONE && subsampling <= SUBSAMP_GRAY) {
-    jpegSubsampling = subsampling;
-  }
+  jpegQuality = quality;
+  jpegSubsampling = subsampling;
 }
 
 bool TightEncoder::checkSolidTile(Rect& r, rdr::U32* colorPtr,
@@ -345,7 +337,7 @@
       sr.setXYWH(dx, dy, dw, dh);
       if (checkSolidTile(sr, &colorValue, false)) {
 
-         if (jpegSubsampling == SUBSAMP_GRAY && jpegQuality != -1) {
+         if (jpegSubsampling == subsampleGray && jpegQuality != -1) {
            Colour rgb;
            serverpf.rgbFromPixel(colorValue, NULL, &rgb);
            rdr::U32 lum = ((257 * rgb.r) + (504 * rgb.g) + (98 * rgb.b)
diff --git a/common/rfb/TightEncoder.h b/common/rfb/TightEncoder.h
index 4fff083..3632539 100644
--- a/common/rfb/TightEncoder.h
+++ b/common/rfb/TightEncoder.h
@@ -21,8 +21,8 @@
 
 #include <rdr/MemOutStream.h>
 #include <rdr/ZlibOutStream.h>
-#include <rfb/TransImageGetter.h>
 #include <rfb/Encoder.h>
+#include <rfb/JpegCompressor.h>
 
 // FIXME: Check if specifying extern "C" is really necessary.
 #include <stdio.h>
@@ -32,6 +32,8 @@
 
 namespace rfb {
 
+  class TransImageGetter;
+
   struct TIGHT_CONF {
     unsigned int maxRectSize, maxRectWidth;
     unsigned int monoMinRectSize;
@@ -39,7 +41,7 @@
     int idxMaxColorsDivisor;
     int palMaxColorsWithJPEG;
     int jpegQuality;
-    JPEG_SUBSAMP jpegSubsampling;
+    int jpegSubsampling;
   };
 
   //
@@ -77,16 +79,16 @@
   
   class TightEncoder : public Encoder {
   public:
-    static Encoder* create(SMsgWriter* writer);
-    virtual void setCompressLevel(int level);
-    virtual void setQualityLevel(int level);
-    virtual void setFineQualityLevel(int quality, JPEG_SUBSAMP subsampling);
-    virtual int getNumRects(const Rect &r);
-    virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual);
+    TightEncoder(SMsgWriter* writer);
     virtual ~TightEncoder();
 
+    virtual void setCompressLevel(int level);
+    virtual void setQualityLevel(int level);
+    virtual void setFineQualityLevel(int quality, int subsampling);
+    virtual int getNumRects(const Rect &r);
+    virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual);
+
   private:
-    TightEncoder(SMsgWriter* writer);
     bool checkSolidTile(Rect& r, rdr::U32* colorPtr, bool needSameColor);
     void extendSolidArea(const Rect& r, rdr::U32 colorValue, Rect& er);
     void findBestSolidArea(Rect& r, rdr::U32 colorValue, Rect& bestr);
@@ -157,7 +159,7 @@
 
     const TIGHT_CONF* pconf;
     int jpegQuality;
-    JPEG_SUBSAMP jpegSubsampling;
+    int jpegSubsampling;
   };
 
 }
diff --git a/common/rfb/TransImageGetter.cxx b/common/rfb/TransImageGetter.cxx
index c1add1c..3900d06 100644
--- a/common/rfb/TransImageGetter.cxx
+++ b/common/rfb/TransImageGetter.cxx
@@ -56,18 +56,18 @@
   PixelTransformer::setColourMapEntries(firstCol, nCols);
 }
 
-const rdr::U8 *TransImageGetter::getRawPixelsR(const Rect &r, int *stride)
+const rdr::U8 *TransImageGetter::getRawBufferR(const Rect &r, int *stride)
 {
   if (!offset.equals(Point(0, 0)))
-    return pb->getPixelsR(r.translate(offset.negate()), stride);
+    return pb->getBuffer(r.translate(offset.negate()), stride);
   else
-    return pb->getPixelsR(r, stride);
+    return pb->getBuffer(r, stride);
 }
 
 void TransImageGetter::getImage(void* outPtr, const Rect& r, int outStride)
 {
   int inStride;
-  const rdr::U8* inPtr = pb->getPixelsR(r.translate(offset.negate()), &inStride);
+  const rdr::U8* inPtr = pb->getBuffer(r.translate(offset.negate()), &inStride);
 
   if (!outStride) outStride = r.width();
 
diff --git a/common/rfb/TransImageGetter.h b/common/rfb/TransImageGetter.h
index f2b35b4..b241b83 100644
--- a/common/rfb/TransImageGetter.h
+++ b/common/rfb/TransImageGetter.h
@@ -72,11 +72,11 @@
     // padding will be outStride-r.width() pixels).
     void getImage(void* outPtr, const Rect& r, int outStride=0);
 
-    // getRawPixelsR() gets the given rectangle of data directly from the
+    // getRawBufferR() gets the given rectangle of data directly from the
     // underlying PixelBuffer, bypassing the translation logic. Only use
     // this when doing something that's independent of the client's pixel
     // format.
-    const rdr::U8 *getRawPixelsR(const Rect &r, int *stride);
+    const rdr::U8 *getRawBufferR(const Rect &r, int *stride);
 
     // setPixelBuffer() changes the pixel buffer to be used.  The new pixel
     // buffer MUST have the same pixel format as the old one - if not you
diff --git a/common/rfb/ZRLEDecoder.cxx b/common/rfb/ZRLEDecoder.cxx
index aba7fc9..111e2de 100644
--- a/common/rfb/ZRLEDecoder.cxx
+++ b/common/rfb/ZRLEDecoder.cxx
@@ -40,11 +40,6 @@
 #undef CPIXEL
 #undef BPP
 
-Decoder* ZRLEDecoder::create(CMsgReader* reader)
-{
-  return new ZRLEDecoder(reader);
-}
-
 ZRLEDecoder::ZRLEDecoder(CMsgReader* reader_) : reader(reader_)
 {
 }
diff --git a/common/rfb/ZRLEDecoder.h b/common/rfb/ZRLEDecoder.h
index fe96c73..2128ab9 100644
--- a/common/rfb/ZRLEDecoder.h
+++ b/common/rfb/ZRLEDecoder.h
@@ -25,11 +25,10 @@
 
   class ZRLEDecoder : public Decoder {
   public:
-    static Decoder* create(CMsgReader* reader);
-    virtual void readRect(const Rect& r, CMsgHandler* handler);
-    virtual ~ZRLEDecoder();
-  private:
     ZRLEDecoder(CMsgReader* reader);
+    virtual ~ZRLEDecoder();
+    virtual void readRect(const Rect& r, CMsgHandler* handler);
+  private:
     CMsgReader* reader;
     rdr::ZlibInStream zis;
   };
diff --git a/common/rfb/ZRLEEncoder.cxx b/common/rfb/ZRLEEncoder.cxx
index a83d79f..e70706b 100644
--- a/common/rfb/ZRLEEncoder.cxx
+++ b/common/rfb/ZRLEEncoder.cxx
@@ -17,7 +17,7 @@
  */
 #include <rdr/OutStream.h>
 #include <rfb/Exception.h>
-#include <rfb/ImageGetter.h>
+#include <rfb/TransImageGetter.h>
 #include <rfb/encodings.h>
 #include <rfb/ConnParams.h>
 #include <rfb/SMsgWriter.h>
@@ -26,9 +26,6 @@
 
 using namespace rfb;
 
-rdr::MemOutStream* ZRLEEncoder::sharedMos = 0;
-int ZRLEEncoder::maxLen = 4097 * 1024; // enough for width 16384 32-bit pixels
-
 IntParameter zlibLevel("ZlibLevel","Zlib compression level",-1);
 
 #define EXTRA_ARGS ImageGetter* ig
@@ -49,39 +46,28 @@
 #undef CPIXEL
 #undef BPP
 
-Encoder* ZRLEEncoder::create(SMsgWriter* writer)
-{
-  return new ZRLEEncoder(writer);
-}
-
 ZRLEEncoder::ZRLEEncoder(SMsgWriter* writer_)
-  : writer(writer_), zos(0,0,zlibLevel)
+  : writer(writer_), zos(0,0,zlibLevel), mos(129*1024)
 {
-  if (sharedMos)
-    mos = sharedMos;
-  else
-    mos = new rdr::MemOutStream(129*1024);
 }
 
 ZRLEEncoder::~ZRLEEncoder()
 {
-  if (!sharedMos)
-    delete mos;
 }
 
 bool ZRLEEncoder::writeRect(const Rect& r, TransImageGetter* ig, Rect* actual)
 {
   rdr::U8* imageBuf = writer->getImageBuf(64 * 64 * 4 + 4);
-  mos->clear();
+  mos.clear();
   bool wroteAll = true;
   *actual = r;
 
   switch (writer->bpp()) {
   case 8:
-    wroteAll = zrleEncode8(r, mos, &zos, imageBuf, maxLen, actual, ig);
+    wroteAll = zrleEncode8(r, &mos, &zos, imageBuf, actual, ig);
     break;
   case 16:
-    wroteAll = zrleEncode16(r, mos, &zos, imageBuf, maxLen, actual, ig);
+    wroteAll = zrleEncode16(r, &mos, &zos, imageBuf, actual, ig);
     break;
   case 32:
     {
@@ -94,16 +80,16 @@
       if ((fitsInLS3Bytes && pf.isLittleEndian()) ||
           (fitsInMS3Bytes && pf.isBigEndian()))
       {
-        wroteAll = zrleEncode24A(r, mos, &zos, imageBuf, maxLen, actual, ig);
+        wroteAll = zrleEncode24A(r, &mos, &zos, imageBuf, actual, ig);
       }
       else if ((fitsInLS3Bytes && pf.isBigEndian()) ||
                (fitsInMS3Bytes && pf.isLittleEndian()))
       {
-        wroteAll = zrleEncode24B(r, mos, &zos, imageBuf, maxLen, actual, ig);
+        wroteAll = zrleEncode24B(r, &mos, &zos, imageBuf, actual, ig);
       }
       else
       {
-        wroteAll = zrleEncode32(r, mos, &zos, imageBuf, maxLen, actual, ig);
+        wroteAll = zrleEncode32(r, &mos, &zos, imageBuf, actual, ig);
       }
       break;
     }
@@ -111,8 +97,8 @@
 
   writer->startRect(*actual, encodingZRLE);
   rdr::OutStream* os = writer->getOutStream();
-  os->writeU32(mos->length());
-  os->writeBytes(mos->data(), mos->length());
+  os->writeU32(mos.length());
+  os->writeBytes(mos.data(), mos.length());
   writer->endRect();
   return wroteAll;
 }
diff --git a/common/rfb/ZRLEEncoder.h b/common/rfb/ZRLEEncoder.h
index 3a0f52a..e3517c1 100644
--- a/common/rfb/ZRLEEncoder.h
+++ b/common/rfb/ZRLEEncoder.h
@@ -26,29 +26,13 @@
 
   class ZRLEEncoder : public Encoder {
   public:
-    static Encoder* create(SMsgWriter* writer);
-    virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual);
-    virtual ~ZRLEEncoder();
-
-    // setMaxLen() sets the maximum size in bytes of any ZRLE rectangle.  This
-    // can be used to stop the MemOutStream from growing too large.  The value
-    // must be large enough to allow for at least one row of ZRLE tiles.  So
-    // for example for a screen width of 2048 32-bit pixels this is 2K*4*64 =
-    // 512Kbytes plus a bit of overhead (the overhead is about 1/16 of the
-    // width, in this example about 128 bytes).
-    static void setMaxLen(int m) { maxLen = m; }
-
-    // setSharedMos() sets a MemOutStream to be shared amongst all
-    // ZRLEEncoders.  Should be called before any ZRLEEncoders are created.
-    static void setSharedMos(rdr::MemOutStream* mos_) { sharedMos = mos_; }
-
-  private:
     ZRLEEncoder(SMsgWriter* writer);
+    virtual ~ZRLEEncoder();
+    virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual);
+  private:
     SMsgWriter* writer;
     rdr::ZlibOutStream zos;
-    rdr::MemOutStream* mos;
-    static rdr::MemOutStream* sharedMos;
-    static int maxLen;
+    rdr::MemOutStream mos;
   };
 }
 #endif
diff --git a/common/rfb/encodings.cxx b/common/rfb/encodings.cxx
index 97f547b..190e032 100644
--- a/common/rfb/encodings.cxx
+++ b/common/rfb/encodings.cxx
@@ -16,9 +16,6 @@
  * USA.
  */
 #include <string.h>
-#ifdef _WIN32
-#define strcasecmp _stricmp
-#endif
 #include <rfb/encodings.h>
 #include <rfb/util.h>
 
diff --git a/common/rfb/hextileDecode.h b/common/rfb/hextileDecode.h
index 77befc7..7aa04d9 100644
--- a/common/rfb/hextileDecode.h
+++ b/common/rfb/hextileDecode.h
@@ -69,13 +69,9 @@
       if (tileType & hextileBgSpecified)
 	bg = is->READ_PIXEL();
 
-#ifdef FAVOUR_FILL_RECT
-      FILL_RECT(t, bg);
-#else
       int len = t.area();
       PIXEL_T* ptr = (PIXEL_T*)buf;
       while (len-- > 0) *ptr++ = bg;
-#endif
 
       if (tileType & hextileFgSpecified)
 	fg = is->READ_PIXEL();
@@ -91,14 +87,6 @@
           int xy = is->readU8();
           int wh = is->readU8();
 
-#ifdef FAVOUR_FILL_RECT
-          Rect s;
-          s.tl.x = t.tl.x + ((xy >> 4) & 15);
-          s.tl.y = t.tl.y + (xy & 15);
-          s.br.x = s.tl.x + ((wh >> 4) & 15) + 1;
-          s.br.y = s.tl.y + (wh & 15) + 1;
-          FILL_RECT(s, fg);
-#else
           int x = ((xy >> 4) & 15);
           int y = (xy & 15);
           int w = ((wh >> 4) & 15) + 1;
@@ -110,12 +98,9 @@
             while (len-- > 0) *ptr++ = fg;
             ptr += rowAdd;
           }
-#endif
         }
       }
-#ifndef FAVOUR_FILL_RECT
       IMAGE_RECT(t, buf);
-#endif
     }
   }
 }
diff --git a/common/rfb/tightDecode.h b/common/rfb/tightDecode.h
index e9f5f6b..06c8477 100644
--- a/common/rfb/tightDecode.h
+++ b/common/rfb/tightDecode.h
@@ -156,7 +156,7 @@
 
   PIXEL_T *buf;
   int stride = r.width();
-  if (directDecode) buf = (PIXEL_T *)handler->getRawPixelsRW(r, &stride);
+  if (directDecode) buf = (PIXEL_T *)handler->getRawBufferRW(r, &stride);
   else buf = (PIXEL_T *)reader->getImageBuf(r.area());
 
   if (palSize == 0) {
@@ -228,7 +228,7 @@
     }
   }
 
-  if (directDecode) handler->releaseRawPixels(r);
+  if (directDecode) handler->releaseRawBuffer(r);
   else IMAGE_RECT(r, buf);
 
   delete [] netbuf;
@@ -256,10 +256,9 @@
 
   // We always use direct decoding with JPEG images
   int stride;
-  rdr::U8 *buf = handler->getRawPixelsRW(r, &stride);
-  jd.decompress(netbuf, compressedLen, buf, stride * clientpf.bpp / 8, r,
-                clientpf);
-  handler->releaseRawPixels(r);
+  rdr::U8 *buf = handler->getRawBufferRW(r, &stride);
+  jd.decompress(netbuf, compressedLen, buf, stride, r, clientpf);
+  handler->releaseRawBuffer(r);
 
   delete [] netbuf;
 }
diff --git a/common/rfb/tightEncode.h b/common/rfb/tightEncode.h
index 8f900b5..c121b7a 100644
--- a/common/rfb/tightEncode.h
+++ b/common/rfb/tightEncode.h
@@ -191,9 +191,9 @@
 {
   int stride;
   rdr::U32 solidColor;
-  const PIXEL_T *rawPixels = (const PIXEL_T *)ig->getRawPixelsR(r, &stride);
+  const PIXEL_T *rawPixels = (const PIXEL_T *)ig->getRawBufferR(r, &stride);
   PIXEL_T *pixels = NULL;
-  bool grayScaleJPEG = (jpegSubsampling == SUBSAMP_GRAY && jpegQuality != -1);
+  bool grayScaleJPEG = (jpegSubsampling == subsampleGray && jpegQuality != -1);
 
 #if (BPP == 32)
   // Check if it's necessary to pack 24-bit pixels, and
@@ -412,7 +412,7 @@
                        rdr::OutStream *os)
 {
   jc.clear();
-  jc.compress((rdr::U8 *)buf, stride * clientpf.bpp / 8, r, clientpf,
+  jc.compress((rdr::U8 *)buf, stride, r, clientpf,
     jpegQuality, jpegSubsampling);
   os->writeU8(0x09 << 4);
   os->writeCompactLength(jc.length());
@@ -540,12 +540,7 @@
     *dataend = &data[stride * h];
   bool willTransform = ig->willTransform();
 
-  if (willTransform) {
-    mask = serverpf.redMax << serverpf.redShift;
-    mask |= serverpf.greenMax << serverpf.greenShift;
-    mask |= serverpf.blueMax << serverpf.blueShift;
-  }
-  else mask = ~0;
+  serverpf.bufferFromPixel((rdr::U8*)&mask, ~0);
 
   c0 = data[0] & mask;
   n0 = 0;
@@ -650,7 +645,7 @@
   int w = r.width(), h = r.height();
 
   int stride = w;
-  buf = (const PIXEL_T *)ig->getRawPixelsR(r, &stride);
+  buf = (const PIXEL_T *)ig->getRawBufferR(r, &stride);
 
   colorValue = *buf;
   if (needSameColor && (rdr::U32)colorValue != *colorPtr)
diff --git a/common/rfb/util.cxx b/common/rfb/util.cxx
index 2709f2c..a41ad96 100644
--- a/common/rfb/util.cxx
+++ b/common/rfb/util.cxx
@@ -38,97 +38,6 @@
 
 #include <rfb/util.h>
 
-// Provide strcasecmp() and/or strncasecmp() if absent on this system.
-
-#ifndef WIN32
-#if !defined(HAVE_STRCASECMP) || !defined(HAVE_STRNCASECMP)
-
-extern "C" {
-
-/*
- * This array is designed for mapping upper and lower case letter
- * together for a case independent comparison.  The mappings are
- * based upon ascii character sequences.
- */
-static unsigned char s_charmap[] = {
-	'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
-	'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
-	'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
-	'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
-	'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
-	'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
-	'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
-	'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
-	'\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
-	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
-	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
-	'\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
-	'\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
-	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
-	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
-	'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
-	'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
-	'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
-	'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
-	'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
-	'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
-	'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
-	'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
-	'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
-	'\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
-	'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
-	'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
-	'\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
-	'\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
-	'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
-	'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
-	'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
-};
-
-#ifndef HAVE_STRCASECMP
-int
-strcasecmp(const char *s1, const char *s2)
-{
-    unsigned char u1, u2;
-
-    for (;;) {
-	u1 = (unsigned char) *s1++;
-	u2 = (unsigned char) *s2++;
-	if (s_charmap[u1] != s_charmap[u2]) {
-	    return s_charmap[u1] - s_charmap[u2];
-	}
-	if (u1 == '\0') {
-	    return 0;
-	}
-    }
-}
-#endif // !defined(HAVE_STRCASECMP)
-
-#ifndef HAVE_STRNCASECMP
-int
-strncasecmp(const char *s1, const char *s2, size_t n)
-{
-    unsigned char u1, u2;
-
-    for (; n != 0; --n) {
-	u1 = (unsigned char) *s1++;
-	u2 = (unsigned char) *s2++;
-	if (s_charmap[u1] != s_charmap[u2]) {
-	    return s_charmap[u1] - s_charmap[u2];
-	}
-	if (u1 == '\0') {
-	    return 0;
-	}
-    }
-    return 0;
-}
-#endif // !defined(HAVE_STRNCASECMP)
-
-} // extern "C"
-
-#endif // !defined(HAVE_STRCASECMP) || !defined(HAVE_STRNCASECMP)
-#endif // defined(WIN32)
-
 namespace rfb {
 
   char* strDup(const char* s) {
diff --git a/common/rfb/util.h b/common/rfb/util.h
index 7d90a6b..13dbe68 100644
--- a/common/rfb/util.h
+++ b/common/rfb/util.h
@@ -104,17 +104,4 @@
 #define __rfbmin(a,b) (((a) < (b)) ? (a) : (b))
 #endif
 
-// Declare strcasecmp() and/or strncasecmp() if absent on this system.
-
-#if !defined(WIN32) && !defined(HAVE_STRCASECMP)
-extern "C" {
-  int strcasecmp(const char *s1, const char *s2);
-}
-#endif
-#if !defined(WIN32) && !defined(HAVE_STRNCASECMP)
-extern "C" {
-  int strncasecmp(const char *s1, const char *s2, size_t n);
-}
-#endif
-
 #endif
diff --git a/common/rfb/zrleDecode.h b/common/rfb/zrleDecode.h
index 8f6f792..d26d4d3 100644
--- a/common/rfb/zrleDecode.h
+++ b/common/rfb/zrleDecode.h
@@ -121,12 +121,6 @@
           }
         }
 
-#ifdef FAVOUR_FILL_RECT
-       //fprintf(stderr,"copying data to screen %dx%d at %d,%d\n",
-        //t.width(),t.height(),t.tl.x,t.tl.y);
-        IMAGE_RECT(t,buf);
-#endif
-
       } else {
 
         if (palSize == 0) {
@@ -149,36 +143,7 @@
               throw Exception ("ZRLE decode error");
             }
 
-#ifdef FAVOUR_FILL_RECT
-            int i = ptr - buf;
-            ptr += len;
-
-            int runX = i % t.width();
-            int runY = i / t.width();
-
-            if (runX + len > t.width()) {
-              if (runX != 0) {
-                FILL_RECT(Rect(t.tl.x+runX, t.tl.y+runY, t.width()-runX, 1),
-                          pix);
-                len -= t.width()-runX;
-                runX = 0;
-                runY++;
-              }
-
-              if (len > t.width()) {
-                FILL_RECT(Rect(t.tl.x, t.tl.y+runY, t.width(), len/t.width()),
-                          pix);
-                runY += len / t.width();
-                len = len % t.width();
-              }
-            }
-
-            if (len != 0) {
-              FILL_RECT(Rect(t.tl.x+runX, t.tl.y+runY, len, 1), pix);
-            }
-#else
             while (len-- > 0) *ptr++ = pix;
-#endif
 
           }
         } else {
@@ -207,45 +172,14 @@
 
             PIXEL_T pix = palette[index];
 
-#ifdef FAVOUR_FILL_RECT
-            int i = ptr - buf;
-            ptr += len;
-
-            int runX = i % t.width();
-            int runY = i / t.width();
-
-            if (runX + len > t.width()) {
-              if (runX != 0) {
-                FILL_RECT(Rect(t.tl.x+runX, t.tl.y+runY, t.width()-runX, 1),
-                          pix);
-                len -= t.width()-runX;
-                runX = 0;
-                runY++;
-              }
-
-              if (len > t.width()) {
-                FILL_RECT(Rect(t.tl.x, t.tl.y+runY, t.width(), len/t.width()),
-                          pix);
-                runY += len / t.width();
-                len = len % t.width();
-              }
-            }
-
-            if (len != 0) {
-              FILL_RECT(Rect(t.tl.x+runX, t.tl.y+runY, len, 1), pix);
-            }
-#else
             while (len-- > 0) *ptr++ = pix;
-#endif
           }
         }
       }
 
-#ifndef FAVOUR_FILL_RECT
       //fprintf(stderr,"copying data to screen %dx%d at %d,%d\n",
       //t.width(),t.height(),t.tl.x,t.tl.y);
       IMAGE_RECT(t,buf);
-#endif
     }
   }
 
diff --git a/common/rfb/zrleEncode.h b/common/rfb/zrleEncode.h
index 9b7263b..0c622b8 100644
--- a/common/rfb/zrleEncode.h
+++ b/common/rfb/zrleEncode.h
@@ -115,7 +115,7 @@
 void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, rdr::OutStream* os);
 
 bool ZRLE_ENCODE (const Rect& r, rdr::OutStream* os,
-                  rdr::ZlibOutStream* zos, void* buf, int maxLen, Rect* actual
+                  rdr::ZlibOutStream* zos, void* buf, Rect* actual
 #ifdef EXTRA_ARGS
                   , EXTRA_ARGS
 #endif
@@ -132,7 +132,8 @@
 
     t.br.y = __rfbmin(r.br.y, t.tl.y + 64);
 
-    if (os->length() + worstCaseLine > maxLen) {
+    // enough for width 16384 32-bit pixels
+    if (os->length() + worstCaseLine > 4097 * 1024) {
       if (t.tl.y == r.tl.y)
         throw Exception("ZRLE: not enough space for first line?");
       actual->tl = r.tl;
diff --git a/config.h.in b/config.h.in
index ec2aed9..0c9e71a 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1,14 +1,8 @@
 #define PACKAGE_NAME "@CMAKE_PROJECT_NAME@"
 #define PACKAGE_VERSION "@VERSION@"
 
-#cmakedefine HAVE_SOCKLEN_T
 #cmakedefine HAVE_INET_ATON
-#cmakedefine HAVE_INET_NTOP
 #cmakedefine HAVE_GETADDRINFO
-#cmakedefine HAVE_SNPRINTF
-#cmakedefine HAVE_STRCASECMP
-#cmakedefine HAVE_STRNCASECMP
-#cmakedefine HAVE_VSNPRINTF
 #cmakedefine HAVE_GNUTLS_SET_GLOBAL_ERRNO
 #cmakedefine HAVE_GNUTLS_SET_ERRNO
 #cmakedefine HAVE_GNUTLS_X509_CRT_PRINT
diff --git a/unix/tx/CMakeLists.txt b/unix/tx/CMakeLists.txt
index ab46f03..6797615 100644
--- a/unix/tx/CMakeLists.txt
+++ b/unix/tx/CMakeLists.txt
@@ -4,10 +4,6 @@
 include_directories(${CMAKE_SOURCE_DIR}/common/rfb)
 
 add_library(tx STATIC
-  TXWindow.cxx
-  TXScrollbar.cxx
-  TXViewport.cxx
-  TXImage.cxx
-  TXMenu.cxx)
+  TXWindow.cxx)
 
 target_link_libraries(tx ${X11_LIBRARIES})
diff --git a/unix/tx/TXEntry.h b/unix/tx/TXEntry.h
deleted file mode 100644
index 1785a5f..0000000
--- a/unix/tx/TXEntry.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-//
-// TXEntry.h
-//
-// A TXEntry allows you to enter a single line of text in a window.  The entry
-// must be tall enough to contain a line of text - if not then it will be
-// resized appropriately.  If the passwd argument to the constructor is true,
-// then the text in the entry will be replaced by asterisks on the screen.
-//
-
-#ifndef __TXENTRY_H__
-#define __TXENTRY_H__
-
-#include "TXWindow.h"
-#include <X11/keysym.h>
-
-#ifndef XK_ISO_Left_Tab
-#define	XK_ISO_Left_Tab					0xFE20
-#endif
-#ifndef XK_KP_Delete
-#define XK_KP_Delete					0xFF9F
-#endif
-
-// TXEntryCallback's entryCallback() method is called when one of three special
-// key presses have happened: Enter/Return, forward tab, or backward tab.
-class TXEntry;
-class TXEntryCallback {
-public:
-  enum Detail { ENTER, NEXT_FOCUS, PREV_FOCUS };
-  virtual void entryCallback(TXEntry* entry, Detail detail, Time time)=0;
-};
-
-
-class TXEntry : public TXWindow, public TXEventHandler {
-public:
-
-  TXEntry(Display* dpy_, TXEntryCallback* cb_=0,
-          TXWindow* parent_=0, bool passwd_=false, int w=1, int h=1)
-    : TXWindow(dpy_, w, h, parent_), cb(cb_),
-      passwd(passwd_), disabled_(false), gotFocus(false)
-  {
-    setEventHandler(this);
-    gc = XCreateGC(dpy, win(), 0, 0);
-    addEventMask(ExposureMask | KeyPressMask | FocusChangeMask
-                 | ButtonPressMask);
-    text[0] = 0;
-    int textHeight = (defaultFS->ascent + defaultFS->descent);
-    int newHeight = __rfbmax(height(), textHeight + yPad*2 + bevel*2);
-    if (height() < newHeight) {
-      resize(width(), newHeight);
-    }
-  }
-
-  virtual ~TXEntry() {
-    XFreeGC(dpy, gc);
-    // overwrite memory used to store password - not critical, but can avoid
-    // accidental exposure of a password in uninitialised memory.
-    if (passwd)
-      memset(text, 0, maxLen);
-  }
-
-  // getText() gets the text in the entry.
-  const char* getText() { return text; }
-
-  // setText() sets the text in the entry.
-  void setText(const char* text_) {
-    strncpy(text, text_, maxLen-1);
-    text[maxLen-1] = 0;
-    paint();
-  }
-
-  // disabled() sets or queries the disabled state of the entry.  A disabled
-  // entry cannot have text entered into it.
-  void disabled(bool b) { disabled_ = b; paint(); }
-  bool disabled() { return disabled_; }
-
-private:
-  void paint() {
-    if (disabled_)
-      drawBevel(gc, 0, 0, width(), height(), bevel, disabledBg,darkBg,lightBg);
-    else
-      drawBevel(gc, 0, 0, width(), height(), bevel, enabledBg, darkBg,lightBg);
-    char* str = text;
-    char stars[maxLen];
-    if (passwd) {
-      int i;
-      for (i = 0; i < (int)strlen(text); i++) stars[i] = '*';
-      stars[i] = 0;
-      str = stars;
-    }
-    int tw = XTextWidth(defaultFS, str, strlen(str));
-    int startx = bevel + xPad;
-    if (startx + tw > width() - 2*bevel) {
-      startx = width() - 2*bevel - tw;
-    }
-    XDrawString(dpy, win(), defaultGC, startx,
-                (height() + defaultFS->ascent - defaultFS->descent) / 2,
-                str, strlen(str));
-    if (!disabled_ && gotFocus)
-      XDrawLine(dpy, win(), defaultGC, startx+tw,
-                (height() - defaultFS->ascent - defaultFS->descent) / 2,
-                startx+tw,
-                (height() + defaultFS->ascent + defaultFS->descent) / 2);
-  }
-
-  virtual void handleEvent(TXWindow* w, XEvent* ev) {
-    switch (ev->type) {
-    case Expose:
-      paint();
-      break;
-
-    case FocusIn:
-      gotFocus = true;
-      paint();
-      break;
-
-    case FocusOut:
-      gotFocus = false;
-      paint();
-      break;
-
-    case ButtonPress:
-      if (!disabled_)
-        XSetInputFocus(dpy, win(), RevertToParent, ev->xbutton.time);
-      break;
-
-    case KeyPress:
-      {
-        if (disabled_ || !gotFocus) break;
-        KeySym keysym;
-        XComposeStatus compose;
-        char buf[10];
-        int count = XLookupString(&ev->xkey, buf, 10, &keysym, &compose);
-        if (count >= 1 && buf[0] >= ' ' && buf[0] <= '~') {
-          if (strlen(text) + count >= maxLen) {
-            XBell(dpy, 0);
-          } else {
-            strncat(text, buf, count);
-            paint();
-          }
-        } else if (keysym == XK_BackSpace || keysym == XK_Delete ||
-                   keysym == XK_KP_Delete) {
-          if (strlen(text) > 0) {
-            text[strlen(text)-1] = 0;
-            paint();
-          }
-        } else if (keysym == XK_Return || keysym == XK_KP_Enter ||
-                   keysym == XK_Linefeed) {
-          if (cb) cb->entryCallback(this, TXEntryCallback::ENTER,
-                                    ev->xkey.time);
-        } else if ((keysym == XK_Tab || keysym == XK_KP_Tab)
-                   && !(ev->xkey.state & ShiftMask))
-        {
-          if (cb) cb->entryCallback(this, TXEntryCallback::NEXT_FOCUS,
-                                    ev->xkey.time);
-        } else if (((keysym == XK_Tab || keysym == XK_KP_Tab)
-                    && (ev->xkey.state & ShiftMask))
-                   || keysym == XK_ISO_Left_Tab)
-        {
-          if (cb) cb->entryCallback(this, TXEntryCallback::PREV_FOCUS,
-                                    ev->xkey.time);
-        }
-      }
-    }
-  }
-  GC gc;
-  enum { maxLen = 256 };
-  char text[maxLen];
-  TXEntryCallback* cb;
-  bool passwd;
-  bool disabled_;
-  bool gotFocus;
-};
-
-#endif
diff --git a/unix/tx/TXImage.cxx b/unix/tx/TXImage.cxx
deleted file mode 100644
index db20d6f..0000000
--- a/unix/tx/TXImage.cxx
+++ /dev/null
@@ -1,361 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-//
-// TXImage.cxx
-//
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <strings.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <list>
-#include <rfb/TransImageGetter.h>
-#include <rfb/Exception.h>
-#include <rfb/LogWriter.h>
-#include "TXWindow.h"
-#include "TXImage.h"
-
-using namespace rfb;
-
-static rfb::LogWriter vlog("TXImage");
-
-TXImage::TXImage(Display* d, int width, int height, Visual* vis_, int depth_)
-  : xim(0), dpy(d), vis(vis_), depth(depth_), tig(0), cube(0)
-{
-#ifdef HAVE_MITSHM
-  shminfo = 0;
-#endif
-  width_ = width;
-  height_ = height;
-  for (int i = 0; i < 256; i++)
-    colourMap[i].r = colourMap[i].g = colourMap[i].b = 0;
-
-  if (!vis)
-    vis = DefaultVisual(dpy,DefaultScreen(dpy));
-  if (!depth)
-    depth = DefaultDepth(dpy,DefaultScreen(dpy));
-
-  createXImage();
-  getNativePixelFormat(vis, depth);
-  colourmap = this;
-  format.bpp = 0;  // just make it different to any valid format, so that...
-  setPF(nativePF); // ...setPF() always works
-}
-
-TXImage::~TXImage()
-{
-  if (data != (rdr::U8*)xim->data) delete [] data;
-  destroyXImage();
-  delete tig;
-  delete cube;
-}
-
-void TXImage::resize(int w, int h)
-{
-  if (w == width() && h == height()) return;
-
-  int oldStrideBytes = getStride() * (format.bpp/8);
-  int rowsToCopy = __rfbmin(h, height());
-  int bytesPerRow = __rfbmin(w, width()) * (format.bpp/8);
-  rdr::U8* oldData = 0;
-  bool allocData = false;
-
-  if (data != (rdr::U8*)xim->data) {
-    oldData = (rdr::U8*)data;
-    allocData = true;
-  } else {
-    oldData = new rdr::U8[xim->bytes_per_line * height()];
-    memcpy(oldData, xim->data, xim->bytes_per_line * height());
-  }
-
-  destroyXImage();
-  width_ = w;
-  height_ = h;
-  createXImage();
-
-  if (allocData)
-    data = new rdr::U8[width() * height() * (format.bpp/8)];
-  else
-    data = (rdr::U8*)xim->data;
-
-  int newStrideBytes = getStride() * (format.bpp/8);
-  for (int i = 0; i < rowsToCopy; i++)
-    memcpy((rdr::U8*)data + newStrideBytes * i, oldData + oldStrideBytes * i,
-           bytesPerRow);
-  delete [] oldData;
-}
-
-void TXImage::setPF(const PixelFormat& newPF)
-{
-  if (newPF.equal(format)) return;
-  format = newPF;
-
-  if (data != (rdr::U8*)xim->data) delete [] data;
-  delete tig;
-  tig = 0;
-
-  if (format.equal(nativePF) && format.trueColour) {
-    data = (rdr::U8*)xim->data;
-  } else {
-    data = new rdr::U8[width() * height() * (format.bpp/8)];
-    tig = new TransImageGetter();
-    tig->init(this, nativePF, 0, cube);
-  }
-}
-
-int TXImage::getStride() const
-{
-  if (data == (rdr::U8*)xim->data)
-    return xim->bytes_per_line / (xim->bits_per_pixel / 8);
-  else
-    return width();
-}
-
-void TXImage::put(Window win, GC gc, const rfb::Rect& r)
-{
-  if (r.is_empty()) return;
-  int x = r.tl.x;
-  int y = r.tl.y;
-  int w = r.width();
-  int h = r.height();
-  if (data != (rdr::U8*)xim->data) {
-    rdr::U8* ximDataStart = ((rdr::U8*)xim->data + y * xim->bytes_per_line
-                             + x * (xim->bits_per_pixel / 8));
-    tig->getImage(ximDataStart, r,
-                  xim->bytes_per_line / (xim->bits_per_pixel / 8));
-  }
-#ifdef HAVE_MITSHM
-  if (usingShm()) {
-    XShmPutImage(dpy, win, gc, xim, x, y, x, y, w, h, False);
-    return;
-  }
-#endif
-  XPutImage(dpy, win, gc, xim, x, y, x, y, w, h);
-}
-
-void TXImage::setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs)
-{
-  for (int i = 0; i < nColours; i++) {
-    colourMap[firstColour+i].r = rgbs[i*3];
-    colourMap[firstColour+i].g = rgbs[i*3+1];
-    colourMap[firstColour+i].b = rgbs[i*3+2];
-  }
-}
-
-void TXImage::updateColourMap()
-{
-  if (tig != 0)
-    tig->setColourMapEntries(0, 0);
-}
-
-void TXImage::lookup(int index, int* r, int* g, int* b)
-{
-  *r = colourMap[index].r;
-  *g = colourMap[index].g;
-  *b = colourMap[index].b;
-}
-
-#ifdef HAVE_MITSHM
-static bool caughtError = false;
-
-static int XShmAttachErrorHandler(Display *dpy, XErrorEvent *error)
-{
-  caughtError = true;
-  return 0;
-}
-
-class TXImageCleanup {
-public:
-  std::list<TXImage*> images;
-  ~TXImageCleanup() {
-    while (!images.empty())
-      delete images.front();
-  }
-};
-
-static TXImageCleanup imageCleanup;
-#endif
-
-void TXImage::createXImage()
-{
-#ifdef HAVE_MITSHM
-  int major, minor;
-  Bool pixmaps;
-
-  if (XShmQueryVersion(dpy, &major, &minor, &pixmaps)) {
-    shminfo = new XShmSegmentInfo;
-
-    xim = XShmCreateImage(dpy, vis, depth, ZPixmap,
-                          0, shminfo, width(), height());
-
-    if (xim) {
-      shminfo->shmid = shmget(IPC_PRIVATE,
-                              xim->bytes_per_line * xim->height,
-                              IPC_CREAT|0777);
-
-      if (shminfo->shmid != -1) {
-        shminfo->shmaddr = xim->data = (char*)shmat(shminfo->shmid, 0, 0);
-
-        if (shminfo->shmaddr != (char *)-1) {
-
-          shminfo->readOnly = False;
-
-          XErrorHandler oldHdlr = XSetErrorHandler(XShmAttachErrorHandler);
-          XShmAttach(dpy, shminfo);
-          XSync(dpy, False);
-          XSetErrorHandler(oldHdlr);
-
-          if (!caughtError) {
-            vlog.debug("Using shared memory XImage");
-            imageCleanup.images.push_back(this);
-            return;
-          }
-
-          shmdt(shminfo->shmaddr);
-        } else {
-          vlog.error("shmat failed");
-          perror("shmat");
-        }
-
-        shmctl(shminfo->shmid, IPC_RMID, 0);
-      } else {
-        vlog.error("shmget failed");
-        perror("shmget");
-      }
-
-      XDestroyImage(xim);
-      xim = 0;
-    } else {
-      vlog.error("XShmCreateImage failed");
-    }
-
-    delete shminfo;
-    shminfo = 0;
-  }
-#endif
-
-  xim = XCreateImage(dpy, vis, depth, ZPixmap,
-                     0, 0, width(), height(), BitmapPad(dpy), 0);
-
-  xim->data = (char*)malloc(xim->bytes_per_line * xim->height);
-  if (!xim->data) {
-    vlog.error("malloc failed");
-    exit(1);
-  }
-}
-
-void TXImage::destroyXImage()
-{
-#ifdef HAVE_MITSHM
-  if (shminfo) {
-    vlog.debug("Freeing shared memory XImage");
-    shmdt(shminfo->shmaddr);
-    shmctl(shminfo->shmid, IPC_RMID, 0);
-    delete shminfo;
-    shminfo = 0;
-    imageCleanup.images.remove(this);
-  }
-#endif
-  // XDestroyImage() will free(xim->data) if appropriate
-  if (xim) XDestroyImage(xim);
-  xim = 0;
-}
-
-
-static bool supportedBPP(int bpp) {
-  return (bpp == 8 || bpp == 16 || bpp == 32);
-}
-
-static int depth2bpp(Display* dpy, int depth)
-{
-  int nformats;
-  XPixmapFormatValues* format = XListPixmapFormats(dpy, &nformats);
-
-  int i;
-  for (i = 0; i < nformats; i++)
-    if (format[i].depth == depth) break;
-
-  if (i == nformats || !supportedBPP(format[i].bits_per_pixel))
-    throw rfb::Exception("Error: couldn't find suitable pixmap format");
-
-  int bpp = format[i].bits_per_pixel;
-  XFree(format);
-  return bpp;
-}
-
-void TXImage::getNativePixelFormat(Visual* vis, int depth)
-{
-  int bpp;
-  int trueColour, bigEndian;
-  int redShift, greenShift, blueShift;
-  int redMax, greenMax, blueMax;
-
-  cube = 0;
-
-  bpp = depth2bpp(dpy, depth);
-  bigEndian = (ImageByteOrder(dpy) == MSBFirst);
-  trueColour = (vis->c_class == TrueColor);
-
-  vlog.info("Using default colormap and visual, %sdepth %d.",
-            (vis->c_class == TrueColor) ? "TrueColor, " :
-            ((vis->c_class == PseudoColor) ? "PseudoColor, " : ""),
-            depth);
-
-  redShift   = ffs(vis->red_mask)   - 1;
-  greenShift = ffs(vis->green_mask) - 1;
-  blueShift  = ffs(vis->blue_mask)  - 1;
-  redMax     = vis->red_mask   >> redShift;
-  greenMax   = vis->green_mask >> greenShift;
-  blueMax    = vis->blue_mask  >> blueShift;
-
-  nativePF = PixelFormat(bpp, depth, bigEndian, trueColour,
-                         redMax, greenMax, blueMax,
-                         redShift, greenShift, blueShift);
-
-  if (!trueColour) {
-    XColor xc[256];
-    cube = new rfb::ColourCube(6,6,6);
-    int r;
-    for (r = 0; r < cube->nRed; r++) {
-      for (int g = 0; g < cube->nGreen; g++) {
-        for (int b = 0; b < cube->nBlue; b++) {
-          int i = (r * cube->nGreen + g) * cube->nBlue + b;
-          xc[i].red =   r * 65535 / (cube->nRed-1);
-          xc[i].green = g * 65535 / (cube->nGreen-1);
-          xc[i].blue =  b * 65535 / (cube->nBlue-1);
-        }
-      }
-    }
-
-    TXWindow::getColours(dpy, xc, cube->size());
-
-    for (r = 0; r < cube->nRed; r++) {
-      for (int g = 0; g < cube->nGreen; g++) {
-        for (int b = 0; b < cube->nBlue; b++) {
-          int i = (r * cube->nGreen + g) * cube->nBlue + b;
-          cube->set(r, g, b, xc[i].pixel);
-        }
-      }
-    }
-  }
-}
diff --git a/unix/tx/TXImage.h b/unix/tx/TXImage.h
deleted file mode 100644
index 055bd22..0000000
--- a/unix/tx/TXImage.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-//
-// TXImage.h
-//
-// A TXImage represents a rectangular off-screen image in any RFB pixel format.
-// By default it will use the "native" pixel format for the screen, which will
-// be an 8-bit colourmap unless the X display is TrueColor.  The pixel format
-// can be changed via the setPF() method.  The pixel data is accessible via the
-// data member inherited from FullFramePixelBuffer, or can be set via the
-// fillRect(), imageRect(), copyRect() and maskRect() methods, also inherited
-// from PixelBuffer.  A rectangle of the image can be drawn into an X Window
-// via the put() method.  If using a colourmap, the setColourMapEntries() and
-// updateColourMap() methods must be called to set up the colourmap as
-// appropriate.
-
-
-#ifndef __TXIMAGE_H__
-#define __TXIMAGE_H__
-
-#include <X11/Xlib.h>
-#include <rfb/PixelBuffer.h>
-#include <rfb/ColourMap.h>
-#include <rfb/ColourCube.h>
-#ifdef HAVE_MITSHM
-#include <X11/extensions/XShm.h>
-#endif
-
-namespace rfb { class TransImageGetter; }
-
-class TXImage : public rfb::FullFramePixelBuffer, public rfb::ColourMap {
-public:
-  TXImage(Display* dpy, int width, int height, Visual* vis=0, int depth=0);
-  ~TXImage();
-
-  // resize() resizes the image, preserving the image data where possible.
-  void resize(int w, int h);
-
-  // put causes the given rectangle to be drawn onto the given window.
-  void put(Window win, GC gc, const rfb::Rect& r);
-
-  // setColourMapEntries() changes some of the entries in the colourmap.
-  // However these settings won't take effect until updateColourMap() is
-  // called.  This is because recalculating the internal translation table can
-  // be expensive.
-  void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs);
-  void updateColourMap();
-
-#ifdef HAVE_MITSHM
-  bool usingShm() { return shminfo; }
-#else
-  bool usingShm() { return 0; }
-#endif
-
-  // PixelBuffer methods
-  // width(), height(), getPF() etc are inherited from PixelBuffer
-  virtual void setPF(const rfb::PixelFormat& pf);
-  virtual int getStride() const;
-
-private:
-
-  // ColourMap method
-  virtual void lookup(int index, int* r, int* g, int* b);
-
-  void createXImage();
-  void destroyXImage();
-  void getNativePixelFormat(Visual* vis, int depth);
-
-  XImage* xim;
-  Display* dpy;
-  Visual* vis;
-  int depth;
-#ifdef HAVE_MITSHM
-  XShmSegmentInfo* shminfo;
-#endif
-  rfb::TransImageGetter* tig;
-  rfb::Colour colourMap[256];
-  rfb::PixelFormat nativePF;
-  rfb::ColourCube* cube;
-};
-
-#endif
diff --git a/unix/tx/TXMenu.cxx b/unix/tx/TXMenu.cxx
deleted file mode 100644
index 92712f5..0000000
--- a/unix/tx/TXMenu.cxx
+++ /dev/null
@@ -1,186 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-//
-// TXMenu.cxx
-//
-
-#include "TXMenu.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <rfb/util.h>
-#include <X11/keysym.h>
-
-TXMenu::TXMenu(Display* dpy_, TXMenuCallback* cb_, int w, int h,
-               TXWindow* parent_)
-  : TXWindow(dpy_, w, h, parent_), cb(cb_), nEntries(0),
-    highlight(-1)
-{
-  setEventHandler(this);
-  gc = XCreateGC(dpy, win(), 0, 0);
-  addEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask |
-               PointerMotionMask | EnterWindowMask | LeaveWindowMask);
-}
-
-TXMenu::~TXMenu()
-{
-  XFreeGC(dpy, gc);
-  for (int i = 0; i < nEntries; i++)
-    delete [] text[i];
-}
-
-inline int TXMenu::entryHeight(int i)
-{
-  if (text[i])
-    return defaultFS->ascent + defaultFS->descent + bevel*2 + yPad*2;
-  else
-    return yPad*2 + 1;
-}
-
-void TXMenu::addEntry(const char* text_, long id_)
-{
-  assert(nEntries < maxEntries);
-  text[nEntries] = rfb::strDup(text_);
-  checked[nEntries] = false;
-  id[nEntries++] = id_;
-  int tw = 0;
-  if (text_)
-    tw = XTextWidth(defaultFS, text_, strlen(text_));
-  int newWidth = width();
-  if (tw + bevel*2 + xPad*5 + tickSize > width())
-    newWidth = tw + bevel*2 + xPad*5 + tickSize;
-  int newHeight = 0;
-  for (int i = 0; i < nEntries; i++)
-    newHeight += entryHeight(i);
-  resize(newWidth, newHeight);
-}
-
-void TXMenu::check(long id_, bool checked_)
-{
-  for (int i = 0; i < nEntries; i++) {
-    if (id[i] == id_) {
-      checked[i] = checked_;
-      break;
-    }
-  }
-}
-
-void TXMenu::paint()
-{
-  int y = 0;
-  for (int i = 0; i < nEntries; i++) {
-    if (text[i]) {
-      if (i == highlight)
-        drawBevel(gc, 0, y, width(), entryHeight(i), bevel,
-                  defaultBg, darkBg, lightBg);
-      else
-        XClearArea(dpy, win(), 0, y, width(), entryHeight(i), false);
-      if (checked[i])
-        XCopyPlane(dpy, tick, win(), defaultGC, 0, 0, tickSize, tickSize,
-                   bevel + xPad,
-                   y + bevel + yPad + defaultFS->ascent - tickSize, 1);
-
-      XDrawImageString(dpy, win(), defaultGC, bevel + xPad*2 + tickSize,
-                       y + bevel + yPad + defaultFS->ascent,
-                       text[i], strlen(text[i]));
-    } else {
-      XDrawLine(dpy, win(), defaultGC, bevel + xPad, y + entryHeight(i) / 2,
-                width() - bevel - xPad, y + entryHeight(i) / 2);
-    }
-    y += entryHeight(i);
-  }
-}
-
-void TXMenu::handleEvent(TXWindow* w, XEvent* ev)
-{
-  switch (ev->type) {
-  case Expose:
-    paint();
-    break;
-
-  case ButtonRelease:
-    {
-      int y = ev->xmotion.y;
-      int entryY = 0;
-      for (int i = 0; i < nEntries; i++) {
-        if (y >= entryY && y <= entryY + entryHeight(i)) {
-          if (cb && text[i])
-            cb->menuSelect(id[i], this);
-          break;
-        }
-        entryY += entryHeight(i);
-      }
-      highlight = -1;
-      paint();
-      break;
-    }
-
-  case ButtonPress:
-  case MotionNotify:
-    {
-      int y = ev->xmotion.y;
-      int entryY = 0;
-      for (int i = 0; i < nEntries; i++) {
-        if (y >= entryY && y <= entryY + entryHeight(i)) {
-          if (highlight != i) {
-            highlight = i;
-            paint();
-          }
-          break;
-        }
-        entryY += entryHeight(i);
-      }
-      break;
-    }
-
-  case KeyPress:
-    {
-      KeySym ks;
-      char str[256];
-      XLookupString(&ev->xkey, str, 256, &ks, NULL);
-      if (ks == XK_Escape) {
-        highlight = -1;
-        unmap();
-      } else if (ks == XK_Down || ks == XK_Up) {
-        if (nEntries < 1) break;
-        if (highlight < 0)
-          highlight = (ks == XK_Down ? nEntries-1 : 0);
-        int start = highlight;
-        int inc = (ks == XK_Down ? 1 : nEntries-1);
-        do {
-          highlight = (highlight + inc) % nEntries;
-        } while (highlight != start && !text[highlight]);
-        paint();
-      } else if (ks == XK_space || ks == XK_KP_Space ||
-                 ks == XK_Return || ks == XK_KP_Enter) {
-        if (cb && highlight >= 0 && text[highlight])
-          cb->menuSelect(id[highlight], this);
-        highlight = -1;
-        paint();
-      }
-      break;
-    }
-
-  case EnterNotify:
-  case LeaveNotify:
-    highlight = -1;
-    paint();
-    break;
-  }
-}
diff --git a/unix/tx/TXMenu.h b/unix/tx/TXMenu.h
deleted file mode 100644
index d0245ee..0000000
--- a/unix/tx/TXMenu.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-//
-// TXMenu.h
-//
-// A TXMenu consists of multiple entries which can be added one at a time.
-// Each entry consists of some text, and has an associated integer identifier.
-// A callback is made when a menu entry is selected.
-//
-
-#ifndef __TXMENU_H__
-#define __TXMENU_H__
-
-#include "TXWindow.h"
-
-// TXMenuCallback's menuSelect() method is called when a particular menu entry
-// is selected.  The id argument identifies the menu entry.
-class TXMenu;
-class TXMenuCallback {
-public:
-  virtual void menuSelect(long id, TXMenu* menu)=0;
-};
-
-class TXMenu : public TXWindow, public TXEventHandler {
-public:
-  TXMenu(Display* dpy_, TXMenuCallback* cb=0, int width=1, int height=1,
-         TXWindow* parent_=0);
-  virtual ~TXMenu();
-
-  // addEntry() adds an entry to the end of the menu with the given text and
-  // identifier.
-  void addEntry(const char* text, long id);
-
-  // check() sets whether the given menu entry should have a tick next to it.
-  void check(long id, bool checked);
-
-private:
-  int entryHeight(int i);
-  virtual void handleEvent(TXWindow* w, XEvent* ev);
-  void paint();
-
-  GC gc;
-  TXMenuCallback* cb;
-  enum { maxEntries = 64 };
-  char* text[maxEntries];
-  long id[maxEntries];
-  bool checked[maxEntries];
-  int nEntries;
-  int highlight;
-};
-
-#endif
diff --git a/unix/tx/TXMsgBox.h b/unix/tx/TXMsgBox.h
deleted file mode 100644
index ff84e6a..0000000
--- a/unix/tx/TXMsgBox.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-//
-// TXMsgBox.h
-//
-// A TXMsgBox is a specialised pop-up dialog window, designed to present
-// the user with a small amount of textual information, and potentially to
-// obtain their response.
-// TXMsgBoxes are always modal, and may have an Ok button, Ok+Cancel buttons,
-// or Yes+No buttons.
-// The MsgBox helper function creates a TXMsgBox on the fly, runs it, and
-// returns the result.
-//
-
-#ifndef __TXMSGBOX_H__
-#define __TXMSGBOX_H__
-
-#include "TXDialog.h"
-#include "TXLabel.h"
-#include "TXButton.h"
-
-enum TXMsgBoxFlags {
-  MB_OK = 0,
-  MB_OKCANCEL = 1,
-  MB_YESNO = 4,
-  MB_ICONERROR = 0x10,
-  MB_ICONQUESTION = 0x20,
-  MB_ICONWARNING = 0x30,
-  MB_ICONINFORMATION = 0x40,
-  MB_DEFBUTTON1 = 0,
-  MB_DEFBUTTON2 = 0x100
-};
-
-class TXMsgBox : public TXDialog, public TXButtonCallback {
-public:
-  TXMsgBox(Display* dpy, const char* text, unsigned int flags, const char* title=0)
-    : TXDialog(dpy, 1, 1, "Message", true),
-      textLabel(dpy, "", this),
-    okButton(dpy, "OK", this, this, 60),
-    cancelButton(dpy, "Cancel", this, this, 60)
-  {
-    textLabel.xPad = 8;
-    textLabel.move(0, yPad*4);
-    textLabel.setText(text);
-    resize(textLabel.width(),
-           textLabel.height() + okButton.height() + yPad*12);
-
-    switch (flags & 0x30) {
-    case MB_ICONERROR:
-      toplevel("Error", this); break;
-    case MB_ICONQUESTION:
-      toplevel("Question", this); break;
-    case MB_ICONWARNING:
-      toplevel("Warning", this); break;
-    case MB_ICONINFORMATION:
-      toplevel("Information", this); break;
-    default:
-      if (title)
-	toplevel(title, this);
-      break;
-    };
-
-    switch (flags & 0x7) {
-    default:
-      okButton.move((width() - okButton.width()) / 2,
-		    height() - yPad*4 - okButton.height());
-      cancelButton.unmap();
-      break;
-    case MB_OKCANCEL:
-    case MB_YESNO:
-      
-      okButton.move(((width()/2) - okButton.width()) / 2,
-		    height() - yPad*4 - okButton.height());
-      cancelButton.move(((width()*3/2) - cancelButton.width()) / 2,
-			height() - yPad*4 - cancelButton.height());
-      if ((flags & 0x7) == MB_YESNO) {
-	okButton.setText("Yes");
-	cancelButton.setText("No");
-      }
-      break;
-    };
-
-    setBorderWidth(1);
-  }
-
-  virtual void buttonActivate(TXButton* b) {
-    ok = (b == &okButton);
-    done = true; 
-    unmap();
-  }
-
-  TXLabel textLabel;
-  TXButton okButton;
-  TXButton cancelButton;
-};
-
-#endif
diff --git a/unix/tx/TXScrollbar.cxx b/unix/tx/TXScrollbar.cxx
deleted file mode 100644
index 47e124c..0000000
--- a/unix/tx/TXScrollbar.cxx
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-//
-// TXScrollbar.cxx
-//
-
-#include "TXScrollbar.h"
-#include <stdio.h>
-#include <assert.h>
-
-TXScrollbar::TXScrollbar(Display* dpy_, int width, int height, bool vert,
-                         TXScrollbarCallback* cb_, TXWindow* parent_)
-  : TXWindow(dpy_, width, height, parent_), cb(cb_), vertical(vert),
-    clickedInThumb(false)
-{
-  setEventHandler(this);
-  gc = XCreateGC(dpy, win(), 0, 0);
-  addEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask |
-               ButtonMotionMask);
-  setBg(scrollbarBg);
-  limit[0] = len[0] = limit[1] = len[1] = 1;
-  start[0] = start[1] = 0;
-}
-
-TXScrollbar::~TXScrollbar()
-{
-  XFreeGC(dpy, gc);
-}
-
-void TXScrollbar::set(int limit_, int start_, int len_, bool vert)
-{
-  assert(limit_ > 0 && len_ >= 0 && len_ <= limit_);
-
-  if (start_ < 0) start_ = 0;
-  if (start_ > limit_ - len_) start_ = limit_ - len_;
-
-  if (limit[vert] != limit_ || start[vert] != start_ || len[vert] != len_) {
-    limit[vert] = limit_;
-    start[vert] = start_;
-    len[vert] = len_;
-    paint();
-  }
-}
-
-void TXScrollbar::paint()
-{
-  int x = scaleToBarX(start[0]);
-  int y = scaleToBarY(start[1]);
-  int w = scaleToBarX(len[0]);
-  int h = scaleToBarY(len[1]);
-  if (y > 0) XClearArea(dpy, win(), 0, 0, 0, y, false);
-  if (x > 0) XClearArea(dpy, win(), 0, y, x, y+h, false);
-  XClearArea(dpy, win(), x+w, y, 0, y+h, false);
-  XClearArea(dpy, win(), 0, y+h, 0, 0, false);
-  drawBevel(gc, x, y, w, h, bevel, defaultBg, lightBg, darkBg);
-}
-
-void TXScrollbar::handleEvent(TXWindow* w, XEvent* ev)
-{
-  switch (ev->type) {
-  case Expose:
-    paint();
-    break;
-
-  case ButtonPress:
-    {
-      xDown = ev->xbutton.x;
-      yDown = ev->xbutton.y;
-      xStart = start[0];
-      yStart = start[1];
-      bool clickedInThumbX = false;
-      if (xDown < scaleToBarX(start[0])) {
-        set(limit[0], start[0] - len[0], len[0], false);
-      } else if (xDown >= scaleToBarX(start[0]+len[0])) {
-        set(limit[0], start[0] + len[0], len[0], false);
-      } else {
-        clickedInThumbX = true;
-      }
-      bool clickedInThumbY = false;
-      if (yDown < scaleToBarY(start[1])) {
-        set(limit[1], start[1] - len[1], len[1], true);
-      } else if (yDown >= scaleToBarY(start[1]+len[1])) {
-        set(limit[1], start[1] + len[1], len[1], true);
-      } else {
-        clickedInThumbY = true;
-      }
-      clickedInThumb = clickedInThumbX && clickedInThumbY;
-      if (cb) cb->scrollbarPos(start[0], start[1], this);
-    }
-    break;
-
-  case ButtonRelease:
-  case MotionNotify:
-    while (XCheckTypedWindowEvent(dpy, win(), MotionNotify, ev));
-    if (clickedInThumb) {
-      int dx = ev->xmotion.x - xDown;
-      int dy = ev->xmotion.y - yDown;
-      set(limit[0], xStart + barToScaleX(dx), len[0], false);
-      set(limit[1], yStart + barToScaleY(dy), len[1], true);
-      if (cb) cb->scrollbarPos(start[0], start[1], this);
-    }
-    break;
-  }
-}
diff --git a/unix/tx/TXScrollbar.h b/unix/tx/TXScrollbar.h
deleted file mode 100644
index 87fec3d..0000000
--- a/unix/tx/TXScrollbar.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-//
-// TXScrollbar.h
-//
-// A TXScrollbar represents a range of values starting at start, of length len,
-// between zero and limit.  The vertical argument to the constructor says
-// whether the scrollbar is horizontal or vertical.
-//
-// In fact it can represent a range in each dimension but usually one of the
-// dimensions is fixed, according to the vertical flag (for a vertical
-// scrollbar, the horizontal dimension is fixed, and vice-versa).
-//
-// The TXScrollbarCallback argument is an object which will be notified when
-// the user has attempted to move the scrollbar.  The x and y arguments to the
-// scrollbarPos() method give the start values in the respective dimensions.
-// They are guaranteed to be between 0 and limit-len.
-//
-
-#ifndef __TXSCROLLBAR_H__
-#define __TXSCROLLBAR_H__
-
-#include "TXWindow.h"
-
-class TXScrollbarCallback;
-
-class TXScrollbar : public TXWindow, public TXEventHandler {
-public:
-  TXScrollbar(Display* dpy_, int width=1, int height=1, bool vertical=false,
-              TXScrollbarCallback* cb=0, TXWindow* parent_=0);
-  virtual ~TXScrollbar();
-
-  // set() sets the limit, start and length of the range represented by the
-  // scrollbar.  The values of limit and len passed in must be valid
-  // (i.e. limit > 0 and 0 <= len <= limit).  Values of start are clipped to
-  // the range 0 to limit-len.
-  void set(int limit, int start, int len) { set(limit, start, len, vertical); }
-
-  // set() with an extra argument vert can be used to represent a range in both
-  // dimensions simultaneously.
-  void set(int limit, int start, int len, bool vert);
-
-  virtual void handleEvent(TXWindow* w, XEvent* ev);
-
-private:
-  int scaleToBarX(int x) { return (x * width() + limit[0]/2) / limit[0]; }
-  int scaleToBarY(int y) { return (y * height() + limit[1]/2) / limit[1]; }
-  int barToScaleX(int x) { return (x * limit[0] + width()/2) / width(); }
-  int barToScaleY(int y) { return (y * limit[1] + height()/2) / height(); }
-  void paint();
-
-  GC gc;
-  TXScrollbarCallback* cb;
-  int limit[2];
-  int start[2];
-  int len[2];
-  int xDown, yDown;
-  int xStart, yStart;
-  bool vertical;
-  bool clickedInThumb;
-};
-
-class TXScrollbarCallback {
-public:
-  virtual void scrollbarPos(int x, int y, TXScrollbar* sb)=0;
-};
-#endif
diff --git a/unix/tx/TXViewport.cxx b/unix/tx/TXViewport.cxx
deleted file mode 100644
index 6064893..0000000
--- a/unix/tx/TXViewport.cxx
+++ /dev/null
@@ -1,189 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-//
-// TXViewport.cxx
-//
-
-#include "TXViewport.h"
-#include <stdio.h>
-
-TXViewport::TXViewport(Display* dpy_, int w, int h, TXWindow* parent_)
-  : TXWindow(dpy_, w, h, parent_), child(0), hScrollbar(0),
-    vScrollbar(0), scrollbarSize(15), xOff(0), yOff(0), bumpScrollTimer(this),
-    bumpScroll(false), needXScrollbar(false), needYScrollbar(false),
-    bumpScrollX(0), bumpScrollY(0)
-{
-  clipper = new TXWindow(dpy, width()-scrollbarSize, height()-scrollbarSize,
-                         this);
-  clipper->setBg(black);
-  hScrollbar = new TXScrollbar(dpy, width()-scrollbarSize, scrollbarSize,
-                               false, this, this);
-  vScrollbar = new TXScrollbar(dpy, scrollbarSize, height()-scrollbarSize,
-                               true, this, this);
-}
-
-TXViewport::~TXViewport()
-{
-  delete clipper;
-  delete hScrollbar;
-  delete vScrollbar;
-}
-
-void TXViewport::setChild(TXWindow* child_)
-{
-  child = child_;
-  XReparentWindow(dpy, child->win(), clipper->win(), 0, 0);
-  xOff = yOff = 0;
-  child->map();
-  resizeNotify();
-}
-
-bool TXViewport::setOffset(int x, int y)
-{
-  if (clipper->width() >= child->width()) {
-    x = (clipper->width() - child->width()) / 2;
-  } else {
-    if (x > 0) x = 0;
-    if (x + child->width() < clipper->width())
-      x = clipper->width() - child->width();
-  }
-
-  if (clipper->height() >= child->height()) {
-    y = (clipper->height() - child->height()) / 2;
-  } else {
-    if (y > 0) y = 0;
-    if (y + child->height() < clipper->height())
-      y = clipper->height() - child->height();
-  }
-
-  if (x != xOff || y != yOff) {
-    xOff = x;
-    yOff = y;
-    child->move(xOff, yOff);
-    return true;
-  }
-
-  return false;
-}
-
-void TXViewport::setBumpScroll(bool b)
-{
-  bumpScroll = b;
-  resizeNotify();
-}
-
-// Note: bumpScrollEvent() only works if the viewport is positioned at 0,0 and
-// is the same width and height as the screen.
-bool TXViewport::bumpScrollEvent(XMotionEvent* ev)
-{
-  if (!bumpScroll) return false;
-  int bumpScrollPixels = 20;
-  bumpScrollX = bumpScrollY = 0;
-
-  if (ev->x_root == width()-1)  bumpScrollX = -bumpScrollPixels;
-  else if (ev->x_root == 0)     bumpScrollX = bumpScrollPixels;
-  if (ev->y_root == height()-1) bumpScrollY = -bumpScrollPixels;
-  else if (ev->y_root == 0)     bumpScrollY = bumpScrollPixels;
-
-  if (bumpScrollX || bumpScrollY) {
-    if (bumpScrollTimer.isStarted()) return true;
-    if (setOffset(xOff + bumpScrollX, yOff + bumpScrollY)) {
-      bumpScrollTimer.start(25);
-      return true;
-    }
-  }
-
-  bumpScrollTimer.stop();
-  return false;
-}
-
-bool TXViewport::handleTimeout(rfb::Timer* timer) {
-  return setOffset(xOff + bumpScrollX, yOff + bumpScrollY);
-}
-
-void TXViewport::resizeNotify()
-{
-  int winMaxWidth, winMaxHeight;
-
-  winMaxWidth = child->width();
-  winMaxHeight = child->height();
-
-  needXScrollbar = false;
-  needYScrollbar = false;
-  if (!bumpScroll && height() > scrollbarSize && width() > scrollbarSize) {
-    needXScrollbar = (width() < child->width());
-    needYScrollbar = (height() < child->height());
-    // Adding an horizontal scrollbar occupies space, which might cause the
-    // need to add a vertical scrollbar, and vice-versa. These additional
-    // checks should solve this problem
-    if (needXScrollbar && (height() - scrollbarSize < child->height()))
-	needYScrollbar = true;
-    if (needYScrollbar && (width() - scrollbarSize < child->width()))
-	needXScrollbar = true;
-  }
-
-  if (needXScrollbar)
-    winMaxHeight += scrollbarSize;
-  if (needYScrollbar)
-    winMaxWidth += scrollbarSize;
-  setMaxSize(winMaxWidth, winMaxHeight);
-
-  if (needXScrollbar && needYScrollbar) {
-    clipper->resize(width()-scrollbarSize, height()-scrollbarSize);
-    hScrollbar->map();
-    vScrollbar->map();
-  } else if (needXScrollbar) {
-    clipper->resize(width(), height()-scrollbarSize);
-    hScrollbar->map();
-    vScrollbar->unmap();
-  } else if (needYScrollbar) {
-    clipper->resize(width()-scrollbarSize, height());
-    hScrollbar->unmap();
-    vScrollbar->map();
-  } else {
-    clipper->resize(width(), height());
-    hScrollbar->unmap();
-    vScrollbar->unmap();
-  }
-
-  setOffset(xOff, yOff);
-
-  if (needXScrollbar) {
-    hScrollbar->move(0, height()-scrollbarSize);
-    hScrollbar->resize(width()-scrollbarSize, scrollbarSize);
-    hScrollbar->set(child->width(), -xOff, width()-scrollbarSize);
-  }
-
-  if (needYScrollbar) {
-    vScrollbar->move(width()-scrollbarSize, 0);
-    vScrollbar->resize(scrollbarSize, height()-scrollbarSize);
-    vScrollbar->set(child->height(), -yOff, height()-scrollbarSize);
-  }
-}
-
-void TXViewport::scrollbarPos(int x, int y, TXScrollbar* sb)
-{
-  if (sb == hScrollbar) {
-    x = -x;
-    y = yOff;
-  } else {
-    x = xOff;
-    y = -y;
-  }
-  setOffset(x, y);
-}
diff --git a/unix/tx/TXViewport.h b/unix/tx/TXViewport.h
deleted file mode 100644
index 823d67a..0000000
--- a/unix/tx/TXViewport.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-//
-// TXViewport.h
-//
-// A TXViewport allows a large window to be viewed by adding scrollbars to the
-// right and bottom if necessary.  It also has a bump-scroll mode where there
-// are no scrollbars, and scrolling is achieved by bumping up against the edge
-// of the screen instead.  Note that this only works when the viewport fills
-// the entire screen.  If the child window is smaller than the viewport, it is
-// always positioned centrally in the viewport.
-
-#ifndef __TXVIEWPORT_H__
-#define __TXVIEWPORT_H__
-
-#include <rfb/Timer.h>
-#include "TXWindow.h"
-#include "TXScrollbar.h"
-
-class TXViewport : public TXWindow, public TXScrollbarCallback,
-                   public rfb::Timer::Callback {
-public:
-  TXViewport(Display* dpy_, int width, int height, TXWindow* parent_=0);
-  virtual ~TXViewport();
-
-  // setChild() sets the child window which is to be viewed in the viewport.
-  void setChild(TXWindow* child_);
-
-  // setOffset() sets the position of the child in the viewport.  Note that the
-  // offsets are negative.  For example when the offset is (-100,-30), position
-  // (100,30) in the child window is at the top-left of the viewport.  The
-  // offsets given are clipped to keep the child window filling the viewport
-  // (except where the child window is smaller than the viewport, in which case
-  // it is always positioned centrally in the viewport).  It returns true if
-  // the child was repositioned.
-  bool setOffset(int x, int y);
-
-  // setBumpScroll() puts the viewport in bump-scroll mode.
-  void setBumpScroll(bool b);
-
-  // bumpScrollEvent() can be called with a MotionNotify event which may
-  // potentially be against the edge of the screen.  It returns true if the
-  // event was used for bump-scrolling, false if it should be processed
-  // normally.
-  bool bumpScrollEvent(XMotionEvent* ev);
-
-private:
-  virtual void resizeNotify();
-  virtual void scrollbarPos(int x, int y, TXScrollbar* sb);
-  virtual bool handleTimeout(rfb::Timer* timer);
-  TXWindow* clipper;
-  TXWindow* child;
-  TXScrollbar* hScrollbar;
-  TXScrollbar* vScrollbar;
-  const int scrollbarSize;
-  int xOff, yOff;
-  rfb::Timer bumpScrollTimer;
-  bool bumpScroll;
-  bool needXScrollbar;
-  bool needYScrollbar;
-  int bumpScrollX, bumpScrollY;
-};
-#endif
diff --git a/unix/x0vncserver/XPixelBuffer.cxx b/unix/x0vncserver/XPixelBuffer.cxx
index f691c57..aa52620 100644
--- a/unix/x0vncserver/XPixelBuffer.cxx
+++ b/unix/x0vncserver/XPixelBuffer.cxx
@@ -1,4 +1,5 @@
 /* Copyright (C) 2007-2008 Constantin Kaplinsky.  All Rights Reserved.
+ * Copyright 2014 Pierre Ossman for Cendio AB
  *    
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -38,16 +39,16 @@
     m_stride(0)
 {
   // Fill in the PixelFormat structure of the parent class.
-  format.bpp        = m_image->xim->bits_per_pixel;
-  format.depth      = m_image->xim->depth;
-  format.bigEndian  = (m_image->xim->byte_order == MSBFirst);
-  format.trueColour = m_image->isTrueColor();
-  format.redShift   = ffs(m_image->xim->red_mask) - 1;
-  format.greenShift = ffs(m_image->xim->green_mask) - 1;
-  format.blueShift  = ffs(m_image->xim->blue_mask) - 1;
-  format.redMax     = m_image->xim->red_mask   >> format.redShift;
-  format.greenMax   = m_image->xim->green_mask >> format.greenShift;
-  format.blueMax    = m_image->xim->blue_mask  >> format.blueShift;
+  format = PixelFormat(m_image->xim->bits_per_pixel,
+                       m_image->xim->depth,
+                       (m_image->xim->byte_order == MSBFirst),
+                       m_image->isTrueColor(),
+                       m_image->xim->red_mask   >> (ffs(m_image->xim->red_mask) - 1),
+                       m_image->xim->green_mask >> (ffs(m_image->xim->green_mask) - 1),
+                       m_image->xim->blue_mask  >> (ffs(m_image->xim->blue_mask) - 1),
+                       ffs(m_image->xim->red_mask) - 1,
+                       ffs(m_image->xim->green_mask) - 1,
+                       ffs(m_image->xim->blue_mask) - 1);
 
   // Set up the remaining data of the parent class.
   width_ = rect.width();
diff --git a/vncviewer/CConn.cxx b/vncviewer/CConn.cxx
index f97b0f4..789cf09 100644
--- a/vncviewer/CConn.cxx
+++ b/vncviewer/CConn.cxx
@@ -44,6 +44,7 @@
 
 #include "CConn.h"
 #include "OptionsDialog.h"
+#include "DesktopWindow.h"
 #include "i18n.h"
 #include "parameters.h"
 #include "vncviewer.h"
@@ -88,11 +89,15 @@
   cp.supportsExtendedDesktopSize = true;
   cp.supportsDesktopRename = true;
 
-  cp.customCompressLevel = customCompressLevel;
-  cp.compressLevel = compressLevel;
+  if (customCompressLevel)
+    cp.compressLevel = compressLevel;
+  else
+    cp.compressLevel = -1;
 
-  cp.noJpeg = noJpeg;
-  cp.qualityLevel = qualityLevel;
+  if (!noJpeg)
+    cp.qualityLevel = qualityLevel;
+  else
+    cp.qualityLevel = -1;
 
   if(sock == NULL) {
     try {
@@ -394,14 +399,17 @@
 {
   desktop->fillRect(r,p);
 }
+
 void CConn::imageRect(const rfb::Rect& r, void* p)
 {
   desktop->imageRect(r,p);
 }
+
 void CConn::copyRect(const rfb::Rect& r, int sx, int sy)
 {
   desktop->copyRect(r,sx,sy);
 }
+
 void CConn::setCursor(int width, int height, const Point& hotspot,
                       void* data, void* mask)
 {
@@ -443,10 +451,10 @@
   }
 }
 
-rdr::U8* CConn::getRawPixelsRW(const rfb::Rect& r, int* stride) {
-  return desktop->getPixelsRW(r, stride);
+rdr::U8* CConn::getRawBufferRW(const rfb::Rect& r, int* stride) {
+  return desktop->getBufferRW(r, stride);
 }
-void CConn::releaseRawPixels(const rfb::Rect& r) {
+void CConn::releaseRawBuffer(const rfb::Rect& r) {
   desktop->damageRect(r);
 }
 
@@ -615,16 +623,19 @@
 
     if (encNum != -1)
       self->currentEncoding = encNum;
-
-    self->cp.qualityLevel = qualityLevel;
   }
 
   self->cp.supportsLocalCursor = true;
 
-  self->cp.customCompressLevel = customCompressLevel;
-  self->cp.compressLevel = compressLevel;
+  if (customCompressLevel)
+    self->cp.compressLevel = compressLevel;
+  else
+    self->cp.compressLevel = -1;
 
-  self->cp.noJpeg = noJpeg;
+  if (!noJpeg && !autoSelect)
+    self->cp.qualityLevel = qualityLevel;
+  else
+    self->cp.qualityLevel = -1;
 
   self->encodingChange = true;
 
diff --git a/vncviewer/CConn.h b/vncviewer/CConn.h
index 24fbbab..286a09e 100644
--- a/vncviewer/CConn.h
+++ b/vncviewer/CConn.h
@@ -20,10 +20,12 @@
 #ifndef __CCONN_H__
 #define __CCONN_H__
 
+#include <FL/Fl.H>
+
 #include <rfb/CConnection.h>
 #include <network/Socket.h>
 
-#include "DesktopWindow.h"
+class DesktopWindow;
 
 class CConn : public rfb::CConnection,
               public rdr::FdInStreamBlockCallback
@@ -67,8 +69,8 @@
   void imageRect(const rfb::Rect& r, void* p);
   void copyRect(const rfb::Rect& r, int sx, int sy);
 
-  rdr::U8* getRawPixelsRW(const rfb::Rect& r, int* stride);
-  void releaseRawPixels(const rfb::Rect& r);
+  rdr::U8* getRawBufferRW(const rfb::Rect& r, int* stride);
+  void releaseRawBuffer(const rfb::Rect& r);
 
   const rfb::PixelFormat &getPreferredPF() { return fullColourPF; }
 
diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx
index 40d08ae..2a2f873 100644
--- a/vncviewer/DesktopWindow.cxx
+++ b/vncviewer/DesktopWindow.cxx
@@ -34,7 +34,9 @@
 #include "parameters.h"
 #include "vncviewer.h"
 #include "CConn.h"
+#include "Viewport.h"
 
+#include <FL/Fl.H>
 #include <FL/Fl_Scroll.H>
 #include <FL/x.H>
 
@@ -220,6 +222,26 @@
   viewport->setColourMapEntries(firstColour, nColours, rgbs);
 }
 
+void DesktopWindow::fillRect(const rfb::Rect& r, rfb::Pixel pix) {
+  viewport->fillRect(r, pix);
+}
+
+void DesktopWindow::imageRect(const rfb::Rect& r, void* pixels) {
+  viewport->imageRect(r, pixels);
+}
+
+void DesktopWindow::copyRect(const rfb::Rect& r, int srcX, int srcY) {
+  viewport->copyRect(r, srcX, srcY);
+}
+
+rdr::U8* DesktopWindow::getBufferRW(const rfb::Rect& r, int* stride) {
+  return viewport->getBufferRW(r, stride);
+}
+
+void DesktopWindow::damageRect(const rfb::Rect& r) {
+  viewport->damageRect(r);
+}
+
 
 // Copy the areas of the framebuffer that have been changed (damaged)
 // to the displayed window.
diff --git a/vncviewer/DesktopWindow.h b/vncviewer/DesktopWindow.h
index 78d9bf7..06f25f5 100644
--- a/vncviewer/DesktopWindow.h
+++ b/vncviewer/DesktopWindow.h
@@ -23,13 +23,13 @@
 #include <map>
 
 #include <rfb/Rect.h>
+#include <rfb/Pixel.h>
 
-#include "Viewport.h"
-
-#include <FL/Fl.H>
 #include <FL/Fl_Window.H>
 
 class CConn;
+class Viewport;
+
 class Fl_Scroll;
 
 class DesktopWindow : public Fl_Window {
@@ -52,22 +52,12 @@
 
   void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs);
 
-  void fillRect(const rfb::Rect& r, rfb::Pixel pix) {
-    viewport->fillRect(r, pix);
-  }
-  void imageRect(const rfb::Rect& r, void* pixels) {
-    viewport->imageRect(r, pixels);
-  }
-  void copyRect(const rfb::Rect& r, int srcX, int srcY) {
-    viewport->copyRect(r, srcX, srcY);
-  }
+  void fillRect(const rfb::Rect& r, rfb::Pixel pix);
+  void imageRect(const rfb::Rect& r, void* pixels);
+  void copyRect(const rfb::Rect& r, int srcX, int srcY);
 
-  rdr::U8* getPixelsRW(const rfb::Rect& r, int* stride) {
-    return viewport->getPixelsRW(r, stride);
-  }
-  void damageRect(const rfb::Rect& r) {
-    viewport->damageRect(r);
-  }
+  rdr::U8* getBufferRW(const rfb::Rect& r, int* stride);
+  void damageRect(const rfb::Rect& r);
 
   void resizeFramebuffer(int new_w, int new_h);
 
diff --git a/vncviewer/OptionsDialog.cxx b/vncviewer/OptionsDialog.cxx
index df9f355..e21f2dd 100644
--- a/vncviewer/OptionsDialog.cxx
+++ b/vncviewer/OptionsDialog.cxx
@@ -41,7 +41,11 @@
 
 #include <FL/Fl_Tabs.H>
 #include <FL/Fl_Button.H>
+#include <FL/Fl_Check_Button.H>
 #include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Round_Button.H>
+#include <FL/Fl_Int_Input.H>
+#include <FL/Fl_Choice.H>
 
 using namespace std;
 using namespace rdr;
diff --git a/vncviewer/OptionsDialog.h b/vncviewer/OptionsDialog.h
index b3ac015..a6b504e 100644
--- a/vncviewer/OptionsDialog.h
+++ b/vncviewer/OptionsDialog.h
@@ -22,11 +22,14 @@
 #include <map>
 
 #include <FL/Fl_Window.H>
-#include <FL/Fl_Group.H>
-#include <FL/Fl_Check_Button.H>
-#include <FL/Fl_Round_Button.H>
-#include <FL/Fl_Int_Input.H>
-#include <FL/Fl_Choice.H>
+
+class Fl_Widget;
+class Fl_Group;
+class Fl_Check_Button;
+class Fl_Round_Button;
+class Fl_Input;
+class Fl_Int_Input;
+class Fl_Choice;
 
 typedef void (OptionsCallback)(void*);
 
diff --git a/vncviewer/ServerDialog.h b/vncviewer/ServerDialog.h
index e023659..7926849 100644
--- a/vncviewer/ServerDialog.h
+++ b/vncviewer/ServerDialog.h
@@ -20,8 +20,9 @@
 #define __SERVERDIALOG_H__
 
 #include <FL/Fl_Window.H>
-#include <FL/Fl_Input.H>
-#include <FL/Fl_File_Chooser.H>
+
+class Fl_Widget;
+class Fl_Input;
 
 class ServerDialog : public Fl_Window {
 protected:
diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx
index 4b8a85b..0ac7602 100644
--- a/vncviewer/Viewport.cxx
+++ b/vncviewer/Viewport.cxx
@@ -27,6 +27,7 @@
 
 #include <rfb/CMsgWriter.h>
 #include <rfb/LogWriter.h>
+#include <rfb/PixelTransformer.h>
 
 // FLTK can pull in the X11 headers on some systems
 #ifndef XK_VoidSymbol
@@ -42,6 +43,7 @@
 #include "Viewport.h"
 #include "CConn.h"
 #include "OptionsDialog.h"
+#include "DesktopWindow.h"
 #include "i18n.h"
 #include "fltk_layout.h"
 #include "parameters.h"
@@ -49,9 +51,25 @@
 #include "menukey.h"
 #include "vncviewer.h"
 
+#if defined(WIN32)
+#include "Win32PixelBuffer.h"
+#elif defined(__APPLE__)
+#include "OSXPixelBuffer.h"
+#else
+#include "X11PixelBuffer.h"
+#endif
+
+// We also have a generic version of the above, using pure FLTK:
+//
+// #include "PlatformPixelBuffer.h"
+//
+
 #include <FL/fl_draw.H>
 #include <FL/fl_ask.H>
 
+#include <FL/Fl_Menu.H>
+#include <FL/Fl_Menu_Button.H>
+
 #ifdef WIN32
 #include "win32.h"
 #endif
@@ -209,6 +227,48 @@
   damage.clear();
 }
 
+void Viewport::fillRect(const rfb::Rect& r, rfb::Pixel pix) {
+  if (pixelTrans) {
+    rfb::Pixel pix2;
+    if (colourMapChange)
+      commitColourMap();
+    pixelTrans->translatePixels(&pix, &pix2, 1);
+    pix = pix2;
+  }
+
+  frameBuffer->fillRect(r, pix);
+  damageRect(r);
+}
+
+void Viewport::imageRect(const rfb::Rect& r, void* pixels) {
+  if (pixelTrans) {
+    if (colourMapChange)
+      commitColourMap();
+    pixelTrans->translateRect(pixels, r.width(),
+                              rfb::Rect(0, 0, r.width(), r.height()),
+                              frameBuffer->data, frameBuffer->getStride(),
+                              r.tl);
+  } else {
+    frameBuffer->imageRect(r, pixels);
+  }
+  damageRect(r);
+}
+
+void Viewport::copyRect(const rfb::Rect& r, int srcX, int srcY) {
+  frameBuffer->copyRect(r, rfb::Point(r.tl.x-srcX, r.tl.y-srcY));
+  damageRect(r);
+}
+
+rdr::U8* Viewport::getBufferRW(const rfb::Rect& r, int* stride) {
+  return frameBuffer->getBufferRW(r, stride);
+}
+
+void Viewport::damageRect(const rfb::Rect& r) {
+  damage.assign_union(rfb::Region(r));
+  if (!Fl::has_timeout(handleUpdateTimeout, this))
+    Fl::add_timeout(0.500, handleUpdateTimeout, this);
+};
+
 #ifdef HAVE_FLTK_CURSOR
 static const char * dotcursor_xpm[] = {
   "5 5 2 1",
@@ -931,7 +991,7 @@
 
   // Back to our proper mouse pointer.
 #ifdef HAVE_FLTK_CURSOR
-  if (Fl::belowmouse() == this)
+  if ((Fl::belowmouse() == this) && cursor)
     window()->cursor(cursor, cursorHotspot.x, cursorHotspot.y);
 #endif
 
diff --git a/vncviewer/Viewport.h b/vncviewer/Viewport.h
index c66c19a..e83a14b 100644
--- a/vncviewer/Viewport.h
+++ b/vncviewer/Viewport.h
@@ -22,31 +22,19 @@
 
 #include <map>
 
-#include <FL/Fl.H>
 #include <FL/Fl_Widget.H>
-#include <FL/Fl_Menu_Button.H>
-#include <FL/Fl_RGB_Image.H>
 
-#include <rfb/Rect.h>
 #include <rfb/Region.h>
-#include <rfb/Timer.h>
-#include <rfb/PixelBuffer.h>
-#include <rfb/PixelTransformer.h>
+#include <rfb/Pixel.h>
+#include <rfb/ColourMap.h>
 
-#if defined(WIN32)
-#include "Win32PixelBuffer.h"
-#elif defined(__APPLE__)
-#include "OSXPixelBuffer.h"
-#else
-#include "X11PixelBuffer.h"
-#endif
+class Fl_Menu_Button;
+class Fl_RGB_Image;
 
-// We also have a generic version of the above, using pure FLTK:
-//
-// #include "PlatformPixelBuffer.h"
-//
+namespace rfb { class PixelTransformer; }
 
 class CConn;
+class PlatformPixelBuffer;
 
 class Viewport : public Fl_Widget {
 public:
@@ -63,49 +51,16 @@
   void updateWindow();
 
   // Methods forwarded from CConn
-  void setName(const char *name);
 
   void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs);
 
-  void fillRect(const rfb::Rect& r, rfb::Pixel pix) {
-    if (pixelTrans) {
-      rfb::Pixel pix2;
-      if (colourMapChange)
-        commitColourMap();
-      pixelTrans->translatePixels(&pix, &pix2, 1);
-      pix = pix2;
-    }
+  void fillRect(const rfb::Rect& r, rfb::Pixel pix);
+  void imageRect(const rfb::Rect& r, void* pixels);
+  void copyRect(const rfb::Rect& r, int srcX, int srcY);
 
-    frameBuffer->fillRect(r, pix);
-    damageRect(r);
-  }
-  void imageRect(const rfb::Rect& r, void* pixels) {
-    if (pixelTrans) {
-      if (colourMapChange)
-        commitColourMap();
-      pixelTrans->translateRect(pixels, r.width(),
-                                rfb::Rect(0, 0, r.width(), r.height()),
-                                frameBuffer->data, frameBuffer->getStride(),
-                                r.tl);
-    } else {
-      frameBuffer->imageRect(r, pixels);
-    }
-    damageRect(r);
-  }
-  void copyRect(const rfb::Rect& r, int srcX, int srcY) {
-    frameBuffer->copyRect(r, rfb::Point(r.tl.x-srcX, r.tl.y-srcY));
-    damageRect(r);
-  }
+  rdr::U8* getBufferRW(const rfb::Rect& r, int* stride);
 
-  rdr::U8* getPixelsRW(const rfb::Rect& r, int* stride) {
-    return frameBuffer->getPixelsRW(r, stride);
-  }
-
-  void damageRect(const rfb::Rect& r) {
-    damage.assign_union(rfb::Region(r));
-    if (!Fl::has_timeout(handleUpdateTimeout, this))
-      Fl::add_timeout(0.500, handleUpdateTimeout, this);
-  };
+  void damageRect(const rfb::Rect& r);
 
   void setCursor(int width, int height, const rfb::Point& hotspot,
                  void* data, void* mask);
diff --git a/vncviewer/Win32PixelBuffer.h b/vncviewer/Win32PixelBuffer.h
index ae2b71a..7d91e09 100644
--- a/vncviewer/Win32PixelBuffer.h
+++ b/vncviewer/Win32PixelBuffer.h
@@ -19,6 +19,8 @@
 #ifndef __WIN32PIXELBUFFER_H__
 #define __WIN32PIXELBUFFER_H__
 
+#include <windows.h>
+
 #include <rfb/PixelBuffer.h>
 
 class PlatformPixelBuffer: public rfb::FullFramePixelBuffer {
diff --git a/win/rfb_win32/CKeyboard.cxx b/win/rfb_win32/CKeyboard.cxx
deleted file mode 100644
index 408e483..0000000
--- a/win/rfb_win32/CKeyboard.cxx
+++ /dev/null
@@ -1,285 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-#include <map>
-
-#define XK_MISCELLANY
-#define XK_LATIN1
-#define XK_CURRENCY
-#include <rfb/keysymdef.h>
-
-#include <rfb_win32/CKeyboard.h>
-#include <rfb/LogWriter.h>
-#include <rfb_win32/OSVersion.h>
-#include "keymap.h"
-
-using namespace rfb;
-
-static LogWriter vlog("CKeyboard");
-
-
-// Client-side RFB keyboard event sythesis
-
-class CKeymapper {
-
-public:
-  CKeymapper()
-  {
-    for (unsigned int i = 0; i < sizeof(keymap) / sizeof(keymap_t); i++) {
-      int extendedVkey = keymap[i].vk + (keymap[i].extended ? 256 : 0);
-      if (keysymMap.find(extendedVkey) == keysymMap.end()) {
-        keysymMap[extendedVkey] = keymap[i].keysym;
-      }
-    }
-  }
-
-  // lookup() tries to find a match for vkey with the extended flag.  We check
-  // first for an exact match including the extended flag, then try without the
-  // extended flag.
-  rdr::U32 lookup(int extendedVkey) {
-
-    // There's no real definition of the meaning of
-    // VK_SEPARATOR/XK_KP_Separator or VK_DECIMAL/XK_KP_Decimal. As
-    // http://blogs.msdn.com/michkap/archive/2006/09/13/752377.aspx
-    // puts it: "As for what is actually assigned to VK_DECIMAL, that
-    // is something that for every keyboard is either defined in a
-    // standard or decided by the person/people who submitted the
-    // keyboard layout. It may match the locale's preferences or it
-    // may not". In a VNC context, we are considering a SEPARATOR to
-    // be a comma and a DECIMAL to be a dot. 
-    if (extendedVkey == VK_DECIMAL || extendedVkey == VK_SEPARATOR) {
-      char buf[4];
-      if (!GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, (LPTSTR) buf,
-			 sizeof(buf) / sizeof(TCHAR))) {
-	vlog.debug("failed to retrieve LOCALE_SDECIMAL");
-      } else {
-	switch (buf[0]) {
-	case ',':
-	  extendedVkey = VK_SEPARATOR;
-	  break;
-	case '.':
-	  extendedVkey = VK_DECIMAL;
-	  break;
-	}
-      }
-    }
-
-    if (keysymMap.find(extendedVkey) != keysymMap.end())
-      return keysymMap[extendedVkey];
-    if (keysymMap.find(extendedVkey ^ 256) != keysymMap.end())
-      return keysymMap[extendedVkey ^ 256];
-    return 0;
-  }
-
-private:
-  std::map<int,rdr::U32> keysymMap;
-} ckeymapper;
-
-
-class ModifierKeyReleaser {
-public:
-  ModifierKeyReleaser(InputHandler* writer_, int vkCode, bool extended)
-    : writer(writer_), extendedVkey(vkCode + (extended ? 256 : 0)),
-      keysym(0)
-  {}
-  void release(std::map<int,rdr::U32>* downKeysym) {
-    if (downKeysym->find(extendedVkey) != downKeysym->end()) {
-      keysym = (*downKeysym)[extendedVkey];
-      vlog.debug("fake release extendedVkey 0x%x, keysym 0x%x",
-                 extendedVkey, keysym);
-      writer->keyEvent(keysym, false);
-    }
-  }
-  ~ModifierKeyReleaser() {
-    if (keysym) {
-      vlog.debug("fake press extendedVkey 0x%x, keysym 0x%x",
-                 extendedVkey, keysym);
-      writer->keyEvent(keysym, true);
-    }
-  }
-  InputHandler* writer;
-  int extendedVkey;
-  rdr::U32 keysym;
-};
-
-// IS_PRINTABLE_LATIN1 tests if a character is either a printable latin1
-// character, or 128, which is the Euro symbol on Windows.
-#define IS_PRINTABLE_LATIN1(c) (((c) >= 32 && (c) <= 126) || (c) == 128 || \
-                                ((c) >= 160 && (c) <= 255))
-
-void win32::CKeyboard::keyEvent(InputHandler* writer, rdr::U8 vkey,
-                                rdr::U32 flags, bool down)
-{
-  bool extended = (flags & 0x1000000);
-  int extendedVkey = vkey + (extended ? 256 : 0);
-
-  // If it's a release, just release whichever keysym corresponded to the same
-  // key being pressed, regardless of how it would be interpreted in the
-  // current keyboard state.
-  if (!down) {
-    releaseKey(writer, extendedVkey);
-    return;
-  }
-
-  // We should always pass every down event to ToAscii() otherwise it can get
-  // out of sync.
-
-  // XXX should we pass CapsLock, ScrollLock or NumLock to ToAscii - they
-  // actually alter the lock state on the keyboard?
-
-  BYTE keystate[256];
-  GetKeyboardState(keystate);
-  rdr::U8 chars[2];
-
-  int nchars = ToAscii(vkey, 0, keystate, (WORD*)&chars, 0);
-
-  // See if it's in the Windows VK code -> X keysym map.  We do this before
-  // looking at the result of ToAscii so that e.g. we recognise that it's
-  // XK_KP_Add rather than '+'.
-
-  rdr::U32 keysym = ckeymapper.lookup(extendedVkey);
-  if (keysym) {
-    vlog.debug("mapped key: extendedVkey 0x%x", extendedVkey);
-    pressKey(writer, extendedVkey, keysym);
-    return;
-  }
-
-  if (nchars < 0) {
-    // Dead key - the next call to ToAscii() will give us either the accented
-    // character or two characters.
-    vlog.debug("ToAscii dead key (1): extendedVkey 0x%x", extendedVkey);
-    return;
-  }
-
-  if (nchars > 0 && IS_PRINTABLE_LATIN1(chars[0])) {
-    // Got a printable latin1 character.  We must release Control and Alt
-    // (AltGr) if they were both pressed, so that the latin1 character is seen
-    // without them by the VNC server.
-    ModifierKeyReleaser lctrl(writer, VK_CONTROL, 0);
-    ModifierKeyReleaser rctrl(writer, VK_CONTROL, 1);
-    ModifierKeyReleaser lalt(writer, VK_MENU, 0);
-    ModifierKeyReleaser ralt(writer, VK_MENU, 1);
-
-    if ((keystate[VK_CONTROL] & 0x80) && (keystate[VK_MENU] & 0x80)) {
-      lctrl.release(&downKeysym);
-      rctrl.release(&downKeysym);
-      lalt.release(&downKeysym);
-      ralt.release(&downKeysym);
-    }
-
-    for (int i = 0; i < nchars; i++) {
-      vlog.debug("ToAscii key (1): extendedVkey 0x%x", extendedVkey);
-      if (chars[i] == 128) { // special hack for euro!
-        pressKey(writer, extendedVkey, XK_EuroSign);
-      } else {
-        pressKey(writer, extendedVkey, chars[i]);
-      }
-    }
-    return;
-  }
-
-  // Either no chars were generated, or something outside the printable
-  // character range.  Try ToAscii() without the Control and Alt keys down to
-  // see if that yields an ordinary character.
-
-  keystate[VK_CONTROL] = keystate[VK_LCONTROL] = keystate[VK_RCONTROL] = 0;
-  keystate[VK_MENU] = keystate[VK_LMENU] = keystate[VK_RMENU] = 0;
-
-  nchars = ToAscii(vkey, 0, keystate, (WORD*)&chars, 0);
-
-  if (nchars < 0) {
-    // So it would be a dead key if neither control nor alt were pressed.
-    // However, we know that at least one of control and alt must be pressed.
-    // We can't leave it at this stage otherwise the next call to ToAscii()
-    // with a valid character will get wrongly interpreted in the context of
-    // this bogus dead key.  Working on the assumption that a dead key followed
-    // by space usually returns the dead character itself, try calling ToAscii
-    // with VK_SPACE.
-    vlog.debug("ToAscii dead key (2): extendedVkey 0x%x", extendedVkey);
-    nchars = ToAscii(VK_SPACE, 0, keystate, (WORD*)&chars, 0);
-    if (nchars < 0) {
-      vlog.debug("ToAscii dead key (3): extendedVkey 0x%x - giving up!",
-                 extendedVkey);
-      return;
-    }
-  }
-
-  if (nchars > 0 && IS_PRINTABLE_LATIN1(chars[0])) {
-    for (int i = 0; i < nchars; i++) {
-      vlog.debug("ToAscii key (2) (no ctrl/alt): extendedVkey 0x%x",
-                 extendedVkey);
-      if (chars[i] == 128) { // special hack for euro!
-        pressKey(writer, extendedVkey, XK_EuroSign);
-      } else {
-        pressKey(writer, extendedVkey, chars[i]);
-      }
-    }
-    return;
-  }
-
-  vlog.debug("no chars regardless of control and alt: extendedVkey 0x%x",
-             extendedVkey);
-}
-
-// releaseAllKeys() - write key release events to the server for all keys
-// that are currently regarded as being down.
-void win32::CKeyboard::releaseAllKeys(InputHandler* writer) {
-  std::map<int,rdr::U32>::iterator i, next_i;
-  for (i=downKeysym.begin(); i!=downKeysym.end(); i=next_i) {
-    next_i = i; next_i++;
-    writer->keyEvent((*i).second, false);
-    downKeysym.erase(i);
-  }
-}
-
-// releaseKey() - write a key up event to the server, but only if we've
-// actually sent a key down event for the given key.  The key up event always
-// contains the same keysym we used in the key down event, regardless of what
-// it would look up as using the current keyboard state.
-void win32::CKeyboard::releaseKey(InputHandler* writer, int extendedVkey)
-{
-  if (downKeysym.find(extendedVkey) != downKeysym.end()) {
-    vlog.debug("release extendedVkey 0x%x, keysym 0x%x",
-               extendedVkey, downKeysym[extendedVkey]);
-    writer->keyEvent(downKeysym[extendedVkey], false);
-    downKeysym.erase(extendedVkey);
-  }
-}
-
-// pressKey() - write a key down event to the server, and record which keysym
-// was sent as corresponding to the given extendedVkey.  The only tricky bit is
-// that if we are trying to press an extendedVkey which is already marked as
-// down but with a different keysym, then we need to release the old keysym
-// first.  This can happen in two cases: (a) when a single key press results in
-// more than one character, and (b) when shift is released while another key is
-// autorepeating.
-void win32::CKeyboard::pressKey(InputHandler* writer, int extendedVkey,
-                                rdr::U32 keysym)
-{
-  if (downKeysym.find(extendedVkey) != downKeysym.end()) {
-    if (downKeysym[extendedVkey] != keysym) {
-      vlog.debug("release extendedVkey 0x%x, keysym 0x%x",
-                 extendedVkey, downKeysym[extendedVkey]);
-      writer->keyEvent(downKeysym[extendedVkey], false);
-    }
-  }
-  vlog.debug("press   extendedVkey 0x%x, keysym 0x%x",
-             extendedVkey, keysym);
-  writer->keyEvent(keysym, true);
-  downKeysym[extendedVkey] = keysym;
-}
diff --git a/win/rfb_win32/CKeyboard.h b/win/rfb_win32/CKeyboard.h
deleted file mode 100644
index bce886d..0000000
--- a/win/rfb_win32/CKeyboard.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-// -=- CKeyboard.h
-//
-// Client-side keyboard handling for Win32
-
-#ifndef __RFB_WIN32_CKEYBOARD_H__
-#define __RFB_WIN32_CKEYBOARD_H__
-
-#include <rfb/InputHandler.h>
-#include <map>
-
-namespace rfb {
-
-  namespace win32 {
-
-    class CKeyboard {
-    public:
-      void keyEvent(InputHandler* writer, rdr::U8 vkey, rdr::U32 flags,
-                    bool down);
-      void releaseAllKeys(InputHandler* writer);
-      const std::map<int,rdr::U32>& pressedKeys() const {return downKeysym;};
-      bool keyPressed(int k) const {return downKeysym.find(k)!=downKeysym.end();}
-    private:
-      void releaseKey(InputHandler* writer, int extendedVkey);
-      void pressKey(InputHandler* writer, int extendedVkey, rdr::U32 keysym);
-      std::map<int,rdr::U32> downKeysym;
-    };
-
-  }; // win32
-
-}; // rfb
-
-#endif // __RFB_WIN32_CKEYBOARD_H__
diff --git a/win/rfb_win32/CMakeLists.txt b/win/rfb_win32/CMakeLists.txt
index 83d7f1c..99d5277 100644
--- a/win/rfb_win32/CMakeLists.txt
+++ b/win/rfb_win32/CMakeLists.txt
@@ -1,8 +1,6 @@
 set(RFB_WIN32_SOURCES
   AboutDialog.cxx
-  CKeyboard.cxx
   Clipboard.cxx
-  CPointer.cxx
   CurrentUser.cxx
   DeviceContext.cxx
   DeviceFrameBuffer.cxx
@@ -12,14 +10,11 @@
   EventManager.cxx
   LaunchProcess.cxx
   ListViewControl.cxx
-  LowLevelKeyEvents.cxx
   MonitorInfo.cxx
   MsgWindow.cxx
   OSVersion.cxx
-  ProgressControl.cxx
   RegConfig.cxx
   Registry.cxx
-  ScaledDIBSectionBuffer.cxx
   SecurityPage.cxx
   SDisplayCorePolling.cxx
   SDisplayCoreWMHooks.cxx
@@ -30,7 +25,6 @@
   SocketManager.cxx
   TCharArray.cxx
   Threading.cxx
-  ToolBar.cxx
   TsSessions.cxx
   Win32Util.cxx
   WMCursor.cxx
diff --git a/win/rfb_win32/CPointer.cxx b/win/rfb_win32/CPointer.cxx
deleted file mode 100644
index eda6e38..0000000
--- a/win/rfb_win32/CPointer.cxx
+++ /dev/null
@@ -1,186 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-#include <windows.h>
-#include <rfb/LogWriter.h>
-#include <rfb_win32/CPointer.h>
-
-using namespace rfb;
-using namespace win32;
-
-static LogWriter vlog("CPointer");
-
-
-CPointer::CPointer() : currButtonMask(0), intervalQueued(false), threeEmulating(false) {
-}
-
-CPointer::~CPointer() {
-  intervalTimer.stop();
-  threeTimer.stop();
-}
-
-
-void CPointer::pointerEvent(InputHandler* writer, const Point& pos, int buttonMask) {
-  //
-  // - Duplicate Event Filtering
-  //
-
-  bool maskChanged = buttonMask != currButtonMask;
-  bool posChanged = !pos.equals(currPos);
-  if (!(posChanged || maskChanged))
-    return;
-
-  // Pass on the event to the event-interval handler
-  threePointerEvent(writer, pos, buttonMask);
-
-  // Save the position and mask
-  currPos = pos;
-  currButtonMask = buttonMask;
-}
-
-
-inline int _abs(int x) {return x>0 ? x : -x;}
-
-int emulate3Mask(int buttonMask) {
-  // - Release left & right and press middle
-  vlog.debug("emulate3: active");
-  buttonMask &= ~5;
-  buttonMask |= 2;
-  return buttonMask;
-}
-
-void CPointer::threePointerEvent(InputHandler* writer, const Point& pos, int buttonMask) {
-  //
-  // - 3-Button Mouse Emulation
-  //
-
-  if (emulate3) {
-
-    bool leftChanged = (buttonMask & 1) != (currButtonMask & 1);
-    bool rightChanged = (buttonMask & 4) != (currButtonMask & 4);
-
-    if (leftChanged || rightChanged) {
-      // - One of left or right have changed
-
-      if ((buttonMask & 5) == 1 || (buttonMask & 5) == 4) {
-        // - One is up, one is down.  Start a timer, so that if it
-        //   expires then we know we should actually send this event
-        vlog.debug("emulate3: start timer");
-        threeTimer.start(100);
-        threePos = pos;
-        threeMask = buttonMask;
-        return;
-
-      } else if (threeTimer.isActive()) {
-        // - Both are up or both are down, and we were timing for an emulation event
-        //   Stop the timer and flush the stored event
-        vlog.debug("emulate3: stop timer (state)");
-        threeTimer.stop();
-        if (threeEmulating == ((buttonMask & 5) == 5))
-          intervalPointerEvent(writer, threePos, threeMask);
-        else
-          threeEmulating = ((buttonMask & 5) == 5);
-      }
-
-    } else {
-    
-      if (threeTimer.isActive()) {
-        // - We are timing for an emulation event
-
-        if (_abs(threePos.x - pos.x) > 4 || _abs(threePos.y - pos.y) > 4) {
-          //   If the mouse has moved too far since the button-change event then flush
-          vlog.debug("emulate3: stop timer (moved)");
-          threeTimer.stop();
-          intervalPointerEvent(writer, threePos, threeMask);
-
-        } else {
-          //   Otherwise, we ignore the new event
-          return;
-        }
-      }
-
-    }
-
-    // - If neither left nor right are down, stop emulating
-    if ((buttonMask & 5) == 0)
-      threeEmulating = false;
-
-    // - If emulating, release left & right and press middle
-    if (threeEmulating)
-      buttonMask = emulate3Mask(buttonMask);
-
-  }
-
-  // - Let the event pass through to the next stage of processing
-  intervalPointerEvent(writer, pos, buttonMask);
-}
-
-void CPointer::intervalPointerEvent(InputHandler* writer, const Point& pos, int buttonMask) {
-  //
-  // - Pointer Event Interval
-  //
-  vlog.write(101, "ptrEvent: %d,%d (%lx)", pos.x, pos.y, buttonMask);
-
-  // Send the event immediately if we haven't sent one for a while
-  bool sendNow = !intervalTimer.isActive();
-
-  if (intervalMask != buttonMask) {
-    // If the buttons have changed then flush queued events and send now
-    sendNow = true;
-    if (intervalQueued)
-      writer->pointerEvent(intervalPos, intervalMask);
-    intervalQueued = false;
-  }
-
-  if (!sendNow) {
-    // If we're not sending now then just queue the event
-    intervalQueued = true;
-    intervalPos = pos;
-    intervalMask = buttonMask;
-  } else {
-    // Start the interval timer if required, and send the event
-    intervalQueued = false;
-    intervalMask = buttonMask;
-    if (pointerEventInterval)
-      intervalTimer.start(pointerEventInterval);
-    writer->pointerEvent(pos, buttonMask);
-  }
-}
-
-void CPointer::handleTimer(InputHandler* writer, int timerId) {
-  if (timerId == intervalTimer.getId()) {
-    // Pointer interval has expired - send any queued events
-    if (intervalQueued) {
-      writer->pointerEvent(intervalPos, intervalMask);
-      intervalQueued = false;
-    } else {
-      intervalTimer.stop();
-    }
-
-  } else if (timerId == threeTimer.getId()) {
-    // 3-Button emulation timer has expired - send what we've got
-    vlog.debug("emulate3: timeout");
-    threeTimer.stop();
-
-    // If emulating, release left & right and press middle
-    if (threeEmulating)
-      threeMask = emulate3Mask(threeMask);
-
-    intervalPointerEvent(writer, threePos, threeMask);
-  }
-}
diff --git a/win/rfb_win32/CPointer.h b/win/rfb_win32/CPointer.h
deleted file mode 100644
index b591601..0000000
--- a/win/rfb_win32/CPointer.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-// -=- CPointer.h
-//
-// Client-side pointer event handling for Win32
-
-#ifndef __RFB_WIN32_CPOINTER_H__
-#define __RFB_WIN32_CPOINTER_H__
-
-#include <rdr/Exception.h>
-#include <rfb/Configuration.h>
-#include <rfb/InputHandler.h>
-#include <rfb/Rect.h>
-#include <rfb_win32/IntervalTimer.h>
-
-namespace rfb {
-
-  namespace win32 {
-
-    class CPointer {
-    public:
-      CPointer();
-      ~CPointer();
-
-      void pointerEvent(InputHandler* writer, const Point& pos, int buttonMask);
-      void handleTimer(InputHandler* writer, int timerId);
-
-      void setHWND(HWND w) {intervalTimer.setHWND(w); threeTimer.setHWND(w);}
-      void setIntervalTimerId(int id) {intervalTimer.setId(id);}
-      void set3ButtonTimerId(int id) {threeTimer.setId(id);}
-
-      void enableEmulate3(bool enable) {emulate3 = enable;}
-      void enableInterval(int millis) {pointerEventInterval = millis;}
-    private:
-      Point currPos;
-      int currButtonMask;
-
-      bool emulate3;
-      int pointerEventInterval;
-
-      void intervalPointerEvent(InputHandler* writer, const Point& pos, int buttonMask);
-      IntervalTimer intervalTimer;
-      bool intervalQueued;
-      Point intervalPos;
-      int intervalMask;
-
-      void threePointerEvent(InputHandler* writer, const Point& pos, int buttonMask);
-      IntervalTimer threeTimer;
-      Point threePos;
-      int threeMask;
-      bool threeEmulating;
-    };
-
-  }; // win32
-
-}; // rfb
-
-#endif // __RFB_WIN32_CPOINTER_H__
diff --git a/win/rfb_win32/DIBSectionBuffer.cxx b/win/rfb_win32/DIBSectionBuffer.cxx
index 3c2f509..0c266b0 100644
--- a/win/rfb_win32/DIBSectionBuffer.cxx
+++ b/win/rfb_win32/DIBSectionBuffer.cxx
@@ -1,4 +1,5 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * Copyright 2014 Pierre Ossman for Cendio AB
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -55,9 +56,11 @@
   if ((pf.bpp <= 8) && pf.trueColour) {
     vlog.info("creating %d-bit TrueColour palette", pf.depth);
     for (int i=0; i < (1<<(pf.depth)); i++) {
-      palette[i].b = ((((i >> pf.blueShift) & pf.blueMax) * 65535) + pf.blueMax/2) / pf.blueMax;
-      palette[i].g = ((((i >> pf.greenShift) & pf.greenMax) * 65535) + pf.greenMax/2) / pf.greenMax;
-      palette[i].r = ((((i >> pf.redShift) & pf.redMax) * 65535) + pf.redMax/2) / pf.redMax;
+      rdr::U16 r, g, b;
+      pf.rgbFromPixel(i, NULL, &r, &g, &b);
+      palette[i].r = r;
+      palette[i].g = g;
+      palette[i].b = b;
     }
     refreshPalette();
   }
@@ -110,9 +113,9 @@
     bi.bmiHeader.biWidth = width_;
     bi.bmiHeader.biHeight = -height_;
     bi.bmiHeader.biCompression = (format.bpp > 8) ? BI_BITFIELDS : BI_RGB;
-    bi.mask.red = format.redMax << format.redShift;
-    bi.mask.green = format.greenMax << format.greenShift;
-    bi.mask.blue = format.blueMax << format.blueShift;
+    bi.mask.red = format.pixelFromRGB((rdr::U16)~0, 0, 0);
+    bi.mask.green = format.pixelFromRGB(0, (rdr::U16)~0, 0);
+    bi.mask.blue = format.pixelFromRGB(0, 0, (rdr::U16)~0);
 
     // Create a DIBSection to draw into
     if (device)
@@ -160,6 +163,11 @@
   }
 
   if (new_bitmap) {
+    int bpp, depth;
+    bool trueColour;
+    int redMax, greenMax, blueMax;
+    int redShift, greenShift, blueShift;
+
     // Set up the new bitmap
     bitmap = new_bitmap;
     data = new_data;
@@ -180,30 +188,34 @@
     }
 
     // Calculate the PixelFormat for the DIB
-    format.bigEndian = 0;
-    format.bpp = format.depth = ds.dsBm.bmBitsPixel;
-    format.trueColour = format.trueColour || format.bpp > 8;
-    if (format.bpp > 8) {
+    bpp = depth = ds.dsBm.bmBitsPixel;
+    trueColour = format.trueColour || format.bpp > 8;
 
+    if (trueColour) {
       // Get the truecolour format used by the DIBSection
-      initMaxAndShift(ds.dsBitfields[0], &format.redMax, &format.redShift);
-      initMaxAndShift(ds.dsBitfields[1], &format.greenMax, &format.greenShift);
-      initMaxAndShift(ds.dsBitfields[2], &format.blueMax, &format.blueShift);
+      initMaxAndShift(ds.dsBitfields[0], &redMax, &redShift);
+      initMaxAndShift(ds.dsBitfields[1], &greenMax, &greenShift);
+      initMaxAndShift(ds.dsBitfields[2], &blueMax, &blueShift);
 
       // Calculate the effective depth
-      format.depth = 0;
+      depth = 0;
       Pixel bits = ds.dsBitfields[0] | ds.dsBitfields[1] | ds.dsBitfields[2];
       while (bits) {
-        format.depth++;
+        depth++;
         bits = bits >> 1;
       }
-      if (format.depth > format.bpp)
+      if (depth > bpp)
         throw Exception("Bad DIBSection format (depth exceeds bpp)");
-    } else {
+    }
+
+    format = PixelFormat(bpp, depth, false, trueColour,
+                         redMax, greenMax, blueMax,
+                         redShift, greenShift, blueShift);
+
+    if (!trueColour) {
       // Set the DIBSection's palette
       refreshPalette();
     }
-
   }
 }
 
diff --git a/win/rfb_win32/DeviceContext.cxx b/win/rfb_win32/DeviceContext.cxx
index 3b97e44..26721a6 100644
--- a/win/rfb_win32/DeviceContext.cxx
+++ b/win/rfb_win32/DeviceContext.cxx
@@ -1,4 +1,5 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * Copyright 2014 Pierre Ossman for Cendio AB
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,7 +34,11 @@
 }
 
 PixelFormat DeviceContext::getPF(HDC dc) {
-  PixelFormat format;
+  bool trueColour, bigEndian;
+  int bpp, depth;
+  int redMax, greenMax, blueMax;
+  int redShift, greenShift, blueShift;
+
   CompatibleBitmap bitmap(dc, 1, 1);
 
   // -=- Get the bitmap format information
@@ -49,11 +54,11 @@
   }
 
   // Set the initial format information
-  format.trueColour = bi.bmiHeader.biBitCount > 8;
-  format.bigEndian = 0;
-  format.bpp = bi.bmiHeader.biBitCount;
+  trueColour = bi.bmiHeader.biBitCount > 8;
+  bigEndian = 0;
+  bpp = bi.bmiHeader.biBitCount;
 
-  if (format.trueColour) {
+  if (trueColour) {
     DWORD rMask=0, gMask=0, bMask=0;
 
     // Which true colour format is the DIB section using?
@@ -92,44 +97,42 @@
     };
 
     // Convert the data we just retrieved
-    initMaxAndShift(rMask, &format.redMax, &format.redShift);
-    initMaxAndShift(gMask, &format.greenMax, &format.greenShift);
-    initMaxAndShift(bMask, &format.blueMax, &format.blueShift);
+    initMaxAndShift(rMask, &redMax, &redShift);
+    initMaxAndShift(gMask, &greenMax, &greenShift);
+    initMaxAndShift(bMask, &blueMax, &blueShift);
 
     // Calculate the depth from the colour shifts
-    format.depth = 0;
+    depth = 0;
     Pixel bits = rMask | gMask | bMask;
     while (bits) {
-      format.depth++;
+      depth++;
       bits = bits >> 1;
     }
 
     // Check that the depth & bpp are valid
-    if (format.depth > format.bpp) {
+    if (depth > bpp) {
       vlog.error("depth exceeds bits per pixel!");
-      format.bpp = format.depth;
+      bpp = depth;
     }
 
     // Correct the bits-per-pixel to something we're happy with
-    if (format.bpp <= 16)
-      format.bpp = 16;
-    else if (format.bpp <= 32)
-      format.bpp = 32;
+    if (bpp <= 16)
+      bpp = 16;
+    else if (bpp <= 32)
+      bpp = 32;
   } else {
     // Palettised format - depth reflects number of colours,
     // but bits-per-pixel is ALWAYS 8
-    format.depth = format.bpp;
-    if (format.bpp < 8)
-      format.bpp = 8;
-    vlog.info("%d-colour palettised", 1<<format.depth);
+    depth = bpp;
+    if (bpp < 8)
+      bpp = 8;
+    vlog.info("%d-colour palettised", 1<<depth);
   }
 
 
-  // Use 10 arguments constructor to trigger PixelFormat::updateState()
-  return PixelFormat(format.bpp, format.depth,
-		     format.bigEndian, format.trueColour,
-		     format.redMax, format.greenMax, format.blueMax,
-		     format.redShift, format.greenShift, format.blueShift);
+  return PixelFormat(bpp, depth, bigEndian, trueColour,
+		                 redMax, greenMax, blueMax,
+		                 redShift, greenShift, blueShift);
 }
 
 Rect DeviceContext::getClipBox() const {
diff --git a/win/rfb_win32/LogicalPalette.h b/win/rfb_win32/LogicalPalette.h
deleted file mode 100644
index 204f108..0000000
--- a/win/rfb_win32/LogicalPalette.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-#ifndef __RFB_WIN32_LOGPALETTE_H__
-#define __RFB_WIN32_LOGPALETTE_H__
-
-#include <windows.h>
-#include <rdr/Exception.h>
-
-namespace rfb {
-  namespace win32 {
-
-    class LogicalPalette {
-    public:
-      LogicalPalette() {
-        BYTE buf[sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY)];
-        LOGPALETTE* logpal = (LOGPALETTE*)buf;
-        logpal->palVersion = 0x300;
-        logpal->palNumEntries = 256;
-        for (int i=0; i<256;i++) {
-          logpal->palPalEntry[i].peRed = 0;
-          logpal->palPalEntry[i].peGreen = 0;
-          logpal->palPalEntry[i].peBlue = 0;
-          logpal->palPalEntry[i].peFlags = 0;
-        }
-        palette = CreatePalette(logpal);
-        if (!palette)
-          throw rdr::SystemException("failed to CreatePalette", GetLastError());
-      }
-      ~LogicalPalette() {
-        if (palette && !DeleteObject(palette))
-          throw rdr::SystemException("del palette failed", GetLastError());
-      }
-      void setEntries(int start, int count, const Colour* cols) {
-        if (numEntries < count) {
-          ResizePalette(palette, start+count);
-          numEntries = start+count;
-        }
-        PALETTEENTRY* logpal = new PALETTEENTRY[count];
-        for (int i=0; i<count; i++) {
-          logpal[i].peRed = cols[i].r >> 8;
-          logpal[i].peGreen = cols[i].g >> 8;
-          logpal[i].peBlue = cols[i].b >> 8;
-          logpal[i].peFlags = 0;
-        }
-        UnrealizeObject(palette);
-        SetPaletteEntries(palette, start, count, logpal);
-        delete [] logpal;
-      }
-      HPALETTE getHandle() {return palette;}
-    protected:
-      HPALETTE palette;
-      int numEntries;
-    };
-
-    class PaletteSelector {
-    public:
-      PaletteSelector(HDC dc, HPALETTE pal) : device(dc), redrawRequired(false) {
-        oldPal = SelectPalette(dc, pal, FALSE);
-        redrawRequired = RealizePalette(dc) > 0;
-      }
-      ~PaletteSelector() {
-        if (oldPal) SelectPalette(device, oldPal, TRUE);
-      }
-      bool isRedrawRequired() {return redrawRequired;}
-    protected:
-      HPALETTE oldPal;
-      HDC device;
-      bool redrawRequired;
-    };
-
-  };
-};
-
-#endif
diff --git a/win/rfb_win32/LowLevelKeyEvents.cxx b/win/rfb_win32/LowLevelKeyEvents.cxx
deleted file mode 100644
index e80ebed..0000000
--- a/win/rfb_win32/LowLevelKeyEvents.cxx
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-#include <windows.h>
-#include <rfb_win32/LowLevelKeyEvents.h>
-#include <rfb/Threading.h>
-#include <rfb/LogWriter.h>
-#include <list>
-
-using namespace rfb;
-using namespace win32;
-
-static LogWriter vlog("LowLevelKeyEvents");
-
-
-HHOOK hook = 0;
-std::list<HWND> windows;
-Mutex windowLock;
-
-
-static bool filterKeyEvent(int vkCode) {
-  switch (vkCode) {
-  case VK_LWIN:
-  case VK_RWIN:
-  case VK_SNAPSHOT:
-    return true;
-  case VK_TAB:
-    if (GetAsyncKeyState(VK_MENU) & 0x8000)
-      return true;
-  case VK_ESCAPE:
-    if (GetAsyncKeyState(VK_MENU) & 0x8000)
-      return true;
-    if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
-      return true;
-  }
-  return false;
-}
-
-LRESULT CALLBACK LowLevelKeyEventProc(int nCode,
-                                      WPARAM wParam,
-                                      LPARAM lParam) {
-  if (nCode >= 0) {
-    Lock l(windowLock);
-    HWND foreground = GetForegroundWindow();
-    std::list<HWND>::iterator i;
-    for (i=windows.begin(); i!=windows.end(); i++) {
-      if (*i == foreground) {
-        UINT msgType = wParam;
-        KBDLLHOOKSTRUCT* msgInfo = (KBDLLHOOKSTRUCT*)lParam;
-        if (filterKeyEvent(msgInfo->vkCode)) {
-          vlog.debug("filtered event %lx(%lu) %lu", msgInfo->vkCode, msgInfo->vkCode, msgType);
-          PostMessage(*i, wParam, msgInfo->vkCode, (msgInfo->scanCode & 0xff) << 16);
-          return 1;
-        }
-      }
-    }
-  }
-  return CallNextHookEx(hook, nCode, wParam, lParam);
-}
-
-
-bool rfb::win32::enableLowLevelKeyEvents(HWND hwnd) {
-// ***  return false; // *** THIS CODE IS EXPERIMENTAL, SO DISABLED BY DEFAULT!
-  Lock l(windowLock);
-  if (windows.empty() && !hook)
-    hook = SetWindowsHookEx(WH_KEYBOARD_LL, &LowLevelKeyEventProc, GetModuleHandle(0), 0);
-  if (hook)
-    windows.push_back(hwnd);
-  vlog.debug("enable %p -> %s", hwnd, hook ? "success" : "failure");
-  return hook != 0;
-}
-
-void rfb::win32::disableLowLevelKeyEvents(HWND hwnd) {
-  vlog.debug("disable %p", hwnd);
-  Lock l(windowLock);
-  windows.remove(hwnd);
-  if (windows.empty() && hook) {
-    UnhookWindowsHookEx(hook);
-    hook = 0;
-  }
-}
diff --git a/win/rfb_win32/LowLevelKeyEvents.h b/win/rfb_win32/LowLevelKeyEvents.h
deleted file mode 100644
index 40d2ecf..0000000
--- a/win/rfb_win32/LowLevelKeyEvents.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-// -=- LowLevelKeyEvents.h
-//
-// This interface allows keyboard events destined for a particular window
-// to be intercepted early in the keyboard message queue and posted directly
-// to the window.  This is used to avoid having the operating system process
-// keys such as VK_LWIN, VK_RWIN, etc.
-//
-
-#ifndef __RFB_WIN32_LOW_LEVEL_KEY_EVENTS_H__
-#define __RFB_WIN32_LOW_LEVEL_KEY_EVENTS_H__
-
-namespace rfb {
-
-  namespace win32 {
-
-    // enableLowLevelKeyEvents
-    //   Specifies that keyboard events destined for the specified window should
-    //   be posted directly to the window, rather than being passed via the normal
-    //   Windows keyboard message queue.
-    bool enableLowLevelKeyEvents(HWND hwnd);
-
-    // disableLowLevelKeyEvents
-    //   Causes the specified window to revert to the normal Windows keyboard
-    //   event processing mechanism.
-    void disableLowLevelKeyEvents(HWND hwnd);
-
-  };
-
-};
-
-#endif // __RFB_WIN32_LOW_LEVEL_KEY_EVENTS_H__
diff --git a/win/rfb_win32/ProgressControl.cxx b/win/rfb_win32/ProgressControl.cxx
deleted file mode 100644
index 5533317..0000000
--- a/win/rfb_win32/ProgressControl.cxx
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Copyright (C) 2005 TightVNC Team.  All Rights Reserved.
- *    
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- *
- * 
- *
- */
-
-// -=- ProgressControl.cxx
-
-#include <rfb_win32/ProgressControl.h>
-
-using namespace rfb;
-using namespace rfb::win32;
-
-#define MAX_RANGE 0xFFFF
-
-ProgressControl::ProgressControl(HWND hwndProgress)
-{
-  m_hwndProgress = hwndProgress;
-  
-  m_dw64MaxValue = 0;
-  m_dw64CurrentValue = 0;
-}
-
-ProgressControl::~ProgressControl()
-{
-}
-
-bool
-ProgressControl::init(DWORD64 maxValue, DWORD64 position)
-{
-  if (m_dw64CurrentValue > m_dw64MaxValue) return false;
-  
-  m_dw64CurrentValue = position;
-  m_dw64MaxValue = maxValue;
-  
-  if (!SendMessage(m_hwndProgress, PBM_SETRANGE, (WPARAM) 0, MAKELPARAM(0, MAX_RANGE))) 
-    return false;
-  
-  return true;
-}
-
-bool
-ProgressControl::clear()
-{
-  m_dw64CurrentValue = 0;
-  return show();
-}
-
-bool
-ProgressControl::increase(DWORD64 value)
-{
-  if ((m_dw64MaxValue - m_dw64CurrentValue) > value) {
-    m_dw64CurrentValue += value;
-  } else {
-    m_dw64CurrentValue = m_dw64MaxValue;
-  }
-  return show();
-}
-
-bool
-ProgressControl::show()
-{
-  DWORD curPos;
-  if (m_dw64MaxValue != 0) {
-    curPos = (DWORD) ((m_dw64CurrentValue * MAX_RANGE) / m_dw64MaxValue);
-  } else {
-    curPos = 0;
-  }
-  
-  if (!SendMessage(m_hwndProgress, PBM_SETPOS, (WPARAM) curPos, (LPARAM) 0))
-    return false;
-  
-  return true;
-}
-
-int 
-ProgressControl::getCurrentPercent()
-{
-  if (m_dw64MaxValue == 0) return 0;
-
-  return ((int) ((m_dw64CurrentValue * 100) / m_dw64MaxValue));
-}
diff --git a/win/rfb_win32/ProgressControl.h b/win/rfb_win32/ProgressControl.h
deleted file mode 100644
index 094c765..0000000
--- a/win/rfb_win32/ProgressControl.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Copyright (C) 2005 TightVNC Team.  All Rights Reserved.
- *    
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- *
- * 
- *
- */
-
-// -=- ProgressControl.h
-
-#ifndef __RFB_WIN32_PROGRESSCONTROL_H__
-#define __RFB_WIN32_PROGRESSCONTROL_H__
-
-#include <windows.h>
-#include <commctrl.h>
-
-namespace rfb {
-  namespace win32 {
-    class ProgressControl
-    {
-    public:
-      ProgressControl(HWND hwndProgress);
-      ~ProgressControl();
-      
-      bool init(DWORD64 maxValue, DWORD64 position);
-      
-      bool increase(DWORD64 value);
-      bool clear();
-
-      int getCurrentPercent();
-      
-    private:
-      HWND m_hwndProgress;
-      
-      DWORD64 m_dw64MaxValue;
-      DWORD64 m_dw64CurrentValue;
-      
-      bool show();
-    };
-  }
-}
-
-#endif // __RFB_WIN32_PROGRESSCONTROL_H__
diff --git a/win/rfb_win32/ScaledDIBSectionBuffer.cxx b/win/rfb_win32/ScaledDIBSectionBuffer.cxx
deleted file mode 100644
index 752cd78..0000000
--- a/win/rfb_win32/ScaledDIBSectionBuffer.cxx
+++ /dev/null
@@ -1,195 +0,0 @@
-/* Copyright (C) 2006 TightVNC Team.  All Rights Reserved.
- *    
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- *
- * 
- *
- */
-
-// -=- ScaledDIBSectionBuffer.cxx
-
-#include <math.h>
-
-#include <rfb_win32/ScaledDIBSectionBuffer.h>
-
-using namespace rfb;
-using namespace win32;
-
-const PixelFormat RGB24(32, 24, 0, 1, 255, 255, 255, 16, 8, 0);
-
-ScaledDIBSectionBuffer::ScaledDIBSectionBuffer(HWND window) 
-  : DIBSectionBuffer(window), src_buffer(0), scaling(false) {
-  scaled_data = &data;
-}
-
-ScaledDIBSectionBuffer::~ScaledDIBSectionBuffer() {
-  if (src_buffer) delete src_buffer;
-}
-
-void ScaledDIBSectionBuffer::setScale(int scale_) {
-  if (scale == scale_ || scale_ <= 0) return;
-  if (!(getPixelFormat().trueColour) && scale_ != 100) throw rfb::UnsupportedPixelFormatException();
-  ScaledPixelBuffer::setScale(scale_);
-  if (scale == 100) scaling = false;
-  else scaling = true;
-  recreateBuffers();
-}
-
-void ScaledDIBSectionBuffer::setPF(const PixelFormat &pf_) {
-  if (memcmp(&(ScaledPixelBuffer::pf), &pf_, sizeof(pf_)) == 0) return;
-
-  if (!pf_.trueColour && isScaling()) throw rfb::UnsupportedPixelFormatException();
-
-  pf = pf_;
-  if (scaling) {
-    if (src_buffer) {
-      src_buffer->setPF(pf);
-    } else {
-      src_buffer = new ManagedPixelBuffer(pf, src_width, src_height);
-      src_data = &(src_buffer->data);
-    }
-    if (memcmp(&(DIBSectionBuffer::getPF()), &RGB24, sizeof(PixelFormat)) != 0) {
-      DIBSectionBuffer::setPF(RGB24);
-    }
-  } else {
-    DIBSectionBuffer::setPF(pf);
-    pf = format;
-  }
-}
-
-void ScaledDIBSectionBuffer::setSize(int src_width_, int src_height_) {
-  if (src_width == src_width_ && src_height == src_height_) return;
-  src_width = src_width_;
-  src_height = src_height_;
-  
-  // FIXME:
-  // Calculate the scale weight tabs must be in the ScalePixelBuffer class
-  recreateRowAccum();
-  freeWeightTabs();
-  calculateScaledBufferSize();
-  scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, &xWeightTabs);
-  scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, &yWeightTabs);
-
-  recreateBuffers();
-}
-
-void ScaledDIBSectionBuffer::setScaleWindowSize(int width, int height) {
-  if (scaled_width == width && scaled_height == height) return;
-
-  freeWeightTabs();
-
-  scaled_width = width_ = width;
-  scaled_height = height_ = height;
-
-  if (scaled_width == src_width && scaled_height == src_height) scaling = false;
-  else scaling = true;
-  scale_ratio_x = (double)scaled_width / src_width;
-  scale_ratio_y = (double)scaled_height / src_height;
-  scale = (int)(scale_ratio_x * 100);
-  
-  // FIXME:
-  // Calculate the scale weight tabs must be in the ScalePixelBuffer class
-  scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, &xWeightTabs);
-  scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, &yWeightTabs);
-
-  recreateBuffers();
-}
-
-void ScaledDIBSectionBuffer::recreateScaledBuffer() {
-  if (scaling && memcmp(&(DIBSectionBuffer::getPF()), &RGB24, sizeof(PixelFormat)) != 0) {
-    DIBSectionBuffer::setPF(RGB24);
-  } else if (!scaling && (memcmp(&(DIBSectionBuffer::getPF()), &pf, sizeof(PixelFormat)) != 0)){
-    DIBSectionBuffer::setPF(pf);
-  } else {
-    DIBSectionBuffer::recreateBuffer();
-  }
-}
-
-void ScaledDIBSectionBuffer::recreateBuffers() {
-  // Recreate the source pixel buffer
-  if (src_width && src_height && pf.depth > 0) {
-    if (scaling) {
-      if (src_buffer) { 
-        if (src_buffer->width() != src_width || src_buffer->width() != src_height)
-          src_buffer->setSize(src_width, src_height);
-      } else {
-        src_buffer = new ManagedPixelBuffer(pf, src_width, src_height);
-        src_data = &(src_buffer->data);
-        if (data) memcpy(src_buffer->data, data, src_width * src_height * (getPF().bpp/8));
-      }
-    }
-  }
-  // Recreate the scaled pixel buffer
-  recreateScaledBuffer();
-  if (scaling && src_buffer && data) scaleRect(Rect(0, 0, src_width, src_height));
-  else if (!scaling && src_buffer) {
-    if (src_buffer->data && data) memcpy(data, src_buffer->data, src_buffer->area() * (getPF().bpp/8));
-    delete src_buffer;
-    src_buffer = 0;
-    src_data = 0;
-  }
-}
-
-void ScaledDIBSectionBuffer::calculateScaledBufferSize() {
-  ScaledPixelBuffer::calculateScaledBufferSize();
-  width_ = scaled_width;
-  height_ = scaled_height;
-}
-
-void ScaledDIBSectionBuffer::fillRect(const Rect &dest, Pixel pix) {
-  if (scaling) {
-    src_buffer->fillRect(dest, pix);
-    scaleRect(dest);
-  } else {
-    DIBSectionBuffer::fillRect(dest, pix);
-  }
-}
-
-void ScaledDIBSectionBuffer::imageRect(const Rect &dest, const void* pixels, int stride) {
-  if (scaling) {
-    src_buffer->imageRect(dest, pixels, stride);
-    scaleRect(dest);
-  } else {
-    DIBSectionBuffer::imageRect(dest, pixels, stride);
-  }
-}
-
-void ScaledDIBSectionBuffer::copyRect(const Rect &dest, const Point &move_by_delta) {
-  if (scaling) {
-    src_buffer->copyRect(dest, move_by_delta);
-    scaleRect(dest);
-  } else {
-    DIBSectionBuffer::copyRect(dest, move_by_delta);
-  }
-}
-      
-void ScaledDIBSectionBuffer::maskRect(const Rect& r, const void* pixels, const void* mask_) {
-  if (scaling) {
-    src_buffer->maskRect(r, pixels, mask_);
-    scaleRect(r);
-  } else {
-    DIBSectionBuffer::maskRect(r, pixels, mask_);
-  }
-}
-
-void ScaledDIBSectionBuffer::maskRect(const Rect& r, Pixel pixel, const void* mask_) {
-  if (scaling) {
-    src_buffer->maskRect(r, pixel, mask_);
-    scaleRect(r);
-  } else {
-    DIBSectionBuffer::maskRect(r, pixel, mask_);
-  }
-}
diff --git a/win/rfb_win32/ScaledDIBSectionBuffer.h b/win/rfb_win32/ScaledDIBSectionBuffer.h
deleted file mode 100644
index 420a97a..0000000
--- a/win/rfb_win32/ScaledDIBSectionBuffer.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Copyright (C) 2006 TightVNC Team.  All Rights Reserved.
- *    
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- *
- * 
- *
- */
-
-// -=- ScaledDIBSectionBuffer.h
-
-#ifndef __RFB_WIN32_SCALED_DIB_SECTION_BUFFER_H__
-#define __RFB_WIN32_SCALED_DIB_SECTION_BUFFER_H__
-
-#include <rfb/ScaledPixelBuffer.h>
-
-#include <rfb_win32/DIBSectionBuffer.h>
-
-namespace rfb {
-
-  namespace win32 {
-
-    //
-    // -=- ScaledDIBSectionBuffer
-    //
-
-    class ScaledDIBSectionBuffer : public ScaledPixelBuffer, public DIBSectionBuffer {
-    public:
-      ScaledDIBSectionBuffer(HWND window);
-      virtual ~ScaledDIBSectionBuffer();
-
-      int width()  const { return scaled_width; }
-      int height() const { return scaled_height; }
-      int area() const { return scaled_width * scaled_height; }
-      bool isScaling() const { return scaling; }
-
-      virtual void setPF(const PixelFormat &pf);
-      virtual const PixelFormat& getPixelFormat() const { return pf; }
-      virtual const PixelFormat& getScaledPixelFormat() const { return getPF(); }
-      virtual void setSize(int w, int h);
-      virtual void setScale(int scale);
-      virtual void setScaleWindowSize(int width, int height);
-      
-      virtual void calculateScaledBufferSize();
-
-      Rect getRect() const { return ScaledPixelBuffer::getRect(); }
-      Rect getRect(const Point& pos) const { return ScaledPixelBuffer::getRect(pos); }
-
-      // -=- Overrides basic rendering operations of 
-      //     FullFramePixelBuffer class
-
-      virtual void fillRect(const Rect &dest, Pixel pix);
-      virtual void imageRect(const Rect &dest, const void* pixels, int stride=0);
-      virtual void copyRect(const Rect &dest, const Point &move_by_delta);
-      virtual void maskRect(const Rect& r, const void* pixels, const void* mask_);
-      virtual void maskRect(const Rect& r, Pixel pixel, const void* mask_);
-
-    protected:
-      virtual void recreateScaledBuffer();
-      virtual void recreateBuffers();
-      virtual void recreateBuffer() {
-        recreateScaledBuffer();
-      };
-
-      ManagedPixelBuffer *src_buffer;
-      bool scaling;
-    };
-
-  };
-
-};
-
-#endif // __RFB_WIN32_SCALED_DIB_SECTION_BUFFER_H__
diff --git a/win/rfb_win32/ToolBar.cxx b/win/rfb_win32/ToolBar.cxx
deleted file mode 100644
index 1bbba30..0000000
--- a/win/rfb_win32/ToolBar.cxx
+++ /dev/null
@@ -1,222 +0,0 @@
-/* Copyright (C) 2004 TightVNC Team.  All Rights Reserved.
- *    
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-// -=- ToolBar control class.
-
-#include "ToolBar.h"
-
-using namespace rfb::win32;
-
-ToolBar::ToolBar() : hwndToolBar(0), tbID(-1) {
-  INITCOMMONCONTROLSEX icex;
-
-  // Ensure that the common control DLL is loaded
-  icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
-  icex.dwICC  = ICC_BAR_CLASSES;
-  InitCommonControlsEx(&icex);
-}
-
-ToolBar::~ToolBar() {
-  DestroyWindow(getHandle());
-}
-
-bool ToolBar::create(int _tbID, HWND _parentHwnd, DWORD dwStyle) {
-  parentHwnd = _parentHwnd;
-  dwStyle |= WS_CHILD;
-
-  // Create the ToolBar window
-  hwndToolBar = CreateWindowEx(0, TOOLBARCLASSNAME, 0, dwStyle, 
-    0, 0, 25, 25, parentHwnd, (HMENU)_tbID, GetModuleHandle(0), 0);
-
-  if (hwndToolBar) {
-    tbID = _tbID;
-
-    // It's required for backward compatibility
-    SendMessage(hwndToolBar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
-  }
-  return (hwndToolBar ? true : false);
-};
-
-int ToolBar::addBitmap(int nButtons, UINT bitmapID) {
-  assert(nButtons > 0);
-  TBADDBITMAP resBitmap;
-  resBitmap.hInst = GetModuleHandle(0);
-  resBitmap.nID = bitmapID;
-  return SendMessage(getHandle(), TB_ADDBITMAP, nButtons, (LPARAM)&resBitmap);
-}
-
-int ToolBar::addSystemBitmap(UINT stdBitmapID) {
-  TBADDBITMAP resBitmap;
-  resBitmap.hInst = HINST_COMMCTRL;
-  resBitmap.nID = stdBitmapID;
-  return SendMessage(getHandle(), TB_ADDBITMAP, 0, (LPARAM)&resBitmap);
-}
-
-bool ToolBar::setBitmapSize(int width, int height) {
-  int result = SendMessage(getHandle(), TB_SETBITMAPSIZE, 
-    0, MAKELONG(width, height));
-  return (result ? true : false);
-}
-
-bool ToolBar::addButton(int iBitmap, int idCommand, BYTE state, BYTE style, UINT dwData, int iString) {
-  TBBUTTON tbb;
-  tbb.iBitmap = iBitmap;
-  tbb.idCommand = idCommand;
-  tbb.fsState = state;
-  tbb.fsStyle = style;
-  tbb.dwData = dwData;
-  tbb.iString = iString;
-
-  int result = SendMessage(getHandle(), TB_ADDBUTTONS, 1, (LPARAM)&tbb);
-  if (result) {
-    SendMessage(getHandle(), TB_AUTOSIZE, 0, 0);
-  }
-  return (result ? true : false);
-}
-
-bool ToolBar::addNButton(int nButtons, LPTBBUTTON tbb) {
-  assert(nButtons > 0);
-  assert(tbb > 0);
-  int result = SendMessage(getHandle(), TB_ADDBUTTONS, nButtons, (LPARAM)tbb);
-  if (result) {
-    SendMessage(getHandle(), TB_AUTOSIZE, 0, 0);
-  }
-  return (result ? true : false);
-}
-
-bool ToolBar::deleteButton(int indexButton) {
-  assert(indexButton >= 0);
-  int result = SendMessage(getHandle(), TB_DELETEBUTTON, indexButton, 0);
-  
-  if (result) {
-    SendMessage(getHandle(), TB_AUTOSIZE, 0, 0);
-  }
-  return (result ? true : false);
-}
-
-bool ToolBar::insertButton(int indexButton, LPTBBUTTON tbb) {
-  assert(indexButton >= 0);
-  assert(tbb > 0);
-  int result = SendMessage(getHandle(), TB_INSERTBUTTON, 
-    indexButton, (LPARAM)tbb);
-
-  if (result) {
-    SendMessage(getHandle(), TB_AUTOSIZE, 0, 0);
-  }
-  return (result ? true : false);
-}
-
-int ToolBar::getButtonInfo(int idButton, TBBUTTONINFO *btnInfo) {
-  assert(idButton >= 0);
-  assert(btnInfo > 0);
-  return SendMessage(getHandle(), TB_GETBUTTONINFO, idButton, (LPARAM)btnInfo);
-}
-
-int ToolBar::getButtonsHeight() {
-  return HIWORD(SendMessage(getHandle(), TB_GETBUTTONSIZE, 0, 0));
-}
-
-int ToolBar::getButtonsWidth() {
-  return LOWORD(SendMessage(getHandle(), TB_GETBUTTONSIZE, 0, 0));
-}
-
-bool ToolBar::setButtonInfo(int idButton, TBBUTTONINFO* btnInfo) {
-  assert(idButton >= 0);
-  assert(btnInfo > 0);
-  int result = SendMessage(getHandle(), TB_SETBUTTONINFO, 
-    idButton, (LPARAM)(LPTBBUTTONINFO)btnInfo);
-  return (result ? true : false);
-}
-
-bool ToolBar::checkButton(int idButton, bool check) {
-  assert(idButton >= 0);
-  int result = SendMessage(getHandle(), TB_CHECKBUTTON, 
-    idButton, MAKELONG(check, 0));
-  return (result ? true : false);
-}
-
-bool ToolBar::enableButton(int idButton, bool enable) {
-  assert(idButton >= 0);
-  int result = SendMessage(getHandle(), TB_ENABLEBUTTON, 
-    idButton, MAKELONG(enable, 0));
-  return (result ? true : false);
-}
-
-bool ToolBar::pressButton(int idButton, bool press) {
-  assert(idButton >= 0);
-  int result = SendMessage(getHandle(), TB_PRESSBUTTON, 
-    idButton, MAKELONG(press, 0));
-  return (result ? true : false);
-}
-
-bool ToolBar::getButtonRect(int nIndex, LPRECT buttonRect) {
-  int result = SendMessage(getHandle(), TB_GETITEMRECT, 
-    nIndex, (LPARAM)buttonRect);
-  return (result ? true : false);
-}
-
-bool ToolBar::setButtonSize(int width, int height) {
-  assert(width > 0);
-  assert(height > 0);
-  int result = SendMessage(getHandle(), TB_SETBUTTONSIZE, 
-    0, MAKELONG(width, height));
-  if (result) {
-    SendMessage(getHandle(), TB_AUTOSIZE, 0, 0);
-    return true;
-  }
-  return false; 
-}
-
-void ToolBar::autoSize() {
-  DWORD style = SendMessage(getHandle(), TB_GETSTYLE,  0, 0);
-  if (style & CCS_NORESIZE) {
-    RECT r, btnRect;
-    GetClientRect(parentHwnd, &r);
-    getButtonRect(0, &btnRect);
-    int height = getButtonsHeight() + btnRect.top * 2 + 2;
-    SetWindowPos(getHandle(), HWND_TOP, 0, 0, r.right - r.left, height, 
-      SWP_NOMOVE);
-  } else {
-    SendMessage(getHandle(), TB_AUTOSIZE, 0, 0);
-  }
-}
-
-int ToolBar::getHeight() {
-  RECT r;
-  GetWindowRect(getHandle(), &r);
-  return r.bottom - r.top;
-}
-
-int ToolBar::getTotalWidth() {
-  SIZE size;
-  SendMessage(getHandle(), TB_GETMAXSIZE, 0, (LPARAM)(LPSIZE)&size);
-  return size.cx;
-}
-
-void ToolBar::show() {
-  ShowWindow(getHandle(), SW_SHOW);
-}
-
-void ToolBar::hide() {
-  ShowWindow(getHandle(), SW_HIDE);
-}
-
-bool ToolBar::isVisible() {
-  DWORD style = GetWindowLong(getHandle(), GWL_STYLE);
-  return (bool)(style & WS_VISIBLE);
-}
diff --git a/win/rfb_win32/ToolBar.h b/win/rfb_win32/ToolBar.h
deleted file mode 100644
index f256c99..0000000
--- a/win/rfb_win32/ToolBar.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Copyright (C) 2004 TightVNC Team.  All Rights Reserved.
- *    
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-// -=- ToolBar control class.
-
-#include <windows.h>
-#include <commctrl.h>
-#include <assert.h>
-
-namespace rfb {
-
-  namespace win32 {
-
-    class ToolBar {
-    public:
-      ToolBar();
-      virtual ~ToolBar();
-
-      // create() creates a windows toolbar. dwStyle is a combination of 
-      // the toolbar control and button styles. It returns TRUE if successful,
-      // or FALSE otherwise.
-      bool create(int tbID, HWND parentHwnd, 
-                  DWORD dwStyle = WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT);
-
-      // -=- Button images operations
-
-      // addBitmap() adds one or more images from resources to
-      // the list of button images available for a toolbar.
-      // Returns the index of the first new image if successful,
-      // or -1 otherwise.
-      int addBitmap(int nButtons, UINT bitmapID);
-
-      // addSystemBitmap() adds the system-defined button bitmaps to the list
-      // of the toolbar button specifying by stdBitmapID. Returns the index of 
-      // the first new image if successful, or -1 otherwise.
-      int addSystemBitmap(UINT stdBitmapID);
-
-      // setBitmapSize() sets the size of the bitmapped images to be added
-      // to a toolbar. It returns TRUE if successful, or FALSE otherwise.
-      // You must call it before addBitmap().
-      bool setBitmapSize(int width, int height);
-
-      // -=- Button operations
-
-      // addButton() adds one button.
-      bool addButton(int iBitmap, int idCommand, BYTE state=TBSTATE_ENABLED, 
-                     BYTE style=TBSTYLE_BUTTON,  UINT dwData=0, int iString=0);
-
-      // addNButton() adds nButtons buttons to a toolbar.
-      bool addNButton(int nButtons, LPTBBUTTON tbb);
-
-      // deleteButton() removes a button from the toolbar.
-      bool deleteButton(int nIndex);
-
-      // insertButton() inserts a button in a toolbar control by index.
-      bool insertButton(int nIndex, LPTBBUTTON tbb);
-
-      // getButtonInfo() retrieves extended information about a toolbar's 
-      // button. It returns index of the button if successful, or -1 otherwise.
-      int getButtonInfo(int idButton, TBBUTTONINFO *btnInfo);
-
-      // getButtonsHeight() retrieves the height of the toolbar buttons.
-      int getButtonsHeight();
-
-      // getButtonsWidth() retrieves the width of the toolbar buttons.
-      int getButtonsWidth();
-
-      // setButtonInfo() sets the information for an existing button 
-      // in a toolbar.
-      bool setButtonInfo(int idButton, TBBUTTONINFO* ptbbi);
-
-      // checkButton() checks or unchecks a given button in a toolbar control.
-      bool checkButton(int idButton, bool check);
-
-      // enableButton() enables or disables the specified button 
-      // in the toolbar.
-      bool enableButton(int idButton, bool enable);
-
-      // pressButton() presses or releases the specified button in the toolbar.
-      bool pressButton(int idButton, bool press);
-
-      // getButtonRect() gets the bounding rectangle of a button in a toolbar.
-      bool getButtonRect(int nIndex, LPRECT buttonRect);
-  
-      // setButtonSize() sets the size of the buttons to be added to a toolbar.
-      // Button size must be largen the button bitmap.
-      bool setButtonSize(int width, int height);
-
-      // -=- ToolBar operations
-
-      // autoSize() resizes the toolbar window.
-      void autoSize();
-
-      // getHandle() returns handle to a toolbar window.
-      HWND getHandle() { return hwndToolBar; }
-
-      // getHeight() returns the toolbar window height.
-      int getHeight();
-
-      // getTotalWidth() returns the total size of all buttons and 
-      // separators in the toolbar.
-      int getTotalWidth();
-
-      // show() displays the toolbar window.
-      void show();
-
-      // hide() hides the toolbar window.
-      void hide();
-
-      // isVisible() check the toolbar window on visible.
-      bool isVisible();
-
-    protected:
-      HWND hwndToolBar;
-      HWND parentHwnd;
-      int tbID;
-    };
-
-  }; // win32
-
-}; // rfb
diff --git a/win/vncconfig/vncconfig.cxx b/win/vncconfig/vncconfig.cxx
index 535febb..16bf172 100644
--- a/win/vncconfig/vncconfig.cxx
+++ b/win/vncconfig/vncconfig.cxx
@@ -19,9 +19,6 @@
 #include <windows.h>
 #include <commctrl.h>
 #include <string.h>
-#ifdef WIN32
-#define strcasecmp _stricmp
-#endif
 
 #include "resource.h"
 #include <rfb/Logger_stdio.h>
diff --git a/win/winvnc/JavaViewer.cxx b/win/winvnc/JavaViewer.cxx
index e1cb6e5..c963122 100644
--- a/win/winvnc/JavaViewer.cxx
+++ b/win/winvnc/JavaViewer.cxx
@@ -25,8 +25,6 @@
 
 #include <windows.h>
 
-#define strcasecmp _stricmp
-
 using namespace winvnc;
 using namespace rfb;
 
diff --git a/win/winvnc/winvnc.cxx b/win/winvnc/winvnc.cxx
index 4aa5dcb..17b3a91 100644
--- a/win/winvnc/winvnc.cxx
+++ b/win/winvnc/winvnc.cxx
@@ -19,9 +19,6 @@
 // -=- VNC Server 4.0 for Windows (WinVNC4)
 
 #include <string.h>
-#ifdef WIN32
-#define strcasecmp _stricmp
-#endif
 
 #include <winvnc/VNCServerWin32.h>
 #include <winvnc/VNCServerService.h>