The code which realizes functionality " Control of selected clients "
control group in Control Panel has been added.


git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@436 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/rfb/ListConnInfo.h b/rfb/ListConnInfo.h
index 029f2a4..e8ca60a 100644
--- a/rfb/ListConnInfo.h
+++ b/rfb/ListConnInfo.h
@@ -79,6 +79,8 @@
 
     int iGetStatus() { return *si;}
 
+    void iSetStatus( int status) { *si = status;}
+
     void Copy(ListConnInfo* InputList) {
       Clear();
       if (InputList->Empty()) return;
diff --git a/rfb/VNCSConnectionST.cxx b/rfb/VNCSConnectionST.cxx
index dce1a56..41e4eb3 100644
--- a/rfb/VNCSConnectionST.cxx
+++ b/rfb/VNCSConnectionST.cxx
@@ -34,7 +34,8 @@
   : sock(s), reverseConnection(reverse), server(server_),
     image_getter(server->useEconomicTranslate),
     drawRenderedCursor(false), removeRenderedCursor(false),
-    pointerEventTime(0), accessRights(AccessDefault)
+    pointerEventTime(0), accessRights(AccessDefault),
+    startTime(time(0))
 {
   setStreams(&sock->inStream(), &sock->outStream());
   peerEndpoint.buf = sock->getPeerEndpoint();
@@ -56,7 +57,6 @@
   }
 
   server->clients.push_front(this);
-  startTime = time(0);
 }
 
 
@@ -341,6 +341,7 @@
 
   // - Mark the entire display as "dirty"
   updates.add_changed(server->pb->getRect());
+  startTime = time(0);
 }
 
 void VNCSConnectionST::queryConnection(const char* userName)
@@ -674,3 +675,28 @@
   result[24] = '\0';
   return result; 
 }
+
+void VNCSConnectionST::setStatus(int status)
+{
+  switch (status) {
+  case 0:
+    accessRights = accessRights | AccessPtrEvents | AccessKeyEvents | AccessView;
+    break;
+  case 1:
+    accessRights = accessRights & !(AccessPtrEvents | AccessKeyEvents) | AccessView;
+    break;
+  case 2:
+    accessRights = accessRights & !(AccessPtrEvents | AccessKeyEvents | AccessView);
+    break;
+  }
+}
+int VNCSConnectionST::getStatus()
+{
+  if ((accessRights & (AccessPtrEvents | AccessKeyEvents | AccessView)) == 0x0007)
+    return 0;
+  if ((accessRights & (AccessPtrEvents | AccessKeyEvents | AccessView)) == 0x0001)
+    return 1;
+  if ((accessRights & (AccessPtrEvents | AccessKeyEvents | AccessView)) == 0x0000)
+    return 2;
+  return 4;
+}
\ No newline at end of file
diff --git a/rfb/VNCSConnectionST.h b/rfb/VNCSConnectionST.h
index 784ac29..b81c3a5 100644
--- a/rfb/VNCSConnectionST.h
+++ b/rfb/VNCSConnectionST.h
@@ -105,6 +105,9 @@
 
     char* getStartTime();
 
+    void setStatus(int status);
+    int getStatus();
+
   private:
     // SConnection callbacks
 
diff --git a/rfb/VNCServerST.cxx b/rfb/VNCServerST.cxx
index c25543d..9e6c480 100644
--- a/rfb/VNCServerST.cxx
+++ b/rfb/VNCServerST.cxx
@@ -513,9 +513,28 @@
   listConn->Clear();
   if (clients.empty())
     return;
