]> source.dussan.org Git - tigervnc.git/commitdiff
Server-side support for the XCursor encoding
authorPeter Åstrand <astrand@cendio.se>
Wed, 16 Feb 2005 13:00:38 +0000 (13:00 +0000)
committerPeter Åstrand <astrand@cendio.se>
Wed, 16 Feb 2005 13:00:38 +0000 (13:00 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@188 3789f03b-4d11-0410-bbf8-ca57d06f2519

rfb/ConnParams.cxx
rfb/ConnParams.h
rfb/SMsgWriter.h
rfb/SMsgWriterV3.cxx
rfb/SMsgWriterV3.h
rfb/VNCSConnectionST.cxx
rfb/encodings.h

index 7dcfdccf98d5575e2f04bcba7d3592c76bd08d8c..4a8e5344bbe484f6cf095d1b28a8ce7a69dc459a 100644 (file)
@@ -27,7 +27,7 @@ using namespace rfb;
 
 ConnParams::ConnParams()
   : majorVersion(0), minorVersion(0), width(0), height(0), useCopyRect(false),
-    supportsLocalCursor(false), supportsDesktopResize(false), supportsLastRect(false), 
+    supportsLocalCursor(false), supportsLocalXCursor(false), supportsDesktopResize(false), supportsLastRect(false), 
     customCompressLevel(false), compressLevel(6), noJpeg(false), qualityLevel(-1), 
     name_(0), nEncodings_(0), encodings_(0), 
     currentEncoding_(encodingRaw), verStrPos(0)
@@ -88,6 +88,7 @@ void ConnParams::setEncodings(int nEncodings, const rdr::U32* encodings)
   nEncodings_ = nEncodings;
   useCopyRect = false;
   supportsLocalCursor = false;
+  supportsLocalXCursor = false;
   supportsLastRect = false;
   customCompressLevel = false;
   compressLevel = -1;
@@ -102,6 +103,8 @@ void ConnParams::setEncodings(int nEncodings, const rdr::U32* encodings)
       useCopyRect = true;
     else if (encodings[i] == pseudoEncodingCursor)
       supportsLocalCursor = true;
+    else if (encodings[i] == pseudoEncodingXCursor)
+      supportsLocalXCursor = true;
     else if (encodings[i] == pseudoEncodingDesktopSize)
       supportsDesktopResize = true;
     else if (encodings[i] == pseudoEncodingLastRect)
index 70578eacb7e321d9bf447f861175cd354e1e641e..09e79c25222e5098649343d1df0afb1c5d566eda 100644 (file)
@@ -70,6 +70,7 @@ namespace rfb {
     bool useCopyRect;
 
     bool supportsLocalCursor;
+    bool supportsLocalXCursor;
     bool supportsDesktopResize;
     bool supportsLastRect;
 
index 72bc10a47563211846bb44b3215dd540d4f3091d..6dc272cf4ff3c34a15cf0dc8f7fa14c6143b8d2a 100644 (file)
@@ -82,6 +82,8 @@ namespace rfb {
     virtual void cursorChange(WriteSetCursorCallback* cb)=0;
     virtual void writeSetCursor(int width, int height, int hotspotX,
                                 int hotspotY, void* data, void* mask)=0;
+    virtual void writeSetXCursor(int width, int height, int hotspotX,
+                                int hotspotY, void* data, void* mask)=0;
 
     // needFakeUpdate() returns true when an immediate update is needed in
     // order to flush out setDesktopSize or setCursor pseudo-rectangles to the
index 20a72801d3d8678bba69fbe66a9b200cff3c4d46..c34f216da3f6a2b07b72a6844e017ee4d3008b1d 100644 (file)
@@ -84,6 +84,32 @@ void SMsgWriterV3::writeSetCursor(int width, int height, int hotspotX,
   os->writeBytes(mask, (width+7)/8 * height);
 }
 
+void SMsgWriterV3::writeSetXCursor(int width, int height, int hotspotX,
+                                  int hotspotY, void* data, void* mask)
+{
+  if (!wsccb) return;
+  if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
+    throw Exception("SMsgWriterV3::writeSetXCursor: nRects out of sync");
+  os->writeS16(hotspotX);
+  os->writeS16(hotspotY);
+  os->writeU16(width);
+  os->writeU16(height);
+  os->writeU32(pseudoEncodingXCursor);
+  // FIXME: We only support black and white cursors, currently. We
+  // could pass the correct color by using the pix0/pix1 values
+  // returned from getBitmap, in writeSetCursorCallback. However, we
+  // would then need to undo the conversion from rgb to Pixel that is
+  // done by FakeAllocColor. 
+  os->writeU8(0);
+  os->writeU8(0);
+  os->writeU8(0);
+  os->writeU8(255);
+  os->writeU8(255);
+  os->writeU8(255);
+  os->writeBytes(data, (width+7)/8 * height);
+  os->writeBytes(mask, (width+7)/8 * height);
+}
+
 void SMsgWriterV3::writeFramebufferUpdateStart(int nRects)
 {
   startMsg(msgTypeFramebufferUpdate);
index 0bad8f178ef0da125286d4322127eebf95e1d68f..fbd07d6836bad56caa071e650928f7fa52c86a90 100644 (file)
@@ -35,6 +35,8 @@ namespace rfb {
     virtual void cursorChange(WriteSetCursorCallback* cb);
     virtual void writeSetCursor(int width, int height, int hotspotX,
                                 int hotspotY, void* data, void* mask);
+    virtual void writeSetXCursor(int width, int height, int hotspotX,
+                                int hotspotY, void* data, void* mask);
     virtual void writeFramebufferUpdateStart(int nRects);
     virtual void writeFramebufferUpdateStart();
     virtual void writeFramebufferUpdateEnd();
index 426ecd4ed76174d0d6fe1545ca67861b5d5ae694..a20ec01d60aac5d4fb01309ec3e1205ea54ce6ae 100644 (file)
@@ -277,7 +277,7 @@ void VNCSConnectionST::renderedCursorChange()
 bool VNCSConnectionST::needRenderedCursor()
 {
   return (state() == RFBSTATE_NORMAL
-          && (!cp.supportsLocalCursor
+          && (!cp.supportsLocalCursor && !cp.supportsLocalXCursor
               || (!server->cursorPos.equals(pointerEventPos) &&
                   (time(0) - pointerEventTime) > 0)));
 }
@@ -478,7 +478,7 @@ void VNCSConnectionST::setInitialColourMap()
 
 void VNCSConnectionST::supportsLocalCursor()
 {
-  if (cp.supportsLocalCursor) {
+  if (cp.supportsLocalCursor || cp.supportsLocalXCursor) {
     removeRenderedCursor = true;
     drawRenderedCursor = false;
     setCursor();
@@ -487,15 +487,37 @@ void VNCSConnectionST::supportsLocalCursor()
 
 void VNCSConnectionST::writeSetCursorCallback()
 {
+  if (cp.supportsLocalXCursor) {
+    Pixel pix0, pix1;
+    rdr::U8Array bitmap(server->cursor.getBitmap(&pix0, &pix1));
+    if (bitmap.buf) {
+      // The client supports XCursor and the cursor only has two
+      // colors. Use the XCursor encoding.
+      writer()->writeSetXCursor(server->cursor.width(),
+                               server->cursor.height(),
+                               server->cursor.hotspot.x,
+                               server->cursor.hotspot.y,
+                               bitmap.buf, server->cursor.mask.buf);
+      return;
+    } else {
+      // More than two colors
+      if (!cp.supportsLocalCursor) {
+       // FIXME: We could reduce to two colors. 
+       vlog.info("Unable to send multicolor cursor: RichCursor not supported by client");
+       return;
+      }
+    }
+  }
+
+  // Use RichCursor
   rdr::U8* transData = writer()->getImageBuf(server->cursor.area());
   image_getter.translatePixels(server->cursor.data, transData,
-                               server->cursor.area());
-
+                              server->cursor.area());
   writer()->writeSetCursor(server->cursor.width(),
-                           server->cursor.height(),
-                           server->cursor.hotspot.x,
-                           server->cursor.hotspot.y,
-                           transData, server->cursor.mask.buf);
+                          server->cursor.height(),
+                          server->cursor.hotspot.x,
+                          server->cursor.hotspot.y,
+                          transData, server->cursor.mask.buf);
 }
 
 
index a40af82210b4d2e54de5464affff652b60708180..550440d54cafd70dc69517dccbc3a9b430bc616f 100644 (file)
@@ -30,6 +30,7 @@ namespace rfb {
 
   const unsigned int encodingMax = 255;
 
+  const unsigned int pseudoEncodingXCursor = 0xffffff10;
   const unsigned int pseudoEncodingCursor = 0xffffff11;
   const unsigned int pseudoEncodingDesktopSize = 0xffffff21;