]> source.dussan.org Git - tigervnc.git/commitdiff
Support the VMware Cursor Position extension on vncviewer 1212/head
authorlhchavez <lhchavez@lhchavez.com>
Mon, 8 Feb 2021 15:09:10 +0000 (07:09 -0800)
committerlhchavez <lhchavez@lhchavez.com>
Thu, 11 Mar 2021 13:15:46 +0000 (05:15 -0800)
This change makes it possible for re-synchronizing the remote cursor on
the vncviewer when in fullscreen mode. This is done by locally moving
the cursor position to what the server thinks it should be.

Now SDL games should work!

13 files changed:
common/rfb/CConnection.cxx
common/rfb/CConnection.h
common/rfb/CMsgHandler.h
common/rfb/CMsgReader.cxx
common/rfb/ClientParams.cxx
common/rfb/ClientParams.h
common/rfb/encodings.h
tests/perf/decperf.cxx
tests/perf/encperf.cxx
vncviewer/CConn.cxx
vncviewer/CConn.h
vncviewer/DesktopWindow.cxx
vncviewer/DesktopWindow.h

index 9a9593e289c766c9972ef6b081bdcb56471c6af0..1c9490095cce1e2c7f5fe5c11d5d527e34254d47 100644 (file)
@@ -43,8 +43,8 @@ static LogWriter vlog("CConnection");
 
 CConnection::CConnection()
   : csecurity(0),
-    supportsLocalCursor(false), supportsDesktopResize(false),
-    supportsLEDState(false),
+    supportsLocalCursor(false), supportsCursorPosition(false),
+    supportsDesktopResize(false), supportsLEDState(false),
     is(0), os(0), reader_(0), writer_(0),
     shared(false),
     state_(RFBSTATE_UNINITIALISED),
@@ -805,6 +805,9 @@ void CConnection::updateEncodings()
     encodings.push_back(pseudoEncodingCursor);
     encodings.push_back(pseudoEncodingXCursor);
   }