-  int s=0;
   std::list<VNCSConnectionST*>::iterator i;
   for (i = clients.begin(); i != clients.end(); i++)
     listConn->addInfo((DWORD)(*i), (*i)->getSock()->getPeerAddress(),
-                      (*i)->getStartTime(), s++);
+                      (*i)->getStartTime(), (*i)->getStatus());
+}
+
+void VNCServerST::setConnStatus(ListConnInfo* listConn)
+{
+  if (listConn->Empty() || clients.empty()) return;
+  for (listConn->iBegin(); !listConn->iEnd(); listConn->iNext()) {
+    VNCSConnectionST* conn = (VNCSConnectionST*)listConn->iGetConn();
+    std::list<VNCSConnectionST*>::iterator i;
+    for (i = clients.begin(); i != clients.end(); i++) {
+      if ((*i) == conn) {
+        int status = listConn->iGetStatus();
+        if (status == 3) {
+          (*i)->close(0);
+        } else {
+          (*i)->setStatus(status);
+        }
+        break;
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/rfb/VNCServerST.h b/rfb/VNCServerST.h
index 596eaab..1cd2089 100644
--- a/rfb/VNCServerST.h
+++ b/rfb/VNCServerST.h
@@ -190,6 +190,7 @@
     void setEconomicTranslate(bool et) { useEconomicTranslate = et; }
 
     void getConnInfo(ListConnInfo * listConn);
+    void setConnStatus(ListConnInfo* listConn);
 
   protected:
 
diff --git a/winvnc/ControlPanel.cxx b/winvnc/ControlPanel.cxx
index fb379d6..1f69306 100644
--- a/winvnc/ControlPanel.cxx
+++ b/winvnc/ControlPanel.cxx
@@ -37,18 +37,9 @@
   case IDC_ADD_CLIENT:
     SendMessage(m_hSTIcon, WM_COMMAND, ID_CONNECT, 0);
     return false;
-  case IDC_KILL_SEL_CLIENT:
-    {
-      
-      return false;
-    }
   case IDC_KILL_ALL:
     {
-      COPYDATASTRUCT copyData;
-      copyData.dwData = 2;
-      copyData.lpData = 0;
-      copyData.cbData = 0;
-      SendMessage(m_hSTIcon, WM_COPYDATA, 0, (LPARAM)&copyData);
+      SendCommand(2, -1);
       return false;
     }
   case IDC_DISABLE_CLIENTS:
@@ -56,6 +47,27 @@
       
       return false;
     }
+  case IDC_KILL_SEL_CLIENT:
+    {     
+      SendCommand(3, 3);
+      return false;
+    }
+  case IDC_VIEW_ONLY:
+    {     
+      SendCommand(3, 1);
+      return false;
+    }
+  case IDC_FULL_CONTROL:
+    {     
+      SendCommand(3, 0);
+      return false;
+    }
+  case IDC_STOP_UPDATE:
+    {     
+      stop_updating = true;
+      EndDialog(handle, 0);
+      return false;
+    }
   }
   return false;
   
@@ -92,6 +104,13 @@
     handle = hwnd;
     initDialog();
     return TRUE;
+  case WM_DESTROY:
+    if (stop_updating) {
+      stop_updating = false;
+      SendCommand(3, 2);
+    }
+    initDialog();
+    return TRUE;
   case WM_COMMAND:
     switch (LOWORD(wParam)) {
     case IDCANCEL:
@@ -117,6 +136,23 @@
   }
 }
 
+void ControlPanel::SendCommand(DWORD command, int data)
+{
+  COPYDATASTRUCT copyData;
+  copyData.dwData = command;
+  copyData.lpData = 0;
+  if (data != -1) {
+    getSelConnInfo();
+    ListConnStatus.Copy(&ListSelConn);
+    for (ListConnStatus.iBegin(); !ListConnStatus.iEnd(); ListConnStatus.iNext())
+      ListConnStatus.iSetStatus(data);
+    copyData.cbData = (DWORD)&ListConnStatus;
+  } else {
+    copyData.cbData = 0;
+  }
+  SendMessage(m_hSTIcon, WM_COPYDATA, 0, (LPARAM)&copyData);
+}
+
 ControlPanel::~ControlPanel()
 {
   
diff --git a/winvnc/ControlPanel.h b/winvnc/ControlPanel.h
index f291b9e..73b859f 100644
--- a/winvnc/ControlPanel.h
+++ b/winvnc/ControlPanel.h
@@ -22,19 +22,23 @@
   public:
     ControlPanel(HWND hSTIcon) : Dialog(GetModuleHandle(0)), ListViewControl(){
       m_hSTIcon = hSTIcon;
+      stop_updating = false;
     };
     virtual bool showDialog();
     virtual void initDialog();
     virtual bool onCommand(int cmd);
     void UpdateListView(rfb::ListConnInfo* LCInfo);
     HWND GetHandle() {return handle;};
+    void SendCommand(DWORD command, int data);
     ~ControlPanel();
+    rfb::ListConnInfo ListConnStatus;
   protected: 
     virtual BOOL dialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
     void getSelConnInfo();
     HWND m_hSTIcon;
     rfb::ListConnInfo ListConn;
     rfb::ListConnInfo ListSelConn;
+    bool stop_updating;
   };
 };
 
diff --git a/winvnc/STrayIcon.cxx b/winvnc/STrayIcon.cxx
index 533c6a7..c5cc3b2 100644
--- a/winvnc/STrayIcon.cxx
+++ b/winvnc/STrayIcon.cxx
@@ -168,6 +168,9 @@
         case 2:
           thread.server.disconnectClients("IPC disconnect");
           break;
+        case 3:
+          thread.server.setClientsStatus((rfb::ListConnInfo *)command->cbData);
+          break;
         };
       };
       break;
diff --git a/winvnc/VNCServerWin32.cxx b/winvnc/VNCServerWin32.cxx
index 7e56270..30e9a72 100644
--- a/winvnc/VNCServerWin32.cxx
+++ b/winvnc/VNCServerWin32.cxx
@@ -274,6 +274,10 @@
   return queueCommand(GetClientsInfo, LCInfo, 0);
 }
 
+bool VNCServerWin32::setClientsStatus(rfb::ListConnInfo* LCInfo) {
+  return queueCommand(SetClientsStatus, LCInfo, 0);
+}
+
 VNCServerST::queryResult VNCServerWin32::queryConnection(network::Socket* sock,
                                             const char* userName,
                                             char** reason)
@@ -336,6 +340,9 @@
   case GetClientsInfo:
     vncServer.getConnInfo((ListConnInfo*)commandData); 
     break;
+  case SetClientsStatus:
+    vncServer.setConnStatus((ListConnInfo*)commandData); 
+    break;
 
   default:
     vlog.error("unknown command %d queued", command);
diff --git a/winvnc/VNCServerWin32.h b/winvnc/VNCServerWin32.h
index f6c6723..0af5fd5 100644
--- a/winvnc/VNCServerWin32.h
+++ b/winvnc/VNCServerWin32.h
@@ -69,13 +69,15 @@
 
     bool getClientsInfo(rfb::ListConnInfo* LCInfo);
 
+    bool setClientsStatus(rfb::ListConnInfo* LCInfo);
+
     // Where to read the configuration settings from
     static const TCHAR* RegConfigPath;
 
   protected:
 
     // Perform a particular internal function in the server thread
-    typedef enum {NoCommand, DisconnectClients, AddClient, QueryConnectionComplete, GetClientsInfo} Command;
+    typedef enum {NoCommand, DisconnectClients, AddClient, QueryConnectionComplete, SetClientsStatus, GetClientsInfo} Command;
     bool queueCommand(Command cmd, const void* data, int len);
     void doCommand();
     Command command;