]> source.dussan.org Git - tigervnc.git/commitdiff
Encapsulate event handling in VNCServerST
authorPierre Ossman <ossman@cendio.se>
Fri, 5 Oct 2018 15:30:52 +0000 (17:30 +0200)
committerPierre Ossman <ossman@cendio.se>
Wed, 10 Oct 2018 11:07:59 +0000 (13:07 +0200)
There is some client coordination needed which is better encapsulated
inside VNCServerST. This also helps hiding the desktop from the
individual clients.

common/rfb/VNCSConnectionST.cxx
common/rfb/VNCServerST.cxx
common/rfb/VNCServerST.h

index 7b7913913f27c50415d4c9bba5e62c458122877d..c83254fbe5c0182c626a5c85eb4cc367f19626d6 100644 (file)
@@ -84,12 +84,9 @@ VNCSConnectionST::~VNCSConnectionST()
 
     vlog.debug("Releasing key 0x%x / 0x%x on client disconnect",
                keysym, keycode);
-    server->desktop->keyEvent(keysym, keycode, false);
+    server->keyEvent(keysym, keycode, false);
   }
 
-  if (server->pointerClient == this)
-    server->pointerClient = 0;
-
   // Remove this client from the server
   server->clients.remove(this);
 
@@ -497,36 +494,29 @@ void VNCSConnectionST::setPixelFormat(const PixelFormat& pf)
 void VNCSConnectionST::pointerEvent(const Point& pos, int buttonMask)
 {
   pointerEventTime = lastEventTime = time(0);
-  server->lastUserInputTime = lastEventTime;
   if (!(accessRights & AccessPtrEvents)) return;
   if (!rfb::Server::acceptPointerEvents) return;
-  if (!server->pointerClient || server->pointerClient == this) {
-    pointerEventPos = pos;
-    if (buttonMask)
-      server->pointerClient = this;
-    else
-      server->pointerClient = 0;
-    server->desktop->pointerEvent(pointerEventPos, buttonMask);
-  }
+  pointerEventPos = pos;
+  server->pointerEvent(this, pointerEventPos, buttonMask);
 }
 
 
 class VNCSConnectionSTShiftPresser {
 public:
-  VNCSConnectionSTShiftPresser(SDesktop* desktop_)
-    : desktop(desktop_), pressed(false) {}
+  VNCSConnectionSTShiftPresser(VNCServerST* server_)
+    : server(server_), pressed(false) {}
   ~VNCSConnectionSTShiftPresser() {
     if (pressed) {
       vlog.debug("Releasing fake Shift_L");
-      desktop->keyEvent(XK_Shift_L, 0, false);
+      server->keyEvent(XK_Shift_L, 0, false);
     }
   }
   void press() {
     vlog.debug("Pressing fake Shift_L");
-    desktop->keyEvent(XK_Shift_L, 0, true);
+    server->keyEvent(XK_Shift_L, 0, true);
     pressed = true;
   }
-  SDesktop* desktop;
+  VNCServerST* server;
   bool pressed;
 };
 
@@ -536,7 +526,6 @@ void VNCSConnectionST::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down) {
   rdr::U32 lookup;
 
   lastEventTime = time(0);
-  server->lastUserInputTime = lastEventTime;
   if (!(accessRights & AccessKeyEvents)) return;
   if (!rfb::Server::acceptKeyEvents) return;
 
@@ -545,16 +534,6 @@ void VNCSConnectionST::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down) {
   else
     vlog.debug("Key released: 0x%x / 0x%x", keysym, keycode);
 
-  // Remap the key if required
-  if (server->keyRemapper) {
-    rdr::U32 newkey;
-    newkey = server->keyRemapper->remapKey(keysym);
-    if (newkey != keysym) {
-      vlog.debug("Key remapped to 0x%x", newkey);
-      keysym = newkey;
-    }
-  }
-
   // Avoid lock keys if we don't know the server state
   if ((server->getLEDState() == ledUnknown) &&
       ((keysym == XK_Caps_Lock) ||
@@ -588,8 +567,8 @@ void VNCSConnectionST::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down) {
 
         if (lock == (uppercase == shift)) {
           vlog.debug("Inserting fake CapsLock to get in sync with client");
-          server->desktop->keyEvent(XK_Caps_Lock, 0, true);
-          server->desktop->keyEvent(XK_Caps_Lock, 0, false);
+          server->keyEvent(XK_Caps_Lock, 0, true);
+          server->keyEvent(XK_Caps_Lock, 0, false);
         }
       }
 
@@ -618,15 +597,15 @@ void VNCSConnectionST::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down) {
           //
         } else if (lock == (number == shift)) {
           vlog.debug("Inserting fake NumLock to get in sync with client");
-          server->desktop->keyEvent(XK_Num_Lock, 0, true);
-          server->desktop->keyEvent(XK_Num_Lock, 0, false);
+          server->keyEvent(XK_Num_Lock, 0, true);
+          server->keyEvent(XK_Num_Lock, 0, false);
         }
       }
     }
   }
 
   // Turn ISO_Left_Tab into shifted Tab.