+  if (supportsCursorPosition) {
+    encodings.push_back(pseudoEncodingVMwareCursorPosition);
+  }
   if (supportsDesktopResize) {
     encodings.push_back(pseudoEncodingDesktopSize);
     encodings.push_back(pseudoEncodingExtendedDesktopSize);
index deab50ae523e2bec25777b9082c35daf8ba3bf69..d5d07ca0b0e92b9be5c9c0193671c691dbe1f139 100644 (file)
@@ -239,6 +239,7 @@ namespace rfb {
     // Optional capabilities that a subclass is expected to set to true
     // if supported
     bool supportsLocalCursor;
+    bool supportsCursorPosition;
     bool supportsDesktopResize;
     bool supportsLEDState;
 
index 5b14806ad1a869a7dafbec4072b7b15e2720c030..43d8df246a4f74b5ce20e4c1a8e384a74a68b39d 100644 (file)
@@ -52,6 +52,7 @@ namespace rfb {
                                         const ScreenSet& layout);
     virtual void setCursor(int width, int height, const Point& hotspot,
                            const rdr::U8* data) = 0;
+    virtual void setCursorPos(const Point& pos) = 0;
     virtual void setPixelFormat(const PixelFormat& pf);
     virtual void setName(const char* name);
     virtual void fence(rdr::U32 flags, unsigned len, const char data[]);
index f69e21deee7314d2e20e1188abac17080d5d6213..2c823d5624fa0ba1ad6bcac452e9d639c13bb658 100644 (file)
@@ -165,6 +165,10 @@ bool CMsgReader::readMsg()
     case pseudoEncodingVMwareCursor:
       ret = readSetVMwareCursor(dataRect.width(), dataRect.height(), dataRect.tl);
       break;
+    case pseudoEncodingVMwareCursorPosition:
+      handler->setCursorPos(dataRect.tl);
+      ret = true;
+      break;
     case pseudoEncodingDesktopName:
       ret = readSetDesktopName(dataRect.tl.x, dataRect.tl.y,
                                dataRect.width(), dataRect.height());
index 6f075a2461673392a2e364160fc7913fc20d3be3..c0cc36416bd507472e10d92c2b5099edc9e60397 100644 (file)
@@ -30,7 +30,7 @@ ClientParams::ClientParams()
     compressLevel(2), qualityLevel(-1), fineQualityLevel(-1),
     subsampling(subsampleUndefined),
     width_(0), height_(0), name_(0),
-    ledState_(ledUnknown)
+    cursorPos_(0, 0), ledState_(ledUnknown)
 {
   setName("");
 
@@ -85,6 +85,11 @@ void ClientParams::setCursor(const Cursor& other)
   cursor_ = new Cursor(other);
 }
 
+void ClientParams::setCursorPos(const Point& pos)
+{
+  cursorPos_ = pos;
+}
+
 bool ClientParams::supportsEncoding(rdr::S32 encoding) const
 {
   return encodings_.count(encoding) != 0;
@@ -182,6 +187,13 @@ bool ClientParams::supportsLocalCursor() const
   return false;
 }
 
+bool ClientParams::supportsCursorPosition() const
+{
+  if (supportsEncoding(pseudoEncodingVMwareCursorPosition))
+    return true;
+  return false;
+}
+
 bool ClientParams::supportsDesktopSize() const
 {
   if (supportsEncoding(pseudoEncodingExtendedDesktopSize))
index 3894ef2dd58e70a36f88f4806d5595e0634efe15..202cef4e2197042f1cfe239ad6f783686d65616e 100644 (file)
@@ -77,6 +77,9 @@ namespace rfb {
     const Cursor& cursor() const { return *cursor_; }
     void setCursor(const Cursor& cursor);
 
+    const Point& cursorPos() const { return cursorPos_; }
+    void setCursorPos(const Point& pos);
+
     bool supportsEncoding(rdr::S32 encoding) const;
 
     void setEncodings(int nEncodings, const rdr::S32* encodings);
@@ -91,6 +94,7 @@ namespace rfb {
     // Wrappers to check for functionality rather than specific
     // encodings
     bool supportsLocalCursor() const;
+    bool supportsCursorPosition() const;
     bool supportsDesktopSize() const;
     bool supportsLEDState() const;
     bool supportsFence() const;
@@ -110,6 +114,7 @@ namespace rfb {
     PixelFormat pf_;
     char* name_;
     Cursor* cursor_;
+    Point cursorPos_;
     std::set<rdr::S32> encodings_;
     unsigned int ledState_;
     rdr::U32 clipFlags;
index cf0c8572fe7ae1e2e417e85cc07588f5a9830d64..f7ad7890e7db8c8b757335aefab4f24c4d6d4de5 100644 (file)
@@ -61,6 +61,7 @@ namespace rfb {
 
   // VMware-specific
   const int pseudoEncodingVMwareCursor = 0x574d5664;
+  const int pseudoEncodingVMwareCursorPosition = 0x574d5666;
   const int pseudoEncodingVMwareLEDState = 0x574d5668;
 
   // UltraVNC-specific
index a6c65a221dfa7c6a2eda22901f3b304c839e5f92..23f3fe24a3378a81c648081d4b25a665c078256d 100644 (file)
@@ -66,6 +66,7 @@ public:
   virtual void initDone();
   virtual void setPixelFormat(const rfb::PixelFormat& pf);
   virtual void setCursor(int, int, const rfb::Point&, const rdr::U8*);
+  virtual void setCursorPos(const rfb::Point&);
   virtual void framebufferUpdateStart();
   virtual void framebufferUpdateEnd();
   virtual void setColourMapEntries(int, int, rdr::U16*);
@@ -144,6 +145,10 @@ void CConn::setCursor(int, int, const rfb::Point&, const rdr::U8*)
 {
 }
 
+void CConn::setCursorPos(const rfb::Point&)
+{
+}
+
 void CConn::framebufferUpdateStart()
 {
   CConnection::framebufferUpdateStart();
index 9f30cab7ab305cea0a47fe688ed2bd1f5ebebe5e..69121ffa4db90eddb1c73e7ff36d9799702ba2b1 100644 (file)
@@ -95,6 +95,7 @@ public:
   virtual void initDone() {};
   virtual void resizeFramebuffer();
   virtual void setCursor(int, int, const rfb::Point&, const rdr::U8*);
+  virtual void setCursorPos(const rfb::Point&);
   virtual void framebufferUpdateStart();
   virtual void framebufferUpdateEnd();
   virtual bool dataRect(const rfb::Rect&, int);
@@ -216,6 +217,10 @@ void CConn::setCursor(int, int, const rfb::Point&, const rdr::U8*)
 {
 }
 
+void CConn::setCursorPos(const rfb::Point&)
+{
+}
+
 void CConn::framebufferUpdateStart()
 {
   CConnection::framebufferUpdateStart();
index 4894ddf78e6e63c5ceace9cfd369d7b341888f9e..e1f5f70a277b5b981e0d0e2a2b03d43b9b1f95f7 100644 (file)
@@ -84,6 +84,7 @@ CConn::CConn(const char* vncServerName, network::Socket* socket=NULL)
   sock = socket;
 
   supportsLocalCursor = true;
+  supportsCursorPosition = true;
   supportsDesktopResize = true;
   supportsLEDState = false;
 
@@ -430,6 +431,11 @@ void CConn::setCursor(int width, int height, const Point& hotspot,
   desktop->setCursor(width, height, hotspot, data);
 }
 
+void CConn::setCursorPos(const Point& pos)
+{
+  desktop->setCursorPos(pos);
+}
+
 void CConn::fence(rdr::U32 flags, unsigned len, const char data[])
 {
   CMsgHandler::fence(flags, len, data);
index ad3fb797bb49f95a1b3766203145220d30c9a702..e662ec8726b609595b0f895af7c6c32d6bc54763 100644 (file)
@@ -63,6 +63,7 @@ public:
 
   void setCursor(int width, int height, const rfb::Point& hotspot,
                  const rdr::U8* data);
+  void setCursorPos(const rfb::Point& pos);
 
   void fence(rdr::U32 flags, unsigned len, const char data[]);
 
index 6dc85f4a9ec407cd441b999146534d1b91c095a2..5401b191fa6840c1a6bb86cdfb9735bfc5ce6220 100644 (file)
@@ -51,6 +51,7 @@
 
 #ifdef __APPLE__
 #include "cocoa.h"
+#include <Carbon/Carbon.h>
 #endif
 
 #define EDGE_SCROLL_SIZE 32
@@ -186,6 +187,14 @@ DesktopWindow::DesktopWindow(int w, int h, const char *name,
 
   // Show hint about menu key
   Fl::add_timeout(0.5, menuOverlay, this);
+
+  // By default we get a slight delay when we warp the pointer, something
+  // we don't want or we'll get jerky movement
+#ifdef __APPLE__
+  CGEventSourceRef event = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
+  CGEventSourceSetLocalEventsSuppressionInterval(event, 0);
+  CFRelease(event);
+#endif
 }
 
 
@@ -322,6 +331,29 @@ void DesktopWindow::setCursor(int width, int height,
 }
 
 
+void DesktopWindow::setCursorPos(const rfb::Point& pos)
+{
+  if (!mouseGrabbed) {
+    // Do nothing if we do not have the mouse captured.
+    return;
+  }
+#if defined(WIN32)
+  SetCursorPos(pos.x + x_root() + viewport->x(),
+               pos.y + y_root() + viewport->y());
+#elif defined(__APPLE__)
+  CGPoint new_pos;
+  new_pos.x = pos.x + x_root() + viewport->x();
+  new_pos.y = pos.y + y_root() + viewport->y();
+  CGWarpMouseCursorPosition(new_pos);
+#else // Assume this is Xlib
+  Window rootwindow = DefaultRootWindow(fl_display);
+  XWarpPointer(fl_display, rootwindow, rootwindow, 0, 0, 0, 0,
+               pos.x + x_root() + viewport->x(),
+               pos.y + y_root() + viewport->y());
+#endif
+}
+
+
 void DesktopWindow::show()
 {
   Fl_Window::show();
index ef3dbb08ec82b3565a5bf11293de532c971b420d..67be6c6a88b25921a8485877f10aa20657fccaba 100644 (file)
@@ -66,6 +66,9 @@ public:
   void setCursor(int width, int height, const rfb::Point& hotspot,
                  const rdr::U8* data);
 
+  // Server-provided cursor position
+  void setCursorPos(const rfb::Point& pos);
+
   // Change client LED state
   void setLEDState(unsigned int state);