Client support for X Cursor
diff --git a/common/rfb/CMsgReader.cxx b/common/rfb/CMsgReader.cxx
index bbb9909..152c2c8 100644
--- a/common/rfb/CMsgReader.cxx
+++ b/common/rfb/CMsgReader.cxx
@@ -88,6 +88,9 @@
     case pseudoEncodingLastRect:
       nUpdateRectsLeft = 1;     // this rectangle is the last one
       break;
+    case pseudoEncodingXCursor:
+      readSetXCursor(w, h, Point(x,y));
+      break;
     case pseudoEncodingCursor:
       readSetCursor(w, h, Point(x,y));
       break;
@@ -191,6 +194,61 @@
   handler->dataRect(r, encoding);
 }
 
+void CMsgReader::readSetXCursor(int width, int height, const Point& hotspot)
+{
+  rdr::U8 pr, pg, pb;
+  rdr::U8 sr, sg, sb;
+  int data_len = ((width+7)/8) * height;
+  int mask_len = ((width+7)/8) * height;
+  rdr::U8Array data(data_len);
+  rdr::U8Array mask(mask_len);
+
+  int x, y;
+  rdr::U8 buf[width*height*4];
+  rdr::U8* out;
+
+  if (width * height) {
+    pr = is->readU8();
+    pg = is->readU8();
+    pb = is->readU8();
+
+    sr = is->readU8();
+    sg = is->readU8();
+    sb = is->readU8();
+
+    is->readBytes(data.buf, data_len);
+    is->readBytes(mask.buf, mask_len);
+  }
+
+  int maskBytesPerRow = (width+7)/8;
+  out = buf;
+  for (y = 0;y < height;y++) {
+    for (x = 0;x < width;x++) {
+      int byte = y * maskBytesPerRow + x / 8;
+      int bit = 7 - x % 8;
+
+      if (data.buf[byte] & (1 << bit)) {
+        out[0] = pr;
+        out[1] = pg;
+        out[2] = pb;
+      } else {
+        out[0] = sr;
+        out[1] = sg;
+        out[2] = sb;
+      }
+
+      if (mask.buf[byte] & (1 << bit))
+        out[3] = 255;
+      else
+        out[3] = 0;
+
+      out += 4;
+    }
+  }
+
+  handler->setCursor(width, height, hotspot, buf);
+}
+
 void CMsgReader::readSetCursor(int width, int height, const Point& hotspot)
 {
   int data_len = width * height * (handler->cp.pf().bpp/8);
diff --git a/common/rfb/CMsgReader.h b/common/rfb/CMsgReader.h
index 42c6496..296d99f 100644
--- a/common/rfb/CMsgReader.h
+++ b/common/rfb/CMsgReader.h
@@ -60,6 +60,7 @@
 
     void readRect(const Rect& r, int encoding);
 
+    void readSetXCursor(int width, int height, const Point& hotspot);
     void readSetCursor(int width, int height, const Point& hotspot);
     void readSetDesktopName(int x, int y, int w, int h);
     void readExtendedDesktopSize(int x, int y, int w, int h);
diff --git a/common/rfb/CMsgWriter.cxx b/common/rfb/CMsgWriter.cxx
index 6536eaf..2ad3a79 100644
--- a/common/rfb/CMsgWriter.cxx
+++ b/common/rfb/CMsgWriter.cxx
@@ -71,8 +71,10 @@
   int nEncodings = 0;
   rdr::U32 encodings[encodingMax+3];
 
-  if (cp->supportsLocalCursor)
+  if (cp->supportsLocalCursor) {
+    encodings[nEncodings++] = pseudoEncodingXCursor;
     encodings[nEncodings++] = pseudoEncodingCursor;
+  }
   if (cp->supportsDesktopResize)
     encodings[nEncodings++] = pseudoEncodingDesktopSize;
   if (cp->supportsExtendedDesktopSize)