-  VNCSConnectionSTShiftPresser shiftPresser(server->desktop);
+  VNCSConnectionSTShiftPresser shiftPresser(server);
   if (keysym == XK_ISO_Left_Tab) {
     if (!isShiftPressed())
       shiftPresser.press();
@@ -652,14 +631,14 @@ void VNCSConnectionST::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down) {
       return;
   }
 
-  server->desktop->keyEvent(keysym, keycode, down);
+  server->keyEvent(keysym, keycode, down);
 }
 
 void VNCSConnectionST::clientCutText(const char* str, int len)
 {
   if (!(accessRights & AccessCutText)) return;
   if (!rfb::Server::acceptCutText) return;
-  server->desktop->clientCutText(str, len);
+  server->clientCutText(str, len);
 }
 
 void VNCSConnectionST::framebufferUpdateRequest(const Rect& r,bool incremental)
index 7e36876ce2af03f6e2f2565b89264994cacc1794..6affe9288e9c140fb364057ad4eac1bc2cc61b1d 100644 (file)
@@ -147,6 +147,10 @@ void VNCServerST::removeSocket(network::Socket* sock) {
   std::list<VNCSConnectionST*>::iterator ci;
   for (ci = clients.begin(); ci != clients.end(); ci++) {
     if ((*ci)->getSock() == sock) {
+      // - Release the cursor if this client owns it
+      if (pointerClient == *ci)
+        pointerClient = NULL;
+
       // - Delete the per-Socket resources
       delete *ci;
 
@@ -467,6 +471,48 @@ void VNCServerST::setLEDState(unsigned int state)
   }
 }
 
+// Event handlers
+
+void VNCServerST::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down)
+{
+  lastUserInputTime = time(0);
+
+  // Remap the key if required
+  if (keyRemapper) {
+    rdr::U32 newkey;
+    newkey = keyRemapper->remapKey(keysym);
+    if (newkey != keysym) {
+      slog.debug("Key remapped to 0x%x", newkey);
+      keysym = newkey;
+    }
+  }
+
+  desktop->keyEvent(keysym, keycode, down);
+}
+
+void VNCServerST::pointerEvent(VNCSConnectionST* client,
+                               const Point& pos, int buttonMask)
+{
+  lastUserInputTime = time(0);
+
+  // Let one client own the cursor whilst buttons are pressed in order
+  // to provide a bit more sane user experience
+  if ((pointerClient != NULL) && (pointerClient != client))
+    return;
+
+  if (buttonMask)
+    pointerClient = client;
+  else
+    pointerClient = NULL;
+
+  desktop->pointerEvent(pos, buttonMask);
+}
+
+void VNCServerST::clientCutText(const char* str, int len)
+{
+  desktop->clientCutText(str, len);
+}
+
 // Other public methods
 
 void VNCServerST::approveConnection(network::Socket* sock, bool accept,
index ef83619c46d0a6008bf3da58ab1a60b011cded42..eff52d073efc2e0e7538240dabc73b31c304a89e 100644 (file)
@@ -120,6 +120,11 @@ namespace rfb {
     const char* getName() const { return name.buf; }
     unsigned getLEDState() const { return ledState; }
 
+    // Event handlers
+    void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
+    void pointerEvent(VNCSConnectionST* client, const Point& pos, int buttonMask);
+    void clientCutText(const char* str, int len);
+
     // closeClients() closes all RFB sessions, except the specified one (if
     // any), and logs the specified reason for closure.
     void closeClients(const char* reason, network::Socket* sock);